@bitmagic/cli 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/cli.d.ts +11 -0
  2. package/dist/cli.js +4 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/build.d.ts +1 -0
  5. package/dist/commands/build.js +16 -0
  6. package/dist/commands/build.js.map +1 -0
  7. package/dist/commands/forge.d.ts +15 -3
  8. package/dist/commands/forge.js +38 -4
  9. package/dist/commands/forge.js.map +1 -1
  10. package/dist/commands/upgrade.d.ts +21 -0
  11. package/dist/commands/upgrade.js +161 -0
  12. package/dist/commands/upgrade.js.map +1 -0
  13. package/dist/commands/verify.js +8 -9
  14. package/dist/commands/verify.js.map +1 -1
  15. package/dist/forge/apply-modifications.js +7 -13
  16. package/dist/forge/apply-modifications.js.map +1 -1
  17. package/dist/publish/bundle.d.ts +31 -0
  18. package/dist/publish/bundle.js +77 -0
  19. package/dist/publish/bundle.js.map +1 -0
  20. package/dist/publish/fingerprint.d.ts +27 -0
  21. package/dist/publish/fingerprint.js +64 -0
  22. package/dist/publish/fingerprint.js.map +1 -0
  23. package/dist/scaffold/dependency-diff.d.ts +28 -0
  24. package/dist/scaffold/dependency-diff.js +28 -0
  25. package/dist/scaffold/dependency-diff.js.map +1 -0
  26. package/dist/scaffold/project-files.d.ts +22 -0
  27. package/dist/scaffold/project-files.js +66 -5
  28. package/dist/scaffold/project-files.js.map +1 -1
  29. package/dist/scaffold/project.d.ts +17 -0
  30. package/dist/scaffold/project.js +24 -4
  31. package/dist/scaffold/project.js.map +1 -1
  32. package/dist/scaffold/upgrade-project.d.ts +35 -0
  33. package/dist/scaffold/upgrade-project.js +63 -0
  34. package/dist/scaffold/upgrade-project.js.map +1 -0
  35. package/dist/verify/result.d.ts +60 -0
  36. package/dist/verify/result.js +74 -0
  37. package/dist/verify/result.js.map +1 -0
  38. package/package.json +1 -1
