@bitmagic/cli 0.1.83-dev.5 → 0.1.83-dev.7
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 +25 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/build.d.ts +4 -0
- package/dist/commands/build.js +20 -3
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/import.js +7 -0
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/pages.d.ts +25 -0
- package/dist/commands/pages.js +95 -0
- package/dist/commands/pages.js.map +1 -0
- package/dist/editor/animation-preview-page.d.ts +8 -0
- package/dist/editor/animation-preview-page.js +15 -1
- package/dist/editor/animation-preview-page.js.map +1 -1
- package/dist/editor/server.js +7 -2
- package/dist/editor/server.js.map +1 -1
- package/dist/editor/shell-page.js +1 -1
- package/dist/forge/upload-proxy.d.ts +1 -1
- package/dist/forge/upload-proxy.js +5 -4
- package/dist/forge/upload-proxy.js.map +1 -1
- package/dist/package/collect-urls.d.ts +3 -4
- package/dist/package/collect-urls.js +51 -9
- package/dist/package/collect-urls.js.map +1 -1
- package/dist/poki/publish.js +4 -3
- package/dist/poki/publish.js.map +1 -1
- package/dist/project/context.d.ts +7 -0
- package/dist/project/context.js.map +1 -1
- package/dist/publish/bundle.d.ts +43 -0
- package/dist/publish/bundle.js +135 -29
- package/dist/publish/bundle.js.map +1 -1
- package/dist/scaffold/engine-capabilities.d.ts +10 -0
- package/dist/scaffold/engine-capabilities.js +1 -4
- package/dist/scaffold/engine-capabilities.js.map +1 -1
- package/dist/scaffold/github-pages.d.ts +83 -0
- package/dist/scaffold/github-pages.js +200 -0
- package/dist/scaffold/github-pages.js.map +1 -0
- package/dist/scaffold/project-files.d.ts +11 -0
- package/dist/scaffold/project-files.js +13 -6
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.d.ts +15 -0
- package/dist/scaffold/project.js +35 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.js +18 -1
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/scaffold/upgrade-project.d.ts +4 -1
- package/dist/scaffold/upgrade-project.js +16 -2
- package/dist/scaffold/upgrade-project.js.map +1 -1
- package/dist/vendor/hud-theme/engine/hud/fonts.js +28 -6
- package/dist/vendor/hud-theme/engine/hud/presets.js +1 -0
- package/package.json +6 -6
package/dist/publish/bundle.js
CHANGED
|
@@ -7,6 +7,9 @@ import { projectBin } from '../project/context.js';
|
|
|
7
7
|
import { spawnBinSync } from '../project/spawn-bin.js';
|
|
8
8
|
import { computeFingerprint } from './fingerprint.js';
|
|
9
9
|
import { describeDevOnlyThreeUses, scanWorkForDevOnlyThree } from '../project/published-three.js';
|
|
10
|
+
import { readEngineCapabilities } from '../scaffold/engine-capabilities.js';
|
|
11
|
+
import { PAGES_OUTPUT_DIR, pagesAssetHostMeta, requireStaticPageEngine, } from '../scaffold/github-pages.js';
|
|
12
|
+
import { renderIndexHtml } from '../scaffold/project-files.js';
|
|
10
13
|
/**
|
|
11
14
|
* The configs the scaffold vendors alongside `engine/`, one per bundle mode.
|
|
12
15
|
*
|
|
@@ -103,38 +106,22 @@ export function isCurrentBundle(root, fingerprint, singleFile) {
|
|
|
103
106
|
return createHash('sha256').update(contents).digest('hex') === manifest.sha256;
|
|
104
107
|
}
|
|
105
108
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* same object to confirm the meta block, so there is nowhere for a second file to go. What the
|
|
110
|
-
* mode changes is what is INSIDE it: by default the engine, the game and its data are inlined
|
|
111
|
-
* while three.js, Rapier and the other CDN packages are fetched at runtime, matching what the
|
|
112
|
-
* Creator publishes; `singleFile` inlines those too, for a game that must run with no network.
|
|
113
|
-
*
|
|
114
|
-
* Exit code 1 on failure, matching the table in the spec: a build failure is the creator's own
|
|
115
|
-
* code, and the compiler's output has already been printed.
|
|
116
|
-
*
|
|
117
|
-
* The pre-flight below runs BEFORE `tsc`, not after: a project scaffolded before the config it
|
|
118
|
-
* needs existed has none for vite to load, and without this check the creator pays a full
|
|
119
|
-
* type-check and then reads a raw vite "config not found" that names no remedy. `bitmagic upgrade`
|
|
120
|
-
* is the remedy — it vendors the file without touching game code — so the error says so. It names
|
|
121
|
-
* the config for the mode actually asked for, since a project can easily have one and not the
|
|
122
|
-
* other: the standalone config was added later than the default one.
|
|
123
|
-
*/
|
|
124
|
-
export function runBuild(root, engineVersion,
|
|
125
|
-
/**
|
|
126
|
-
* `stderr: true` sends the compiler's and bundler's own chatter to stderr instead of inheriting
|
|
127
|
-
* stdout — a `--json` run must keep stdout clean for its single result document.
|
|
109
|
+
* The pre-flight every bundle mode shares. It runs BEFORE `tsc`, not after: a project scaffolded
|
|
110
|
+
* before the config it needs existed has none for vite to load, and without this check the creator
|
|
111
|
+
* pays a full type-check and then reads a raw vite "config not found" that names no remedy.
|
|
128
112
|
*/
|
|
129
|
-
|
|
130
|
-
const singleFile = options.singleFile === true;
|
|
131
|
-
const configFile = publishConfigFor(singleFile);
|
|
113
|
+
function requirePublishConfig(root, configFile) {
|
|
132
114
|
if (!fs.existsSync(path.join(root, configFile))) {
|
|
133
115
|
throw new CliError(`This project has no ${configFile}, which \`bitmagic build\` needs to bundle it. ` +
|
|
134
116
|
'It was added to the scaffold after this project was created — run `bitmagic upgrade` to ' +
|
|
135
117
|
'vendor it (your game code is not touched), then build again.', 1);
|
|
136
118
|
}
|
|
137
|
-
|
|
119
|
+
}
|
|
120
|
+
function buildStdio(options) {
|
|
121
|
+
return options.stderr === true ? ['ignore', 2, 2] : 'inherit';
|
|
122
|
+
}
|
|
123
|
+
/** `tsc`, then the dev-only three.js scan: what has to pass before anything is bundled. */
|
|
124
|
+
function compileForBundle(root, stdio) {
|
|
138
125
|
const tsc = projectBin(root, 'tsc');
|
|
139
126
|
const compile = spawnBinSync(tsc, [], { cwd: root, stdio });
|
|
140
127
|
if (compile.error)
|
|
@@ -146,8 +133,8 @@ options = {}) {
|
|
|
146
133
|
const devOnlyThree = scanWorkForDevOnlyThree(root);
|
|
147
134
|
if (devOnlyThree.length > 0)
|
|
148
135
|
throw new CliError(`Build failed. ${describeDevOnlyThreeUses(devOnlyThree)}`, 1);
|
|
149
|
-
|
|
150
|
-
|
|
136
|
+
}
|
|
137
|
+
function bundleWithVite(root, configFile, outDir, stdio) {
|
|
151
138
|
const vite = projectBin(root, 'vite');
|
|
152
139
|
// Covers `bitmagic build`, `bitmagic publish` and `bitmagic ios` in one
|
|
153
140
|
// place: the vendored configs read BUNDLE_RAPIER_FLAVOR and stub the Rapier
|
|
@@ -155,7 +142,7 @@ options = {}) {
|
|
|
155
142
|
// variable is OWNED here — an inherited value from the caller's shell never
|
|
156
143
|
// overrides the game's own physics mode.
|
|
157
144
|
const bundleEnv = { ...process.env, BUNDLE_RAPIER_FLAVOR: resolveRapierFlavor(root) };
|
|
158
|
-
const bundle = spawnBinSync(vite, ['build', '--config', configFile, '--outDir',
|
|
145
|
+
const bundle = spawnBinSync(vite, ['build', '--config', configFile, '--outDir', outDir, '--emptyOutDir'], {
|
|
159
146
|
cwd: root,
|
|
160
147
|
stdio,
|
|
161
148
|
env: bundleEnv,
|
|
@@ -164,6 +151,40 @@ options = {}) {
|
|
|
164
151
|
throw new CliError(`Could not run vite: ${bundle.error.message}`, 1);
|
|
165
152
|
if (bundle.status !== 0)
|
|
166
153
|
throw new CliError('Build failed: the bundle did not complete.', 1);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Compile and bundle the project into one HTML file, and record what was built.
|
|
157
|
+
*
|
|
158
|
+
* One file either way — `bitmagic publish` PUTs a single object and api-server range-reads that
|
|
159
|
+
* same object to confirm the meta block, so there is nowhere for a second file to go. What the
|
|
160
|
+
* mode changes is what is INSIDE it: by default the engine, the game and its data are inlined
|
|
161
|
+
* while three.js, Rapier and the other CDN packages are fetched at runtime, matching what the
|
|
162
|
+
* Creator publishes; `singleFile` inlines those too, for a game that must run with no network.
|
|
163
|
+
*
|
|
164
|
+
* Exit code 1 on failure, matching the table in the spec: a build failure is the creator's own
|
|
165
|
+
* code, and the compiler's output has already been printed.
|
|
166
|
+
*
|
|
167
|
+
* The pre-flight below runs BEFORE `tsc`, not after: a project scaffolded before the config it
|
|
168
|
+
* needs existed has none for vite to load, and without this check the creator pays a full
|
|
169
|
+
* type-check and then reads a raw vite "config not found" that names no remedy. `bitmagic upgrade`
|
|
170
|
+
* is the remedy — it vendors the file without touching game code — so the error says so. It names
|
|
171
|
+
* the config for the mode actually asked for, since a project can easily have one and not the
|
|
172
|
+
* other: the standalone config was added later than the default one.
|
|
173
|
+
*/
|
|
174
|
+
export function runBuild(root, engineVersion,
|
|
175
|
+
/**
|
|
176
|
+
* `stderr: true` sends the compiler's and bundler's own chatter to stderr instead of inheriting
|
|
177
|
+
* stdout — a `--json` run must keep stdout clean for its single result document.
|
|
178
|
+
*/
|
|
179
|
+
options = {}) {
|
|
180
|
+
const singleFile = options.singleFile === true;
|
|
181
|
+
const configFile = publishConfigFor(singleFile);
|
|
182
|
+
requirePublishConfig(root, configFile);
|
|
183
|
+
const stdio = buildStdio(options);
|
|
184
|
+
compileForBundle(root, stdio);
|
|
185
|
+
const { dir, htmlPath } = buildBundlePaths(root);
|
|
186
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
187
|
+
bundleWithVite(root, configFile, dir, stdio);
|
|
167
188
|
if (!fs.existsSync(htmlPath)) {
|
|
168
189
|
throw new CliError(`Build produced no ${path.relative(root, htmlPath)}. Check ${configFile}.`, 1);
|
|
169
190
|
}
|
|
@@ -179,4 +200,89 @@ options = {}) {
|
|
|
179
200
|
writeBuildManifest(root, manifest);
|
|
180
201
|
return manifest;
|
|
181
202
|
}
|
|
203
|
+
/** Where `bitmagic build --pages` puts its page, and the scratch directory it builds it from. */
|
|
204
|
+
export function pagesBundlePaths(root) {
|
|
205
|
+
const dir = path.join(root, PAGES_OUTPUT_DIR);
|
|
206
|
+
return { dir, htmlPath: path.join(dir, 'index.html'), sourceDir: path.join(root, '.bitmagic', 'pages-src') };
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The Vite config a Pages build runs: the project's own vendored publish config, with the static
|
|
210
|
+
* page as its input instead of the project's `index.html`. Everything else (aliases, the CDN
|
|
211
|
+
* table, `__BUNDLED__`, the Rapier stub, the licence banner, single-file output) is the vendored
|
|
212
|
+
* config's, so a Pages page ships exactly what a publish ships around a different entry module.
|
|
213
|
+
*
|
|
214
|
+
* Generated next to the page for each build rather than vendored, so the vendored configs stay
|
|
215
|
+
* byte-identical in every project and a project on an older scaffold needs no upgrade for it. Vite
|
|
216
|
+
* bundles a config's relative imports, which is how this file reaches the vendored one.
|
|
217
|
+
*/
|
|
218
|
+
export function renderPagesViteConfig(baseConfigFile, inputHtml) {
|
|
219
|
+
return `// Generated by \`bitmagic build --pages\` for one build; never edit it, it is rewritten every time.
|
|
220
|
+
// The project's vendored ${baseConfigFile}, with the static GitHub Pages page as the input.
|
|
221
|
+
import base from '../../${baseConfigFile}';
|
|
222
|
+
|
|
223
|
+
export default {
|
|
224
|
+
...base,
|
|
225
|
+
build: {
|
|
226
|
+
...base.build,
|
|
227
|
+
rollupOptions: {
|
|
228
|
+
...base.build.rollupOptions,
|
|
229
|
+
input: ${JSON.stringify(inputHtml)},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
`;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* `bitmagic build --pages`: compile and bundle the project into `.bitmagic/pages/index.html`, the
|
|
237
|
+
* STATIC page the GitHub Pages workflow deploys (`scaffold/github-pages.ts`).
|
|
238
|
+
*
|
|
239
|
+
* The page differs from the publish bundle in its entry and its metas only: it boots
|
|
240
|
+
* `bitmagic/boot-static.js` (no platform services, so nothing calls api-server or game-server from
|
|
241
|
+
* a `*.github.io` origin) and declares `bm:platform` `bitmagic-static`, plus `bm:asset-host` for a
|
|
242
|
+
* non-default `pagesHosting`. It never touches `.bitmagic/build/`, whose manifest `publish` reuses.
|
|
243
|
+
*
|
|
244
|
+
* An engine without `staticPage` is refused before the compile, as is an unreadable `pagesHosting`.
|
|
245
|
+
*/
|
|
246
|
+
export function runPagesBuild(root, options = {}) {
|
|
247
|
+
const capabilities = readEngineCapabilities(path.join(root, 'engine'));
|
|
248
|
+
requireStaticPageEngine(capabilities);
|
|
249
|
+
const assetHost = pagesAssetHostMeta(options.pagesHosting);
|
|
250
|
+
const singleFile = options.singleFile === true;
|
|
251
|
+
const configFile = publishConfigFor(singleFile);
|
|
252
|
+
requirePublishConfig(root, configFile);
|
|
253
|
+
const stdio = buildStdio(options);
|
|
254
|
+
compileForBundle(root, stdio);
|
|
255
|
+
const { dir, htmlPath, sourceDir } = pagesBundlePaths(root);
|
|
256
|
+
fs.rmSync(sourceDir, { recursive: true, force: true });
|
|
257
|
+
fs.mkdirSync(sourceDir, { recursive: true });
|
|
258
|
+
const inputHtml = path.join(sourceDir, 'index.html');
|
|
259
|
+
fs.writeFileSync(inputHtml, renderIndexHtml({ capabilities, staticPage: { assetHost } }));
|
|
260
|
+
const pagesConfig = path.join(sourceDir, 'vite.pages.config.mjs');
|
|
261
|
+
fs.writeFileSync(pagesConfig, renderPagesViteConfig(configFile, inputHtml));
|
|
262
|
+
try {
|
|
263
|
+
bundleWithVite(root, path.relative(root, pagesConfig), dir, stdio);
|
|
264
|
+
// Vite writes an HTML input under its path relative to the root, so the page lands at
|
|
265
|
+
// <outDir>/.bitmagic/pages-src/index.html; Pages serves the directory's own index.html.
|
|
266
|
+
const emitted = path.join(dir, path.relative(root, inputHtml));
|
|
267
|
+
if (!fs.existsSync(emitted)) {
|
|
268
|
+
throw new CliError(`Build produced no ${path.relative(root, emitted)}. Check ${configFile}.`, 1);
|
|
269
|
+
}
|
|
270
|
+
fs.renameSync(emitted, htmlPath);
|
|
271
|
+
fs.rmSync(path.join(dir, path.relative(root, inputHtml).split(path.sep)[0]), {
|
|
272
|
+
recursive: true,
|
|
273
|
+
force: true,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
fs.rmSync(sourceDir, { recursive: true, force: true });
|
|
278
|
+
}
|
|
279
|
+
const contents = fs.readFileSync(htmlPath);
|
|
280
|
+
return {
|
|
281
|
+
htmlPath,
|
|
282
|
+
singleFile,
|
|
283
|
+
assetHost,
|
|
284
|
+
bytes: contents.byteLength,
|
|
285
|
+
sha256: createHash('sha256').update(contents).digest('hex'),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
182
288
|
//# sourceMappingURL=bundle.js.map
|
|
@@ -1 +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,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAqB,MAAM,wCAAwC,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.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;AAC7B,OAAO,EAAE,mBAAmB,EAAqB,MAAM,wCAAwC,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAClG,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAC5D,MAAM,CAAC,MAAM,8BAA8B,GAAG,mCAAmC,CAAC;AAElF,sDAAsD;AACtD,MAAM,UAAU,gBAAgB,CAAC,UAAmB;IAClD,OAAO,UAAU,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,mBAAmB,CAAC;AAC3E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACzD,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAA4B,CAAC;IAC9E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,QAAQ,CAChB,iDAAiD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB;YACzF,IAAI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,8CAA8C;YAClG,qCAAqC,EACvC,CAAC,CACF,CAAC;IACJ,CAAC;IACD,OAAO,mBAAmB,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;AACtE,CAAC;AA0BD,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,+FAA+F;IAC/F,0FAA0F;IAC1F,iGAAiG;IACjG,gGAAgG;IAChG,2EAA2E;IAC3E,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,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,WAAmB,EAAE,UAAmB;IACpF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,WAAW,KAAK,WAAW,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACpG,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,IAAY,EAAE,UAAkB;IAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,QAAQ,CAChB,uBAAuB,UAAU,iDAAiD;YAChF,0FAA0F;YAC1F,8DAA8D,EAChE,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAID,SAAS,UAAU,CAAC,OAA6B;IAC/C,OAAO,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED,2FAA2F;AAC3F,SAAS,gBAAgB,CAAC,IAAY,EAAE,KAAiB;IACvD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,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;IAC/F,+FAA+F;IAC/F,iDAAiD;IACjD,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,iBAAiB,wBAAwB,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAChH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,UAAkB,EAAE,MAAc,EAAE,KAAiB;IACzF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,wEAAwE;IACxE,4EAA4E;IAC5E,sEAAsE;IACtE,4EAA4E;IAC5E,yCAAyC;IACzC,MAAM,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtF,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE;QACxG,GAAG,EAAE,IAAI;QACT,KAAK;QACL,GAAG,EAAE,SAAS;KACf,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;AAC/F,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAY,EACZ,aAAqB;AACrB;;;GAGG;AACH,UAAsD,EAAE;IAExD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;IAC/C,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAChD,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE9B,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,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7C,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,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;IACpG,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,UAAU;QACV,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;AAED,iGAAiG;AACjG,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAC9C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;AAC/G,CAAC;AAaD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,cAAsB,EAAE,SAAiB;IAC7E,OAAO;4BACmB,cAAc;0BAChB,cAAc;;;;;;;;eAQzB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;CAIvC,CAAC;AACF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,UAA8E,EAAE;IAEhF,MAAM,YAAY,GAAG,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvE,uBAAuB,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;IAC/C,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAChD,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAEvC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE9B,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC5D,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACrD,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1F,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAClE,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,qBAAqB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IAE5E,IAAI,CAAC;QACH,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACnE,sFAAsF;QACtF,wFAAwF;QACxF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,QAAQ,CAAC,qBAAqB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;QACnG,CAAC;QACD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAW,CAAC,EAAE;YACrF,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3C,OAAO;QACL,QAAQ;QACR,UAAU;QACV,SAAS;QACT,KAAK,EAAE,QAAQ,CAAC,UAAU;QAC1B,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAC5D,CAAC;AACJ,CAAC"}
|
|
@@ -15,6 +15,16 @@
|
|
|
15
15
|
* it the page loads `engine/GameTemplate.js` as it always has (`renderIndexHtml`).
|
|
16
16
|
* - `gameExchange`: the engine can show Game Exchange tiles. Older engines are recognised by
|
|
17
17
|
* their exchange module instead; see `vendoredEngineSupportsExchange`.
|
|
18
|
+
* - `hostingSeam`: asset hosting is a platform slice. The engine's `AnimationAssets` exports a
|
|
19
|
+
* pure `createAnimationAssets(hosting)`, and the Bitmagic package carries its own preset in
|
|
20
|
+
* `bitmagic/hosting/BitmagicCdnHosting.js` (`bitmagicCdn()`). Node readers of the engine's
|
|
21
|
+
* URL tables (`loadAnimationAssets`) pass that preset explicitly instead of taking the engine's
|
|
22
|
+
* default, which stops being Bitmagic's. Without it they import the module's `animationAssets`
|
|
23
|
+
* as they always have.
|
|
24
|
+
* - `staticPage`: the engine carries `bitmagic/boot-static.js`, the entry of the static page
|
|
25
|
+
* `bitmagic build --pages` builds for GitHub Pages (no platform services, the engine's files
|
|
26
|
+
* on the Bitmagic CDN). Without it `bitmagic pages init` and `build --pages` refuse with an
|
|
27
|
+
* upgrade hint (`requireStaticPageEngine` in `github-pages.ts`).
|
|
18
28
|
*/
|
|
19
29
|
export interface EngineCapabilities {
|
|
20
30
|
readonly [name: string]: number | undefined;
|
|
@@ -18,10 +18,7 @@ export function readEngineCapabilities(engineDir) {
|
|
|
18
18
|
catch {
|
|
19
19
|
return NO_ENGINE_CAPABILITIES;
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
return NO_ENGINE_CAPABILITIES;
|
|
23
|
-
}
|
|
24
|
-
const raw = parsed.capabilities;
|
|
21
|
+
const raw = typeof parsed === 'object' && parsed !== null && 'capabilities' in parsed ? parsed.capabilities : null;
|
|
25
22
|
if (typeof raw !== 'object' || raw === null)
|
|
26
23
|
return NO_ENGINE_CAPABILITIES;
|
|
27
24
|
const capabilities = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-capabilities.js","sourceRoot":"","sources":["../../src/scaffold/engine-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"engine-capabilities.js","sourceRoot":"","sources":["../../src/scaffold/engine-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAkC7B,2FAA2F;AAC3F,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;AAEpF,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAuB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE5E;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,wBAAwB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,sBAAsB,CAAC;IAChC,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IACnH,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,sBAAsB,CAAC;IAC3E,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;YAAE,YAAY,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACpG,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB,CACjC,YAAgC,EAChC,IAAY,EACZ,OAAO,GAAG,CAAC;IAEX,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,OAAO,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { PackageManager } from '../project/package-manager.js';
|
|
2
|
+
import { type EngineCapabilities } from './engine-capabilities.js';
|
|
3
|
+
/**
|
|
4
|
+
* The GitHub Pages target for a standalone project (engine OSS audit W5.6 §2.6, decision H-h):
|
|
5
|
+
* `bitmagic pages init` writes the workflow below, and the workflow runs `bitmagic build --pages`
|
|
6
|
+
* on every push to the default branch and deploys `.bitmagic/pages/` with GitHub's own Pages
|
|
7
|
+
* actions.
|
|
8
|
+
*
|
|
9
|
+
* What `build --pages` makes is a STATIC page: it boots through `bitmagic/boot-static.js`, which
|
|
10
|
+
* registers no platform services, so a `*.github.io` page never calls api-server, game-server or
|
|
11
|
+
* GTM. Only the engine's own files still come from Bitmagic: the Bitmagic CDN, until the open
|
|
12
|
+
* engine's asset site exists (`pagesHosting` in `bitmagic.json` switches that).
|
|
13
|
+
*/
|
|
14
|
+
/** Where `bitmagic pages init` writes the workflow, relative to the project root. */
|
|
15
|
+
export declare const PAGES_WORKFLOW_PATH = ".github/workflows/bitmagic-pages.yml";
|
|
16
|
+
/** The directory `bitmagic build --pages` writes and the workflow uploads, relative to the root. */
|
|
17
|
+
export declare const PAGES_OUTPUT_DIR = ".bitmagic/pages";
|
|
18
|
+
/** The engine capability a vendored engine advertises once it carries `bitmagic/boot-static.ts`. */
|
|
19
|
+
export declare const STATIC_PAGE_CAPABILITY = "staticPage";
|
|
20
|
+
/** The `bm:platform` id the static page declares and `bitmagic/register-static.ts` registers. */
|
|
21
|
+
export declare const BITMAGIC_STATIC_PLATFORM_ID = "bitmagic-static";
|
|
22
|
+
/**
|
|
23
|
+
* Refuses an engine without the static page, before anything is written or built. The page boots
|
|
24
|
+
* `bitmagic/boot-static.js`; on an engine that has none, the build would compile clean and then
|
|
25
|
+
* fail in Vite on an unresolved entry, naming a file the creator never wrote.
|
|
26
|
+
*/
|
|
27
|
+
export declare function requireStaticPageEngine(capabilities: EngineCapabilities): void;
|
|
28
|
+
/** The values `pagesHosting` in `bitmagic.json` takes, besides a root URL. */
|
|
29
|
+
export declare const PAGES_HOSTING_PRESETS: readonly ["bitmagic-cdn", "github-pages"];
|
|
30
|
+
export type PagesHostingPreset = (typeof PAGES_HOSTING_PRESETS)[number];
|
|
31
|
+
/** The default: the engine's files from the Bitmagic CDN, which is where they all are today. */
|
|
32
|
+
export declare const DEFAULT_PAGES_HOSTING: PagesHostingPreset;
|
|
33
|
+
/**
|
|
34
|
+
* The `<meta name="bm:asset-host">` content the static page carries for `bitmagic.json`'s
|
|
35
|
+
* `pagesHosting`, or null for none.
|
|
36
|
+
*
|
|
37
|
+
* - absent, or `"bitmagic-cdn"`: no meta. The static platform registers the Bitmagic CDN preset,
|
|
38
|
+
* and a page with no meta takes the platform's hosting (`resolveHosting` in the engine's
|
|
39
|
+
* `runtime/hosting.ts`).
|
|
40
|
+
* - `"github-pages"`: the meta `github-pages`, the open engine's own asset site. That site does
|
|
41
|
+
* not exist yet, so a page built this way loads no engine assets until it does.
|
|
42
|
+
* - a root URL (`https://…`, `http://…`, or a page-relative `./…`, `../…` or `/…` path): the meta
|
|
43
|
+
* names that root, which the engine reads as a self-hosted copy of the engine's files.
|
|
44
|
+
*
|
|
45
|
+
* Anything else is refused: the engine would read an unknown name as an unregistered provider and
|
|
46
|
+
* silently fall back to the platform's hosting, which is the opposite of what the creator asked.
|
|
47
|
+
*/
|
|
48
|
+
export declare function pagesAssetHostMeta(pagesHosting: unknown): string | null;
|
|
49
|
+
export interface GithubPagesWorkflowOptions {
|
|
50
|
+
/**
|
|
51
|
+
* The CLI version the workflow runs, pinned: the version that scaffolded it. An unpinned `npx`
|
|
52
|
+
* would build with whatever was published last, against an engine this project may not have.
|
|
53
|
+
*/
|
|
54
|
+
cliVersion: string;
|
|
55
|
+
/** The project's package manager, from its lockfile (`detectPackageManager`). */
|
|
56
|
+
packageManager: PackageManager;
|
|
57
|
+
/**
|
|
58
|
+
* The branch whose pushes deploy: the repository's default branch (`detectDefaultBranch`).
|
|
59
|
+
* Named literally, because `$default-branch` only works in GitHub's workflow templates; in a
|
|
60
|
+
* repository's own workflow file it is a branch called `$default-branch`, and nothing deploys.
|
|
61
|
+
*/
|
|
62
|
+
branch: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* `.github/workflows/bitmagic-pages.yml`.
|
|
66
|
+
*
|
|
67
|
+
* Action majors follow this repository's own workflows (`actions/checkout@v6`,
|
|
68
|
+
* `actions/setup-node@v6`, `pnpm/action-setup@v5`); the two Pages actions, which the repository
|
|
69
|
+
* does not otherwise use, are pinned to their current majors. Checkout fetches LFS objects,
|
|
70
|
+
* because a project may keep large models there and the bundle inlines nothing it cannot read.
|
|
71
|
+
*/
|
|
72
|
+
export declare function renderGithubPagesWorkflow(options: GithubPagesWorkflowOptions): string;
|
|
73
|
+
/**
|
|
74
|
+
* What `bitmagic pages init` prints after writing the workflow: the one step only the creator can
|
|
75
|
+
* take, the limits GitHub sets, and the terms note. Lines, so `--json` can carry them as an array.
|
|
76
|
+
*/
|
|
77
|
+
export declare function pagesSetupNotes(): string[];
|
|
78
|
+
/**
|
|
79
|
+
* The repository's default branch, for the workflow's push trigger: the remote's `HEAD` when the
|
|
80
|
+
* clone knows it, else the branch checked out now, else `main` (GitHub's default for a new
|
|
81
|
+
* repository). `bitmagic pages init --branch` overrides it.
|
|
82
|
+
*/
|
|
83
|
+
export declare function detectDefaultBranch(root: string): string;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { CliError } from '../errors.js';
|
|
2
|
+
import { spawnPathCommandSync } from '../project/spawn-bin.js';
|
|
3
|
+
import { hasEngineCapability } from './engine-capabilities.js';
|
|
4
|
+
/**
|
|
5
|
+
* The GitHub Pages target for a standalone project (engine OSS audit W5.6 §2.6, decision H-h):
|
|
6
|
+
* `bitmagic pages init` writes the workflow below, and the workflow runs `bitmagic build --pages`
|
|
7
|
+
* on every push to the default branch and deploys `.bitmagic/pages/` with GitHub's own Pages
|
|
8
|
+
* actions.
|
|
9
|
+
*
|
|
10
|
+
* What `build --pages` makes is a STATIC page: it boots through `bitmagic/boot-static.js`, which
|
|
11
|
+
* registers no platform services, so a `*.github.io` page never calls api-server, game-server or
|
|
12
|
+
* GTM. Only the engine's own files still come from Bitmagic: the Bitmagic CDN, until the open
|
|
13
|
+
* engine's asset site exists (`pagesHosting` in `bitmagic.json` switches that).
|
|
14
|
+
*/
|
|
15
|
+
/** Where `bitmagic pages init` writes the workflow, relative to the project root. */
|
|
16
|
+
export const PAGES_WORKFLOW_PATH = '.github/workflows/bitmagic-pages.yml';
|
|
17
|
+
/** The directory `bitmagic build --pages` writes and the workflow uploads, relative to the root. */
|
|
18
|
+
export const PAGES_OUTPUT_DIR = '.bitmagic/pages';
|
|
19
|
+
/** The engine capability a vendored engine advertises once it carries `bitmagic/boot-static.ts`. */
|
|
20
|
+
export const STATIC_PAGE_CAPABILITY = 'staticPage';
|
|
21
|
+
/** The `bm:platform` id the static page declares and `bitmagic/register-static.ts` registers. */
|
|
22
|
+
export const BITMAGIC_STATIC_PLATFORM_ID = 'bitmagic-static';
|
|
23
|
+
/**
|
|
24
|
+
* Refuses an engine without the static page, before anything is written or built. The page boots
|
|
25
|
+
* `bitmagic/boot-static.js`; on an engine that has none, the build would compile clean and then
|
|
26
|
+
* fail in Vite on an unresolved entry, naming a file the creator never wrote.
|
|
27
|
+
*/
|
|
28
|
+
export function requireStaticPageEngine(capabilities) {
|
|
29
|
+
if (hasEngineCapability(capabilities, STATIC_PAGE_CAPABILITY))
|
|
30
|
+
return;
|
|
31
|
+
throw new CliError('This project\'s engine predates the GitHub Pages target: it has no static page '
|
|
32
|
+
+ '(`staticPage` in engine/engine/engine-manifest.json). Run `bitmagic upgrade` to update the '
|
|
33
|
+
+ 'engine (your game code is not touched), then try again.', 1);
|
|
34
|
+
}
|
|
35
|
+
/** The values `pagesHosting` in `bitmagic.json` takes, besides a root URL. */
|
|
36
|
+
export const PAGES_HOSTING_PRESETS = ['bitmagic-cdn', 'github-pages'];
|
|
37
|
+
/** The default: the engine's files from the Bitmagic CDN, which is where they all are today. */
|
|
38
|
+
export const DEFAULT_PAGES_HOSTING = 'bitmagic-cdn';
|
|
39
|
+
/**
|
|
40
|
+
* The `<meta name="bm:asset-host">` content the static page carries for `bitmagic.json`'s
|
|
41
|
+
* `pagesHosting`, or null for none.
|
|
42
|
+
*
|
|
43
|
+
* - absent, or `"bitmagic-cdn"`: no meta. The static platform registers the Bitmagic CDN preset,
|
|
44
|
+
* and a page with no meta takes the platform's hosting (`resolveHosting` in the engine's
|
|
45
|
+
* `runtime/hosting.ts`).
|
|
46
|
+
* - `"github-pages"`: the meta `github-pages`, the open engine's own asset site. That site does
|
|
47
|
+
* not exist yet, so a page built this way loads no engine assets until it does.
|
|
48
|
+
* - a root URL (`https://…`, `http://…`, or a page-relative `./…`, `../…` or `/…` path): the meta
|
|
49
|
+
* names that root, which the engine reads as a self-hosted copy of the engine's files.
|
|
50
|
+
*
|
|
51
|
+
* Anything else is refused: the engine would read an unknown name as an unregistered provider and
|
|
52
|
+
* silently fall back to the platform's hosting, which is the opposite of what the creator asked.
|
|
53
|
+
*/
|
|
54
|
+
export function pagesAssetHostMeta(pagesHosting) {
|
|
55
|
+
if (pagesHosting === undefined || pagesHosting === DEFAULT_PAGES_HOSTING)
|
|
56
|
+
return null;
|
|
57
|
+
if (pagesHosting === 'github-pages')
|
|
58
|
+
return 'github-pages';
|
|
59
|
+
if (typeof pagesHosting === 'string' && /^(https?:\/\/[^\s"<>]+|\.{0,2}\/[^\s"<>]*)$/.test(pagesHosting)) {
|
|
60
|
+
return pagesHosting;
|
|
61
|
+
}
|
|
62
|
+
throw new CliError(`bitmagic.json's "pagesHosting" is ${JSON.stringify(pagesHosting)}, which is not one of `
|
|
63
|
+
+ `${PAGES_HOSTING_PRESETS.map((p) => `"${p}"`).join(', ')} or a root URL (https://… or ./…). `
|
|
64
|
+
+ 'Remove the field to keep the default, the Bitmagic CDN.', 1);
|
|
65
|
+
}
|
|
66
|
+
/** A branch name the workflow can carry unquoted in a YAML flow sequence. */
|
|
67
|
+
const PLAIN_BRANCH = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
|
|
68
|
+
/**
|
|
69
|
+
* The install steps for the project's lockfile, indented to sit in the build job's `steps:`.
|
|
70
|
+
*
|
|
71
|
+
* pnpm needs its own setup action (a scaffolded package.json has no `packageManager` field, so the
|
|
72
|
+
* major version is named here) and must come before setup-node's cache. The frozen-lockfile
|
|
73
|
+
* installs are deliberate: CI must build what was committed, not re-resolve it.
|
|
74
|
+
*/
|
|
75
|
+
function installSteps(manager) {
|
|
76
|
+
if (manager === 'pnpm') {
|
|
77
|
+
return ` - uses: pnpm/action-setup@v5
|
|
78
|
+
with:
|
|
79
|
+
version: 10
|
|
80
|
+
- uses: actions/setup-node@v6
|
|
81
|
+
with:
|
|
82
|
+
node-version: 24
|
|
83
|
+
cache: pnpm
|
|
84
|
+
- run: pnpm install --frozen-lockfile`;
|
|
85
|
+
}
|
|
86
|
+
if (manager === 'yarn') {
|
|
87
|
+
return ` - uses: actions/setup-node@v6
|
|
88
|
+
with:
|
|
89
|
+
node-version: 24
|
|
90
|
+
cache: yarn
|
|
91
|
+
- run: yarn install --frozen-lockfile`;
|
|
92
|
+
}
|
|
93
|
+
return ` - uses: actions/setup-node@v6
|
|
94
|
+
with:
|
|
95
|
+
node-version: 24
|
|
96
|
+
cache: npm
|
|
97
|
+
- run: npm ci`;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* `.github/workflows/bitmagic-pages.yml`.
|
|
101
|
+
*
|
|
102
|
+
* Action majors follow this repository's own workflows (`actions/checkout@v6`,
|
|
103
|
+
* `actions/setup-node@v6`, `pnpm/action-setup@v5`); the two Pages actions, which the repository
|
|
104
|
+
* does not otherwise use, are pinned to their current majors. Checkout fetches LFS objects,
|
|
105
|
+
* because a project may keep large models there and the bundle inlines nothing it cannot read.
|
|
106
|
+
*/
|
|
107
|
+
export function renderGithubPagesWorkflow(options) {
|
|
108
|
+
if (!/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/.test(options.cliVersion)) {
|
|
109
|
+
throw new CliError(`Cannot pin the workflow to this CLI's version (${JSON.stringify(options.cliVersion)}). `
|
|
110
|
+
+ 'Reinstall the CLI with `bitmagic self-update` and run `bitmagic pages init` again.', 1);
|
|
111
|
+
}
|
|
112
|
+
if (!PLAIN_BRANCH.test(options.branch)) {
|
|
113
|
+
throw new CliError(`Cannot deploy from the branch ${JSON.stringify(options.branch)}: name a plain branch with --branch.`, 1);
|
|
114
|
+
}
|
|
115
|
+
return `# Builds this Bitmagic game and deploys it to GitHub Pages on every push to ${options.branch}.
|
|
116
|
+
# Written by \`bitmagic pages init\`; run it again to refresh this file.
|
|
117
|
+
#
|
|
118
|
+
# One-time setup: Settings -> Pages -> Build and deployment -> Source: GitHub Actions.
|
|
119
|
+
#
|
|
120
|
+
# The page is static: no Bitmagic sign-in, cloud saves, leaderboards, multiplayer or runtime AI.
|
|
121
|
+
# The engine's own files load from the Bitmagic CDN (\`pagesHosting\` in bitmagic.json).
|
|
122
|
+
name: Deploy to GitHub Pages
|
|
123
|
+
|
|
124
|
+
on:
|
|
125
|
+
push:
|
|
126
|
+
branches: [${options.branch}]
|
|
127
|
+
workflow_dispatch:
|
|
128
|
+
|
|
129
|
+
permissions:
|
|
130
|
+
contents: read
|
|
131
|
+
pages: write
|
|
132
|
+
id-token: write
|
|
133
|
+
|
|
134
|
+
concurrency:
|
|
135
|
+
group: pages
|
|
136
|
+
cancel-in-progress: false
|
|
137
|
+
|
|
138
|
+
jobs:
|
|
139
|
+
build:
|
|
140
|
+
runs-on: ubuntu-latest
|
|
141
|
+
steps:
|
|
142
|
+
- uses: actions/checkout@v6
|
|
143
|
+
with:
|
|
144
|
+
lfs: true
|
|
145
|
+
${installSteps(options.packageManager)}
|
|
146
|
+
- run: npx --yes @bitmagic/cli@${options.cliVersion} build --pages
|
|
147
|
+
- uses: actions/upload-pages-artifact@v5
|
|
148
|
+
with:
|
|
149
|
+
path: ${PAGES_OUTPUT_DIR}/
|
|
150
|
+
|
|
151
|
+
deploy:
|
|
152
|
+
needs: build
|
|
153
|
+
runs-on: ubuntu-latest
|
|
154
|
+
environment:
|
|
155
|
+
name: github-pages
|
|
156
|
+
url: \${{ steps.deployment.outputs.page_url }}
|
|
157
|
+
steps:
|
|
158
|
+
- id: deployment
|
|
159
|
+
uses: actions/deploy-pages@v5
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* What `bitmagic pages init` prints after writing the workflow: the one step only the creator can
|
|
164
|
+
* take, the limits GitHub sets, and the terms note. Lines, so `--json` can carry them as an array.
|
|
165
|
+
*/
|
|
166
|
+
export function pagesSetupNotes() {
|
|
167
|
+
return [
|
|
168
|
+
'One manual step: on GitHub, open the repository\'s Settings -> Pages -> Build and deployment, '
|
|
169
|
+
+ 'and set Source to "GitHub Actions". Then push to the default branch (or run the workflow from '
|
|
170
|
+
+ 'the Actions tab) and the game deploys.',
|
|
171
|
+
'The page is static: no Bitmagic sign-in, cloud saves, leaderboards, multiplayer or runtime AI. '
|
|
172
|
+
+ 'The engine\'s own files (characters, animations) load from the Bitmagic CDN.',
|
|
173
|
+
'GitHub Pages limits: 1 GB per site, and a soft bandwidth limit of 100 GB per month.',
|
|
174
|
+
'GitHub Pages is not meant to run a commercial business. A game run mainly as one fits the '
|
|
175
|
+
+ 'Bitmagic CDN (`bitmagic publish`) or another host better. Your game\'s licence terms are in '
|
|
176
|
+
+ 'engine/LICENSE.md.',
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The repository's default branch, for the workflow's push trigger: the remote's `HEAD` when the
|
|
181
|
+
* clone knows it, else the branch checked out now, else `main` (GitHub's default for a new
|
|
182
|
+
* repository). `bitmagic pages init --branch` overrides it.
|
|
183
|
+
*/
|
|
184
|
+
export function detectDefaultBranch(root) {
|
|
185
|
+
const git = (args) => {
|
|
186
|
+
const result = spawnPathCommandSync('git', ['-C', root, ...args], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
187
|
+
if (result.error !== undefined || result.status !== 0)
|
|
188
|
+
return null;
|
|
189
|
+
const out = String(result.stdout).trim();
|
|
190
|
+
return out.length > 0 ? out : null;
|
|
191
|
+
};
|
|
192
|
+
const remoteHead = git(['symbolic-ref', '--short', 'refs/remotes/origin/HEAD']);
|
|
193
|
+
if (remoteHead !== null && remoteHead.startsWith('origin/'))
|
|
194
|
+
return remoteHead.slice('origin/'.length);
|
|
195
|
+
const current = git(['symbolic-ref', '--short', 'HEAD']);
|
|
196
|
+
if (current !== null)
|
|
197
|
+
return current;
|
|
198
|
+
return 'main';
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=github-pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-pages.js","sourceRoot":"","sources":["../../src/scaffold/github-pages.ts"],"names":[],"mappings":"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"}
|
|
@@ -63,6 +63,17 @@ export interface IndexHtmlOptions {
|
|
|
63
63
|
* directory to load.
|
|
64
64
|
*/
|
|
65
65
|
capabilities: EngineCapabilities;
|
|
66
|
+
/**
|
|
67
|
+
* Render the STATIC page `bitmagic build --pages` bundles for GitHub Pages instead of the
|
|
68
|
+
* project's own page: it boots through `bitmagic/boot-static.js` (no platform services, the
|
|
69
|
+
* engine's files on the Bitmagic CDN) and declares `<meta name="bm:platform"
|
|
70
|
+
* content="bitmagic-static">`, plus `<meta name="bm:asset-host">` when `assetHost` is a string
|
|
71
|
+
* (`pagesAssetHostMeta` in `github-pages.ts`). Only for an engine that advertises `staticPage`.
|
|
72
|
+
* Absent, the page is byte for byte the one every project is scaffolded with.
|
|
73
|
+
*/
|
|
74
|
+
staticPage?: {
|
|
75
|
+
assetHost: string | null;
|
|
76
|
+
};
|
|
66
77
|
}
|
|
67
78
|
/** The `bm:platform` value a page carries when it boots through the Bitmagic platform package. */
|
|
68
79
|
export declare const BITMAGIC_PLATFORM_ID = "bitmagic";
|
|
@@ -2,6 +2,7 @@ import { FAVICON_LINK_ID } from '@bitmagic/asset-core/favicon';
|
|
|
2
2
|
import { describeArtStyle } from '@bitmagic/asset-core/art-style';
|
|
3
3
|
import { tsconfigPaths, importMapEntries, viteAliasEntries } from './aliases.js';
|
|
4
4
|
import { hasEngineCapability } from './engine-capabilities.js';
|
|
5
|
+
import { BITMAGIC_STATIC_PLATFORM_ID } from './github-pages.js';
|
|
5
6
|
import { currentPortLane } from '../port-lane.js';
|
|
6
7
|
import { AGENTS_MD_REFERENCE_SECTION, GAME_DESIGN_REFERENCE_HINT, GENERATE_SKILL_REFERENCE_SECTION, PLANNING_SKILL_REFERENCE_STEP1, PLANNING_SKILL_REFERENCE_STEP4, } from './reference-guidance.js';
|
|
7
8
|
import { ALWAYS_AGENTS, PRIMARY_SKILLS_DIR, joinWithAnd, skillDirsFor, } from './agent-targets.js';
|
|
@@ -273,14 +274,20 @@ export function renderIndexHtml(options) {
|
|
|
273
274
|
const imports = { ...CDN_IMPORTS, ...aliasImports };
|
|
274
275
|
// Derived from the same alias model as the import map above, not a hardcoded literal, so the
|
|
275
276
|
// two cannot drift: the entry point is an alias's import-map target plus its filename.
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
const staticPage = options.staticPage;
|
|
278
|
+
const engineEntryPoint = staticPage !== undefined
|
|
279
|
+
? `${aliasImports['bitmagic/']}boot-static.js`
|
|
280
|
+
: platformEntry
|
|
281
|
+
? `${aliasImports['bitmagic/']}boot.js`
|
|
282
|
+
: `${aliasImports['engine/']}GameTemplate.js`;
|
|
279
283
|
// Only on a page that registers the platform: the engine logs an error when a page declares a
|
|
280
284
|
// platform that never registered, so an older engine's page must not carry it.
|
|
281
|
-
const platformMeta =
|
|
282
|
-
? `\n <meta name="bm:platform" content="${
|
|
283
|
-
|
|
285
|
+
const platformMeta = staticPage !== undefined
|
|
286
|
+
? `\n <meta name="bm:platform" content="${BITMAGIC_STATIC_PLATFORM_ID}">`
|
|
287
|
+
+ (staticPage.assetHost === null ? '' : `\n <meta name="bm:asset-host" content="${staticPage.assetHost}">`)
|
|
288
|
+
: platformEntry
|
|
289
|
+
? `\n <meta name="bm:platform" content="${BITMAGIC_PLATFORM_ID}">`
|
|
290
|
+
: '';
|
|
284
291
|
// The #game-container div below is required, not decorative: GameTemplate.ts
|
|
285
292
|
// does document.getElementById('game-container') as HTMLElement, and GameEngine.ts
|
|
286
293
|
// appendChild()s into it. The "as HTMLElement" cast erases the null a missing div would
|