diff --git a/docs/dependency-policy.md b/docs/dependency-policy.md index c2edafc..c6c4514 100644 --- a/docs/dependency-policy.md +++ b/docs/dependency-policy.md @@ -27,3 +27,13 @@ After a generated repository adds `package.json`, extend `.github/dependabot.yml Run the project's smallest relevant verification before merging dependency updates. For Node projects, that usually means lint, tests, typecheck, and build when those scripts exist. + +## Refreshing the Next.js template lockfile + +The `next-app` template keeps its generated npm lockfile in +`templates/next-app/package-lock.json`. Refresh a transitive package with +`npm update --package-lock-only --ignore-scripts` inside a freshly +generated `next-app`, then copy the resulting lockfile back into the template. +Run `pnpm test` to check the repository's deterministic lockfile invariants and +`pnpm run release:check` to exercise the generated app's clean install, lint, +production build, audit, and validation gates. diff --git a/scripts/check-template-registry.mjs b/scripts/check-template-registry.mjs index 97d4cbb..8f40ccd 100644 --- a/scripts/check-template-registry.mjs +++ b/scripts/check-template-registry.mjs @@ -1,5 +1,6 @@ #!/usr/bin/env node import { execFileSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; import { listTemplates, TEMPLATE_KEYS, TEMPLATE_REGISTRY } from '../dist/templates.js'; const expectedKeys = ['next-app', 'oss-cli', 'python-api']; @@ -36,4 +37,20 @@ if (JSON.stringify(parsed.templates) !== JSON.stringify(templates)) { throw new Error('CLI templates output does not match typed registry'); } +const nextAppLock = JSON.parse(readFileSync(new URL('../templates/next-app/package-lock.json', import.meta.url), 'utf8')); +const nanoid = nextAppLock.packages?.['node_modules/nanoid']; +if (!nanoid?.version) { + throw new Error('Next.js template lockfile is missing nanoid'); +} + +const minimumNanoidVersion = [3, 3, 17]; +const nanoidVersion = nanoid.version.split('.').map(Number); +const firstDifference = nanoidVersion.findIndex((part, index) => part !== minimumNanoidVersion[index]); +const nanoidIsSupported = nanoidVersion.length === 3 + && nanoidVersion.every(Number.isInteger) + && (firstDifference === -1 || nanoidVersion[firstDifference] > minimumNanoidVersion[firstDifference]); +if (!nanoidIsSupported) { + throw new Error(`Next.js template requires nanoid >=3.3.17, got ${nanoid.version}`); +} + console.log('template registry check passed'); diff --git a/templates/next-app/package-lock.json b/templates/next-app/package-lock.json index 3cb7c8c..b0b64cb 100644 --- a/templates/next-app/package-lock.json +++ b/templates/next-app/package-lock.json @@ -1,11 +1,11 @@ { - "name": "{{PACKAGE_NAME}}", + "name": "web-app", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "{{PACKAGE_NAME}}", + "name": "web-app", "version": "0.1.0", "dependencies": { "next": "16.2.12", @@ -4582,9 +4582,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "funding": [ { "type": "github",