@bitmagic/cli 0.1.54-dev.0 → 0.1.54-dev.2
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 +47 -4
- package/dist/cli.d.ts +8 -0
- package/dist/commands/dev.d.ts +8 -0
- package/dist/commands/dev.js +100 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/mobile/asset-hosts.d.ts +45 -0
- package/dist/mobile/asset-hosts.js +79 -0
- package/dist/mobile/asset-hosts.js.map +1 -0
- package/dist/mobile/bridge.d.ts +61 -0
- package/dist/mobile/bridge.js +224 -0
- package/dist/mobile/bridge.js.map +1 -0
- package/dist/mobile/dev-cert.d.ts +30 -0
- package/dist/mobile/dev-cert.js +114 -0
- package/dist/mobile/dev-cert.js.map +1 -0
- package/dist/mobile/lan-address.d.ts +30 -0
- package/dist/mobile/lan-address.js +54 -0
- package/dist/mobile/lan-address.js.map +1 -0
- package/dist/mobile/rewrite-shim.d.ts +26 -0
- package/dist/mobile/rewrite-shim.js +152 -0
- package/dist/mobile/rewrite-shim.js.map +1 -0
- package/dist/project/dev-handle.d.ts +8 -0
- package/dist/project/dev-handle.js.map +1 -1
- package/dist/render/qr-output.d.ts +12 -0
- package/dist/render/qr-output.js +13 -1
- package/dist/render/qr-output.js.map +1 -1
- package/dist/scaffold/project-files.js +5 -0
- package/dist/scaffold/project-files.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -193,7 +193,7 @@ browser reloads itself on every change and the assets panel shows each generatio
|
|
|
193
193
|
| `bitmagic whoami [--env <env>]` | Show the identity the CLI is authenticated as — the account's email address alongside its user id — and which environment answered, including where that environment was chosen from. |
|
|
194
194
|
| `bitmagic init [dir] [--template <id>] [--name <name>] [--idea "<pitch>"] [--env <env>] [--force]` | Scaffold a new project: mints a game, downloads the vendored engine, writes `AGENTS.md`, `GAME-DESIGN.md` and templates. Starts from `empty-3d` unless told otherwise. `--idea` seeds the design doc's pitch **and** picks the template whose camera and controls fit it — "a doom-like corridor shooter" scaffolds `first-person`, "jump between floating islands" scaffolds `sidescroller`. `--template` overrides both; a suggestion that fails for any reason falls back to `empty-3d` rather than failing the scaffold. Dependencies are installed with **pnpm** when your machine has it and npm otherwise — the lockfile that produces is what every later command reads, so it never tells you to run the wrong one. |
|
|
195
195
|
| `bitmagic check` | Typecheck (`tsc --noEmit`) against the vendored engine. Fast; does not prove the game runs. |
|
|
196
|
-
| `bitmagic dev [--port <port>] [--editor-port <port>] [--no-open]` | Build, then serve everything and keep it running: `tsc --watch`, `vite` on 3010, and a **Game / Editor** view on 3011 that reloads itself when the project changes, and shows where the game is published (with a QR code) once it has been. Opens the view in your browser; `--no-open` (or `BITMAGIC_NO_OPEN=1`) skips that. The one command to leave open. See **The dev view** below. |
|
|
196
|
+
| `bitmagic dev [--port <port>] [--editor-port <port>] [--no-open] [--mobile] [--mobile-http]` | Build, then serve everything and keep it running: `tsc --watch`, `vite` on 3010, and a **Game / Editor** view on 3011 that reloads itself when the project changes, and shows where the game is published (with a QR code) once it has been. Opens the view in your browser; `--no-open` (or `BITMAGIC_NO_OPEN=1`) skips that. `--mobile` also serves the game to phones on your network, over https, and prints a QR code for that. The one command to leave open. See **The dev view** below. |
|
|
197
197
|
| `bitmagic reload [--port <port>]` | Tell a running `bitmagic dev` to reload the browser now. For agents: run it when you finish a round of edits. Exits 0 and does nothing when no dev server is running. |
|
|
198
198
|
| `bitmagic verify [--timeout <ms>] [--renderer webgpu\|webgl] [--platform desktop\|mobile\|both] [--fast] [--watch]` | Build, boot the game in a headless browser, press the engine's Play button like a player would, and report what broke. A game without the button passes as long as gameplay starts by itself (auto-starting genres, custom start UIs); a run where gameplay never starts fails. The settle is adaptive: the run ends as soon as the live engine proves stable gameplay (state, rendered frames, no fresh errors, player standing), with `--timeout` as the cap. The verdict includes live engine state — actual GPU backend, fps, player position, physics body count, gameplay events (see **Gameplay events** below) — recorded in `result.json`. `--renderer` pins the pipeline (default `webgpu`, what players run; a silent WebGPU→WebGL2 fallback **fails** the run, and `--renderer webgl` is the deliberate escape hatch). A run failing on a lost WebGL context retries once on software rendering automatically. `--fast` skips the screenshot pipeline (then there is no thumbnail candidate from this run). `--watch` keeps everything warm — incremental `tsc --watch`, one vite, one browser — and re-verifies on file change in seconds; `--fast` is the watch default (`--no-fast` restores the screenshot). `--platform` picks what the run emulates — see **Verifying the mobile path** below. Every run also reports the engine's mobile-parity check: a desktop action with no touch button is a warning, and a **failure** when `game.json` declares `primaryPlatform: "mobile"`. Writes the artifacts the publish gate reads (see below). |
|
|
199
199
|
| `bitmagic build [--single-file]` | Bundle the game into a single `.bitmagic/build/index.html`. The engine, your game and its data are inlined; three.js, Rapier and the other third-party packages load from a CDN at the versions your import map pins — the same shape a game published from bitmagic.ai has. `--single-file` inlines those too, for a game that has to run with no network (offline, `file://`, a packaged shell); the file is several megabytes bigger. Rarely needs to be run by hand — `publish` builds automatically when the project changed. |
|
|
@@ -323,6 +323,7 @@ my-game/
|
|
|
323
323
|
cover.json # its URL and the design hash it was generated from
|
|
324
324
|
AGENTS.md.latest # the current AGENTS.md template, when upgrade kept your edited one
|
|
325
325
|
dev.json # the running `bitmagic dev`'s ports, so `bitmagic reload` finds it
|
|
326
|
+
mobile-qr.png # the phone URL as a QR code, written when --mobile cannot draw one
|
|
326
327
|
jobs/ # one file per generation in flight — what the assets panel reads
|
|
327
328
|
previews/ # rendered asset thumbnails, cached so they are drawn once
|
|
328
329
|
build/
|
|
@@ -452,6 +453,45 @@ clipboard write the image is saved to your downloads instead, and the status bar
|
|
|
452
453
|
|
|
453
454
|
3010 still serves the game on its own, for a second window or a bookmark.
|
|
454
455
|
|
|
456
|
+
### On a real phone
|
|
457
|
+
|
|
458
|
+
`bitmagic dev --mobile` serves the game to your own network as well, and prints a QR code to scan:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
bitmagic dev --mobile
|
|
462
|
+
# On your phone https://192.168.1.23:3012/
|
|
463
|
+
# QR code .bitmagic/mobile-qr.png — open it to scan.
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
This is the thing no browser can fake. Emulation gets you a small viewport and synthetic touches;
|
|
467
|
+
a phone gets you iOS Safari's fullscreen rules, the real orientation behaviour, real multi-touch,
|
|
468
|
+
and a real thermal budget on a real GPU. The emulated run (**Verifying the mobile path** above)
|
|
469
|
+
still comes first — it is faster and it catches the obvious — but it is not a device.
|
|
470
|
+
|
|
471
|
+
Three things are worth knowing about how it works.
|
|
472
|
+
|
|
473
|
+
**The game is proxied, so its assets load.** Your levels and models live on the asset CDN, which
|
|
474
|
+
answers only the origins it allowlists — `http://localhost:3000`–`3199`, and no address a phone can
|
|
475
|
+
present. A phone asking the bucket directly gets nothing, and a level whose terrain never arrived
|
|
476
|
+
looks like a broken forge rather than a blocked request: you fall through the floor forever. So the
|
|
477
|
+
phone never asks the bucket. It asks your machine, which fetches on its behalf, where the rule does
|
|
478
|
+
not apply. Only `*.bitmagic.ai` and `*.bitmagic.cloud` are relayed this way; a third-party CDN in
|
|
479
|
+
your game has to allow the origin itself, as most do.
|
|
480
|
+
|
|
481
|
+
**It is served over https, and the certificate is self-signed.** Your phone will warn once per
|
|
482
|
+
address — tap *Show Details*, then *Visit Website*, and it remembers. The warning buys something
|
|
483
|
+
real: `navigator.gpu` exists only in a secure context, so over plain `http` the device would quietly
|
|
484
|
+
run the classic WebGL renderer and you would be testing a pipeline your players are not on. Pass
|
|
485
|
+
`--mobile-http` to skip the certificate anyway, and accept WebGL on the device. If `openssl` is not
|
|
486
|
+
installed, that is what happens by itself, and the banner says so.
|
|
487
|
+
|
|
488
|
+
**Reloads reach the phone.** It listens on the same channel the dev view does, so an agent edit —
|
|
489
|
+
or `bitmagic reload` — reloads what you are holding, without picking it up.
|
|
490
|
+
|
|
491
|
+
The editor is not exposed: the phone gets the game and the game's assets, and nothing that can write
|
|
492
|
+
to your project. The game, though, is genuinely visible to everything on your network for as long as
|
|
493
|
+
the command runs. On a café's Wi-Fi, that is worth a thought.
|
|
494
|
+
|
|
455
495
|
**If those ports are busy it moves and tells you** — it does not refuse to start. That matters
|
|
456
496
|
because agents run `bitmagic dev` as a background task, so a refusal would die into a log nobody
|
|
457
497
|
reads. `.bitmagic/dev.json` records what it actually bound, so `bitmagic reload` still finds it, and
|
|
@@ -812,9 +852,12 @@ The code is extra, never a substitute — the URL is always printed as a plain l
|
|
|
812
852
|
everything still works if neither a drawing nor a file appears. `--no-qr` and `BITMAGIC_NO_QR`
|
|
813
853
|
suppress both.
|
|
814
854
|
|
|
815
|
-
`bitmagic dev`
|
|
816
|
-
|
|
817
|
-
|
|
855
|
+
`bitmagic dev --mobile` is the same loop without the publish — see **On a real phone** above. It
|
|
856
|
+
takes a detour to get there: the asset CDN serves assets only to `localhost` origins, so a phone
|
|
857
|
+
pointed straight at your machine's LAN address loads the game with no terrain and drops the player
|
|
858
|
+
through the floor. `--mobile` fetches those assets on the phone's behalf, which is what makes the
|
|
859
|
+
LAN address work at all. Publishing privately is still the way onto a device that is not on your
|
|
860
|
+
network, or into someone else's hands.
|
|
818
861
|
|
|
819
862
|
### Which platform the game is catalogued as
|
|
820
863
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -205,6 +205,14 @@ declare const rawCommands: {
|
|
|
205
205
|
readonly type: "boolean";
|
|
206
206
|
readonly description: "Do not open a browser. Same as setting BITMAGIC_NO_OPEN.";
|
|
207
207
|
};
|
|
208
|
+
readonly mobile: {
|
|
209
|
+
readonly type: "boolean";
|
|
210
|
+
readonly description: "Also serve the game to phones on this network, and print a QR code for it.";
|
|
211
|
+
};
|
|
212
|
+
readonly 'mobile-http': {
|
|
213
|
+
readonly type: "boolean";
|
|
214
|
+
readonly description: "Serve --mobile over http instead of a self-signed certificate (no WebGPU on the device).";
|
|
215
|
+
};
|
|
208
216
|
}>;
|
|
209
217
|
reload: CommandDef<{
|
|
210
218
|
readonly port: {
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -11,4 +11,12 @@ export declare const devCommand: import("citty").CommandDef<{
|
|
|
11
11
|
readonly type: "boolean";
|
|
12
12
|
readonly description: "Do not open a browser. Same as setting BITMAGIC_NO_OPEN.";
|
|
13
13
|
};
|
|
14
|
+
readonly mobile: {
|
|
15
|
+
readonly type: "boolean";
|
|
16
|
+
readonly description: "Also serve the game to phones on this network, and print a QR code for it.";
|
|
17
|
+
};
|
|
18
|
+
readonly 'mobile-http': {
|
|
19
|
+
readonly type: "boolean";
|
|
20
|
+
readonly description: "Serve --mobile over http instead of a self-signed certificate (no WebGPU on the device).";
|
|
21
|
+
};
|
|
14
22
|
}>;
|
package/dist/commands/dev.js
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { defineCommand } from 'citty';
|
|
18
18
|
import { spawn, spawnSync } from 'child_process';
|
|
19
|
+
import * as fs from 'fs';
|
|
20
|
+
import * as os from 'os';
|
|
19
21
|
import * as path from 'path';
|
|
20
22
|
import { CliError } from '../errors.js';
|
|
21
23
|
import { loadProjectContext, projectBin } from '../project/context.js';
|
|
@@ -27,6 +29,10 @@ import { ReloadBus } from '../editor/reload-bus.js';
|
|
|
27
29
|
import { ReloadCoordinator, pipeTscWatch, watchProject } from '../editor/watch.js';
|
|
28
30
|
import { CORS_ALLOWED_PORT_MAX, CORS_ALLOWED_PORT_MIN, isPortFree, parseLocalPort, resolveDevPort, } from '../local-port.js';
|
|
29
31
|
import { openInBrowser, NO_OPEN_ENV } from '../open-browser.js';
|
|
32
|
+
import { lanAddresses } from '../mobile/lan-address.js';
|
|
33
|
+
import { ensureDevCert } from '../mobile/dev-cert.js';
|
|
34
|
+
import { startMobileBridge } from '../mobile/bridge.js';
|
|
35
|
+
import { devQrPath, emitQr } from '../render/qr-output.js';
|
|
30
36
|
import { waitForServer } from '../verify/wait-for-server.js';
|
|
31
37
|
import { engineUpdateNotice } from '../project/engine-update.js';
|
|
32
38
|
import { reportCommandEvent } from '../telemetry/report.js';
|
|
@@ -62,6 +68,9 @@ async function notifyIfEngineOutdated(environment, projectEngineVersion, log) {
|
|
|
62
68
|
}
|
|
63
69
|
}
|
|
64
70
|
const DEFAULT_GAME_PORT = 3010;
|
|
71
|
+
// The editor's own default now lives beside the handle that records it (project/dev-handle.ts);
|
|
72
|
+
// only the phone bridge's is still this file's to name.
|
|
73
|
+
const DEFAULT_MOBILE_PORT = 3012;
|
|
65
74
|
/**
|
|
66
75
|
* The port to bind, given what the creator asked for.
|
|
67
76
|
*
|
|
@@ -109,6 +118,14 @@ export const devCommand = defineCommand({
|
|
|
109
118
|
type: 'boolean',
|
|
110
119
|
description: `Do not open a browser. Same as setting ${NO_OPEN_ENV}.`,
|
|
111
120
|
},
|
|
121
|
+
mobile: {
|
|
122
|
+
type: 'boolean',
|
|
123
|
+
description: 'Also serve the game to phones on this network, and print a QR code for it.',
|
|
124
|
+
},
|
|
125
|
+
'mobile-http': {
|
|
126
|
+
type: 'boolean',
|
|
127
|
+
description: 'Serve --mobile over http instead of a self-signed certificate (no WebGPU on the device).',
|
|
128
|
+
},
|
|
112
129
|
},
|
|
113
130
|
async run({ args }) {
|
|
114
131
|
const context = loadProjectContext();
|
|
@@ -170,6 +187,44 @@ export const devCommand = defineCommand({
|
|
|
170
187
|
coordinator,
|
|
171
188
|
log: (message) => console.log(message),
|
|
172
189
|
});
|
|
190
|
+
/**
|
|
191
|
+
* The phone-facing bridge, when asked for. Started before the children for the same reason the
|
|
192
|
+
* sidecar is: a machine on no network, or a taken port, should stop the command here rather
|
|
193
|
+
* than after vite has claimed a port and tsc has begun a watch.
|
|
194
|
+
*/
|
|
195
|
+
let mobile = null;
|
|
196
|
+
let mobileAddresses = [];
|
|
197
|
+
let mobilePort = 0;
|
|
198
|
+
let mobileSecure = false;
|
|
199
|
+
if (args.mobile === true) {
|
|
200
|
+
mobileAddresses = lanAddresses(os.networkInterfaces());
|
|
201
|
+
const primary = mobileAddresses[0];
|
|
202
|
+
if (primary === undefined) {
|
|
203
|
+
throw new CliError('`--mobile` found no local network address to serve on. Connect this machine to the same '
|
|
204
|
+
+ 'Wi-Fi as the phone, then run it again.');
|
|
205
|
+
}
|
|
206
|
+
// The certificate is what buys a secure context, and a secure context is what exposes
|
|
207
|
+
// `navigator.gpu` — without it the device silently tests the WebGL renderer instead of the
|
|
208
|
+
// one production runs. A machine with no openssl still gets a phone URL; it gets told what
|
|
209
|
+
// that costs rather than being refused the feature.
|
|
210
|
+
const cert = args['mobile-http'] === true ? null : ensureDevCert(primary.address);
|
|
211
|
+
if (cert === null && args['mobile-http'] !== true) {
|
|
212
|
+
console.log('Could not generate a certificate (is `openssl` installed?) — serving the phone over http '
|
|
213
|
+
+ 'instead. WebGPU is only exposed to secure contexts, so the device will run WebGL.');
|
|
214
|
+
}
|
|
215
|
+
mobileSecure = cert !== null;
|
|
216
|
+
mobilePort = await claimPort(DEFAULT_MOBILE_PORT, false, '--mobile', new Set([gamePort, editorPort]));
|
|
217
|
+
mobile = await startMobileBridge({
|
|
218
|
+
gamePort,
|
|
219
|
+
port: mobilePort,
|
|
220
|
+
address: primary.address,
|
|
221
|
+
tls: cert,
|
|
222
|
+
log: (message) => console.log(message),
|
|
223
|
+
// The phone joins the same push channel the shell is on, so an agent edit reloads it too.
|
|
224
|
+
// Read-only, and the only thing on the sidecar the network can reach.
|
|
225
|
+
subscribe: (req, res) => bus.subscribe(req, res),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
173
228
|
const children = [
|
|
174
229
|
// Piped rather than inherited — see the file header and editor/watch.ts.
|
|
175
230
|
{ name: 'tsc --watch', process: pipeTscWatch(tsc, context.root, coordinator) },
|
|
@@ -179,7 +234,12 @@ export const devCommand = defineCommand({
|
|
|
179
234
|
},
|
|
180
235
|
];
|
|
181
236
|
const watcher = watchProject(context.root, coordinator, (m) => console.log(m));
|
|
182
|
-
writeDevHandle(context.root, {
|
|
237
|
+
writeDevHandle(context.root, {
|
|
238
|
+
editorPort,
|
|
239
|
+
gamePort,
|
|
240
|
+
pid: process.pid,
|
|
241
|
+
...(mobile === null ? {} : { mobileUrl: mobile.url }),
|
|
242
|
+
});
|
|
183
243
|
let shuttingDown = false;
|
|
184
244
|
let requestedByUser = false;
|
|
185
245
|
const shutdown = () => {
|
|
@@ -193,6 +253,7 @@ export const devCommand = defineCommand({
|
|
|
193
253
|
bus.close();
|
|
194
254
|
removeDevHandle(context.root);
|
|
195
255
|
void editor.close();
|
|
256
|
+
void mobile?.close();
|
|
196
257
|
};
|
|
197
258
|
process.on('SIGINT', () => {
|
|
198
259
|
requestedByUser = true;
|
|
@@ -230,6 +291,43 @@ export const devCommand = defineCommand({
|
|
|
230
291
|
// being told — the journal is the only record of intentions the editor cannot carry out
|
|
231
292
|
// itself, and of who changed what.
|
|
232
293
|
console.log(` Editor actions ${path.relative(context.root, editor.journalPath)}`);
|
|
294
|
+
if (mobile !== null) {
|
|
295
|
+
const scheme = mobileSecure ? 'https' : 'http';
|
|
296
|
+
console.log(`\n On your phone ${mobile.url}`);
|
|
297
|
+
// Every address, not just the best guess: a laptop on Wi-Fi and Ethernet at once has two
|
|
298
|
+
// right answers and only the creator knows which network the phone is on.
|
|
299
|
+
for (const other of mobileAddresses.slice(1)) {
|
|
300
|
+
console.log(` or ${scheme}://${other.address}:${mobilePort}/ (${other.name})`);
|
|
301
|
+
}
|
|
302
|
+
// Written to a file when it cannot be drawn, because `dev` is usually started as a
|
|
303
|
+
// background task by an agent — a pipe, where the creator never sees this terminal.
|
|
304
|
+
const qrPath = emitQr(mobile.url, {
|
|
305
|
+
root: context.root, json: false, disabled: false, file: devQrPath(context.root),
|
|
306
|
+
});
|
|
307
|
+
if (qrPath !== null) {
|
|
308
|
+
console.log(` QR code ${path.relative(context.root, qrPath)} — open it to scan.`);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
// Drawn, so no file was written — and one left from an earlier run holds an address
|
|
312
|
+
// this machine may no longer have. A stale QR is worse than none: it scans, and then
|
|
313
|
+
// the phone sits on a URL nothing answers, with nothing on screen to say why.
|
|
314
|
+
try {
|
|
315
|
+
fs.rmSync(devQrPath(context.root));
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// There was no file to clear, which is the normal case.
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (mobileSecure) {
|
|
322
|
+
console.log('\n The certificate is self-signed: the phone warns once per address —'
|
|
323
|
+
+ ' tap Show Details, then Visit Website.');
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
console.log('\n Serving over http, so the device has no secure context: it will run the'
|
|
327
|
+
+ ' WebGL renderer, not WebGPU.');
|
|
328
|
+
}
|
|
329
|
+
console.log(' Anything on your local network can open the game while this is running.');
|
|
330
|
+
}
|
|
233
331
|
console.log('\nThe browser reloads itself when the project changes. `bitmagic reload` forces it.\n');
|
|
234
332
|
})
|
|
235
333
|
.catch(() => {
|
|
@@ -261,6 +359,7 @@ export const devCommand = defineCommand({
|
|
|
261
359
|
// Both children are gone by here — via a signal handler or via the failure path above, each of
|
|
262
360
|
// which has already run shutdown(). This awaits the close that shutdown() could only start.
|
|
263
361
|
await editor.close();
|
|
362
|
+
await mobile?.close();
|
|
264
363
|
if (failure) {
|
|
265
364
|
throw new CliError(`${failure.name} ${failure.detail}. \`bitmagic dev\` stopped.`);
|
|
266
365
|
}
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EACL,yBAAyB,EACzB,2BAA2B,GAE5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,GACxE,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAqB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AACxG,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,UAAU,EACV,cAAc,EACd,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE;;;;;;;;;;GAUG;AACH,KAAK,UAAU,sBAAsB,CAAC,WAAwB,EAAE,oBAA4B,EAAE,GAAwB;IACpH,IAAI,CAAC;QACH,2FAA2F;QAC3F,sFAAsF;QACtF,MAAM,CAAC,EAAE,oBAAoB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,mBAAmB,EAAE,CAAC,GAC3E,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,MAAM,CAAC,2BAA2B,CAAC;YACnC,MAAM,CAAC,oBAAoB,CAAC;YAC5B,MAAM,CAAC,gCAAgC,CAAC;SACzC,CAAC,CAAC;QACL,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACpL,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5F,MAAM,MAAM,GAAG,kBAAkB,CAAC,oBAAoB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,MAAM,KAAK,IAAI;YAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,0FAA0F;IAC5F,CAAC;AACH,CAAC;AAED,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAO/B;;;;;;;;;;;;;;;GAeG;AACH,KAAK,UAAU,SAAS,CACtB,SAAiB,EACjB,WAAoB,EACpB,IAAY,EACZ,OAA4B;IAE5B,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,QAAQ,CAChB,QAAQ,SAAS,wDAAwD;kBACvE,oDAAoD,IAAI,KAAK,CAChE,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACtD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,QAAQ,CAChB,mBAAmB,qBAAqB,OAAO,qBAAqB,iBAAiB;cACnF,2FAA2F;cAC3F,kDAAkD,CACrD,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC;IACtC,IAAI,EAAE;QACJ,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,mFAAmF;KACjG;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,iBAAiB,IAAI,EAAE;QAClG,aAAa,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kDAAkD,mBAAmB,IAAI;SACvF;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,0CAA0C,WAAW,GAAG;SACtE;KACF;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QACrC,0FAA0F;QAC1F,sFAAsF;QACtF,mEAAmE;QACnE,MAAM,SAAS,GAAG,2BAA2B,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CACT,gBAAgB,SAAS,CAAC,WAAW,CAAC,IAAI,KAAK,yBAAyB,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAC9F,CAAC;QACF,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,gGAAgG;QAChG,iGAAiG;QACjG,gGAAgG;QAChG,kFAAkF;QAClF,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,QAAQ,CAChB,0EAA0E,OAAO,CAAC,UAAU,IAAI;kBAC9F,QAAQ,OAAO,CAAC,GAAG,mDAAmD,CACzE,CAAC;QACJ,CAAC;QAED,MAAM,iBAAiB,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QACjF,MAAM,mBAAmB,GAAG,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;QACtG,IAAI,iBAAiB,KAAK,mBAAmB,EAAE,CAAC;YAC9C,MAAM,IAAI,QAAQ,CAAC,oFAAoF,CAAC,CAAC;QAC3G,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAClG,MAAM,UAAU,GAAG,MAAM,SAAS,CAChC,mBAAmB,EACnB,IAAI,CAAC,aAAa,CAAC,KAAK,SAAS,EACjC,eAAe,EACf,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CACpB,CAAC;QACF,IAAI,QAAQ,KAAK,iBAAiB,IAAI,UAAU,KAAK,mBAAmB,EAAE,CAAC;YACzE,OAAO,CAAC,GAAG,CAAC,SAAS,iBAAiB,IAAI,mBAAmB,sBAAsB,QAAQ,IAAI,UAAU,GAAG,CAAC,CAAC;QAChH,CAAC;QAED,0FAA0F;QAC1F,4FAA4F;QAC5F,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,MAAM,IAAI,QAAQ,CAAC,oEAAoE,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QAC9G,CAAC;QAED,4EAA4E;QAC5E,KAAK,sBAAsB,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1G,8FAA8F;QAC9F,8DAA8D;QAC9D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAExB,6FAA6F;QAC7F,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,IAAI,iBAAiB,CAAC;YACxC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;SACzD,CAAC,CAAC;QAEH,+FAA+F;QAC/F,MAAM,MAAM,GAAiB,MAAM,iBAAiB,CAAC;YACnD,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM;YAC/B,QAAQ;YACR,IAAI,EAAE,UAAU;YAChB,GAAG;YACH,WAAW;YACX,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;SACvC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAiB;YAC7B,yEAAyE;YACzE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE;YAC9E;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;aAC5G;SACF,CAAC;QAEF,MAAM,OAAO,GAAmB,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAEzE,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC1B,IAAI,YAAY;gBAAE,OAAO;YACzB,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,MAAM,KAAK,IAAI,QAAQ;gBAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5D,WAAW,CAAC,IAAI,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,GAAG,CAAC,KAAK,EAAE,CAAC;YACZ,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9B,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACxB,eAAe,GAAG,IAAI,CAAC;YACvB,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACzB,eAAe,GAAG,IAAI,CAAC;YACvB,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,yFAAyF;QACzF,+FAA+F;QAC/F,4FAA4F;QAC5F,gEAAgE;QAChE,KAAK,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC;aACjC,IAAI,CAAC,GAAG,EAAE;YACT,uFAAuF;YACvF,yFAAyF;YACzF,yFAAyF;YACzF,wFAAwF;YACxF,uFAAuF;YACvF,MAAM,gBAAgB,GAAG,cAAc,EAAE,EAAE,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACnE,KAAK,kBAAkB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC;YACnG,yFAAyF;YACzF,0FAA0F;YAC1F,4EAA4E;YAC5E,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE;gBACvC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI;gBAClC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;aAC3B,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,MAAM;gBAChB,CAAC,CAAC,cAAc,MAAM,CAAC,GAAG,oBAAoB;gBAC9C,CAAC,CAAC,cAAc,MAAM,CAAC,GAAG,oBAAoB,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,yCAAyC,QAAQ,GAAG,CAAC,CAAC;YAClE,uFAAuF;YACvF,wFAAwF;YACxF,mCAAmC;YACnC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACrF,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;QACvG,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,wFAAwF;YACxF,oCAAoC;QACtC,CAAC,CAAC,CAAC;QAEL,6FAA6F;QAC7F,wFAAwF;QACxF,0FAA0F;QAC1F,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAA+C,CAAC,OAAO,EAAE,EAAE;YAC1F,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBAClC,QAAQ,EAAE,CAAC;oBACX,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,oBAAoB,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC7E,CAAC,CAAC,CAAC;gBACH,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;oBACxC,WAAW,IAAI,CAAC,CAAC;oBACjB,IAAI,CAAC,eAAe,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtC,QAAQ,EAAE,CAAC;wBACX,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,oBAAoB,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC1G,CAAC;yBAAM,IAAI,WAAW,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;wBAC3C,OAAO,CAAC,SAAS,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,+FAA+F;QAC/F,4FAA4F;QAC5F,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAErB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,6BAA6B,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which absolute URLs the mobile bridge proxies, and the path it proxies them under.
|
|
3
|
+
*
|
|
4
|
+
* A phone on the local network loads the game from a LAN origin, and the asset bucket's CORS policy
|
|
5
|
+
* allowlists literal `http://localhost:3000`-`3199` origins and nothing else (see `../local-port.ts`
|
|
6
|
+
* for what that costs when it is violated: a terrain-less world and a player falling forever). No
|
|
7
|
+
* origin a phone can present is ever on that list, and broadening the list to cover private IP
|
|
8
|
+
* ranges is not expressible in GCS CORS — it would mean `*` for everyone.
|
|
9
|
+
*
|
|
10
|
+
* So the phone never talks to the bucket. It asks the BRIDGE, same-origin, and the dev machine
|
|
11
|
+
* fetches the asset server-side, where CORS does not exist at all. This module is the two halves of
|
|
12
|
+
* that redirection: which hosts are ours to fetch on the browser's behalf, and the reversible path
|
|
13
|
+
* that carries one.
|
|
14
|
+
*
|
|
15
|
+
* The host suffixes are the same environment classification `rehost-imported-assets.ts` uses in
|
|
16
|
+
* game-play-agent: `bitmagic.ai` is prod (`mini.bitmagic.ai`, `forged-assets.bitmagic.ai`, ...) and
|
|
17
|
+
* `bitmagic.cloud` is dev/sandbox (`beta.portal.bitmagic.cloud`,
|
|
18
|
+
* `magic-mesh-gen.sandbox.dev.bitmagic.cloud`, ...). Everything else is deliberately left alone:
|
|
19
|
+
* `esm.sh` serves the import map's modules and already answers `*`, and an unrecognised host is
|
|
20
|
+
* more likely to be a creator's own endpoint than an asset we should be relaying.
|
|
21
|
+
*/
|
|
22
|
+
/** The bridge route every proxied asset is fetched through. Trailing slash included. */
|
|
23
|
+
export declare const CDN_PROXY_PREFIX = "/__bm/cdn/";
|
|
24
|
+
/** Host suffixes that identify a bitmagic-controlled asset host. See the file header. */
|
|
25
|
+
export declare const MANAGED_HOST_SUFFIXES: readonly ["bitmagic.ai", "bitmagic.cloud"];
|
|
26
|
+
export declare function isManagedAssetHost(hostname: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The same-origin path that stands in for `url`, or null when the URL is not ours to proxy.
|
|
29
|
+
*
|
|
30
|
+
* Path-PRESERVING rather than `?u=<encoded>`, because GLTFLoader resolves a `.bin` or a texture
|
|
31
|
+
* sibling RELATIVE to the URL the .glb came from. Under a query-string form that resolution drops
|
|
32
|
+
* the query and lands on the bridge's own root; under this form it lands next to the .glb, on the
|
|
33
|
+
* same upstream host, which is where it actually lives.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toProxyPath(url: string): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* The upstream URL a proxy path stands for, or null when the path is not one (or names a host we
|
|
38
|
+
* do not relay for).
|
|
39
|
+
*
|
|
40
|
+
* The host allowlist is re-checked HERE rather than trusted from `toProxyPath`: this half runs on
|
|
41
|
+
* request paths the bridge receives, which anything on the local network can compose. Traversal in
|
|
42
|
+
* the remainder needs no separate guard — every form of it stays on the host named in the first
|
|
43
|
+
* segment, which is the only thing this decides.
|
|
44
|
+
*/
|
|
45
|
+
export declare function fromProxyPath(requestPath: string): string | null;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which absolute URLs the mobile bridge proxies, and the path it proxies them under.
|
|
3
|
+
*
|
|
4
|
+
* A phone on the local network loads the game from a LAN origin, and the asset bucket's CORS policy
|
|
5
|
+
* allowlists literal `http://localhost:3000`-`3199` origins and nothing else (see `../local-port.ts`
|
|
6
|
+
* for what that costs when it is violated: a terrain-less world and a player falling forever). No
|
|
7
|
+
* origin a phone can present is ever on that list, and broadening the list to cover private IP
|
|
8
|
+
* ranges is not expressible in GCS CORS — it would mean `*` for everyone.
|
|
9
|
+
*
|
|
10
|
+
* So the phone never talks to the bucket. It asks the BRIDGE, same-origin, and the dev machine
|
|
11
|
+
* fetches the asset server-side, where CORS does not exist at all. This module is the two halves of
|
|
12
|
+
* that redirection: which hosts are ours to fetch on the browser's behalf, and the reversible path
|
|
13
|
+
* that carries one.
|
|
14
|
+
*
|
|
15
|
+
* The host suffixes are the same environment classification `rehost-imported-assets.ts` uses in
|
|
16
|
+
* game-play-agent: `bitmagic.ai` is prod (`mini.bitmagic.ai`, `forged-assets.bitmagic.ai`, ...) and
|
|
17
|
+
* `bitmagic.cloud` is dev/sandbox (`beta.portal.bitmagic.cloud`,
|
|
18
|
+
* `magic-mesh-gen.sandbox.dev.bitmagic.cloud`, ...). Everything else is deliberately left alone:
|
|
19
|
+
* `esm.sh` serves the import map's modules and already answers `*`, and an unrecognised host is
|
|
20
|
+
* more likely to be a creator's own endpoint than an asset we should be relaying.
|
|
21
|
+
*/
|
|
22
|
+
/** The bridge route every proxied asset is fetched through. Trailing slash included. */
|
|
23
|
+
export const CDN_PROXY_PREFIX = '/__bm/cdn/';
|
|
24
|
+
/** Host suffixes that identify a bitmagic-controlled asset host. See the file header. */
|
|
25
|
+
export const MANAGED_HOST_SUFFIXES = ['bitmagic.ai', 'bitmagic.cloud'];
|
|
26
|
+
/** A hostname with no port and no credentials — what a proxy path's first segment may hold. */
|
|
27
|
+
const HOSTNAME = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;
|
|
28
|
+
export function isManagedAssetHost(hostname) {
|
|
29
|
+
const host = hostname.toLowerCase();
|
|
30
|
+
if (!HOSTNAME.test(host))
|
|
31
|
+
return false;
|
|
32
|
+
return MANAGED_HOST_SUFFIXES.some((suffix) => host === suffix || host.endsWith(`.${suffix}`));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The same-origin path that stands in for `url`, or null when the URL is not ours to proxy.
|
|
36
|
+
*
|
|
37
|
+
* Path-PRESERVING rather than `?u=<encoded>`, because GLTFLoader resolves a `.bin` or a texture
|
|
38
|
+
* sibling RELATIVE to the URL the .glb came from. Under a query-string form that resolution drops
|
|
39
|
+
* the query and lands on the bridge's own root; under this form it lands next to the .glb, on the
|
|
40
|
+
* same upstream host, which is where it actually lives.
|
|
41
|
+
*/
|
|
42
|
+
export function toProxyPath(url) {
|
|
43
|
+
let parsed;
|
|
44
|
+
try {
|
|
45
|
+
parsed = new URL(url);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')
|
|
51
|
+
return null;
|
|
52
|
+
if (parsed.port !== '' || parsed.username !== '' || parsed.password !== '')
|
|
53
|
+
return null;
|
|
54
|
+
if (!isManagedAssetHost(parsed.hostname))
|
|
55
|
+
return null;
|
|
56
|
+
return `${CDN_PROXY_PREFIX}${parsed.hostname}${parsed.pathname}${parsed.search}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The upstream URL a proxy path stands for, or null when the path is not one (or names a host we
|
|
60
|
+
* do not relay for).
|
|
61
|
+
*
|
|
62
|
+
* The host allowlist is re-checked HERE rather than trusted from `toProxyPath`: this half runs on
|
|
63
|
+
* request paths the bridge receives, which anything on the local network can compose. Traversal in
|
|
64
|
+
* the remainder needs no separate guard — every form of it stays on the host named in the first
|
|
65
|
+
* segment, which is the only thing this decides.
|
|
66
|
+
*/
|
|
67
|
+
export function fromProxyPath(requestPath) {
|
|
68
|
+
if (!requestPath.startsWith(CDN_PROXY_PREFIX))
|
|
69
|
+
return null;
|
|
70
|
+
const rest = requestPath.slice(CDN_PROXY_PREFIX.length);
|
|
71
|
+
const slash = rest.indexOf('/');
|
|
72
|
+
if (slash <= 0)
|
|
73
|
+
return null;
|
|
74
|
+
const host = rest.slice(0, slash).toLowerCase();
|
|
75
|
+
if (!isManagedAssetHost(host))
|
|
76
|
+
return null;
|
|
77
|
+
return `https://${host}${rest.slice(slash)}`;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=asset-hosts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-hosts.js","sourceRoot":"","sources":["../../src/mobile/asset-hosts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,wFAAwF;AACxF,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C,yFAAyF;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,aAAa,EAAE,gBAAgB,CAAU,CAAC;AAEhF,+FAA+F;AAC/F,MAAM,QAAQ,GAAG,mEAAmE,CAAC;AAErF,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC7E,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE,IAAI,MAAM,CAAC,QAAQ,KAAK,EAAE,IAAI,MAAM,CAAC,QAAQ,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACxF,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,OAAO,GAAG,gBAAgB,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;AACnF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,WAAW,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The mobile bridge: the one server `bitmagic dev` exposes to the local network.
|
|
3
|
+
*
|
|
4
|
+
* `dev` normally binds nothing outside loopback. vite serves the game on 127.0.0.1 and the editor
|
|
5
|
+
* sidecar deliberately stays there too — it writes files in the creator's project, and no phone
|
|
6
|
+
* needs the shell. So rather than opening either of them up, `--mobile` puts THIS in front: a
|
|
7
|
+
* reverse proxy that terminates the phone's connection, forwards the game, and does the two things
|
|
8
|
+
* a plain `--host` on vite could not.
|
|
9
|
+
*
|
|
10
|
+
* 1. It serves the CDN. A LAN origin is on no bucket's CORS allowlist, so the phone asking the
|
|
11
|
+
* bucket directly gets nothing (`../local-port.ts` documents what that looks like from the
|
|
12
|
+
* creator's side: a level with no terrain). Same-origin `/__bm/cdn/<host>/<path>` requests
|
|
13
|
+
* land here instead and are fetched server-side, where CORS does not apply.
|
|
14
|
+
* 2. It injects `rewrite-shim.ts` into every HTML page it passes through, which is what makes
|
|
15
|
+
* the engine ask for (1) in the first place.
|
|
16
|
+
*
|
|
17
|
+
* WebSocket upgrades are piped straight through to vite, so its HMR client connects from the phone
|
|
18
|
+
* and the page reloads on a rebuild exactly as the desktop shell does.
|
|
19
|
+
*
|
|
20
|
+
* What is NOT here is as deliberate: no route to the sidecar, and therefore no way for anything on
|
|
21
|
+
* the network to save a scene, start a generation, or read the editor journal. The phone gets the
|
|
22
|
+
* game and the game's assets.
|
|
23
|
+
*/
|
|
24
|
+
import * as http from 'http';
|
|
25
|
+
export interface MobileBridgeOptions {
|
|
26
|
+
/** Where vite is serving the game, on loopback. */
|
|
27
|
+
gamePort: number;
|
|
28
|
+
/** The port to expose on the network. */
|
|
29
|
+
port: number;
|
|
30
|
+
/** The LAN address the printed URL names. The bridge itself listens on every interface. */
|
|
31
|
+
address: string;
|
|
32
|
+
/** A key/cert pair from `dev-cert.ts`, or null to serve plain http (no WebGPU on the device). */
|
|
33
|
+
tls: {
|
|
34
|
+
key: string;
|
|
35
|
+
cert: string;
|
|
36
|
+
} | null;
|
|
37
|
+
log: (message: string) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Hands one request to the reload bus as an SSE stream, putting the phone on the SAME push
|
|
40
|
+
* channel as the desktop shell — the coordinator's, which only fires once a compile has landed.
|
|
41
|
+
*
|
|
42
|
+
* Passed as a function rather than the bus itself so this module stays unaware of the editor's
|
|
43
|
+
* half of `dev`. It is the one sidecar capability the network is given, and it is one-directional
|
|
44
|
+
* and read-only: nothing on the other end of it can save a scene or read the journal.
|
|
45
|
+
*/
|
|
46
|
+
subscribe?: (req: http.IncomingMessage, res: http.ServerResponse) => void;
|
|
47
|
+
/** Seam for the test; production uses the runtime's own fetch. */
|
|
48
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
49
|
+
}
|
|
50
|
+
export interface MobileBridge {
|
|
51
|
+
/** What to print, and what the QR encodes. */
|
|
52
|
+
url: string;
|
|
53
|
+
close(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Start the bridge and return the URL to hand the phone.
|
|
57
|
+
*
|
|
58
|
+
* Listens on every interface — that is the point of the command — which is why `dev` prints what
|
|
59
|
+
* that means alongside the URL.
|
|
60
|
+
*/
|
|
61
|
+
export declare function startMobileBridge(options: MobileBridgeOptions): Promise<MobileBridge>;
|