@bitmagic/cli 0.1.7 → 0.1.9
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.
- package/README.md +140 -0
- package/dist/auth/session.js +1 -1
- package/dist/auth/session.js.map +1 -1
- package/dist/cli.d.ts +29 -0
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/build.d.ts +1 -0
- package/dist/commands/build.js +16 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/publish.d.ts +44 -0
- package/dist/commands/publish.js +202 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/upgrade.d.ts +36 -0
- package/dist/commands/upgrade.js +170 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/verify.js +8 -9
- package/dist/commands/verify.js.map +1 -1
- package/dist/forge/apply-modifications.js +7 -13
- package/dist/forge/apply-modifications.js.map +1 -1
- package/dist/project/context.js +6 -1
- package/dist/project/context.js.map +1 -1
- package/dist/project/package-manager.d.ts +17 -0
- package/dist/project/package-manager.js +48 -0
- package/dist/project/package-manager.js.map +1 -0
- package/dist/publish/bundle.d.ts +37 -0
- package/dist/publish/bundle.js +88 -0
- package/dist/publish/bundle.js.map +1 -0
- package/dist/publish/client.d.ts +94 -0
- package/dist/publish/client.js +150 -0
- package/dist/publish/client.js.map +1 -0
- package/dist/publish/fingerprint.d.ts +27 -0
- package/dist/publish/fingerprint.js +84 -0
- package/dist/publish/fingerprint.js.map +1 -0
- package/dist/publish/meta-block.d.ts +26 -0
- package/dist/publish/meta-block.js +48 -0
- package/dist/publish/meta-block.js.map +1 -0
- package/dist/scaffold/dependency-diff.d.ts +28 -0
- package/dist/scaffold/dependency-diff.js +28 -0
- package/dist/scaffold/dependency-diff.js.map +1 -0
- package/dist/scaffold/project-files.d.ts +22 -0
- package/dist/scaffold/project-files.js +114 -5
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.d.ts +17 -0
- package/dist/scaffold/project.js +24 -4
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/upgrade-project.d.ts +35 -0
- package/dist/scaffold/upgrade-project.js +63 -0
- package/dist/scaffold/upgrade-project.js.map +1 -0
- package/dist/verify/result.d.ts +60 -0
- package/dist/verify/result.js +74 -0
- package/dist/verify/result.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { spawnSync } from 'child_process';
|
|
6
|
+
import { CliError } from '../errors.js';
|
|
7
|
+
import { resolveEnvironment, resolveAuth0ClientId } from '../config/environments.js';
|
|
8
|
+
import { readDefaultEnvironment } from '../config/credentials.js';
|
|
9
|
+
import { getAccessToken } from '../auth/session.js';
|
|
10
|
+
import { fetchEngineManifest, downloadAndVerify, extractEngine } from '../scaffold/engine-download.js';
|
|
11
|
+
import { upgradeProject } from '../scaffold/upgrade-project.js';
|
|
12
|
+
import { diffDependencies } from '../scaffold/dependency-diff.js';
|
|
13
|
+
import { DEPENDENCIES, DEV_DEPENDENCIES } from '../scaffold/project-files.js';
|
|
14
|
+
import { loadProjectContext } from '../project/context.js';
|
|
15
|
+
import { addCommand, detectPackageManager } from '../project/package-manager.js';
|
|
16
|
+
const deps = {
|
|
17
|
+
fetch: globalThis.fetch,
|
|
18
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* The boundary that makes `upgrade` safe to run at all: the whole value of the command is that a
|
|
22
|
+
* creator can read what it changed as a git diff. Overwriting vendored files on top of already
|
|
23
|
+
* -uncommitted work mixes the two together and makes that diff unreadable, so a dirty tree is
|
|
24
|
+
* refused unless the creator opts in with --force. Kept as a pure function, separate from the
|
|
25
|
+
* git call that produces `status`, so it is reachable from a test with no real repo involved.
|
|
26
|
+
*/
|
|
27
|
+
export function assertCleanTree(status, force) {
|
|
28
|
+
if (status.dirty && !force) {
|
|
29
|
+
throw new CliError('The working tree has uncommitted changes. Commit or stash them first so the upgrade shows ' +
|
|
30
|
+
'up as its own reviewable diff, or pass --force to upgrade anyway.');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* When the project isn't a git repository (or git itself isn't installed), there is no diff to
|
|
35
|
+
* protect in the first place — treated as clean rather than blocked, so `upgrade` still works for
|
|
36
|
+
* a project a creator hasn't put under version control.
|
|
37
|
+
*
|
|
38
|
+
* Scoped to `root` with `-- .`: plain `git status --porcelain` reports the whole repository from
|
|
39
|
+
* any subdirectory, which would block a creator keeping several games in one repo over dirt in a
|
|
40
|
+
* sibling project that `upgrade` never touches.
|
|
41
|
+
*/
|
|
42
|
+
function getGitStatus(root) {
|
|
43
|
+
const result = spawnSync('git', ['status', '--porcelain', '--', '.'], { cwd: root, encoding: 'utf-8' });
|
|
44
|
+
if (result.error || result.status !== 0) {
|
|
45
|
+
return { dirty: false };
|
|
46
|
+
}
|
|
47
|
+
return { dirty: result.stdout.trim().length > 0 };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Reads just the two dependency maps out of package.json, tolerating anything else about the
|
|
51
|
+
* file being absent or malformed — this check is advisory (upgradeProject has already succeeded
|
|
52
|
+
* by the time it runs), so a bad package.json here must not turn into a hard failure.
|
|
53
|
+
*/
|
|
54
|
+
function readPackageJsonDeps(root) {
|
|
55
|
+
let raw;
|
|
56
|
+
try {
|
|
57
|
+
raw = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
if (typeof raw !== 'object' || raw === null)
|
|
63
|
+
return {};
|
|
64
|
+
const obj = raw;
|
|
65
|
+
return {
|
|
66
|
+
dependencies: isStringRecord(obj.dependencies) ? obj.dependencies : undefined,
|
|
67
|
+
devDependencies: isStringRecord(obj.devDependencies) ? obj.devDependencies : undefined,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function isStringRecord(value) {
|
|
71
|
+
return (typeof value === 'object' &&
|
|
72
|
+
value !== null &&
|
|
73
|
+
!Array.isArray(value) &&
|
|
74
|
+
Object.values(value).every((entry) => typeof entry === 'string'));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The other half of "package.json is never rewritten": upgradeProject leaves it untouched even
|
|
78
|
+
* when the vendored engine now needs a dependency it doesn't have (e.g. vite-plugin-singlefile,
|
|
79
|
+
* which every pre-Task-3 project's package.json predates) — silently doing nothing here would
|
|
80
|
+
* mean `upgrade` reports success while `bitmagic build` still fails later with an opaque
|
|
81
|
+
* module-resolution error. Prints the exact install command instead; never writes the file.
|
|
82
|
+
*
|
|
83
|
+
* The command names the project's OWN package manager (`detectPackageManager`), not a hardcoded
|
|
84
|
+
* npm: a creator on pnpm who runs the printed `npm install` gets a tree npm linked and a second,
|
|
85
|
+
* far less obvious failure on the next build.
|
|
86
|
+
*
|
|
87
|
+
* Exported for its test — the detection helpers can be unit-tested on their own, but only
|
|
88
|
+
* calling this proves the printed line actually uses them.
|
|
89
|
+
*/
|
|
90
|
+
export function printDependencyReport(root) {
|
|
91
|
+
const mismatches = diffDependencies(readPackageJsonDeps(root), {
|
|
92
|
+
dependencies: DEPENDENCIES,
|
|
93
|
+
devDependencies: DEV_DEPENDENCIES,
|
|
94
|
+
});
|
|
95
|
+
if (mismatches.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
console.log('');
|
|
98
|
+
console.log("package.json is not touched by upgrade, and it is missing or outdated on dependencies the " +
|
|
99
|
+
'vendored engine now needs. Run:');
|
|
100
|
+
const manager = detectPackageManager(root);
|
|
101
|
+
const deps = mismatches.filter((m) => m.kind === 'dependency');
|
|
102
|
+
const devDeps = mismatches.filter((m) => m.kind === 'devDependency');
|
|
103
|
+
if (deps.length > 0) {
|
|
104
|
+
console.log(` ${addCommand(manager, false, deps.map((m) => `${m.name}@${m.required}`))}`);
|
|
105
|
+
}
|
|
106
|
+
if (devDeps.length > 0) {
|
|
107
|
+
console.log(` ${addCommand(manager, true, devDeps.map((m) => `${m.name}@${m.required}`))}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export const upgradeCommand = defineCommand({
|
|
111
|
+
meta: {
|
|
112
|
+
name: 'upgrade',
|
|
113
|
+
description: "Refresh this project's vendored engine and platform config files without touching your game.",
|
|
114
|
+
},
|
|
115
|
+
args: {
|
|
116
|
+
engine: { type: 'string', description: 'Engine version to upgrade to (must be the currently published one).' },
|
|
117
|
+
force: { type: 'boolean', description: 'Upgrade even with uncommitted changes in the working tree.' },
|
|
118
|
+
},
|
|
119
|
+
async run({ args }) {
|
|
120
|
+
const context = loadProjectContext();
|
|
121
|
+
assertCleanTree(getGitStatus(context.root), args.force === true);
|
|
122
|
+
const environment = resolveEnvironment({ storedDefault: readDefaultEnvironment() });
|
|
123
|
+
const clientId = resolveAuth0ClientId(environment);
|
|
124
|
+
const token = await getAccessToken(environment, clientId, deps);
|
|
125
|
+
console.log('Fetching the engine manifest…');
|
|
126
|
+
const manifest = await fetchEngineManifest(environment, token, { fetch: globalThis.fetch });
|
|
127
|
+
// The manifest endpoint only ever serves the currently published engine — there is no way to
|
|
128
|
+
// fetch an older or specific version's tarball. An explicit --engine that names anything else
|
|
129
|
+
// must fail loudly rather than silently downloading the current tarball and mislabeling
|
|
130
|
+
// bitmagic.json with a version that doesn't match what actually landed on disk.
|
|
131
|
+
const targetVersion = args.engine ?? manifest.version;
|
|
132
|
+
if (targetVersion !== manifest.version) {
|
|
133
|
+
throw new CliError(`Cannot upgrade to engine ${targetVersion}: the server only serves the currently published ` +
|
|
134
|
+
`version, ${manifest.version}. Omit --engine to upgrade to it.`);
|
|
135
|
+
}
|
|
136
|
+
const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bitmagic-upgrade-'));
|
|
137
|
+
try {
|
|
138
|
+
const tarballPath = path.join(workDir, 'engine.tar.gz');
|
|
139
|
+
console.log(`Downloading engine ${manifest.version}…`);
|
|
140
|
+
await downloadAndVerify(manifest.tarballUrl, manifest.sha256, tarballPath, { fetch: globalThis.fetch });
|
|
141
|
+
const extracted = path.join(workDir, 'extracted');
|
|
142
|
+
const templatesDir = path.join(workDir, 'templates');
|
|
143
|
+
await extractEngine(tarballPath, extracted, templatesDir);
|
|
144
|
+
const result = upgradeProject({
|
|
145
|
+
root: context.root,
|
|
146
|
+
extractedEngineDir: extracted,
|
|
147
|
+
engineVersion: manifest.version,
|
|
148
|
+
});
|
|
149
|
+
console.log('');
|
|
150
|
+
if (result.previousEngineVersion === result.engineVersion) {
|
|
151
|
+
// A project scaffolded before `vite.publish.config.js` existed lands here: no engine
|
|
152
|
+
// bump, but this run is exactly how it gains the file `bitmagic build` needs. Say so
|
|
153
|
+
// explicitly rather than reporting "already up to date" and doing nothing.
|
|
154
|
+
console.log(`Already on engine ${result.engineVersion}. Refreshed the platform files anyway.`);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
console.log(`Upgraded engine ${result.previousEngineVersion} -> ${result.engineVersion}.`);
|
|
158
|
+
}
|
|
159
|
+
console.log('Replaced:');
|
|
160
|
+
for (const file of result.replaced) {
|
|
161
|
+
console.log(` ${file}`);
|
|
162
|
+
}
|
|
163
|
+
printDependencyReport(context.root);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
fs.rmSync(workDir, { recursive: true, force: true });
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=upgrade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/verify.js
CHANGED
|
@@ -8,6 +8,8 @@ import { reserveCorsAllowedPort, CORS_ALLOWED_PORT_MIN, CORS_ALLOWED_PORT_MAX }
|
|
|
8
8
|
import { runHeadlessCheck } from '../verify/browser.js';
|
|
9
9
|
import { classifyVerifyRun } from '../verify/classify.js';
|
|
10
10
|
import { waitForServer } from '../verify/wait-for-server.js';
|
|
11
|
+
import { computeFingerprint } from '../publish/fingerprint.js';
|
|
12
|
+
import { writeVerifyRecord, decideVerifyOutcome, recordAndGateVerify } from '../verify/result.js';
|
|
11
13
|
const DEFAULT_SETTLE_MS = 15_000;
|
|
12
14
|
/**
|
|
13
15
|
* A free port INSIDE the CORS-allowed window, never an OS-assigned ephemeral one.
|
|
@@ -106,15 +108,12 @@ export const verifyCommand = defineCommand({
|
|
|
106
108
|
settleMs,
|
|
107
109
|
});
|
|
108
110
|
const result = classifyVerifyRun(observations);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
throw new CliError('Verification failed.');
|
|
116
|
-
}
|
|
117
|
-
console.log(`Verification passed. Artifacts in ${artifactDir}`);
|
|
111
|
+
const outcome = decideVerifyOutcome(result, computeFingerprint(context.root), new Date().toISOString());
|
|
112
|
+
recordAndGateVerify(artifactDir, outcome, { consolePath, screenshotPath }, {
|
|
113
|
+
write: writeVerifyRecord,
|
|
114
|
+
info: (line) => console.log(line),
|
|
115
|
+
error: (line) => console.error(line),
|
|
116
|
+
});
|
|
118
117
|
}
|
|
119
118
|
finally {
|
|
120
119
|
server?.kill('SIGTERM');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAElG,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC;;;;;;;;GAQG;AACH,KAAK,UAAU,QAAQ;IACrB,MAAM,IAAI,GAAG,MAAM,sBAAsB,EAAE,CAAC;IAC5C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,QAAQ,CAChB,wBAAwB,qBAAqB,QAAQ,qBAAqB,iBAAiB;cACzF,0FAA0F,CAC7F,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,KAAmB,EAAE,SAAuB;IACrE,OAAO,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QACtC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAChC,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,CAAC,mDAAmD;YAChF,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO;YACvB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,CACJ,IAAI,QAAQ,CACV,mDAAmD,IAAI,IAAI;gBACzD,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAChC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,MAAM,CAAC,IAAI,QAAQ,CAAC,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;qGACqG;AACrG,SAAS,eAAe,CAAC,GAAuB;IAC9C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,iBAAiB,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,QAAQ,CAChB,4DAA4D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CACnF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wDAAwD,EAAE;IAC/F,IAAI,EAAE;QACJ,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,iBAAiB,IAAI,EAAE;KAC9F;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAE9C,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1E,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,QAAQ,CAAC,0CAA0C,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,+EAA+E;YAC/E,MAAM,IAAI,QAAQ,CAAC,8CAA8C,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QACnE,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAE1D,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC9B,IAAI,MAAgC,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,EAAE;gBAC7D,GAAG,EAAE,OAAO,CAAC,IAAI;gBACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;aACpC,CAAC,CAAC;YACH,IAAI,UAAU,GAAG,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC;gBAC3B,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC;aAC5C,CAAC,CAAC;YAEH,4FAA4F;YAC5F,2DAA2D;YAC3D,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC;gBAC1C,GAAG,EAAE,oBAAoB,IAAI,eAAe;gBAC5C,cAAc;gBACd,WAAW;gBACX,QAAQ;aACT,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,mBAAmB,CACjC,MAAM,EACN,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,EAChC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CACzB,CAAC;YACF,mBAAmB,CACjB,WAAW,EACX,OAAO,EACP,EAAE,WAAW,EAAE,cAAc,EAAE,EAC/B;gBACE,KAAK,EAAE,iBAAiB;gBACxB,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBACjC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;aACrC,CACF,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -21,14 +21,9 @@
|
|
|
21
21
|
* here is the correct direction. The semantics below mirror `applyModification` in
|
|
22
22
|
* game-play-agent's `utils/world-json-editor.ts` case for case — that is the reference
|
|
23
23
|
* implementation both lanes' persist plans were written against, and the two must not drift.
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* The web lane re-validates the document against the engine's `GameData` schema AFTER applying
|
|
28
|
-
* and refuses a write that introduces a NEW violation (`world-json-editor.ts:361,371`, baseline-
|
|
29
|
-
* diff so legacy games still accept unrelated writes). This applier has no such gate: it checks
|
|
30
|
-
* the document it READ and writes atomically, but does not check the result. Tracked in issue
|
|
31
|
-
* #819 — it needs the validator lifted somewhere the CLI can reach.
|
|
24
|
+
* That includes the post-apply `GameData` schema gate (see `applyModificationsToWorld` below),
|
|
25
|
+
* which both lanes run baseline-diffed so a legacy game's existing violations still accept
|
|
26
|
+
* unrelated writes.
|
|
32
27
|
*/
|
|
33
28
|
import * as fs from 'fs';
|
|
34
29
|
import * as path from 'path';
|
|
@@ -181,11 +176,10 @@ export function applyModificationsToWorld(worldPath, modifications) {
|
|
|
181
176
|
const preExisting = new Set(validateWorldData(world));
|
|
182
177
|
const summary = modifications.map((modification) => applyOne(world, modification));
|
|
183
178
|
// The engine statically casts world.json to Partial<GameData> (game/src/bundle/WorldDataLoader.ts),
|
|
184
|
-
// so a non-conforming document breaks `tsc` in a file the creator cannot edit.
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
// project that no longer builds and an error pointing at the engine rather than at the value.
|
|
179
|
+
// so a non-conforming document breaks `tsc` in a file the creator cannot edit. The gate matters
|
|
180
|
+
// more in this lane than in the web one: by the time it runs the design and geometry are already
|
|
181
|
+
// PAID FOR, so a bad batch would leave the creator with a project that no longer builds and an
|
|
182
|
+
// error pointing at the engine rather than at the offending value.
|
|
189
183
|
//
|
|
190
184
|
// Thrown BEFORE the rename, so world.json keeps whatever it had — the same guarantee every other
|
|
191
185
|
// failure path in this function already makes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-modifications.js","sourceRoot":"","sources":["../../src/forge/apply-modifications.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"apply-modifications.js","sourceRoot":"","sources":["../../src/forge/apply-modifications.ts"],"names":[],"mappings":"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"}
|
package/dist/project/context.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { CliError } from '../errors.js';
|
|
4
|
+
import { detectPackageManager, installAllCommand } from './package-manager.js';
|
|
4
5
|
const MARKER = 'bitmagic.json';
|
|
5
6
|
const REQUIRED_STRING_FIELDS = [
|
|
6
7
|
'gameId',
|
|
@@ -60,7 +61,11 @@ export function loadProjectContext(startDir = process.cwd()) {
|
|
|
60
61
|
export function projectBin(root, name) {
|
|
61
62
|
const binary = path.join(root, 'node_modules', '.bin', name);
|
|
62
63
|
if (!fs.existsSync(binary)) {
|
|
63
|
-
|
|
64
|
+
// Names the project's OWN package manager: telling a pnpm project to run `npm install`
|
|
65
|
+
// installs the tree under a different linker, and the next build fails on module
|
|
66
|
+
// resolution instead — a worse failure than the one this message is trying to fix.
|
|
67
|
+
throw new CliError(`Cannot find \`${name}\` in this project's dependencies. `
|
|
68
|
+
+ `Run \`${installAllCommand(detectPackageManager(root))}\` in ${root} first.`);
|
|
64
69
|
}
|
|
65
70
|
return binary;
|
|
66
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type PackageManager = 'pnpm' | 'yarn' | 'npm';
|
|
2
|
+
/**
|
|
3
|
+
* Decide from the project's lockfile. npm is the fallback: it is what the scaffold's own docs
|
|
4
|
+
* use and what ships with Node, so it is the right guess when there is no lockfile at all.
|
|
5
|
+
*
|
|
6
|
+
* Checked most-specific-first — a repo can carry both a `pnpm-lock.yaml` and a leftover
|
|
7
|
+
* `package-lock.json`, and pnpm is the one actually in use there.
|
|
8
|
+
*/
|
|
9
|
+
export declare function detectPackageManager(root: string): PackageManager;
|
|
10
|
+
/**
|
|
11
|
+
* The command that adds `specs` as (dev) dependencies. yarn's syntax differs from npm's and
|
|
12
|
+
* pnpm's (`yarn add --dev`, not `--save-dev`), which is why this is a function rather than a
|
|
13
|
+
* template string at each call site.
|
|
14
|
+
*/
|
|
15
|
+
export declare function addCommand(manager: PackageManager, dev: boolean, specs: string[]): string;
|
|
16
|
+
/** The command that installs everything already declared in package.json. */
|
|
17
|
+
export declare function installAllCommand(manager: PackageManager): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which package manager a scaffolded project is installed with, and the command lines that
|
|
3
|
+
* follow from it.
|
|
4
|
+
*
|
|
5
|
+
* Every command that tells a creator to install something prints a line meant to be run
|
|
6
|
+
* verbatim — by a person or by the agent driving this CLI. Naming the wrong manager is not
|
|
7
|
+
* cosmetic: running `npm install` in a pnpm project rewrites the tree under a different linker,
|
|
8
|
+
* and the very next `bitmagic build` fails on module resolution. That turns one clear instruction
|
|
9
|
+
* into a second, far more opaque failure — precisely the trap `bitmagic upgrade`'s dependency
|
|
10
|
+
* report and `projectBin`'s missing-binary error both exist to keep creators out of.
|
|
11
|
+
*
|
|
12
|
+
* Kept in `project/` rather than inside a command, because both `commands/upgrade.ts` and
|
|
13
|
+
* `project/context.ts` need it and a command module must not be imported from `project/`.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
/**
|
|
18
|
+
* Decide from the project's lockfile. npm is the fallback: it is what the scaffold's own docs
|
|
19
|
+
* use and what ships with Node, so it is the right guess when there is no lockfile at all.
|
|
20
|
+
*
|
|
21
|
+
* Checked most-specific-first — a repo can carry both a `pnpm-lock.yaml` and a leftover
|
|
22
|
+
* `package-lock.json`, and pnpm is the one actually in use there.
|
|
23
|
+
*/
|
|
24
|
+
export function detectPackageManager(root) {
|
|
25
|
+
if (fs.existsSync(path.join(root, 'pnpm-lock.yaml')))
|
|
26
|
+
return 'pnpm';
|
|
27
|
+
if (fs.existsSync(path.join(root, 'yarn.lock')))
|
|
28
|
+
return 'yarn';
|
|
29
|
+
return 'npm';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The command that adds `specs` as (dev) dependencies. yarn's syntax differs from npm's and
|
|
33
|
+
* pnpm's (`yarn add --dev`, not `--save-dev`), which is why this is a function rather than a
|
|
34
|
+
* template string at each call site.
|
|
35
|
+
*/
|
|
36
|
+
export function addCommand(manager, dev, specs) {
|
|
37
|
+
const joined = specs.join(' ');
|
|
38
|
+
if (manager === 'yarn')
|
|
39
|
+
return `yarn add ${dev ? '--dev ' : ''}${joined}`;
|
|
40
|
+
if (manager === 'pnpm')
|
|
41
|
+
return `pnpm add ${dev ? '--save-dev ' : ''}${joined}`;
|
|
42
|
+
return `npm install ${dev ? '--save-dev ' : ''}${joined}`;
|
|
43
|
+
}
|
|
44
|
+
/** The command that installs everything already declared in package.json. */
|
|
45
|
+
export function installAllCommand(manager) {
|
|
46
|
+
return `${manager} install`;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=package-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/project/package-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAuB,EAAE,GAAY,EAAE,KAAe;IAC/E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,YAAY,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1E,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAC/E,OAAO,eAAe,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;AAC5D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB,CAAC,OAAuB;IACvD,OAAO,GAAG,OAAO,UAAU,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** The config the scaffold vendors alongside `engine/`. */
|
|
2
|
+
export declare const VITE_PUBLISH_CONFIG = "vite.publish.config.js";
|
|
3
|
+
/**
|
|
4
|
+
* What was built, and from what.
|
|
5
|
+
*
|
|
6
|
+
* `fingerprint` is the same value `verify` records, which is what lets `publish` reuse an
|
|
7
|
+
* existing bundle instead of rebuilding: same inputs, same bundle.
|
|
8
|
+
*/
|
|
9
|
+
export interface BuildManifest {
|
|
10
|
+
engineVersion: string;
|
|
11
|
+
fingerprint: string;
|
|
12
|
+
bytes: number;
|
|
13
|
+
/** Recorded for the publish audit trail. The server stores it; it cannot verify it. */
|
|
14
|
+
sha256: string;
|
|
15
|
+
builtAt: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function buildBundlePaths(root: string): {
|
|
18
|
+
dir: string;
|
|
19
|
+
htmlPath: string;
|
|
20
|
+
manifestPath: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function writeBuildManifest(root: string, manifest: BuildManifest): void;
|
|
23
|
+
/** The last build's manifest, or null if there is none to trust — same contract as readVerifyRecord. */
|
|
24
|
+
export declare function readBuildManifest(root: string): BuildManifest | null;
|
|
25
|
+
/**
|
|
26
|
+
* Compile and bundle the project into one self-contained HTML, and record what was built.
|
|
27
|
+
*
|
|
28
|
+
* Exit code 1 on failure, matching the table in the spec: a build failure is the creator's own
|
|
29
|
+
* code, and the compiler's output has already been printed.
|
|
30
|
+
*
|
|
31
|
+
* The pre-flight below runs BEFORE `tsc`, not after: a project scaffolded before
|
|
32
|
+
* `vite.publish.config.js` existed has no config for vite to load, and without this check the
|
|
33
|
+
* creator pays a full type-check and then reads a raw vite "config not found" that names no
|
|
34
|
+
* remedy. `bitmagic upgrade` is the remedy — it vendors the file without touching game code —
|
|
35
|
+
* so the error says so.
|
|
36
|
+
*/
|
|
37
|
+
export declare function runBuild(root: string, engineVersion: string): BuildManifest;
|
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
* The pre-flight below runs BEFORE `tsc`, not after: a project scaffolded before
|
|
46
|
+
* `vite.publish.config.js` existed has no config for vite to load, and without this check the
|
|
47
|
+
* creator pays a full type-check and then reads a raw vite "config not found" that names no
|
|
48
|
+
* remedy. `bitmagic upgrade` is the remedy — it vendors the file without touching game code —
|
|
49
|
+
* so the error says so.
|
|
50
|
+
*/
|
|
51
|
+
export function runBuild(root, engineVersion) {
|
|
52
|
+
if (!fs.existsSync(path.join(root, VITE_PUBLISH_CONFIG))) {
|
|
53
|
+
throw new CliError(`This project has no ${VITE_PUBLISH_CONFIG}, which \`bitmagic build\` needs to bundle it. ` +
|
|
54
|
+
'It was added to the scaffold after this project was created — run `bitmagic upgrade` to ' +
|
|
55
|
+
'vendor it (your game code is not touched), then build again.', 1);
|
|
56
|
+
}
|
|
57
|
+
const tsc = projectBin(root, 'tsc');
|
|
58
|
+
const compile = spawnSync(tsc, [], { cwd: root, stdio: 'inherit' });
|
|
59
|
+
if (compile.error)
|
|
60
|
+
throw new CliError(`Could not run the TypeScript compiler: ${compile.error.message}`, 1);
|
|
61
|
+
if (compile.status !== 0)
|
|
62
|
+
throw new CliError('Build failed: the project does not compile.', 1);
|
|
63
|
+
const { dir, htmlPath } = buildBundlePaths(root);
|
|
64
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
65
|
+
const vite = projectBin(root, 'vite');
|
|
66
|
+
const bundle = spawnSync(vite, ['build', '--config', VITE_PUBLISH_CONFIG, '--outDir', dir, '--emptyOutDir'], {
|
|
67
|
+
cwd: root,
|
|
68
|
+
stdio: 'inherit',
|
|
69
|
+
});
|
|
70
|
+
if (bundle.error)
|
|
71
|
+
throw new CliError(`Could not run vite: ${bundle.error.message}`, 1);
|
|
72
|
+
if (bundle.status !== 0)
|
|
73
|
+
throw new CliError('Build failed: the bundle did not complete.', 1);
|
|
74
|
+
if (!fs.existsSync(htmlPath)) {
|
|
75
|
+
throw new CliError(`Build produced no ${path.relative(root, htmlPath)}. Check ${VITE_PUBLISH_CONFIG}.`, 1);
|
|
76
|
+
}
|
|
77
|
+
const contents = fs.readFileSync(htmlPath);
|
|
78
|
+
const manifest = {
|
|
79
|
+
engineVersion,
|
|
80
|
+
fingerprint: computeFingerprint(root),
|
|
81
|
+
bytes: contents.byteLength,
|
|
82
|
+
sha256: createHash('sha256').update(contents).digest('hex'),
|
|
83
|
+
builtAt: new Date().toISOString(),
|
|
84
|
+
};
|
|
85
|
+
writeBuildManifest(root, manifest);
|
|
86
|
+
return manifest;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
|