@@ -0,0 +1,77 @@
1
+ import { createHash } from 'crypto';
2
+ import { spawnSync } from 'child_process';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import { CliError } from '../errors.js';
6
+ import { projectBin } from '../project/context.js';
7
+ import { computeFingerprint } from './fingerprint.js';
8
+ /** The config the scaffold vendors alongside `engine/`. */
9
+ export const VITE_PUBLISH_CONFIG = 'vite.publish.config.js';
10
+ export function buildBundlePaths(root) {
11
+ const dir = path.join(root, '.bitmagic', 'build');
12
+ return { dir, htmlPath: path.join(dir, 'index.html'), manifestPath: path.join(dir, 'manifest.json') };
13
+ }
14
+ export function writeBuildManifest(root, manifest) {
15
+ const { dir, manifestPath } = buildBundlePaths(root);
16
+ fs.mkdirSync(dir, { recursive: true });
17
+ fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
18
+ }
19
+ function isManifest(value) {
20
+ if (typeof value !== 'object' || value === null)
21
+ return false;
22
+ const m = value;
23
+ return (typeof m.engineVersion === 'string'
24
+ && typeof m.fingerprint === 'string'
25
+ && typeof m.bytes === 'number'
26
+ && typeof m.sha256 === 'string'
27
+ && typeof m.builtAt === 'string');
28
+ }
29
+ /** The last build's manifest, or null if there is none to trust — same contract as readVerifyRecord. */
30
+ export function readBuildManifest(root) {
31
+ try {
32
+ const parsed = JSON.parse(fs.readFileSync(buildBundlePaths(root).manifestPath, 'utf-8'));
33
+ return isManifest(parsed) ? parsed : null;
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * Compile and bundle the project into one self-contained HTML, and record what was built.
41
+ *
42
+ * Exit code 1 on failure, matching the table in the spec: a build failure is the creator's own
43
+ * code, and the compiler's output has already been printed.
44
+ */
45
+ export function runBuild(root, engineVersion) {
46
+ const tsc = projectBin(root, 'tsc');
47
+ const compile = spawnSync(tsc, [], { cwd: root, stdio: 'inherit' });
48
+ if (compile.error)
49
+ throw new CliError(`Could not run the TypeScript compiler: ${compile.error.message}`, 1);
50
+ if (compile.status !== 0)
51
+ throw new CliError('Build failed: the project does not compile.', 1);
52
+ const { dir, htmlPath } = buildBundlePaths(root);
53
+ fs.mkdirSync(dir, { recursive: true });
54
+ const vite = projectBin(root, 'vite');
55
+ const bundle = spawnSync(vite, ['build', '--config', VITE_PUBLISH_CONFIG, '--outDir', dir, '--emptyOutDir'], {
56
+ cwd: root,
57
+ stdio: 'inherit',
58
+ });
59
+ if (bundle.error)
60
+ throw new CliError(`Could not run vite: ${bundle.error.message}`, 1);
61
+ if (bundle.status !== 0)
62
+ throw new CliError('Build failed: the bundle did not complete.', 1);
63
+ if (!fs.existsSync(htmlPath)) {
64
+ throw new CliError(`Build produced no ${path.relative(root, htmlPath)}. Check ${VITE_PUBLISH_CONFIG}.`, 1);
65
+ }
66
+ const contents = fs.readFileSync(htmlPath);
67
+ const manifest = {
68
+ engineVersion,
69
+ fingerprint: computeFingerprint(root),
70
+ bytes: contents.byteLength,
71
+ sha256: createHash('sha256').update(contents).digest('hex'),
72
+ builtAt: new Date().toISOString(),
73
+ };
74
+ writeBuildManifest(root, manifest);
75
+ return manifest;
76
+ }
77
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,2DAA2D;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAiB5D,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAClD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,CAAC;AACxG,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAAuB;IACtE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CACL,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ;WAChC,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ;WACjC,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;WAC3B,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;WAC5B,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CACjC,CAAC;AACJ,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAClG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,aAAqB;IAC1D,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,KAAK;QAAE,MAAM,IAAI,QAAQ,CAAC,0CAA0C,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5G,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,6CAA6C,EAAE,CAAC,CAAC,CAAC;IAE/F,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACjD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,CAAC,EAAE;QAC3G,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,KAAK;QAAE,MAAM,IAAI,QAAQ,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACvF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,4CAA4C,EAAE,CAAC,CAAC,CAAC;IAE7F,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC,qBAAqB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,mBAAmB,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7G,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAkB;QAC9B,aAAa;QACb,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC;QACrC,KAAK,EAAE,QAAQ,CAAC,UAAU;QAC1B,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC3D,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAClC,CAAC;IACF,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A relative path as the fingerprint hashes it: always forward-slashed.
3
+ *
4
+ * `sep` is a parameter rather than a direct `path.sep` read so this is testable on any
5
+ * platform — the Windows behaviour that makes normalization necessary cannot otherwise be
6
+ * exercised on the POSIX runners CI uses, which is exactly how a vacuous test gets written.
7
+ */
8
+ export declare function toPosixPath(relativePath: string, sep?: string): string;
9
+ /**
10
+ * A hash of everything that determines the published bundle.
11
+ *
12
+ * This is what lets `publish` decide whether a `verify` is too stale to trust, by CONTENT
13
+ * rather than by clock: a timestamp policy would accept an edit made one second after
14
+ * verifying and reject an untouched project that merely sat overnight.
15
+ *
16
+ * The path is hashed alongside the content so that moving a file — which changes what the
17
+ * bundle imports — changes the fingerprint even though no byte of any file did.
18
+ *
19
+ * Kept deliberately coarse (every tracked file, not a module graph): a false "stale" costs one
20
+ * `bitmagic verify`, while a false "fresh" ships an unverified bundle.
21
+ *
22
+ * Any filesystem error (unreadable directory, permission denied, etc.) propagates immediately
23
+ * rather than being silently omitted: the project source is the creator's own files, so an
24
+ * unreadable subtree is a real problem worth surfacing, not something to hide. An omitted
25
+ * directory would produce a fingerprint that matches a stale project — the costly failure mode.
26
+ */
27
+ export declare function computeFingerprint(root: string): string;
@@ -0,0 +1,64 @@
1
+ import { createHash } from 'crypto';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ /**
5
+ * Directories whose contents never change what the bundle contains: our own artifacts
6
+ * (`.bitmagic/`, `dist/`), the dependency tree (`node_modules/` — pinned by the lockfile the
7
+ * scaffold writes), and vite's cache. Including any of them would make the fingerprint change
8
+ * on every build, which would make the staleness gate reject every publish.
9
+ */
10
+ const EXCLUDED_DIRS = new Set(['.bitmagic', 'node_modules', 'dist', '.vite-cache']);
11
+ /**
12
+ * A relative path as the fingerprint hashes it: always forward-slashed.
13
+ *
14
+ * `sep` is a parameter rather than a direct `path.sep` read so this is testable on any
15
+ * platform — the Windows behaviour that makes normalization necessary cannot otherwise be
16
+ * exercised on the POSIX runners CI uses, which is exactly how a vacuous test gets written.
17
+ */
18
+ export function toPosixPath(relativePath, sep = path.sep) {
19
+ return relativePath.split(sep).join('/');
20
+ }
21
+ function walk(dir, root, out) {
22
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
23
+ for (const entry of entries) {
24
+ if (entry.isDirectory()) {
25
+ if (EXCLUDED_DIRS.has(entry.name))
26
+ continue;
27
+ walk(path.join(dir, entry.name), root, out);
28
+ }
29
+ else if (entry.isFile()) {
30
+ const relPath = path.relative(root, path.join(dir, entry.name));
31
+ out.push(toPosixPath(relPath));
32
+ }
33
+ }
34
+ }
35
+ /**
36
+ * A hash of everything that determines the published bundle.
37
+ *
38
+ * This is what lets `publish` decide whether a `verify` is too stale to trust, by CONTENT
39
+ * rather than by clock: a timestamp policy would accept an edit made one second after
40
+ * verifying and reject an untouched project that merely sat overnight.
41
+ *
42
+ * The path is hashed alongside the content so that moving a file — which changes what the
43
+ * bundle imports — changes the fingerprint even though no byte of any file did.
44
+ *
45
+ * Kept deliberately coarse (every tracked file, not a module graph): a false "stale" costs one
46
+ * `bitmagic verify`, while a false "fresh" ships an unverified bundle.
47
+ *
48
+ * Any filesystem error (unreadable directory, permission denied, etc.) propagates immediately
49
+ * rather than being silently omitted: the project source is the creator's own files, so an
50
+ * unreadable subtree is a real problem worth surfacing, not something to hide. An omitted
51
+ * directory would produce a fingerprint that matches a stale project — the costly failure mode.
52
+ */
53
+ export function computeFingerprint(root) {
54
+ const files = [];
55
+ walk(root, root, files);
56
+ files.sort();
57
+ const hash = createHash('sha256');
58
+ for (const rel of files) {
59
+ const content = fs.readFileSync(path.join(root, rel));
60
+ hash.update(`${rel}:${createHash('sha256').update(content).digest('hex')}\n`);
61
+ }
62
+ return hash.digest('hex');
63
+ }
64
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/publish/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAEpF;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,MAAc,IAAI,CAAC,GAAG;IACtE,OAAO,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,IAAY,EAAE,GAAa;IACpD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAChE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACxB,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** The subset of package.json this module reads — never the whole file. */
2
+ export interface PackageJsonDeps {
3
+ dependencies?: Record<string, string>;
4
+ devDependencies?: Record<string, string>;
5
+ }
6
+ export interface RequiredDependencies {
7
+ dependencies: Record<string, string>;
8
+ devDependencies: Record<string, string>;
9
+ }
10
+ export interface DependencyMismatch {
11
+ name: string;
12
+ kind: 'dependency' | 'devDependency';
13
+ required: string;
14
+ /** undefined when the package is missing from package.json entirely, not just outdated. */
15
+ current?: string;
16
+ }
17
+ /**
18
+ * Compares a project's declared dependencies against what the vendored engine actually needs
19
+ * (`DEPENDENCIES`/`DEV_DEPENDENCIES` in project-files.ts), and reports every mismatch — missing
20
+ * entirely, or present at a different version string.
21
+ *
22
+ * Pure and filesystem-free by design: `upgradeProject` never writes package.json (a creator's
23
+ * added dependencies must survive an upgrade untouched), so this is the other half of that
24
+ * decision — the mismatch it creates has to be *reported*, not silently left for `bitmagic build`
25
+ * to fail on later with an opaque module-resolution error. Kept separate from the command layer
26
+ * that reads package.json off disk so the comparison itself is testable without a fixture file.
27
+ */
28
+ export declare function diffDependencies(pkg: PackageJsonDeps, required: RequiredDependencies): DependencyMismatch[];
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Compares a project's declared dependencies against what the vendored engine actually needs
3
+ * (`DEPENDENCIES`/`DEV_DEPENDENCIES` in project-files.ts), and reports every mismatch — missing
4
+ * entirely, or present at a different version string.
5
+ *
6
+ * Pure and filesystem-free by design: `upgradeProject` never writes package.json (a creator's
7
+ * added dependencies must survive an upgrade untouched), so this is the other half of that
8
+ * decision — the mismatch it creates has to be *reported*, not silently left for `bitmagic build`
9
+ * to fail on later with an opaque module-resolution error. Kept separate from the command layer
10
+ * that reads package.json off disk so the comparison itself is testable without a fixture file.
11
+ */
12
+ export function diffDependencies(pkg, required) {
13
+ const mismatches = [];
14
+ for (const [name, version] of Object.entries(required.dependencies)) {
15
+ const current = pkg.dependencies?.[name];
16
+ if (current !== version) {
17
+ mismatches.push({ name, kind: 'dependency', required: version, current });
18
+ }
19
+ }
20
+ for (const [name, version] of Object.entries(required.devDependencies)) {
21
+ const current = pkg.devDependencies?.[name];
22
+ if (current !== version) {
23
+ mismatches.push({ name, kind: 'devDependency', required: version, current });
24
+ }
25
+ }
26
+ return mismatches;
27
+ }
28
+ //# sourceMappingURL=dependency-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-diff.js","sourceRoot":"","sources":["../../src/scaffold/dependency-diff.ts"],"names":[],"mappings":"AAmBA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAoB,EAAE,QAA8B;IACnF,MAAM,UAAU,GAAyB,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACpE,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACvE,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -1,7 +1,29 @@
1
+ /**
2
+ * Mirrors game/package.json so the pro lane resolves exactly what CI builds against.
3
+ *
4
+ * Exported so `bitmagic upgrade` can diff a project's actual package.json against what the
5
+ * vendored engine currently needs — package.json itself is never rewritten (see
6
+ * PLATFORM_GENERATED_FILES in project.ts), so this is the only source of truth upgrade has for
7
+ * telling a creator what to add by hand.
8
+ */
9
+ export declare const DEPENDENCIES: Record<string, string>;
10
+ export declare const DEV_DEPENDENCIES: Record<string, string>;
1
11
  export declare function renderPackageJson(name: string): string;
2
12
  export declare function renderTsconfig(): string;
3
13
  export declare function renderIndexHtml(): string;
4
14
  export declare function renderViteConfig(): string;
15
+ /**
16
+ * The production bundle config, vendored into the project next to `engine/`.
17
+ *
18
+ * One self-contained HTML: `viteSingleFile` with an effectively unlimited inline limit, so the
19
+ * engine and all JS/CSS land inside index.html. Game ASSETS are deliberately NOT inlined — they
20
+ * already live on the CDN with absolute URLs, and inlining them is what produced multi-hundred-MB
21
+ * bundles and OOM-killed the web publish pod.
22
+ *
23
+ * Vendored rather than generated per-build so a creator can read exactly what ships, and so it
24
+ * versions with the engine it was written for.
25
+ */
26
+ export declare function renderVitePublishConfig(): string;
5
27
  export declare function renderGitignore(): string;
6
28
  export interface ProjectMetadata {
7
29
  gameId: string;
@@ -1,6 +1,13 @@
1
1
  import { tsconfigPaths, importMapEntries, viteAliasEntries } from './aliases.js';
2
- /** Mirrors game/package.json so the pro lane resolves exactly what CI builds against. */
3
- const DEPENDENCIES = {
2
+ /**
3
+ * Mirrors game/package.json so the pro lane resolves exactly what CI builds against.
4
+ *
5
+ * Exported so `bitmagic upgrade` can diff a project's actual package.json against what the
6
+ * vendored engine currently needs — package.json itself is never rewritten (see
7
+ * PLATFORM_GENERATED_FILES in project.ts), so this is the only source of truth upgrade has for
8
+ * telling a creator what to add by hand.
9
+ */
10
+ export const DEPENDENCIES = {
4
11
  '@dimforge/rapier2d-compat': '^0.19.3',
5
12
  '@dimforge/rapier3d-compat': '^0.19.3',
6
13
  '@msgpack/msgpack': '^3.1.3',
@@ -10,7 +17,7 @@ const DEPENDENCIES = {
10
17
  jszip: '^3.10.1',
11
18
  three: '^0.185.1',
12
19
  };
13
- const DEV_DEPENDENCIES = {
20
+ export const DEV_DEPENDENCIES = {
14
21
  '@types/node': '^24.10.0',
15
22
  '@types/three': '^0.185.4',
16
23
  // engine/types/ammo.d.ts opens with a triple-slash reference to this package's ambient types.
@@ -20,6 +27,7 @@ const DEV_DEPENDENCIES = {
20
27
  '@webgpu/types': '^0.1.69',
21
28
  typescript: '^5.9.2',
22
29
  vite: '^7.3.1',
30
+ 'vite-plugin-singlefile': '^2.3.3',
23
31
  };
24
32
  /**
25
33
  * The three.js release every `three*` import map entry below resolves to. Written once because
@@ -185,10 +193,19 @@ ${JSON.stringify({ imports }, null, 8).replace(/^/gm, ' ')}
185
193
  </html>
186
194
  `;
187
195
  }
188
- export function renderViteConfig() {
189
- const entries = Object.entries(viteAliasEntries())
196
+ /**
197
+ * The `resolve.alias` body shared by both vendored vite configs (this one and the publish
198
+ * config below): one `'key': 'target'` line per alias, comma-joined, indented to sit inside a
199
+ * template literal's `alias: { ... }` block. Kept in one place so the two configs' aliases
200
+ * cannot drift into two different renderings of the same `viteAliasEntries()` data.
201
+ */
202
+ function renderAliasEntries() {
203
+ return Object.entries(viteAliasEntries())
190
204
  .map(([key, target]) => ` '${key}': '${target}'`)
191
205
  .join(',\n');
206
+ }
207
+ export function renderViteConfig() {
208
+ const entries = renderAliasEntries();
192
209
  return `import { defineConfig } from 'vite';
193
210
 
194
211
  // Aliases mirror tsconfig paths but point at the COMPILED output: tsc emits to dist/ and the
@@ -209,6 +226,50 @@ ${entries}
209
226
  });
210
227
  `;
211
228
  }
229
+ /**
230
+ * The production bundle config, vendored into the project next to `engine/`.
231
+ *
232
+ * One self-contained HTML: `viteSingleFile` with an effectively unlimited inline limit, so the
233
+ * engine and all JS/CSS land inside index.html. Game ASSETS are deliberately NOT inlined — they
234
+ * already live on the CDN with absolute URLs, and inlining them is what produced multi-hundred-MB
235
+ * bundles and OOM-killed the web publish pod.
236
+ *
237
+ * Vendored rather than generated per-build so a creator can read exactly what ships, and so it
238
+ * versions with the engine it was written for.
239
+ */
240
+ export function renderVitePublishConfig() {
241
+ const entries = renderAliasEntries();
242
+ return `import { defineConfig } from 'vite';
243
+ import { viteSingleFile } from 'vite-plugin-singlefile';
244
+
245
+ // Aliases mirror vite.config.js's, deliberately NOT wrapped in path.resolve(): every target here
246
+ // already starts with '/', which Vite resolves as project-root-relative in both serve and build
247
+ // mode. A path.resolve(__dirname, target) wrapper looks more "correct" but is actively wrong —
248
+ // Node's path.resolve() drops the trailing slash from an already-absolute second argument, and
249
+ // Vite's directory-style alias substitution needs that slash to join the replacement with the
250
+ // rest of the specifier. Strip it and 'engine/GameTemplate.js' resolves to the nonexistent
251
+ // 'dist/engine/engineGameTemplate.js' instead of 'dist/engine/engine/GameTemplate.js' — silently,
252
+ // since Rollup then just treats the unmatched id as an unresolved bare specifier and fails the
253
+ // build. Verified against a real \`vite build\` before trusting the plain-string form.
254
+ export default defineConfig({
255
+ resolve: {
256
+ alias: {
257
+ ${entries}
258
+ }
259
+ },
260
+ build: {
261
+ // Effectively unlimited: everything the bundle references locally is inlined so the
262
+ // published artifact is a single file. CDN assets are absolute URLs and are untouched.
263
+ assetsInlineLimit: 100000000,
264
+ cssCodeSplit: false,
265
+ rollupOptions: {
266
+ output: { inlineDynamicImports: true },
267
+ },
268
+ },
269
+ plugins: [viteSingleFile()],
270
+ });
271
+ `;
272
+ }
212
273
  export function renderGitignore() {
213
274
  return ['dist/', 'node_modules/', '.bitmagic/', '.vite-cache/', ''].join('\n');
214
275
  }
@@ -1 +1 @@
1
- {"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,2BAA2B,EAAE,SAAS;IACtC,2BAA2B,EAAE,SAAS;IACtC,kBAAkB,EAAE,QAAQ;IAC5B,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,kCAAkC,EAAE,QAAQ;IAC5C,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,UAAU;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,aAAa,EAAE,UAAU;IACzB,cAAc,EAAE,UAAU;IAC1B,8FAA8F;IAC9F,cAAc,EAAE,QAAQ;IACxB,4FAA4F;IAC5F,mFAAmF;IACnF,eAAe,EAAE,SAAS;IAC1B,UAAU,EAAE,QAAQ;IACpB,IAAI,EAAE,QAAQ;IACd,wBAAwB,EAAE,QAAQ;CACnC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG;IACjB,uBAAuB;IACvB,oCAAoC,aAAa,WAAW;IAC5D,kDAAkD,aAAa,2CAA2C;IAC1G,8CAA8C,aAAa,uCAAuC;IAClG,gDAAgD,aAAa,wCAAwC;CACtG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEX,oGAAoG;AACpG,MAAM,WAAW,GAA2B;IAC1C,2FAA2F;IAC3F,4FAA4F;IAC5F,4FAA4F;IAC5F,KAAK,EAAE,UAAU;IACjB,cAAc,EAAE,wBAAwB,aAAa,SAAS;IAC9D,WAAW,EAAE,wBAAwB,aAAa,MAAM;IACxD,2FAA2F;IAC3F,6FAA6F;IAC7F,+FAA+F;IAC/F,4FAA4F;IAC5F,6FAA6F;IAC7F,6FAA6F;IAC7F,eAAe,EAAE,yBAAyB,aAAa,UAAU;IACjE,qBAAqB,EAAE,yBAAyB,aAAa,gBAAgB;IAC7E,QAAQ,EAAE,wBAAwB,aAAa,GAAG;IAClD,2BAA2B,EAAE,iDAAiD;IAC9E,2BAA2B,EAAE,iDAAiD;IAC9E,OAAO,EAAE,+BAA+B;IACxC,kCAAkC,EAAE,uDAAuD;IAC3F,kBAAkB,EAAE,uCAAuC;IAC3D,MAAM,EAAE,6BAA6B;CACtC,CAAC;AAEF,sFAAsF;AACtF,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,UAAU,CAAC;QAChB,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,cAAc;YACrB,GAAG,EAAE,MAAM;SACZ;QACD,YAAY,EAAE,YAAY;QAC1B,eAAe,EAAE,gBAAgB;KAClC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC;QAChB,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;YACtB,OAAO,EAAE,GAAG;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG;YACZ,KAAK,EAAE,aAAa,EAAE;YACtB,gBAAgB,EAAE,SAAS;YAC3B,MAAM,EAAE,IAAI;YACZ,wBAAwB,EAAE,IAAI;YAC9B,0BAA0B,EAAE,KAAK;YACjC,oBAAoB,EAAE,IAAI;YAC1B,eAAe,EAAE,IAAI;YACrB,eAAe,EAAE,OAAO;YACxB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,IAAI;YACrB,4BAA4B,EAAE,IAAI;YAClC,gCAAgC,EAAE,IAAI;YACtC,aAAa,EAAE,IAAI;YACnB,iBAAiB,EAAE,IAAI;YACvB,SAAS,EAAE,IAAI;YACf,wFAAwF;YACxF,yFAAyF;YACzF,wFAAwF;YACxF,0FAA0F;YAC1F,sFAAsF;YACtF,yFAAyF;YACzF,gFAAgF;YAChF,KAAK,EAAE,CAAC,eAAe,CAAC;YACxB,SAAS,EAAE,CAAC,cAAc,EAAE,qBAAqB,EAAE,wCAAwC,CAAC;SAC7F;QACD,OAAO,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC;QACpC,uFAAuF;QACvF,uFAAuF;QACvF,oFAAoF;QACpF,wFAAwF;QACxF,wDAAwD;QACxD,OAAO,EAAE;YACP,cAAc;YACd,MAAM;YACN,qBAAqB;YACrB,0BAA0B;YAC1B,kBAAkB;YAClB,uBAAuB;YACvB,oBAAoB;SACrB;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,GAAG,WAAW,EAAE,GAAG,YAAY,EAAE,CAAC;IACpD,6FAA6F;IAC7F,yFAAyF;IACzF,MAAM,gBAAgB,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,iBAAiB,CAAC;IACrE,0FAA0F;IAC1F,0FAA0F;IAC1F,wFAAwF;IACxF,2FAA2F;IAC3F,mDAAmD;IACnD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BP,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;;;iCAG5B,gBAAgB;;;CAGhD,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB;IACzB,OAAO,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,UAAU,GAAG,OAAO,MAAM,GAAG,CAAC;SACrD,IAAI,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,OAAO;;;;;;;;;;;EAWP,OAAO;;;;;;;CAOR,CAAC;AACF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,OAAO;;;;;;;;;;;;;;;EAeP,OAAO;;;;;;;;;;;;;;CAcR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjF,CAAC;AASD,MAAM,UAAU,kBAAkB,CAAC,QAAyB;IAC1D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiHR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;CAIR,CAAC;AACF,CAAC"}
@@ -15,6 +15,23 @@ export interface TemplateEntry {
15
15
  * parallel copy that silently goes stale when an entry is added here.
16
16
  */
17
17
  export declare const VENDORED_DIRS: string[];
18
+ /**
19
+ * The subset of the generated files that are pure platform output: regenerated byte-for-byte
20
+ * from these renderers with no creator content ever entering them. `bitmagic upgrade` overwrites
21
+ * exactly this list (plus bitmagic.json, handled separately since only its engineVersion field is
22
+ * platform-owned, and engine/ + sw-cache-buster.js, handled separately since they are copied, not
23
+ * rendered).
24
+ *
25
+ * Deliberately excludes package.json (creators add dependencies to it), AGENTS.md/CLAUDE.md (the
26
+ * creator's own agent reads and may edit them), and .gitignore (same reasoning) — those are
27
+ * generated once by `scaffoldProject` but are creator-owned from that point on.
28
+ *
29
+ * Exported so `scaffoldProject` and `upgradeProject` share one definition instead of two lists
30
+ * that can drift — the exact failure that motivated this: `vite.publish.config.js` was added
31
+ * to init's inline list with no equivalent path for existing projects to ever receive it, because
32
+ * `upgrade` didn't exist yet.
33
+ */
34
+ export declare const PLATFORM_GENERATED_FILES: Array<[string, () => string]>;
18
35
  export declare function resolveTemplate(templatesDir: string, requestedId?: string): TemplateEntry;
19
36
  export interface ScaffoldOptions {
20
37
  targetDir: string;
@@ -2,7 +2,7 @@ import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { CliError } from '../errors.js';
4
4
  import { aliasSourceDir } from './aliases.js';
5
- import { renderPackageJson, renderTsconfig, renderIndexHtml, renderViteConfig, renderGitignore, renderBitmagicJson, renderAgentsMd, renderClaudeMd, renderSkillsReadme, renderGenerateSkill, } from './project-files.js';
5
+ import { renderPackageJson, renderTsconfig, renderIndexHtml, renderViteConfig, renderVitePublishConfig, renderGitignore, renderBitmagicJson, renderAgentsMd, renderClaudeMd, renderSkillsReadme, renderGenerateSkill, } from './project-files.js';
6
6
  /**
7
7
  * Directories moved out of the extracted tree into the project's vendored engine/.
8
8
  *
@@ -24,6 +24,28 @@ export const VENDORED_DIRS = [
24
24
  'utils',
25
25
  'core',
26
26
  ];
27
+ /**
28
+ * The subset of the generated files that are pure platform output: regenerated byte-for-byte
29
+ * from these renderers with no creator content ever entering them. `bitmagic upgrade` overwrites
30
+ * exactly this list (plus bitmagic.json, handled separately since only its engineVersion field is
31
+ * platform-owned, and engine/ + sw-cache-buster.js, handled separately since they are copied, not
32
+ * rendered).
33
+ *
34
+ * Deliberately excludes package.json (creators add dependencies to it), AGENTS.md/CLAUDE.md (the
35
+ * creator's own agent reads and may edit them), and .gitignore (same reasoning) — those are
36
+ * generated once by `scaffoldProject` but are creator-owned from that point on.
37
+ *
38
+ * Exported so `scaffoldProject` and `upgradeProject` share one definition instead of two lists
39
+ * that can drift — the exact failure that motivated this: `vite.publish.config.js` was added
40
+ * to init's inline list with no equivalent path for existing projects to ever receive it, because
41
+ * `upgrade` didn't exist yet.
42
+ */
43
+ export const PLATFORM_GENERATED_FILES = [
44
+ ['tsconfig.json', renderTsconfig],
45
+ ['vite.config.js', renderViteConfig],
46
+ ['vite.publish.config.js', renderVitePublishConfig],
47
+ ['index.html', renderIndexHtml],
48
+ ];
27
49
  export function resolveTemplate(templatesDir, requestedId) {
28
50
  const indexPath = path.join(templatesDir, 'index.json');
29
51
  let raw;
@@ -98,9 +120,7 @@ export function scaffoldProject(options) {
98
120
  }
99
121
  const files = [
100
122
  ['package.json', renderPackageJson(projectName)],
101
- ['tsconfig.json', renderTsconfig()],
102
- ['vite.config.js', renderViteConfig()],
103
- ['index.html', renderIndexHtml()],
123
+ ...PLATFORM_GENERATED_FILES.map((entry) => [entry[0], entry[1]()]),
104
124
  ['bitmagic.json', renderBitmagicJson(metadata)],
105
125
  ['AGENTS.md', renderAgentsMd()],
106
126
  ['CLAUDE.md', renderClaudeMd()],
@@ -1 +1 @@
1
- {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/scaffold/project.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/scaffold/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface UpgradeOptions {
2
+ root: string;
3
+ /** Where extractEngine unpacked the new engine tree, same shape scaffoldProject reads from. */
4
+ extractedEngineDir: string;
5
+ /** The engine version being upgraded to, written into bitmagic.json's engineVersion field. */
6
+ engineVersion: string;
7
+ }
8
+ export interface UpgradeResult {
9
+ engineVersion: string;
10
+ previousEngineVersion: string;
11
+ /** Every top-level path this run actually rewrote, in the order it rewrote them. */
12
+ replaced: string[];
13
+ }
14
+ /**
15
+ * Refreshes the platform-owned parts of a scaffolded project in place, and nothing else. This is
16
+ * the file-boundary described in the task brief: `engine/` (every VENDORED_DIRS entry) and
17
+ * sw-cache-buster.js are wholesale-replaced, the config files in PLATFORM_GENERATED_FILES are
18
+ * re-rendered, and bitmagic.json is read-modified-written so only its engineVersion field
19
+ * changes. Everything else on disk — src/, world.json, game.json, package.json, AGENTS.md,
20
+ * CLAUDE.md, .claude/, .gitignore — is never opened.
21
+ *
22
+ * Mirrors scaffoldProject's copy behaviour (same VENDORED_DIRS loop, same corrupt-tarball error
23
+ * when a directory is missing from the extracted tree), except it clears engine/ first: unlike a
24
+ * brand new project's empty target, an existing engine/ may hold files a since-removed
25
+ * VENDORED_DIRS entry left behind, or a leftover from a bad manual edit, and cpSync alone would
26
+ * merge over those rather than remove them.
27
+ *
28
+ * That "clear first" step is exactly why every VENDORED_DIRS source is validated to exist
29
+ * *before* engine/ is touched at all, in its own pass below: scaffoldProject can afford to check
30
+ * existence inside its copy loop because its target starts empty, so a missing source just leaves
31
+ * a partially-populated (but otherwise harmless) new directory. Here the target is a live
32
+ * project's engine/, already rm'd — the same ordering would demolish it and fail partway through
33
+ * repopulating it, and a project not under version control has no way to recover that.
34
+ */
35
+ export declare function upgradeProject(options: UpgradeOptions): UpgradeResult;
@@ -0,0 +1,63 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { CliError } from '../errors.js';
4
+ import { VENDORED_DIRS, PLATFORM_GENERATED_FILES } from './project.js';
5
+ /**
6
+ * Refreshes the platform-owned parts of a scaffolded project in place, and nothing else. This is
7
+ * the file-boundary described in the task brief: `engine/` (every VENDORED_DIRS entry) and
8
+ * sw-cache-buster.js are wholesale-replaced, the config files in PLATFORM_GENERATED_FILES are
9
+ * re-rendered, and bitmagic.json is read-modified-written so only its engineVersion field
10
+ * changes. Everything else on disk — src/, world.json, game.json, package.json, AGENTS.md,
11
+ * CLAUDE.md, .claude/, .gitignore — is never opened.
12
+ *
13
+ * Mirrors scaffoldProject's copy behaviour (same VENDORED_DIRS loop, same corrupt-tarball error
14
+ * when a directory is missing from the extracted tree), except it clears engine/ first: unlike a
15
+ * brand new project's empty target, an existing engine/ may hold files a since-removed
16
+ * VENDORED_DIRS entry left behind, or a leftover from a bad manual edit, and cpSync alone would
17
+ * merge over those rather than remove them.
18
+ *
19
+ * That "clear first" step is exactly why every VENDORED_DIRS source is validated to exist
20
+ * *before* engine/ is touched at all, in its own pass below: scaffoldProject can afford to check
21
+ * existence inside its copy loop because its target starts empty, so a missing source just leaves
22
+ * a partially-populated (but otherwise harmless) new directory. Here the target is a live
23
+ * project's engine/, already rm'd — the same ordering would demolish it and fail partway through
24
+ * repopulating it, and a project not under version control has no way to recover that.
25
+ */
26
+ export function upgradeProject(options) {
27
+ const { root, extractedEngineDir, engineVersion } = options;
28
+ const replaced = [];
29
+ for (const dir of VENDORED_DIRS) {
30
+ const source = path.join(extractedEngineDir, dir);
31
+ if (!fs.existsSync(source)) {
32
+ throw new CliError(`The engine bundle has no "${dir}" directory at ${source}. The tarball is incomplete or corrupt.`);
33
+ }
34
+ }
35
+ const engineDir = path.join(root, 'engine');
36
+ fs.rmSync(engineDir, { recursive: true, force: true });
37
+ fs.mkdirSync(engineDir, { recursive: true });
38
+ for (const dir of VENDORED_DIRS) {
39
+ fs.cpSync(path.join(extractedEngineDir, dir), path.join(engineDir, dir), { recursive: true });
40
+ }
41
+ replaced.push('engine/');
42
+ // Same "missing is not corrupt" allowance as scaffoldProject: a tarball published before this
43
+ // feature shipped simply won't have it, and upgrade must not fail a project onto that tarball.
44
+ const serviceWorker = path.join(extractedEngineDir, 'sw-cache-buster.js');
45
+ if (fs.existsSync(serviceWorker)) {
46
+ fs.cpSync(serviceWorker, path.join(root, 'sw-cache-buster.js'));
47
+ replaced.push('sw-cache-buster.js');
48
+ }
49
+ for (const [name, render] of PLATFORM_GENERATED_FILES) {
50
+ fs.writeFileSync(path.join(root, name), render());
51
+ replaced.push(name);
52
+ }
53
+ // Read-modify-write, not re-rendered from renderBitmagicJson: re-rendering would discard any
54
+ // field a later CLI/engine version adds to the metadata that this version doesn't know about.
55
+ const bitmagicJsonPath = path.join(root, 'bitmagic.json');
56
+ const meta = JSON.parse(fs.readFileSync(bitmagicJsonPath, 'utf-8'));
57
+ const previousEngineVersion = typeof meta.engineVersion === 'string' ? meta.engineVersion : '';
58
+ meta.engineVersion = engineVersion;
59
+ fs.writeFileSync(bitmagicJsonPath, `${JSON.stringify(meta, null, 2)}\n`);
60
+ replaced.push('bitmagic.json');
61
+ return { engineVersion, previousEngineVersion, replaced };
62
+ }
63
+ //# sourceMappingURL=upgrade-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-project.js","sourceRoot":"","sources":["../../src/scaffold/upgrade-project.ts"],"names":[],"mappings":"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"}