.agents/skills/migrate-internal-package/references/legacy-integration.md
Read this reference when the imported package is JavaScript or CommonJS. The import PR establishes ownership and a green workspace package; it does not modernize the implementation.
Change only what Ghost needs to consume and verify the package:
"private": true and the internal placeholder version;ghostPackage.goldenPath to migration and describe the remaining
modernization work in ghostPackage.reason;workspace:*;Do not rename source files, change module format, introduce TypeScript, redesign
exports or clean up implementation details. Use the
convert-internal-package-to-typescript skill for that later work.
Use the shared Node library factory in CommonJS mode and declare
@internal/cfg-eslint plus eslint as package dev dependencies:
import {nodeLibConfig} from '@internal/cfg-eslint';
export default nodeLibConfig({
typescript: false,
commonjs: true,
legacyLocalFilenames: true,
srcGlobs: ['index.js', 'lib/**/*.js'],
testGlobs: ['test/**/*.js']
});
Prefer fixing trivial configuration drift. When a Ghost rule conflicts with a
test that intentionally exercises legacy behavior, use a narrow, documented
extraTestRules exception instead of changing runtime semantics. Rules must be
'error' or 'off', never warnings.
The shared default targets TypeScript, so override its globs for JavaScript. Preserve the source repository's coverage thresholds where practical:
import {createVitestConfig} from '@internal/cfg-vitest';
export default createVitestConfig({
test: {
globals: true,
include: ['test/**/*.test.js'],
coverage: {
include: ['lib/**/*.js'],
thresholds: {
lines: 90,
functions: 90,
branches: 80,
statements: 90
}
}
}
});
Declare @internal/cfg-vitest, @vitest/coverage-v8 and vitest in the
package's dev dependencies. Match the actual source and test layout rather than
copying these example globs blindly.
Source workspace:* ranges cannot be copied blindly when their packages are
not also Ghost workspaces. For each dependency:
workspace:* for an existing Ghost package.catalog:<name>; never inline the version.Record temporary named-catalog entries in the PR and reassess them during modernization.
Run the package through its Nx surface and exercise a real consumer:
pnpm nx run @tryghost/<package>:lint
pnpm nx run @tryghost/<package>:test
pnpm build
Also verify:
require() or import;pnpm archive succeeds from ghost/core;Generated archives are verification artifacts, not files to commit.