@dreamboard-games/cli 0.1.30-alpha.1 → 0.1.30-alpha.3
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 +179 -22
- package/dist/agent-verifier/agent-workspace-verifier.mjs +30 -30
- package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-JH22JNYD.mjs → chunk-3UKQVWLV.mjs} +82 -19
- package/dist/agent-verifier/chunk-3UKQVWLV.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-4WD3YU2E.mjs → chunk-776W3UGV.mjs} +4 -3
- package/dist/agent-verifier/chunk-776W3UGV.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-CJEEA6NJ.mjs → chunk-7WWGFAAU.mjs} +9 -10
- package/dist/agent-verifier/chunk-7WWGFAAU.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-2SZHMP6F.mjs → chunk-A64ZZUZV.mjs} +6 -9
- package/dist/agent-verifier/chunk-A64ZZUZV.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-6A5HRJMQ.mjs → chunk-E7SSWJXJ.mjs} +62 -99
- package/dist/agent-verifier/chunk-E7SSWJXJ.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-2GBBP27W.mjs → chunk-F2DIOJJZ.mjs} +1 -0
- package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-CFU5EWIC.mjs → chunk-G42BGGG2.mjs} +7 -6
- package/dist/agent-verifier/chunk-G42BGGG2.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-SHUMAVAP.mjs → chunk-H76MT5UR.mjs} +7 -9
- package/dist/agent-verifier/chunk-H76MT5UR.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-7E65UQLY.mjs → chunk-HGMUAL33.mjs} +3 -2
- package/dist/agent-verifier/chunk-HGMUAL33.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-LM3OZLZG.mjs → chunk-IAYRNVUC.mjs} +1 -0
- package/dist/agent-verifier/chunk-IAYRNVUC.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-VYJTHSYR.mjs → chunk-JGT4P4UD.mjs} +2 -1
- package/dist/agent-verifier/chunk-JGT4P4UD.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-CEDUHGNH.mjs → chunk-LUZ7KE6H.mjs} +8 -3
- package/dist/agent-verifier/chunk-LUZ7KE6H.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-2E5P5NWG.mjs → chunk-NAK77WXW.mjs} +58 -126
- package/dist/agent-verifier/chunk-NAK77WXW.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-SYPLYRGB.mjs → chunk-O4YCPU7C.mjs} +116 -15
- package/dist/agent-verifier/chunk-O4YCPU7C.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-BVVNBJM4.mjs → chunk-S34FRJHS.mjs} +2 -1
- package/dist/agent-verifier/chunk-S34FRJHS.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-HJFQDSTU.mjs → chunk-SH5JKYOB.mjs} +6 -5
- package/dist/agent-verifier/chunk-SH5JKYOB.mjs.map +1 -0
- package/dist/agent-verifier/chunk-SKI2ESE5.mjs +44 -0
- package/dist/agent-verifier/{chunk-MINCYHXN.mjs → chunk-TAEQKBJB.mjs} +1 -0
- package/dist/agent-verifier/chunk-TAEQKBJB.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-CEQ2VJWN.mjs → chunk-UIOLGH4A.mjs} +2 -1
- package/dist/agent-verifier/chunk-UIOLGH4A.mjs.map +1 -0
- package/dist/agent-verifier/chunk-UIZNWRM6.mjs +2432 -0
- package/dist/agent-verifier/chunk-UIZNWRM6.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-2QMNAVV4.mjs → chunk-VS573ERH.mjs} +2 -1
- package/dist/agent-verifier/chunk-VS573ERH.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-EOQIV6PS.mjs → chunk-W3N3QJ4V.mjs} +75 -100
- package/dist/agent-verifier/chunk-W3N3QJ4V.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-EIQWDQWJ.mjs → chunk-XGWCY624.mjs} +11 -12
- package/dist/agent-verifier/chunk-XGWCY624.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-7653FPGJ.mjs → chunk-XQXDOBYB.mjs} +3 -2
- package/dist/agent-verifier/chunk-XQXDOBYB.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-MRCUP5SW.mjs → chunk-YE7UAO3T.mjs} +1 -0
- package/dist/agent-verifier/chunk-YE7UAO3T.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-RBDDIIPM.mjs → chunk-ZEELHSY3.mjs} +1 -0
- package/dist/agent-verifier/chunk-ZEELHSY3.mjs.map +1 -0
- package/dist/agent-verifier/{compile-5QSPIOUT.mjs → compile-TEQVA46V.mjs} +24 -25
- package/dist/agent-verifier/compile-TEQVA46V.mjs.map +1 -0
- package/dist/agent-verifier/{global-config-WX3ZZIVU.mjs → global-config-Y2NTSK4R.mjs} +6 -5
- package/dist/{keychain-backend-JHTXAKWC.js → agent-verifier/keychain-backend-SPQWGKZN.mjs} +2 -2
- package/dist/agent-verifier/keychain-backend-SPQWGKZN.mjs.map +1 -0
- package/dist/agent-verifier/{local-files-MTPLP62S.mjs → local-files-JFOQQZDL.mjs} +10 -11
- package/dist/agent-verifier/local-files-JFOQQZDL.mjs.map +1 -0
- package/dist/agent-verifier/local-typecheck-XVGWI75X.mjs +10 -0
- package/dist/agent-verifier/local-typecheck-XVGWI75X.mjs.map +1 -0
- package/dist/agent-verifier/{materialize-workspace-FKALAE2T.mjs → materialize-workspace-ZAVGQQSF.mjs} +17 -18
- package/dist/agent-verifier/materialize-workspace-ZAVGQQSF.mjs.map +1 -0
- package/dist/agent-verifier/{project-state-7GR6BQTQ.mjs → project-state-K576C2TE.mjs} +3 -2
- package/dist/agent-verifier/project-state-K576C2TE.mjs.map +1 -0
- package/dist/{prompt-GMZABCJC.js → agent-verifier/prompt-MJRJMOGQ.mjs} +2 -2
- package/dist/agent-verifier/prompt-MJRJMOGQ.mjs.map +1 -0
- package/dist/agent-verifier/{reducer-bundle-preflight-C73LEXI2.mjs → reducer-bundle-preflight-LXNJUBKL.mjs} +6 -9
- package/dist/agent-verifier/reducer-bundle-preflight-LXNJUBKL.mjs.map +1 -0
- package/dist/agent-verifier/reducer-contract-preflight-TUMQ43JV.mjs +11 -0
- package/dist/agent-verifier/reducer-contract-preflight-TUMQ43JV.mjs.map +1 -0
- package/dist/agent-verifier/{reducer-native-test-harness-GMWBUISX.mjs → reducer-native-test-harness-CHX5MBL5.mjs} +14 -17
- package/dist/agent-verifier/reducer-native-test-harness-CHX5MBL5.mjs.map +1 -0
- package/dist/agent-verifier/static-scaffold-R7SVDRQI.mjs +27 -0
- package/dist/agent-verifier/static-scaffold-R7SVDRQI.mjs.map +1 -0
- package/dist/agent-verifier/{sync-3DUQH32H.mjs → sync-THAI546U.mjs} +31 -37
- package/dist/agent-verifier/sync-THAI546U.mjs.map +1 -0
- package/dist/agent-verifier/{test-P4U5INTD.mjs → test-AFAQFKOB.mjs} +28 -31
- package/dist/agent-verifier/test-AFAQFKOB.mjs.map +1 -0
- package/dist/agent-verifier/workspace-codegen-2ZMQRIKJ.mjs +10 -0
- package/dist/agent-verifier/workspace-codegen-2ZMQRIKJ.mjs.map +1 -0
- package/dist/agent-verifier/{workspace-dependencies-HZ6VVS4G.mjs → workspace-dependencies-NOOQBK6I.mjs} +5 -4
- package/dist/agent-verifier/workspace-dependencies-NOOQBK6I.mjs.map +1 -0
- package/dist/{chunk-C6UAT6EH.js → chunk-N7XPNNUI.js} +9 -12
- package/dist/chunk-N7XPNNUI.js.map +1 -0
- package/dist/chunk-SEGVTWSK.js +44 -0
- package/dist/chunk-SEGVTWSK.js.map +1 -0
- package/dist/{chunk-RS7UXJZV.js → chunk-TAQKH67O.js} +21300 -35881
- package/dist/chunk-TAQKH67O.js.map +1 -0
- package/dist/{global-config-AGFBDFYD.js → global-config-S4ZIPECE.js} +3 -3
- package/dist/global-config-S4ZIPECE.js.map +1 -0
- package/dist/index.js +415 -37
- package/dist/index.js.map +1 -1
- package/dist/internal.js +3 -4
- package/dist/{agent-verifier/keychain-backend-TNOPQV3Z.mjs → keychain-backend-HDF4TZDL.js} +2 -1
- package/dist/{agent-verifier/prompt-3BAINGAQ.mjs → prompt-NDV3AE5L.js} +2 -1
- package/package.json +8 -7
- package/skills/dreamboard/references/building-your-first-game.md +510 -0
- package/skills/dreamboard/references/cli.md +104 -0
- package/skills/dreamboard/references/game-interface.md +548 -0
- package/skills/dreamboard/references/manifest-authoring.md +597 -0
- package/skills/dreamboard/references/quickstart.md +66 -0
- package/skills/dreamboard/references/reducer.md +864 -0
- package/skills/dreamboard/references/rule-authoring.md +147 -0
- package/skills/dreamboard/references/testing.md +249 -0
- package/skills/dreamboard/scripts/events-extract.mjs +218 -0
- package/dist/agent-verifier/chunk-54TAYXUD.mjs +0 -12
- package/dist/agent-verifier/chunk-6UUJEYDV.mjs +0 -213
- package/dist/agent-verifier/chunk-HBNDKQT5.mjs +0 -8381
- package/dist/agent-verifier/chunk-LI3ZR3BI.mjs +0 -41
- package/dist/agent-verifier/chunk-U6OJN7XS.mjs +0 -8092
- package/dist/agent-verifier/chunk-XYDL7GY6.mjs +0 -10
- package/dist/agent-verifier/local-typecheck-QFYYAZOK.mjs +0 -9
- package/dist/agent-verifier/reducer-contract-preflight-22X7DSZW.mjs +0 -10
- package/dist/agent-verifier/static-scaffold-AJMZZQWS.mjs +0 -28
- package/dist/agent-verifier/testing-5K2BJYF2.mjs +0 -674
- package/dist/agent-verifier/workspace-codegen-JDZJRSDV.mjs +0 -11
- package/dist/chunk-2H7UOFLK.js +0 -11
- package/dist/chunk-7FOO4AJI.js +0 -50
- package/dist/chunk-7FOO4AJI.js.map +0 -1
- package/dist/chunk-C6UAT6EH.js.map +0 -1
- package/dist/chunk-RS7UXJZV.js.map +0 -1
- package/dist/internal.d.ts +0 -311
- package/dist/runtime-packages/ui-host-runtime/src/actor-principal.ts +0 -71
- package/dist/runtime-packages/ui-host-runtime/src/browser-interaction.ts +0 -139
- package/dist/runtime-packages/ui-host-runtime/src/components/host-controls.tsx +0 -374
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback-toaster.tsx +0 -266
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback.tsx +0 -212
- package/dist/runtime-packages/ui-host-runtime/src/components/host-primitives.tsx +0 -271
- package/dist/runtime-packages/ui-host-runtime/src/components/host-session-metadata.tsx +0 -135
- package/dist/runtime-packages/ui-host-runtime/src/components/index.ts +0 -5
- package/dist/runtime-packages/ui-host-runtime/src/components/perf-overlay.tsx +0 -194
- package/dist/runtime-packages/ui-host-runtime/src/gameplay-authority-transport.ts +0 -626
- package/dist/runtime-packages/ui-host-runtime/src/host-controls.tsx +0 -1
- package/dist/runtime-packages/ui-host-runtime/src/host-feedback.tsx +0 -1
- package/dist/runtime-packages/ui-host-runtime/src/host-session-transport.ts +0 -294
- package/dist/runtime-packages/ui-host-runtime/src/index.ts +0 -3
- package/dist/runtime-packages/ui-host-runtime/src/logger.ts +0 -11
- package/dist/runtime-packages/ui-host-runtime/src/perf.ts +0 -324
- package/dist/runtime-packages/ui-host-runtime/src/plugin-bridge.ts +0 -195
- package/dist/runtime-packages/ui-host-runtime/src/plugin-health-check.ts +0 -138
- package/dist/runtime-packages/ui-host-runtime/src/plugin-messages.ts +0 -159
- package/dist/runtime-packages/ui-host-runtime/src/plugin-session-gateway.ts +0 -551
- package/dist/runtime-packages/ui-host-runtime/src/runtime/index.ts +0 -13
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/projection-to-snapshot.ts +0 -122
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/static-store-api.ts +0 -26
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress-controller.ts +0 -583
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress.ts +0 -219
- package/dist/runtime-packages/ui-host-runtime/src/session-live-runtime.ts +0 -117
- package/dist/runtime-packages/ui-host-runtime/src/session-model.ts +0 -431
- package/dist/runtime-packages/ui-host-runtime/src/session-projection.ts +0 -211
- package/dist/runtime-packages/ui-host-runtime/src/session-recovery.ts +0 -80
- package/dist/runtime-packages/ui-host-runtime/src/session-state-reducer.ts +0 -1034
- package/dist/runtime-packages/ui-host-runtime/src/sse-manager.ts +0 -416
- package/dist/runtime-packages/ui-host-runtime/src/unified-session-store.ts +0 -184
- package/dist/testing-KLSV6CPJ.js +0 -674
- package/dist/testing-KLSV6CPJ.js.map +0 -1
- /package/dist/{chunk-2H7UOFLK.js.map → agent-verifier/chunk-SKI2ESE5.mjs.map} +0 -0
- /package/dist/{global-config-AGFBDFYD.js.map → agent-verifier/global-config-Y2NTSK4R.mjs.map} +0 -0
- /package/dist/{keychain-backend-JHTXAKWC.js.map → keychain-backend-HDF4TZDL.js.map} +0 -0
- /package/dist/{prompt-GMZABCJC.js.map → prompt-NDV3AE5L.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
toDreamboardApiError
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-S34FRJHS.mjs";
|
|
5
5
|
import {
|
|
6
6
|
createGameRevision,
|
|
7
7
|
createProjectSourceBlobUploadSession,
|
|
@@ -15,12 +15,18 @@ import {
|
|
|
15
15
|
listProjectCompiledResults,
|
|
16
16
|
queueProjectRevisionCompile,
|
|
17
17
|
uploadInitialProjection
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-O4YCPU7C.mjs";
|
|
19
19
|
import {
|
|
20
20
|
external_exports
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-VS573ERH.mjs";
|
|
22
22
|
|
|
23
|
-
// ../../
|
|
23
|
+
// ../../node_modules/.pnpm/citty@0.2.2/node_modules/citty/dist/index.mjs
|
|
24
|
+
import { parseArgs as parseArgs$1 } from "util";
|
|
25
|
+
function defineCommand(def) {
|
|
26
|
+
return def;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ../../packages/api-client/dist/source-revisions.js
|
|
24
30
|
var textEncoder = new TextEncoder();
|
|
25
31
|
function bytesToHex(bytes) {
|
|
26
32
|
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
@@ -28,10 +34,7 @@ function bytesToHex(bytes) {
|
|
|
28
34
|
async function sha256Hex(bytes) {
|
|
29
35
|
const normalizedBytes = new Uint8Array(bytes.byteLength);
|
|
30
36
|
normalizedBytes.set(bytes);
|
|
31
|
-
const digest = await crypto.subtle.digest(
|
|
32
|
-
"SHA-256",
|
|
33
|
-
normalizedBytes.buffer
|
|
34
|
-
);
|
|
37
|
+
const digest = await crypto.subtle.digest("SHA-256", normalizedBytes.buffer);
|
|
35
38
|
return bytesToHex(new Uint8Array(digest));
|
|
36
39
|
}
|
|
37
40
|
function getUtf8ByteSize(content) {
|
|
@@ -48,28 +51,24 @@ async function describeSourceBlob(content) {
|
|
|
48
51
|
}
|
|
49
52
|
async function materializeSourceChangeOperations(changes) {
|
|
50
53
|
const blobsByHash = /* @__PURE__ */ new Map();
|
|
51
|
-
const materialized = await Promise.all(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
68
|
-
);
|
|
54
|
+
const materialized = await Promise.all(Array.from(changes, async (change) => {
|
|
55
|
+
if (change.kind === "delete") {
|
|
56
|
+
return change;
|
|
57
|
+
}
|
|
58
|
+
const blob = await describeSourceBlob(change.content);
|
|
59
|
+
const existing = blobsByHash.get(blob.contentHash);
|
|
60
|
+
if (!existing) {
|
|
61
|
+
blobsByHash.set(blob.contentHash, blob);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
kind: "upsert",
|
|
65
|
+
path: change.path,
|
|
66
|
+
contentHash: blob.contentHash,
|
|
67
|
+
byteSize: blob.byteSize
|
|
68
|
+
};
|
|
69
|
+
}));
|
|
69
70
|
return {
|
|
70
|
-
blobs: Array.from(blobsByHash.values()).sort(
|
|
71
|
-
(left, right) => left.contentHash.localeCompare(right.contentHash)
|
|
72
|
-
),
|
|
71
|
+
blobs: Array.from(blobsByHash.values()).sort((left, right) => left.contentHash.localeCompare(right.contentHash)),
|
|
73
72
|
changes: materialized
|
|
74
73
|
};
|
|
75
74
|
}
|
|
@@ -91,8 +90,6 @@ function mapUpsertBlobContentsByContentHash(localChanges, materializedChanges) {
|
|
|
91
90
|
return uploadBlobs;
|
|
92
91
|
}
|
|
93
92
|
var SourceBlobUploadError = class extends Error {
|
|
94
|
-
status;
|
|
95
|
-
details;
|
|
96
93
|
constructor(status, details) {
|
|
97
94
|
const suffix = details.trim().length > 0 ? `: ${details.trim()}` : "";
|
|
98
95
|
super(`Failed to upload source blob (HTTP ${status}${suffix})`);
|
|
@@ -124,8 +121,6 @@ async function uploadSourceBlob(uploadTarget, content) {
|
|
|
124
121
|
throw new SourceBlobUploadError(response.status, details);
|
|
125
122
|
}
|
|
126
123
|
var SourceBlobSessionRequestError = class extends Error {
|
|
127
|
-
apiError;
|
|
128
|
-
response;
|
|
129
124
|
constructor(message, apiError, response) {
|
|
130
125
|
super(message);
|
|
131
126
|
this.name = "SourceBlobSessionRequestError";
|
|
@@ -135,11 +130,7 @@ var SourceBlobSessionRequestError = class extends Error {
|
|
|
135
130
|
};
|
|
136
131
|
function assertSourceBlobUploadSession(data, response) {
|
|
137
132
|
if (!data || typeof data !== "object" || !Array.isArray(data.uploads)) {
|
|
138
|
-
throw new SourceBlobSessionRequestError(
|
|
139
|
-
"Source blob upload session response did not include an uploads array",
|
|
140
|
-
data,
|
|
141
|
-
response
|
|
142
|
-
);
|
|
133
|
+
throw new SourceBlobSessionRequestError("Source blob upload session response did not include an uploads array", data, response);
|
|
143
134
|
}
|
|
144
135
|
}
|
|
145
136
|
async function confirmSourceBlobAlreadyExists(options) {
|
|
@@ -151,11 +142,7 @@ async function confirmSourceBlobAlreadyExists(options) {
|
|
|
151
142
|
}
|
|
152
143
|
]);
|
|
153
144
|
if (error || !data) {
|
|
154
|
-
throw new SourceBlobSessionRequestError(
|
|
155
|
-
"Failed to create source blob upload session",
|
|
156
|
-
error,
|
|
157
|
-
response
|
|
158
|
-
);
|
|
145
|
+
throw new SourceBlobSessionRequestError("Failed to create source blob upload session", error, response);
|
|
159
146
|
}
|
|
160
147
|
assertSourceBlobUploadSession(data, response);
|
|
161
148
|
return data.uploads[0]?.status === "exists";
|
|
@@ -170,26 +157,18 @@ async function uploadSourceBlobs(options) {
|
|
|
170
157
|
continue;
|
|
171
158
|
}
|
|
172
159
|
if (existing.byteSize !== blob.byteSize) {
|
|
173
|
-
throw new Error(
|
|
174
|
-
`Source blob ${blob.contentHash} has conflicting byte sizes.`
|
|
175
|
-
);
|
|
160
|
+
throw new Error(`Source blob ${blob.contentHash} has conflicting byte sizes.`);
|
|
176
161
|
}
|
|
177
162
|
}
|
|
178
163
|
if (uniqueBlobs.size === 0) {
|
|
179
164
|
return;
|
|
180
165
|
}
|
|
181
|
-
const { data, error, response } = await requestUploadSession(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}))
|
|
186
|
-
);
|
|
166
|
+
const { data, error, response } = await requestUploadSession(Array.from(uniqueBlobs.values(), ({ contentHash, byteSize }) => ({
|
|
167
|
+
contentHash,
|
|
168
|
+
byteSize
|
|
169
|
+
})));
|
|
187
170
|
if (error || !data) {
|
|
188
|
-
throw new SourceBlobSessionRequestError(
|
|
189
|
-
"Failed to create source blob upload session",
|
|
190
|
-
error,
|
|
191
|
-
response
|
|
192
|
-
);
|
|
171
|
+
throw new SourceBlobSessionRequestError("Failed to create source blob upload session", error, response);
|
|
193
172
|
}
|
|
194
173
|
assertSourceBlobUploadSession(data, response);
|
|
195
174
|
for (const upload of data.uploads) {
|
|
@@ -198,21 +177,15 @@ async function uploadSourceBlobs(options) {
|
|
|
198
177
|
}
|
|
199
178
|
const blob = uniqueBlobs.get(upload.contentHash);
|
|
200
179
|
if (!blob) {
|
|
201
|
-
throw new Error(
|
|
202
|
-
`Upload session referenced unknown source blob ${upload.contentHash}.`
|
|
203
|
-
);
|
|
180
|
+
throw new Error(`Upload session referenced unknown source blob ${upload.contentHash}.`);
|
|
204
181
|
}
|
|
205
182
|
if (!upload.uploadTarget) {
|
|
206
|
-
throw new Error(
|
|
207
|
-
`Upload target missing for source blob ${upload.contentHash}.`
|
|
208
|
-
);
|
|
183
|
+
throw new Error(`Upload target missing for source blob ${upload.contentHash}.`);
|
|
209
184
|
}
|
|
210
185
|
try {
|
|
211
186
|
await uploadSourceBlob(upload.uploadTarget, blob.content);
|
|
212
187
|
if (!await confirmSourceBlobAlreadyExists({ requestUploadSession, blob })) {
|
|
213
|
-
throw new Error(
|
|
214
|
-
`Source blob ${blob.contentHash} was uploaded but not registered.`
|
|
215
|
-
);
|
|
188
|
+
throw new Error(`Source blob ${blob.contentHash} was uploaded but not registered.`);
|
|
216
189
|
}
|
|
217
190
|
} catch (error2) {
|
|
218
191
|
if (isDuplicateDirectUploadError(error2) && await confirmSourceBlobAlreadyExists({ requestUploadSession, blob })) {
|
|
@@ -541,37 +514,6 @@ function isTransientJobPollMessage(message) {
|
|
|
541
514
|
return normalized.includes("fetch failed") || normalized.includes("network") || normalized.includes("timeout") || normalized.includes("econnreset") || normalized.includes("econnrefused") || normalized.includes("socket");
|
|
542
515
|
}
|
|
543
516
|
|
|
544
|
-
// src/services/api/preview-api.ts
|
|
545
|
-
async function uploadInitialProjectionSdk(gameId, projectionJson) {
|
|
546
|
-
const { error, response } = await uploadInitialProjection({
|
|
547
|
-
path: { gameId },
|
|
548
|
-
body: { projectionJson }
|
|
549
|
-
});
|
|
550
|
-
if (error) {
|
|
551
|
-
throw toDreamboardApiError(
|
|
552
|
-
error,
|
|
553
|
-
response,
|
|
554
|
-
"Failed to upload initial preview projection"
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// src/services/api/source-revisions-api.ts
|
|
560
|
-
async function uploadProjectSourceBlobsSdk(projectId, blobs) {
|
|
561
|
-
try {
|
|
562
|
-
await uploadProjectSourceBlobs({ projectId, blobs });
|
|
563
|
-
} catch (error) {
|
|
564
|
-
if (error instanceof SourceBlobSessionRequestError) {
|
|
565
|
-
throw toDreamboardApiError(
|
|
566
|
-
error.apiError,
|
|
567
|
-
error.response,
|
|
568
|
-
error.message
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
throw error;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
517
|
// src/services/api/project-api.ts
|
|
576
518
|
async function loadRemoteProjectIdentity() {
|
|
577
519
|
const [versionResponse, userResponse] = await Promise.all([
|
|
@@ -630,7 +572,39 @@ async function createGameRevisionSdk(options) {
|
|
|
630
572
|
return data;
|
|
631
573
|
}
|
|
632
574
|
|
|
575
|
+
// src/services/api/preview-api.ts
|
|
576
|
+
async function uploadInitialProjectionSdk(gameId, projectionJson) {
|
|
577
|
+
const { error, response } = await uploadInitialProjection({
|
|
578
|
+
path: { gameId },
|
|
579
|
+
body: { projectionJson }
|
|
580
|
+
});
|
|
581
|
+
if (error) {
|
|
582
|
+
throw toDreamboardApiError(
|
|
583
|
+
error,
|
|
584
|
+
response,
|
|
585
|
+
"Failed to upload initial preview projection"
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// src/services/api/source-revisions-api.ts
|
|
591
|
+
async function uploadProjectSourceBlobsSdk(projectId, blobs) {
|
|
592
|
+
try {
|
|
593
|
+
await uploadProjectSourceBlobs({ projectId, blobs });
|
|
594
|
+
} catch (error) {
|
|
595
|
+
if (error instanceof SourceBlobSessionRequestError) {
|
|
596
|
+
throw toDreamboardApiError(
|
|
597
|
+
error.apiError,
|
|
598
|
+
error.response,
|
|
599
|
+
error.message
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
throw error;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
633
606
|
export {
|
|
607
|
+
defineCommand,
|
|
634
608
|
materializeSourceChangeOperations,
|
|
635
609
|
mapUpsertBlobContentsByContentHash,
|
|
636
610
|
CONFIG_FLAG_ARGS,
|
|
@@ -641,9 +615,10 @@ export {
|
|
|
641
615
|
getProjectCompiledResultSdk,
|
|
642
616
|
queueProjectRevisionCompileSdk,
|
|
643
617
|
waitForCompiledResultJobSdk,
|
|
644
|
-
uploadInitialProjectionSdk,
|
|
645
|
-
uploadProjectSourceBlobsSdk,
|
|
646
618
|
loadRemoteProjectIdentity,
|
|
647
619
|
ensureProjectSdk,
|
|
648
|
-
createGameRevisionSdk
|
|
620
|
+
createGameRevisionSdk,
|
|
621
|
+
uploadInitialProjectionSdk,
|
|
622
|
+
uploadProjectSourceBlobsSdk
|
|
649
623
|
};
|
|
624
|
+
//# sourceMappingURL=chunk-W3N3QJ4V.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../node_modules/.pnpm/citty@0.2.2/node_modules/citty/dist/index.mjs","../../../../packages/api-client/dist/source-revisions.js","../../src/command-args.ts","../../src/flags.ts","../../src/utils/strings.ts","../../src/services/api/compiled-results-api.ts","../../src/services/api/project-api.ts","../../src/services/api/preview-api.ts","../../src/services/api/source-revisions-api.ts"],"sourcesContent":["import { n as kebabCase, r as snakeCase, t as camelCase } from \"./_chunks/libs/scule.mjs\";\nimport { parseArgs as parseArgs$1 } from \"node:util\";\n//#region src/_utils.ts\nfunction toArray(val) {\n\tif (Array.isArray(val)) return val;\n\treturn val === void 0 ? [] : [val];\n}\nfunction formatLineColumns(lines, linePrefix = \"\") {\n\tconst maxLength = [];\n\tfor (const line of lines) for (const [i, element] of line.entries()) maxLength[i] = Math.max(maxLength[i] || 0, element.length);\n\treturn lines.map((l) => l.map((c, i) => linePrefix + c[i === 0 ? \"padStart\" : \"padEnd\"](maxLength[i])).join(\" \")).join(\"\\n\");\n}\nfunction resolveValue(input) {\n\treturn typeof input === \"function\" ? input() : input;\n}\nvar CLIError = class extends Error {\n\tcode;\n\tconstructor(message, code) {\n\t\tsuper(message);\n\t\tthis.name = \"CLIError\";\n\t\tthis.code = code;\n\t}\n};\n//#endregion\n//#region src/_parser.ts\nfunction parseRawArgs(args = [], opts = {}) {\n\tconst booleans = new Set(opts.boolean || []);\n\tconst strings = new Set(opts.string || []);\n\tconst aliasMap = opts.alias || {};\n\tconst defaults = opts.default || {};\n\tconst aliasToMain = /* @__PURE__ */ new Map();\n\tconst mainToAliases = /* @__PURE__ */ new Map();\n\tfor (const [key, value] of Object.entries(aliasMap)) {\n\t\tconst targets = value;\n\t\tfor (const target of targets) {\n\t\t\taliasToMain.set(key, target);\n\t\t\tif (!mainToAliases.has(target)) mainToAliases.set(target, []);\n\t\t\tmainToAliases.get(target).push(key);\n\t\t\taliasToMain.set(target, key);\n\t\t\tif (!mainToAliases.has(key)) mainToAliases.set(key, []);\n\t\t\tmainToAliases.get(key).push(target);\n\t\t}\n\t}\n\tconst options = {};\n\tfunction getType(name) {\n\t\tif (booleans.has(name)) return \"boolean\";\n\t\tconst aliases = mainToAliases.get(name) || [];\n\t\tfor (const alias of aliases) if (booleans.has(alias)) return \"boolean\";\n\t\treturn \"string\";\n\t}\n\tfunction isStringType(name) {\n\t\tif (strings.has(name)) return true;\n\t\tconst aliases = mainToAliases.get(name) || [];\n\t\tfor (const alias of aliases) if (strings.has(alias)) return true;\n\t\treturn false;\n\t}\n\tconst allOptions = new Set([\n\t\t...booleans,\n\t\t...strings,\n\t\t...Object.keys(aliasMap),\n\t\t...Object.values(aliasMap).flat(),\n\t\t...Object.keys(defaults)\n\t]);\n\tfor (const name of allOptions) if (!options[name]) options[name] = {\n\t\ttype: getType(name),\n\t\tdefault: defaults[name]\n\t};\n\tfor (const [alias, main] of aliasToMain.entries()) if (alias.length === 1 && options[main] && !options[main].short) options[main].short = alias;\n\tconst processedArgs = [];\n\tconst negatedFlags = {};\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\t\tif (arg === \"--\") {\n\t\t\tprocessedArgs.push(...args.slice(i));\n\t\t\tbreak;\n\t\t}\n\t\tif (arg.startsWith(\"--no-\")) {\n\t\t\tconst flagName = arg.slice(5);\n\t\t\tnegatedFlags[flagName] = true;\n\t\t\tcontinue;\n\t\t}\n\t\tprocessedArgs.push(arg);\n\t}\n\tlet parsed;\n\ttry {\n\t\tparsed = parseArgs$1({\n\t\t\targs: processedArgs,\n\t\t\toptions: Object.keys(options).length > 0 ? options : void 0,\n\t\t\tallowPositionals: true,\n\t\t\tstrict: false\n\t\t});\n\t} catch {\n\t\tparsed = {\n\t\t\tvalues: {},\n\t\t\tpositionals: processedArgs\n\t\t};\n\t}\n\tconst out = { _: [] };\n\tout._ = parsed.positionals;\n\tfor (const [key, value] of Object.entries(parsed.values)) {\n\t\tlet coerced = value;\n\t\tif (getType(key) === \"boolean\" && typeof value === \"string\") coerced = value !== \"false\";\n\t\telse if (isStringType(key) && typeof value === \"boolean\") coerced = \"\";\n\t\tout[key] = coerced;\n\t}\n\tfor (const [name] of Object.entries(negatedFlags)) {\n\t\tout[name] = false;\n\t\tconst mainName = aliasToMain.get(name);\n\t\tif (mainName) out[mainName] = false;\n\t\tconst aliases = mainToAliases.get(name);\n\t\tif (aliases) for (const alias of aliases) out[alias] = false;\n\t}\n\tfor (const [alias, main] of aliasToMain.entries()) {\n\t\tif (out[alias] !== void 0 && out[main] === void 0) out[main] = out[alias];\n\t\tif (out[main] !== void 0 && out[alias] === void 0) out[alias] = out[main];\n\t\tif (out[alias] !== out[main] && defaults[main] === out[main]) out[main] = out[alias];\n\t}\n\treturn out;\n}\n//#endregion\n//#region src/_color.ts\nconst noColor = /* @__PURE__ */ (() => {\n\tconst env = globalThis.process?.env ?? {};\n\treturn env.NO_COLOR === \"1\" || env.TERM === \"dumb\" || env.TEST || env.CI;\n})();\nconst _c = (c, r = 39) => (t) => noColor ? t : `\\u001B[${c}m${t}\\u001B[${r}m`;\nconst bold = /* @__PURE__ */ _c(1, 22);\nconst cyan = /* @__PURE__ */ _c(36);\nconst gray = /* @__PURE__ */ _c(90);\nconst underline = /* @__PURE__ */ _c(4, 24);\n//#endregion\n//#region src/args.ts\nfunction parseArgs(rawArgs, argsDef) {\n\tconst parseOptions = {\n\t\tboolean: [],\n\t\tstring: [],\n\t\talias: {},\n\t\tdefault: {}\n\t};\n\tconst args = resolveArgs(argsDef);\n\tfor (const arg of args) {\n\t\tif (arg.type === \"positional\") continue;\n\t\tif (arg.type === \"string\" || arg.type === \"enum\") parseOptions.string.push(arg.name);\n\t\telse if (arg.type === \"boolean\") parseOptions.boolean.push(arg.name);\n\t\tif (arg.default !== void 0) parseOptions.default[arg.name] = arg.default;\n\t\tif (arg.alias) parseOptions.alias[arg.name] = arg.alias;\n\t\tconst camelName = camelCase(arg.name);\n\t\tconst kebabName = kebabCase(arg.name);\n\t\tif (camelName !== arg.name || kebabName !== arg.name) {\n\t\t\tconst existingAliases = toArray(parseOptions.alias[arg.name] || []);\n\t\t\tif (camelName !== arg.name && !existingAliases.includes(camelName)) existingAliases.push(camelName);\n\t\t\tif (kebabName !== arg.name && !existingAliases.includes(kebabName)) existingAliases.push(kebabName);\n\t\t\tif (existingAliases.length > 0) parseOptions.alias[arg.name] = existingAliases;\n\t\t}\n\t}\n\tconst parsed = parseRawArgs(rawArgs, parseOptions);\n\tconst [ ...positionalArguments] = parsed._;\n\tconst parsedArgsProxy = new Proxy(parsed, { get(target, prop) {\n\t\treturn target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)];\n\t} });\n\tfor (const [, arg] of args.entries()) if (arg.type === \"positional\") {\n\t\tconst nextPositionalArgument = positionalArguments.shift();\n\t\tif (nextPositionalArgument !== void 0) parsedArgsProxy[arg.name] = nextPositionalArgument;\n\t\telse if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, \"EARG\");\n\t\telse parsedArgsProxy[arg.name] = arg.default;\n\t} else if (arg.type === \"enum\") {\n\t\tconst argument = parsedArgsProxy[arg.name];\n\t\tconst options = arg.options || [];\n\t\tif (argument !== void 0 && options.length > 0 && !options.includes(argument)) throw new CLIError(`Invalid value for argument: ${cyan(`--${arg.name}`)} (${cyan(argument)}). Expected one of: ${options.map((o) => cyan(o)).join(\", \")}.`, \"EARG\");\n\t} else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, \"EARG\");\n\treturn parsedArgsProxy;\n}\nfunction resolveArgs(argsDef) {\n\tconst args = [];\n\tfor (const [name, argDef] of Object.entries(argsDef || {})) args.push({\n\t\t...argDef,\n\t\tname,\n\t\talias: toArray(argDef.alias)\n\t});\n\treturn args;\n}\n//#endregion\n//#region src/plugin.ts\nfunction defineCittyPlugin(plugin) {\n\treturn plugin;\n}\nasync function resolvePlugins(plugins) {\n\treturn Promise.all(plugins.map((p) => resolveValue(p)));\n}\n//#endregion\n//#region src/command.ts\nfunction defineCommand(def) {\n\treturn def;\n}\nasync function runCommand(cmd, opts) {\n\tconst cmdArgs = await resolveValue(cmd.args || {});\n\tconst parsedArgs = parseArgs(opts.rawArgs, cmdArgs);\n\tconst context = {\n\t\trawArgs: opts.rawArgs,\n\t\targs: parsedArgs,\n\t\tdata: opts.data,\n\t\tcmd\n\t};\n\tconst plugins = await resolvePlugins(cmd.plugins ?? []);\n\tlet result;\n\tlet runError;\n\ttry {\n\t\tfor (const plugin of plugins) await plugin.setup?.(context);\n\t\tif (typeof cmd.setup === \"function\") await cmd.setup(context);\n\t\tconst subCommands = await resolveValue(cmd.subCommands);\n\t\tif (subCommands && Object.keys(subCommands).length > 0) {\n\t\t\tconst subCommandArgIndex = findSubCommandIndex(opts.rawArgs, cmdArgs);\n\t\t\tconst explicitName = opts.rawArgs[subCommandArgIndex];\n\t\t\tif (explicitName) {\n\t\t\t\tconst subCommand = await _findSubCommand(subCommands, explicitName);\n\t\t\t\tif (!subCommand) throw new CLIError(`Unknown command ${cyan(explicitName)}`, \"E_UNKNOWN_COMMAND\");\n\t\t\t\tawait runCommand(subCommand, { rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1) });\n\t\t\t} else {\n\t\t\t\tconst defaultSubCommand = await resolveValue(cmd.default);\n\t\t\t\tif (defaultSubCommand) {\n\t\t\t\t\tif (cmd.run) throw new CLIError(`Cannot specify both 'run' and 'default' on the same command.`, \"E_DEFAULT_CONFLICT\");\n\t\t\t\t\tconst subCommand = await _findSubCommand(subCommands, defaultSubCommand);\n\t\t\t\t\tif (!subCommand) throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`, \"E_UNKNOWN_COMMAND\");\n\t\t\t\t\tawait runCommand(subCommand, { rawArgs: opts.rawArgs });\n\t\t\t\t} else if (!cmd.run) throw new CLIError(`No command specified.`, \"E_NO_COMMAND\");\n\t\t\t}\n\t\t}\n\t\tif (typeof cmd.run === \"function\") result = await cmd.run(context);\n\t} catch (error) {\n\t\trunError = error;\n\t}\n\tconst cleanupErrors = [];\n\tif (typeof cmd.cleanup === \"function\") try {\n\t\tawait cmd.cleanup(context);\n\t} catch (error) {\n\t\tcleanupErrors.push(error);\n\t}\n\tfor (const plugin of [...plugins].reverse()) try {\n\t\tawait plugin.cleanup?.(context);\n\t} catch (error) {\n\t\tcleanupErrors.push(error);\n\t}\n\tif (runError) throw runError;\n\tif (cleanupErrors.length === 1) throw cleanupErrors[0];\n\tif (cleanupErrors.length > 1) throw new Error(\"Multiple cleanup errors\", { cause: cleanupErrors });\n\treturn { result };\n}\nasync function resolveSubCommand(cmd, rawArgs, parent) {\n\tconst subCommands = await resolveValue(cmd.subCommands);\n\tif (subCommands && Object.keys(subCommands).length > 0) {\n\t\tconst subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));\n\t\tconst subCommandName = rawArgs[subCommandArgIndex];\n\t\tconst subCommand = await _findSubCommand(subCommands, subCommandName);\n\t\tif (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);\n\t}\n\treturn [cmd, parent];\n}\nasync function _findSubCommand(subCommands, name) {\n\tif (name in subCommands) return resolveValue(subCommands[name]);\n\tfor (const sub of Object.values(subCommands)) {\n\t\tconst resolved = await resolveValue(sub);\n\t\tconst meta = await resolveValue(resolved?.meta);\n\t\tif (meta?.alias) {\n\t\t\tif (toArray(meta.alias).includes(name)) return resolved;\n\t\t}\n\t}\n}\nfunction findSubCommandIndex(rawArgs, argsDef) {\n\tfor (let i = 0; i < rawArgs.length; i++) {\n\t\tconst arg = rawArgs[i];\n\t\tif (arg === \"--\") return -1;\n\t\tif (arg.startsWith(\"-\")) {\n\t\t\tif (!arg.includes(\"=\") && _isValueFlag(arg, argsDef)) i++;\n\t\t\tcontinue;\n\t\t}\n\t\treturn i;\n\t}\n\treturn -1;\n}\nfunction _isValueFlag(flag, argsDef) {\n\tconst name = flag.replace(/^-{1,2}/, \"\");\n\tconst normalized = camelCase(name);\n\tfor (const [key, def] of Object.entries(argsDef)) {\n\t\tif (def.type !== \"string\" && def.type !== \"enum\") continue;\n\t\tif (normalized === camelCase(key)) return true;\n\t\tif ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;\n\t}\n\treturn false;\n}\n//#endregion\n//#region src/usage.ts\nasync function showUsage(cmd, parent) {\n\ttry {\n\t\tconsole.log(await renderUsage(cmd, parent) + \"\\n\");\n\t} catch (error) {\n\t\tconsole.error(error);\n\t}\n}\nconst negativePrefixRe = /^no[-A-Z]/;\nasync function renderUsage(cmd, parent) {\n\tconst cmdMeta = await resolveValue(cmd.meta || {});\n\tconst cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));\n\tconst parentMeta = await resolveValue(parent?.meta || {});\n\tconst commandName = `${parentMeta.name ? `${parentMeta.name} ` : \"\"}` + (cmdMeta.name || process.argv[1]);\n\tconst argLines = [];\n\tconst posLines = [];\n\tconst commandsLines = [];\n\tconst usageLine = [];\n\tfor (const arg of cmdArgs) if (arg.type === \"positional\") {\n\t\tconst name = arg.name.toUpperCase();\n\t\tconst isRequired = arg.required !== false && arg.default === void 0;\n\t\tposLines.push([cyan(name + renderValueHint(arg)), renderDescription(arg, isRequired)]);\n\t\tusageLine.push(isRequired ? `<${name}>` : `[${name}]`);\n\t} else {\n\t\tconst isRequired = arg.required === true && arg.default === void 0;\n\t\tconst argStr = [...(arg.alias || []).map((a) => `-${a}`), `--${arg.name}`].join(\", \") + renderValueHint(arg);\n\t\targLines.push([cyan(argStr), renderDescription(arg, isRequired)]);\n\t\t/**\n\t\t* print negative boolean arg variant usage when\n\t\t* - enabled by default or has `negativeDescription`\n\t\t* - not prefixed with `no-` or `no[A-Z]`\n\t\t*/\n\t\tif (arg.type === \"boolean\" && (arg.default === true || arg.negativeDescription) && !negativePrefixRe.test(arg.name)) {\n\t\t\tconst negativeArgStr = [...(arg.alias || []).map((a) => `--no-${a}`), `--no-${arg.name}`].join(\", \");\n\t\t\targLines.push([cyan(negativeArgStr), [arg.negativeDescription, isRequired ? gray(\"(Required)\") : \"\"].filter(Boolean).join(\" \")]);\n\t\t}\n\t\tif (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));\n\t}\n\tif (cmd.subCommands) {\n\t\tconst commandNames = [];\n\t\tconst subCommands = await resolveValue(cmd.subCommands);\n\t\tfor (const [name, sub] of Object.entries(subCommands)) {\n\t\t\tconst meta = await resolveValue((await resolveValue(sub))?.meta);\n\t\t\tif (meta?.hidden) continue;\n\t\t\tconst aliases = toArray(meta?.alias);\n\t\t\tconst label = [name, ...aliases].join(\", \");\n\t\t\tcommandsLines.push([cyan(label), meta?.description || \"\"]);\n\t\t\tcommandNames.push(name, ...aliases);\n\t\t}\n\t\tusageLine.push(commandNames.join(\"|\"));\n\t}\n\tconst usageLines = [];\n\tconst version = cmdMeta.version || parentMeta.version;\n\tusageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : \"\")})`), \"\");\n\tconst hasOptions = argLines.length > 0 || posLines.length > 0;\n\tusageLines.push(`${underline(bold(\"USAGE\"))} ${cyan(`${commandName}${hasOptions ? \" [OPTIONS]\" : \"\"} ${usageLine.join(\" \")}`)}`, \"\");\n\tif (posLines.length > 0) {\n\t\tusageLines.push(underline(bold(\"ARGUMENTS\")), \"\");\n\t\tusageLines.push(formatLineColumns(posLines, \" \"));\n\t\tusageLines.push(\"\");\n\t}\n\tif (argLines.length > 0) {\n\t\tusageLines.push(underline(bold(\"OPTIONS\")), \"\");\n\t\tusageLines.push(formatLineColumns(argLines, \" \"));\n\t\tusageLines.push(\"\");\n\t}\n\tif (commandsLines.length > 0) {\n\t\tusageLines.push(underline(bold(\"COMMANDS\")), \"\");\n\t\tusageLines.push(formatLineColumns(commandsLines, \" \"));\n\t\tusageLines.push(\"\", `Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);\n\t}\n\treturn usageLines.filter((l) => typeof l === \"string\").join(\"\\n\");\n}\nfunction renderValueHint(arg) {\n\tconst valueHint = arg.valueHint ? `=<${arg.valueHint}>` : \"\";\n\tconst fallbackValueHint = valueHint || `=<${snakeCase(arg.name)}>`;\n\tif (!arg.type || arg.type === \"positional\" || arg.type === \"boolean\") return valueHint;\n\tif (arg.type === \"enum\" && arg.options?.length) return `=<${arg.options.join(\"|\")}>`;\n\treturn fallbackValueHint;\n}\nfunction renderDescription(arg, required) {\n\tconst requiredHint = required ? gray(\"(Required)\") : \"\";\n\tconst defaultHint = arg.default === void 0 ? \"\" : gray(`(Default: ${arg.default})`);\n\treturn [\n\t\targ.description,\n\t\trequiredHint,\n\t\tdefaultHint\n\t].filter(Boolean).join(\" \");\n}\n//#endregion\n//#region src/main.ts\nasync function runMain(cmd, opts = {}) {\n\tconst rawArgs = opts.rawArgs || process.argv.slice(2);\n\tconst showUsage$1 = opts.showUsage || showUsage;\n\ttry {\n\t\tconst builtinFlags = await _resolveBuiltinFlags(cmd);\n\t\tif (builtinFlags.help.length > 0 && rawArgs.some((arg) => builtinFlags.help.includes(arg))) {\n\t\t\tawait showUsage$1(...await resolveSubCommand(cmd, rawArgs));\n\t\t\tprocess.exit(0);\n\t\t} else if (rawArgs.length === 1 && builtinFlags.version.includes(rawArgs[0])) {\n\t\t\tconst meta = typeof cmd.meta === \"function\" ? await cmd.meta() : await cmd.meta;\n\t\t\tif (!meta?.version) throw new CLIError(\"No version specified\", \"E_NO_VERSION\");\n\t\t\tconsole.log(meta.version);\n\t\t} else await runCommand(cmd, { rawArgs });\n\t} catch (error) {\n\t\tif (error instanceof CLIError) {\n\t\t\tawait showUsage$1(...await resolveSubCommand(cmd, rawArgs));\n\t\t\tconsole.error(error.message);\n\t\t} else console.error(error, \"\\n\");\n\t\tprocess.exit(1);\n\t}\n}\nfunction createMain(cmd) {\n\treturn (opts = {}) => runMain(cmd, opts);\n}\nasync function _resolveBuiltinFlags(cmd) {\n\tconst argsDef = await resolveValue(cmd.args || {});\n\tconst userNames = /* @__PURE__ */ new Set();\n\tconst userAliases = /* @__PURE__ */ new Set();\n\tfor (const [name, def] of Object.entries(argsDef)) {\n\t\tuserNames.add(name);\n\t\tfor (const alias of toArray(def.alias)) userAliases.add(alias);\n\t}\n\treturn {\n\t\thelp: _getBuiltinFlags(\"help\", \"h\", userNames, userAliases),\n\t\tversion: _getBuiltinFlags(\"version\", \"v\", userNames, userAliases)\n\t};\n}\nfunction _getBuiltinFlags(long, short, userNames, userAliases) {\n\tif (userNames.has(long) || userAliases.has(long)) return [];\n\tif (userNames.has(short) || userAliases.has(short)) return [`--${long}`];\n\treturn [`--${long}`, `-${short}`];\n}\n//#endregion\nexport { createMain, defineCittyPlugin, defineCommand, parseArgs, renderUsage, runCommand, runMain, showUsage };\n","import { createProjectSourceBlobUploadSession, createSourceBlobUploadSession, } from \"./sdk.gen.js\";\nconst textEncoder = new TextEncoder();\nfunction bytesToHex(bytes) {\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\nasync function sha256Hex(bytes) {\n const normalizedBytes = new Uint8Array(bytes.byteLength);\n normalizedBytes.set(bytes);\n const digest = await crypto.subtle.digest(\"SHA-256\", normalizedBytes.buffer);\n return bytesToHex(new Uint8Array(digest));\n}\nfunction getUtf8ByteSize(content) {\n return textEncoder.encode(content).byteLength;\n}\nasync function computeSourceContentHash(content) {\n return sha256Hex(textEncoder.encode(content));\n}\nasync function describeSourceBlob(content) {\n return {\n contentHash: await computeSourceContentHash(content),\n byteSize: getUtf8ByteSize(content),\n };\n}\nexport async function materializeSourceChangeOperations(changes) {\n const blobsByHash = new Map();\n const materialized = await Promise.all(Array.from(changes, async (change) => {\n if (change.kind === \"delete\") {\n return change;\n }\n const blob = await describeSourceBlob(change.content);\n const existing = blobsByHash.get(blob.contentHash);\n if (!existing) {\n blobsByHash.set(blob.contentHash, blob);\n }\n return {\n kind: \"upsert\",\n path: change.path,\n contentHash: blob.contentHash,\n byteSize: blob.byteSize,\n };\n }));\n return {\n blobs: Array.from(blobsByHash.values()).sort((left, right) => left.contentHash.localeCompare(right.contentHash)),\n changes: materialized,\n };\n}\nexport function mapUpsertBlobContentsByContentHash(localChanges, materializedChanges) {\n const uploadBlobs = new Map();\n const length = Math.min(localChanges.length, materializedChanges.length);\n for (let index = 0; index < length; index += 1) {\n const localChange = localChanges[index];\n const materializedChange = materializedChanges[index];\n if (localChange?.kind !== \"upsert\" ||\n materializedChange?.kind !== \"upsert\") {\n continue;\n }\n uploadBlobs.set(materializedChange.contentHash, {\n contentHash: materializedChange.contentHash,\n byteSize: materializedChange.byteSize,\n content: localChange.content,\n });\n }\n return uploadBlobs;\n}\nclass SourceBlobUploadError extends Error {\n constructor(status, details) {\n const suffix = details.trim().length > 0 ? `: ${details.trim()}` : \"\";\n super(`Failed to upload source blob (HTTP ${status}${suffix})`);\n this.name = \"SourceBlobUploadError\";\n this.status = status;\n this.details = details;\n }\n}\nfunction isDuplicateDirectUploadError(error) {\n if (!(error instanceof SourceBlobUploadError)) {\n return false;\n }\n if (error.status === 409) {\n return true;\n }\n const normalizedDetails = error.details.toLowerCase();\n return (normalizedDetails.includes(\"duplicate\") ||\n normalizedDetails.includes(\"already exists\") ||\n normalizedDetails.includes(\"resource already exists\"));\n}\nasync function uploadSourceBlob(uploadTarget, content) {\n const response = await fetch(uploadTarget.url, {\n method: uploadTarget.method,\n headers: uploadTarget.headers,\n body: textEncoder.encode(content),\n });\n if (response.ok) {\n return;\n }\n const details = await response.text().catch(() => \"\");\n throw new SourceBlobUploadError(response.status, details);\n}\nexport class SourceBlobSessionRequestError extends Error {\n constructor(message, apiError, response) {\n super(message);\n this.name = \"SourceBlobSessionRequestError\";\n this.apiError = apiError;\n this.response = response;\n }\n}\nfunction assertSourceBlobUploadSession(data, response) {\n if (!data ||\n typeof data !== \"object\" ||\n !Array.isArray(data.uploads)) {\n throw new SourceBlobSessionRequestError(\"Source blob upload session response did not include an uploads array\", data, response);\n }\n}\nasync function confirmSourceBlobAlreadyExists(options) {\n const { requestUploadSession, blob } = options;\n const { data, error, response } = await requestUploadSession([\n {\n contentHash: blob.contentHash,\n byteSize: blob.byteSize,\n },\n ]);\n if (error || !data) {\n throw new SourceBlobSessionRequestError(\"Failed to create source blob upload session\", error, response);\n }\n assertSourceBlobUploadSession(data, response);\n return data.uploads[0]?.status === \"exists\";\n}\nasync function uploadSourceBlobs(options) {\n const { blobs, requestUploadSession } = options;\n const uniqueBlobs = new Map();\n for (const blob of blobs) {\n const existing = uniqueBlobs.get(blob.contentHash);\n if (!existing) {\n uniqueBlobs.set(blob.contentHash, blob);\n continue;\n }\n if (existing.byteSize !== blob.byteSize) {\n throw new Error(`Source blob ${blob.contentHash} has conflicting byte sizes.`);\n }\n }\n if (uniqueBlobs.size === 0) {\n return;\n }\n const { data, error, response } = await requestUploadSession(Array.from(uniqueBlobs.values(), ({ contentHash, byteSize }) => ({\n contentHash,\n byteSize,\n })));\n if (error || !data) {\n throw new SourceBlobSessionRequestError(\"Failed to create source blob upload session\", error, response);\n }\n assertSourceBlobUploadSession(data, response);\n for (const upload of data.uploads) {\n if (upload.status !== \"upload_required\") {\n continue;\n }\n const blob = uniqueBlobs.get(upload.contentHash);\n if (!blob) {\n throw new Error(`Upload session referenced unknown source blob ${upload.contentHash}.`);\n }\n if (!upload.uploadTarget) {\n throw new Error(`Upload target missing for source blob ${upload.contentHash}.`);\n }\n try {\n await uploadSourceBlob(upload.uploadTarget, blob.content);\n if (!(await confirmSourceBlobAlreadyExists({ requestUploadSession, blob }))) {\n throw new Error(`Source blob ${blob.contentHash} was uploaded but not registered.`);\n }\n }\n catch (error) {\n if (isDuplicateDirectUploadError(error) &&\n (await confirmSourceBlobAlreadyExists({ requestUploadSession, blob }))) {\n continue;\n }\n throw error;\n }\n }\n}\nexport async function uploadGameSourceBlobs(options) {\n const { gameId, blobs } = options;\n return uploadSourceBlobs({\n blobs,\n requestUploadSession: (uploadBlobs) => createSourceBlobUploadSession({\n path: { gameId },\n body: { blobs: uploadBlobs },\n }),\n });\n}\nexport async function uploadProjectSourceBlobs(options) {\n const { projectId, blobs } = options;\n return uploadSourceBlobs({\n blobs,\n requestUploadSession: (uploadBlobs) => createProjectSourceBlobUploadSession({\n path: { projectId },\n body: { blobs: uploadBlobs },\n }),\n });\n}\n","export const CONFIG_FLAG_ARGS = {\n env: {\n type: \"string\" as const,\n description: \"Environment: local | staging | prod\",\n },\n token: {\n type: \"string\" as const,\n description: \"Auth token (Dreamboard bearer JWT)\",\n },\n};\n","import { z } from \"zod\";\n\nconst configFlagsSchema = z.object({\n env: z.enum([\"local\", \"staging\", \"prod\"]).optional(),\n token: z.string().optional(),\n});\n\nconst ruleInputFlagsSchema = z.object({\n \"rule-file\": z.string().optional(),\n rule: z.string().optional(),\n});\n\nconst playerCountFlagsSchema = z.object({\n players: z.string().optional(),\n \"player-count\": z.string().optional(),\n});\n\nconst newCommandArgsSchema = configFlagsSchema.extend({\n slug: z.string().min(1),\n description: z.string().min(1),\n force: z.boolean().default(false),\n});\n\nconst cloneCommandArgsSchema = configFlagsSchema.extend({\n slug: z.string().min(1),\n});\n\nconst queryCommandArgsSchema = configFlagsSchema.extend({\n title: z.string().min(1),\n});\n\nconst pullCommandArgsSchema = configFlagsSchema.extend({\n force: z.boolean().default(false),\n});\n\nconst syncCommandArgsSchema = configFlagsSchema.extend({\n force: z.boolean().default(false),\n yes: z.boolean().default(false),\n});\n\nconst compileCommandArgsSchema = configFlagsSchema.extend({\n debug: z.boolean().default(false),\n \"skip-local-check\": z.boolean().default(false),\n});\n\nconst statusCommandArgsSchema = configFlagsSchema.extend({\n json: z.boolean().default(false),\n});\n\nconst devCommandArgsSchema = configFlagsSchema.extend({\n seed: z.string().optional(),\n \"setup-profile\": z.string().optional(),\n players: z.string().optional(),\n \"player-count\": z.string().optional(),\n debug: z.boolean().default(false),\n resume: z.string().optional(),\n \"from-scenario\": z.string().optional(),\n \"new-session\": z.boolean().default(false),\n open: z.boolean().default(false),\n port: z.string().optional(),\n host: z.union([z.string(), z.boolean()]).optional(),\n \"allowed-host\": z.string().optional(),\n});\n\nconst joinCommandArgsSchema = configFlagsSchema.extend({\n session: z.string().min(1).optional(),\n player: z.string().min(1),\n \"raw-events\": z.boolean().default(false),\n});\n\nconst loginCommandArgsSchema = configFlagsSchema;\n\nconst configCommandArgsSchema = configFlagsSchema.extend({\n action: z.string().optional().default(\"show\"),\n scope: z.enum([\"global\", \"workspace\"]).optional().default(\"global\"),\n});\n\nconst authCommandArgsSchema = z.object({\n action: z.enum([\"set\", \"clear\", \"login\", \"env\", \"status\"]),\n tokenValue: z.string().optional(),\n token: z.string().optional(),\n jwt: z.boolean().optional(),\n env: z.enum([\"local\", \"staging\", \"prod\"]).optional(),\n});\n\nexport type ConfigFlags = z.infer<typeof configFlagsSchema>;\nexport type RuleInputFlags = z.infer<typeof ruleInputFlagsSchema>;\nexport type PlayerCountFlags = z.infer<typeof playerCountFlagsSchema>;\n\nexport type NewCommandArgs = z.infer<typeof newCommandArgsSchema>;\nexport type CloneCommandArgs = z.infer<typeof cloneCommandArgsSchema>;\nexport type QueryCommandArgs = z.infer<typeof queryCommandArgsSchema>;\nexport type PullCommandArgs = z.infer<typeof pullCommandArgsSchema>;\nexport type SyncCommandArgs = z.infer<typeof syncCommandArgsSchema>;\nexport type CompileCommandArgs = z.infer<typeof compileCommandArgsSchema>;\nexport type StatusCommandArgs = z.infer<typeof statusCommandArgsSchema>;\nexport type DevCommandArgs = z.infer<typeof devCommandArgsSchema>;\nexport type JoinCommandArgs = z.infer<typeof joinCommandArgsSchema>;\nexport type LoginCommandArgs = z.infer<typeof loginCommandArgsSchema>;\nexport type ConfigCommandArgs = z.infer<typeof configCommandArgsSchema>;\nexport type AuthCommandArgs = z.infer<typeof authCommandArgsSchema>;\n\nfunction parseArgs<TOutput>(\n commandName: string,\n schema: z.ZodType<TOutput>,\n args: unknown,\n): TOutput {\n const parsed = schema.safeParse(args);\n if (parsed.success) {\n return parsed.data;\n }\n\n const details = parsed.error.issues\n .map((issue) => {\n const field = issue.path.length > 0 ? issue.path.join(\".\") : \"args\";\n return `${field}: ${issue.message}`;\n })\n .join(\"; \");\n throw new Error(`Invalid arguments for '${commandName}': ${details}`);\n}\n\nexport function parseConfigFlags(args: unknown): ConfigFlags {\n return parseArgs(\"config-flags\", configFlagsSchema, args);\n}\n\nexport function parseRuleInputFlags(args: unknown): RuleInputFlags {\n return parseArgs(\"rule-flags\", ruleInputFlagsSchema, args);\n}\n\nexport function parsePlayerCountFlags(args: unknown): PlayerCountFlags {\n return parseArgs(\"player-count\", playerCountFlagsSchema, args);\n}\n\nexport function parseNewCommandArgs(args: unknown): NewCommandArgs {\n return parseArgs(\"new\", newCommandArgsSchema, args);\n}\n\nexport function parseCloneCommandArgs(args: unknown): CloneCommandArgs {\n return parseArgs(\"clone\", cloneCommandArgsSchema, args);\n}\n\nexport function parseQueryCommandArgs(args: unknown): QueryCommandArgs {\n return parseArgs(\"query\", queryCommandArgsSchema, args);\n}\n\nexport function parsePullCommandArgs(args: unknown): PullCommandArgs {\n return parseArgs(\"pull\", pullCommandArgsSchema, args);\n}\n\nexport function parseSyncCommandArgs(args: unknown): SyncCommandArgs {\n return parseArgs(\"sync\", syncCommandArgsSchema, args);\n}\n\nexport function parseCompileCommandArgs(args: unknown): CompileCommandArgs {\n return parseArgs(\"compile\", compileCommandArgsSchema, args);\n}\n\nexport function parseStatusCommandArgs(args: unknown): StatusCommandArgs {\n return parseArgs(\"status\", statusCommandArgsSchema, args);\n}\n\nexport function parseDevCommandArgs(args: unknown): DevCommandArgs {\n return parseArgs(\"dev\", devCommandArgsSchema, args);\n}\n\nexport function parseJoinCommandArgs(args: unknown): JoinCommandArgs {\n return parseArgs(\"join\", joinCommandArgsSchema, args);\n}\n\nexport function parseLoginCommandArgs(args: unknown): LoginCommandArgs {\n return parseArgs(\"login\", loginCommandArgsSchema, args);\n}\n\nexport function parseConfigCommandArgs(args: unknown): ConfigCommandArgs {\n return parseArgs(\"config\", configCommandArgsSchema, args);\n}\n\nexport function parseAuthCommandArgs(args: unknown): AuthCommandArgs {\n return parseArgs(\"auth\", authCommandArgsSchema, args);\n}\n","import path from \"node:path\";\nimport type { RuleInputFlags } from \"../flags.js\";\nimport { readTextFile } from \"./fs.js\";\n\nexport function normalizeSlug(input: string): string {\n const lowered = input.trim().toLowerCase();\n const replaced = lowered.replace(/[^a-z0-9]+/g, \"-\");\n return replaced.replace(/^-+/, \"\").replace(/-+$/, \"\");\n}\n\nexport function titleFromSlug(slug: string): string {\n return slug\n .split(\"-\")\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nexport async function readRuleInput(flags: RuleInputFlags): Promise<string> {\n if (flags[\"rule-file\"] && typeof flags[\"rule-file\"] === \"string\") {\n const filePath = path.resolve(process.cwd(), flags[\"rule-file\"]);\n return readTextFile(filePath);\n }\n if (flags.rule && typeof flags.rule === \"string\") {\n return flags.rule;\n }\n throw new Error('Provide rule input via --rule-file or --rule \"...\".');\n}\n\nexport function parsePositiveInt(value: string, label: string): number {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(`${label} must be a positive integer.`);\n }\n return parsed;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import {\n getCompiledResult,\n getJob,\n getLatestCompiledResult,\n getProjectCompiledResult,\n listProjectCompiledResults,\n listCompiledResults,\n queueProjectRevisionCompile,\n type CompiledResult,\n type JobDetailResponse,\n type QueueCompiledResultJobResponse,\n} from \"@dreamboard-games/api-client\";\nimport { toDreamboardApiError } from \"../../utils/errors.js\";\n\nconst COMPILE_JOB_POLL_INTERVAL_MS = 1000;\nconst DEFAULT_COMPILE_JOB_WAIT_TIMEOUT_MS = 10 * 60 * 1000;\nimport { sleep } from \"../../utils/strings.js\";\n\nfunction firstNonEmpty(\n ...values: Array<string | null | undefined>\n): string | null {\n for (const value of values) {\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n return null;\n}\n\nfunction formatTerminalCompileJobMessage(\n job: Pick<\n JobDetailResponse,\n \"createdAt\" | \"errorMessage\" | \"jobId\" | \"message\" | \"phase\" | \"status\"\n >,\n): string {\n const detail = firstNonEmpty(job.errorMessage, job.message);\n const phase = firstNonEmpty(job.phase);\n const prefix = `Compile ${job.status.toLowerCase()}${phase ? ` [${phase}]` : \"\"}`;\n return detail\n ? `${prefix}: ${detail}`\n : `${prefix}: job ${job.jobId} ended before a compiled result was created.`;\n}\n\nfunction compareCreatedAtDesc(\n left: Pick<CompiledResult, \"createdAt\">,\n right: Pick<CompiledResult, \"createdAt\">,\n): number {\n const leftTime = Date.parse(left.createdAt);\n const rightTime = Date.parse(right.createdAt);\n if (Number.isFinite(leftTime) && Number.isFinite(rightTime)) {\n return rightTime - leftTime;\n }\n if (Number.isFinite(rightTime)) {\n return 1;\n }\n if (Number.isFinite(leftTime)) {\n return -1;\n }\n return 0;\n}\n\nasync function findFallbackCompiledResultForJob(options: {\n gameId?: string;\n projectId?: string;\n job: Pick<JobDetailResponse, \"createdAt\">;\n}): Promise<CompiledResult | null> {\n const { gameId, projectId, job } = options;\n const results = projectId\n ? await listProjectCompiledResults({\n path: { projectId },\n query: { limit: 100 },\n })\n : await listCompiledResults({\n path: { gameId: gameId! },\n query: { limit: 100 },\n });\n if (results.error || !results.data) {\n return null;\n }\n if (results.data.results.length === 0) {\n return null;\n }\n\n const jobCreatedAtMs = Date.parse(job.createdAt);\n const resultsCreatedAfterJob = Number.isFinite(jobCreatedAtMs)\n ? results.data.results.filter((result) => {\n const resultCreatedAtMs = Date.parse(result.createdAt);\n return (\n !Number.isFinite(resultCreatedAtMs) ||\n resultCreatedAtMs >= jobCreatedAtMs\n );\n })\n : results.data.results;\n const candidateResults =\n resultsCreatedAfterJob.length > 0\n ? resultsCreatedAfterJob\n : results.data.results;\n\n return [...candidateResults].sort(compareCreatedAtDesc)[0] ?? null;\n}\n\nexport async function findLatestSuccessfulCompiledResult(\n gameId: string,\n): Promise<CompiledResult | null> {\n const { data } = await getLatestCompiledResult({\n path: { gameId },\n query: { successOnly: true },\n });\n return data ?? null;\n}\n\nexport async function findCompiledResultsForAuthoringState(options: {\n gameId: string;\n authoringStateId: string;\n}): Promise<CompiledResult[]> {\n const { gameId, authoringStateId } = options;\n const { data, error, response } = await listCompiledResults({\n path: { gameId },\n query: {\n limit: 100,\n authoringStateId,\n },\n });\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to list compiled results\",\n );\n }\n return data.results;\n}\n\nexport async function getCompiledResultSdk(\n gameId: string,\n compiledResultId: string,\n): Promise<CompiledResult> {\n const { data, error, response } = await getCompiledResult({\n path: {\n gameId,\n compiledResultId,\n },\n });\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to fetch compiled result\",\n );\n }\n return data;\n}\n\nexport async function findProjectCompiledResultsForRevision(options: {\n projectId: string;\n revisionDigest: string;\n}): Promise<CompiledResult[]> {\n const { projectId, revisionDigest } = options;\n const { data, error, response } = await listProjectCompiledResults({\n path: { projectId },\n query: { limit: 100 },\n });\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to list compiled results\",\n );\n }\n return data.results.filter(\n (result) => {\n const maybeRevisionDigest = (result as { revisionDigest?: string })\n .revisionDigest;\n return (\n maybeRevisionDigest === revisionDigest ||\n result.authoringStateId === revisionDigest\n );\n },\n );\n}\n\nexport async function getProjectCompiledResultSdk(\n projectId: string,\n compiledResultId: string,\n): Promise<CompiledResult> {\n const { data, error, response } = await getProjectCompiledResult({\n path: { projectId, compiledResultId },\n });\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to fetch compiled result\",\n );\n }\n return data;\n}\n\nexport async function queueProjectRevisionCompileSdk(options: {\n projectId: string;\n revisionDigest: string;\n}): Promise<QueueCompiledResultJobResponse> {\n const { data, error, response } = await queueProjectRevisionCompile({\n path: {\n projectId: options.projectId,\n revisionDigest: options.revisionDigest,\n },\n });\n\n if (error || !data) {\n throw toDreamboardApiError(error, response, \"Failed to create compile job\");\n }\n\n return data;\n}\n\nexport async function waitForCompiledResultJobSdk(options: {\n gameId?: string;\n projectId?: string;\n jobId: string;\n onProgress?: (job: JobDetailResponse) => void;\n}): Promise<{\n job: JobDetailResponse;\n compiledResult: CompiledResult;\n}> {\n const { gameId, projectId, jobId, onProgress } = options;\n let previousTransitionKey: string | null = null;\n const startedAt = Date.now();\n const timeoutMs = readCompileJobWaitTimeoutMs();\n\n while (Date.now() - startedAt < timeoutMs) {\n const {\n data: job,\n error,\n response,\n } = await getJob({\n path: { jobId },\n });\n if (error || !job) {\n if (isTransientJobPollError(error, response)) {\n await sleep(COMPILE_JOB_POLL_INTERVAL_MS);\n continue;\n }\n throw toDreamboardApiError(error, response, \"Failed to get job\");\n }\n\n const transitionKey = `${job.status}:${job.phase ?? \"\"}`;\n if (transitionKey !== previousTransitionKey) {\n previousTransitionKey = transitionKey;\n onProgress?.(job);\n }\n\n if (job.status === \"COMPLETED\" || job.status === \"FAILED\") {\n const compiledResultId =\n job.createdCompiledResultId ?? job.createdAppScriptId;\n if (compiledResultId) {\n if (projectId) {\n const compiledResult = await getProjectCompiledResultSdk(\n projectId,\n compiledResultId,\n );\n return { job, compiledResult };\n }\n const compiledResult = await getCompiledResultSdk(\n gameId!,\n compiledResultId,\n );\n return { job, compiledResult };\n }\n\n const fallbackCompiledResult = await findFallbackCompiledResultForJob({\n gameId,\n projectId,\n job,\n });\n if (fallbackCompiledResult) {\n return { job, compiledResult: fallbackCompiledResult };\n }\n\n throw new Error(formatTerminalCompileJobMessage(job));\n }\n\n if (job.status === \"CANCELLED\" || job.status === \"INTERRUPTED\") {\n throw new Error(formatTerminalCompileJobMessage(job));\n }\n\n await sleep(COMPILE_JOB_POLL_INTERVAL_MS);\n }\n\n throw new Error(`Compile job ${jobId} did not complete in time.`);\n}\n\nfunction readCompileJobWaitTimeoutMs(): number {\n const raw = process.env.DREAMBOARD_COMPILE_WAIT_TIMEOUT_MS;\n if (!raw) return DEFAULT_COMPILE_JOB_WAIT_TIMEOUT_MS;\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return DEFAULT_COMPILE_JOB_WAIT_TIMEOUT_MS;\n }\n return parsed;\n}\n\nfunction isTransientJobPollError(error: unknown, response: unknown): boolean {\n if (response) return false;\n if (!error) return false;\n if (error instanceof Error) {\n return isTransientJobPollMessage(error.message);\n }\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return isTransientJobPollMessage(String(error.message));\n }\n return isTransientJobPollMessage(String(error));\n}\n\nfunction isTransientJobPollMessage(message: string): boolean {\n const normalized = message.toLowerCase();\n return (\n normalized.includes(\"fetch failed\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"timeout\") ||\n normalized.includes(\"econnreset\") ||\n normalized.includes(\"econnrefused\") ||\n normalized.includes(\"socket\")\n );\n}\n","import {\n createGameRevision,\n createProjectSession,\n createProjectSessionFromReducerSnapshot,\n ensureProject,\n ensureProjectDevCompile,\n getApiVersion,\n getCurrentAuthUser,\n getProjectBySlug,\n getProjectRevisionSources,\n getProjectSources,\n type CreateSessionFromReducerSnapshotRequest,\n type CreateSessionRequest,\n type CreateSessionResponse,\n type CreateGameRevisionRequest,\n type EnsureDevCompileRequest,\n type EnsureDevCompileResponse,\n type GameRevision,\n type GameSourcesResponse,\n type HostSessionSnapshot,\n type Project,\n type ProjectRevisionSourcesResponse,\n} from \"@dreamboard-games/api-client\";\nimport { toDreamboardApiError } from \"../../utils/errors.js\";\nimport { titleFromSlug } from \"../../utils/strings.js\";\n\nexport type RemoteProjectIdentity = {\n deploymentId: string;\n ownerScopeId: string;\n bindingKey: string;\n};\n\nexport async function loadRemoteProjectIdentity(): Promise<RemoteProjectIdentity> {\n const [versionResponse, userResponse] = await Promise.all([\n getApiVersion(),\n getCurrentAuthUser(),\n ]);\n\n if (versionResponse.error || !versionResponse.data) {\n throw toDreamboardApiError(\n versionResponse.error as Parameters<typeof toDreamboardApiError>[0],\n versionResponse.response,\n \"Failed to resolve backend deployment identity\",\n );\n }\n if (userResponse.error || !userResponse.data) {\n throw toDreamboardApiError(\n userResponse.error,\n userResponse.response,\n \"Failed to resolve authenticated owner scope\",\n );\n }\n\n const deploymentId = versionResponse.data.deploymentId;\n const ownerScopeId = userResponse.data.ownerScopeId;\n return {\n deploymentId,\n ownerScopeId,\n bindingKey: `${deploymentId}:${ownerScopeId}`,\n };\n}\n\nexport async function ensureProjectSdk(options: {\n projectId: string;\n slug: string;\n description?: string;\n updateAlias?: boolean;\n}): Promise<Project> {\n const { data, error, response } = await ensureProject({\n path: { projectId: options.projectId },\n body: {\n slug: options.slug,\n name: titleFromSlug(options.slug),\n description:\n options.description ?? `Dreamboard workspace for ${options.slug}.`,\n ...(options.updateAlias ? { updateAlias: true } : {}),\n },\n });\n\n if (error || !data) {\n throw toDreamboardApiError(error, response, \"Failed to ensure project\");\n }\n\n return data;\n}\n\nexport async function getProjectBySlugSdk(slug: string): Promise<Project> {\n const { data, error, response } = await getProjectBySlug({\n path: { slug },\n });\n\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n `Project '${slug}' not found`,\n );\n }\n\n return data;\n}\n\nexport async function createGameRevisionSdk(options: {\n projectId: string;\n request: CreateGameRevisionRequest;\n}): Promise<GameRevision> {\n const { data, error, response } = await createGameRevision({\n path: { projectId: options.projectId },\n body: options.request,\n });\n\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to create game revision\",\n );\n }\n\n return data;\n}\n\nexport async function getProjectSourcesSdk(\n projectId: string,\n): Promise<GameSourcesResponse | null> {\n const { data, error, response } = await getProjectSources({\n path: { projectId },\n });\n\n if (response?.status === 404) {\n return null;\n }\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to fetch project sources\",\n );\n }\n\n return data;\n}\n\nexport async function getProjectRevisionSourcesSdk(options: {\n projectId: string;\n revisionDigest: string;\n}): Promise<ProjectRevisionSourcesResponse> {\n const { data, error, response } = await getProjectRevisionSources({\n path: {\n projectId: options.projectId,\n revisionDigest: options.revisionDigest,\n },\n });\n\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to fetch project revision sources\",\n );\n }\n\n return data;\n}\n\nexport async function ensureProjectDevCompileSdk(options: {\n projectId: string;\n request: EnsureDevCompileRequest;\n}): Promise<EnsureDevCompileResponse> {\n const { data, error, response } = await ensureProjectDevCompile({\n path: { projectId: options.projectId },\n body: options.request,\n });\n\n if (error || !data) {\n throw toDreamboardApiError(error, response, \"Failed to ensure dev compile\");\n }\n\n return data;\n}\n\nexport async function createProjectSessionSdk(options: {\n projectId: string;\n request: CreateSessionRequest;\n}): Promise<CreateSessionResponse> {\n const { data, error, response } = await createProjectSession({\n path: { projectId: options.projectId },\n body: options.request,\n });\n\n if (error || !data) {\n throw toDreamboardApiError(error, response, \"Failed to create session\");\n }\n\n return data;\n}\n\nexport async function createProjectSessionFromReducerSnapshotSdk(options: {\n projectId: string;\n request: CreateSessionFromReducerSnapshotRequest;\n}): Promise<HostSessionSnapshot> {\n const { data, error, response } =\n await createProjectSessionFromReducerSnapshot({\n path: { projectId: options.projectId },\n body: options.request,\n });\n\n if (error || !data) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to create session from reducer snapshot\",\n );\n }\n\n return data;\n}\n","import { uploadInitialProjection } from \"@dreamboard-games/api-client\";\nimport { toDreamboardApiError } from \"../../utils/errors.js\";\n\nexport async function uploadInitialProjectionSdk(\n gameId: string,\n projectionJson: string,\n): Promise<void> {\n const { error, response } = await uploadInitialProjection({\n path: { gameId },\n body: { projectionJson },\n });\n if (error) {\n throw toDreamboardApiError(\n error,\n response,\n \"Failed to upload initial preview projection\",\n );\n }\n}\n","import {\n createSourceRevision,\n type CreateSourceRevisionRequest,\n queueCompiledResultJob,\n type QueueCompiledResultJobResponse,\n type SourceRevision,\n} from \"@dreamboard-games/api-client\";\nimport {\n SourceBlobSessionRequestError,\n uploadGameSourceBlobs,\n uploadProjectSourceBlobs,\n type SourceBlobUploadInput,\n} from \"@dreamboard-games/api-client/source-revisions\";\nimport { toDreamboardApiError } from \"../../utils/errors.js\";\n\nexport async function createSourceRevisionSdk(\n gameId: string,\n request: CreateSourceRevisionRequest,\n): Promise<SourceRevision> {\n const response = await createSourceRevision({\n path: { gameId },\n body: request,\n });\n\n if (response.error || !response.data) {\n throw toDreamboardApiError(\n response.error,\n response.response,\n \"Failed to create source revision\",\n );\n }\n\n return response.data;\n}\n\nexport async function uploadSourceBlobsSdk(\n gameId: string,\n blobs: SourceBlobUploadInput[],\n): Promise<void> {\n try {\n await uploadGameSourceBlobs({ gameId, blobs });\n } catch (error) {\n if (error instanceof SourceBlobSessionRequestError) {\n throw toDreamboardApiError(\n error.apiError as Parameters<typeof toDreamboardApiError>[0],\n error.response,\n error.message,\n );\n }\n throw error;\n }\n}\n\nexport async function uploadProjectSourceBlobsSdk(\n projectId: string,\n blobs: SourceBlobUploadInput[],\n): Promise<void> {\n try {\n await uploadProjectSourceBlobs({ projectId, blobs });\n } catch (error) {\n if (error instanceof SourceBlobSessionRequestError) {\n throw toDreamboardApiError(\n error.apiError as Parameters<typeof toDreamboardApiError>[0],\n error.response,\n error.message,\n );\n }\n throw error;\n }\n}\n\nexport async function queueCompiledResultJobSdk(options: {\n gameId: string;\n authoringStateId: string;\n}): Promise<QueueCompiledResultJobResponse> {\n const { gameId, authoringStateId } = options;\n const { data, error, response } = await queueCompiledResultJob({\n path: { gameId },\n body: {\n authoringStateId,\n },\n });\n\n if (error || !data) {\n throw toDreamboardApiError(error, response, \"Failed to create compile job\");\n }\n\n return data;\n}\n"],"mappings":"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","names":["error","compiledResult"]}
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
hashContent,
|
|
4
|
+
isAllowedGamePath,
|
|
5
|
+
isDynamicGeneratedPath,
|
|
6
|
+
isLibraryPath,
|
|
4
7
|
materializeManifest,
|
|
5
8
|
writeManifestSource
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-O4YCPU7C.mjs";
|
|
7
10
|
import {
|
|
8
11
|
atomicWriteFile
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
isAllowedGamePath,
|
|
12
|
-
isAuthoritativeGeneratedPath,
|
|
13
|
-
isLibraryPath
|
|
14
|
-
} from "./chunk-U6OJN7XS.mjs";
|
|
12
|
+
} from "./chunk-TAEQKBJB.mjs";
|
|
15
13
|
import {
|
|
16
14
|
readJsonFile,
|
|
17
15
|
readTextFile,
|
|
18
16
|
readTextFileIfExists,
|
|
19
17
|
writeTextFile
|
|
20
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-IAYRNVUC.mjs";
|
|
21
19
|
import {
|
|
22
20
|
LOCAL_IGNORE_DIRS,
|
|
23
21
|
MANIFEST_FILE,
|
|
24
22
|
PROJECT_DIR_NAME,
|
|
25
23
|
RULE_FILE,
|
|
26
24
|
SNAPSHOT_FILE
|
|
27
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-H76MT5UR.mjs";
|
|
28
26
|
|
|
29
27
|
// src/services/project/local-files.ts
|
|
30
28
|
import { readdir, unlink } from "fs/promises";
|
|
@@ -119,7 +117,7 @@ async function writeSnapshotFromFiles(rootDir, files) {
|
|
|
119
117
|
};
|
|
120
118
|
for (const [filePath, content] of Object.entries(files)) {
|
|
121
119
|
if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;
|
|
122
|
-
if (
|
|
120
|
+
if (isDynamicGeneratedPath(filePath)) continue;
|
|
123
121
|
snapshot.files[filePath] = hashContent(content);
|
|
124
122
|
}
|
|
125
123
|
const snapshotPath = path.join(rootDir, PROJECT_DIR_NAME, SNAPSHOT_FILE);
|
|
@@ -144,7 +142,7 @@ async function getLocalDiff(rootDir) {
|
|
|
144
142
|
for (const [filePath, content] of Object.entries(files)) {
|
|
145
143
|
if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;
|
|
146
144
|
if (isIgnorableLocalDiffPath(filePath)) continue;
|
|
147
|
-
if (
|
|
145
|
+
if (isDynamicGeneratedPath(filePath)) continue;
|
|
148
146
|
currentHashes[filePath] = hashContent(content);
|
|
149
147
|
}
|
|
150
148
|
const modified = [];
|
|
@@ -160,7 +158,7 @@ async function getLocalDiff(rootDir) {
|
|
|
160
158
|
}
|
|
161
159
|
for (const filePath of Object.keys(snapshot.files)) {
|
|
162
160
|
if (isIgnorableLocalDiffPath(filePath)) continue;
|
|
163
|
-
if (
|
|
161
|
+
if (isDynamicGeneratedPath(filePath)) continue;
|
|
164
162
|
if (!currentHashes[filePath]) {
|
|
165
163
|
deleted.push(filePath);
|
|
166
164
|
}
|
|
@@ -184,3 +182,4 @@ export {
|
|
|
184
182
|
writeSnapshotFromFiles,
|
|
185
183
|
getLocalDiff
|
|
186
184
|
};
|
|
185
|
+
//# sourceMappingURL=chunk-XGWCY624.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/project/local-files.ts"],"sourcesContent":["import { readdir, unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { GameTopologyManifest } from \"@dreamboard-games/sdk/types\";\nimport {\n PROJECT_DIR_NAME,\n MANIFEST_FILE,\n RULE_FILE,\n SNAPSHOT_FILE,\n LOCAL_IGNORE_DIRS,\n} from \"../../constants.js\";\nimport type { Snapshot } from \"../../types.js\";\nimport {\n readJsonFile,\n readTextFile,\n readTextFileIfExists,\n writeTextFile,\n} from \"../../utils/fs.js\";\nimport { atomicWriteFile } from \"../../utils/atomic-file.js\";\nimport { hashContent } from \"../../utils/crypto.js\";\nimport {\n computeManifestHash,\n materializeManifest,\n writeManifestSource,\n} from \"./manifest-authoring.js\";\nimport {\n isAllowedGamePath as isAllowedPathFromOwnership,\n isDynamicGeneratedPath,\n isLibraryPath as isLibraryPathFromOwnership,\n} from \"./scaffold-ownership.js\";\n\n/**\n * Returns true when a path is inside the canonical game project structure.\n * Anything outside app/, ui/, shared/, or the known root files is rejected.\n */\nexport function isAllowedGamePath(filePath: string): boolean {\n return isAllowedPathFromOwnership(filePath);\n}\n\nexport function isLibraryPath(filePath: string): boolean {\n return isLibraryPathFromOwnership(filePath);\n}\n\ntype WriteDecision = \"write\" | \"skip\";\n\n/**\n * Decide whether a file from the scaffold response should be written to disk.\n *\n * - Library files → always overwrite (they are fully generated).\n * - Everything else → only write if the file does not yet exist or is empty\n * locally (first-time seeding; preserves user edits).\n */\nfunction shouldWriteScaffoldFile(\n filePath: string,\n existingContent: string | null,\n): WriteDecision {\n if (isLibraryPath(filePath)) return \"write\";\n const hasContent =\n existingContent !== null && existingContent.trim().length > 0;\n return hasContent ? \"skip\" : \"write\";\n}\n\nexport async function writeSourceFiles(\n rootDir: string,\n files: Record<string, string | null>,\n): Promise<void> {\n for (const [relativePath, content] of Object.entries(files)) {\n if (content === null || content === undefined) continue;\n const filePath = path.join(rootDir, relativePath);\n await writeTextFile(filePath, content);\n }\n}\n\nexport interface ScaffoldWriteResult {\n written: string[];\n skipped: string[];\n}\n\n/**\n * Write scaffold files using local-merge logic.\n *\n * - Library files are always overwritten.\n * - User-owned files (phases, components, etc.) are only written when the\n * local file does not exist or is empty. Files with content are skipped\n * so user edits are never lost.\n *\n * Returns lists of files that were written (and actually changed) and files\n * that were skipped because a non-empty local copy already exists.\n */\nexport async function writeScaffoldFiles(\n rootDir: string,\n files: Record<string, string | null>,\n): Promise<ScaffoldWriteResult> {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const [relativePath, content] of Object.entries(files)) {\n if (content === null || content === undefined) continue;\n\n const fullPath = path.join(rootDir, relativePath);\n const existingContent = await readTextFileIfExists(fullPath);\n\n const decision = shouldWriteScaffoldFile(relativePath, existingContent);\n\n if (decision === \"skip\") {\n skipped.push(relativePath);\n continue;\n }\n\n await writeTextFile(fullPath, content);\n\n if (existingContent !== content) {\n written.push(relativePath);\n }\n }\n\n written.sort();\n skipped.sort();\n return { written, skipped };\n}\n\nexport async function removeExtraneousFiles(\n rootDir: string,\n keep: Set<string>,\n): Promise<void> {\n const localFiles = await collectLocalFiles(rootDir);\n for (const filePath of Object.keys(localFiles)) {\n if (filePath === MANIFEST_FILE || filePath === RULE_FILE) continue;\n if (!keep.has(filePath)) {\n await unlink(path.join(rootDir, filePath));\n }\n }\n}\n\nexport async function collectLocalFiles(\n rootDir: string,\n): Promise<Record<string, string>> {\n const result: Record<string, string> = {};\n await walkDir(rootDir, rootDir, result);\n return result;\n}\n\nexport async function walkDir(\n rootDir: string,\n currentDir: string,\n result: Record<string, string>,\n): Promise<void> {\n const entries = await readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (LOCAL_IGNORE_DIRS.has(entry.name)) continue;\n await walkDir(rootDir, path.join(currentDir, entry.name), result);\n } else if (entry.isFile()) {\n const filePath = path.join(currentDir, entry.name);\n const relativePath = path.relative(rootDir, filePath);\n result[relativePath] = await readTextFile(filePath);\n }\n }\n}\n\nexport async function writeManifest(\n rootDir: string,\n manifest: GameTopologyManifest,\n): Promise<void> {\n await writeManifestSource(rootDir, manifest);\n}\n\nexport async function writeRule(\n rootDir: string,\n ruleText: string,\n): Promise<void> {\n const filePath = path.join(rootDir, RULE_FILE);\n await writeTextFile(filePath, ruleText);\n}\n\nexport async function loadManifest(\n rootDir: string,\n): Promise<GameTopologyManifest> {\n return materializeManifest(rootDir);\n}\n\nexport { computeManifestHash };\n\nexport async function loadRule(rootDir: string): Promise<string> {\n const filePath = path.join(rootDir, RULE_FILE);\n return readTextFile(filePath);\n}\n\nexport async function writeSnapshot(rootDir: string): Promise<void> {\n const files = await collectLocalFiles(rootDir);\n await writeSnapshotFromFiles(rootDir, files);\n}\n\nexport async function writeSnapshotFromFiles(\n rootDir: string,\n files: Record<string, string>,\n): Promise<void> {\n const snapshot: Snapshot = {\n files: {},\n };\n\n for (const [filePath, content] of Object.entries(files)) {\n if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;\n if (isDynamicGeneratedPath(filePath)) continue;\n snapshot.files[filePath] = hashContent(content);\n }\n\n const snapshotPath = path.join(rootDir, PROJECT_DIR_NAME, SNAPSHOT_FILE);\n // Atomic write: a crash mid-snapshot (e.g. user kills a long `dreamboard\n // sync`) must not leave `.dreamboard/snapshot.json` truncated, or\n // `getLocalDiff` will silently report everything as \"added\" on the\n // next run and force a full re-sync.\n await atomicWriteFile(\n snapshotPath,\n `${JSON.stringify(snapshot, null, 2)}\\n`,\n { mode: 0o644 },\n );\n}\n\nfunction isIgnorableLocalDiffPath(filePath: string): boolean {\n return (\n filePath.startsWith(\"test/generated/\") ||\n filePath.startsWith(\".playwright-cli/\")\n );\n}\n\nexport async function getLocalDiff(rootDir: string): Promise<{\n modified: string[];\n added: string[];\n deleted: string[];\n}> {\n const snapshotPath = path.join(rootDir, PROJECT_DIR_NAME, SNAPSHOT_FILE);\n const snapshot = await readJsonFile<Snapshot>(snapshotPath).catch(() => null);\n if (!snapshot) {\n return { modified: [], added: [], deleted: [] };\n }\n\n const files = await collectLocalFiles(rootDir);\n const currentHashes: Record<string, string> = {};\n\n for (const [filePath, content] of Object.entries(files)) {\n if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;\n if (isIgnorableLocalDiffPath(filePath)) continue;\n if (isDynamicGeneratedPath(filePath)) continue;\n currentHashes[filePath] = hashContent(content);\n }\n\n const modified: string[] = [];\n const added: string[] = [];\n const deleted: string[] = [];\n\n for (const [filePath, hash] of Object.entries(currentHashes)) {\n const prevHash = snapshot.files[filePath];\n if (!prevHash) {\n added.push(filePath);\n } else if (prevHash !== hash) {\n modified.push(filePath);\n }\n }\n\n for (const filePath of Object.keys(snapshot.files)) {\n if (isIgnorableLocalDiffPath(filePath)) continue;\n if (isDynamicGeneratedPath(filePath)) continue;\n if (!currentHashes[filePath]) {\n deleted.push(filePath);\n }\n }\n\n return { modified, added, deleted };\n}\n"],"mappings":"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","names":["isAllowedGamePath","isLibraryPath"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
FRAMEWORK_PNPM_OVERRIDES
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZEELHSY3.mjs";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_WEB_BASE_URL
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-H76MT5UR.mjs";
|
|
8
8
|
|
|
9
9
|
// src/services/project/workspace-dependencies.ts
|
|
10
10
|
import crypto from "crypto";
|
|
@@ -379,3 +379,4 @@ export {
|
|
|
379
379
|
installWorkspaceDependencies,
|
|
380
380
|
reconcileWorkspaceDependencies
|
|
381
381
|
};
|
|
382
|
+
//# sourceMappingURL=chunk-XQXDOBYB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/project/workspace-dependencies.ts","../../src/services/project/dependency-tooling-messages.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport { spawn } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, lstat, readFile, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { Readable } from \"node:stream\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n buildDependencyPreparationFailureMessage,\n buildMissingDependencyToolingMessage,\n buildMissingGeneratedLockfileMessage,\n buildPackageLockConflictMessage,\n} from \"./dependency-tooling-messages.js\";\nimport { FRAMEWORK_PNPM_OVERRIDES } from \"./framework-dependencies.js\";\n\ntype LockfileGenerationOptions = Record<string, never>;\n\ntype PackageJsonShape = {\n packageManager?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n pnpm?: Record<string, unknown>;\n};\n\ntype DependencyInstallMetadata = {\n dependencyFingerprint: string;\n installedAt: string;\n packageManager: string;\n};\n\ntype LockfileCommand = {\n binary: string;\n args: string[];\n};\n\nexport type WorkspaceDependencyReconciliationResult = {\n required: boolean;\n installed: boolean;\n lockfileGenerated: boolean;\n packageManagerNormalized: boolean;\n fingerprint: string | null;\n};\n\nconst MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));\nconst CLI_ROOT = path.resolve(MODULE_DIR, \"../../..\");\nconst REPO_ROOT = path.resolve(CLI_ROOT, \"../..\");\nconst REPO_PACKAGE_JSON_PATH = path.join(REPO_ROOT, \"package.json\");\nconst DEFAULT_PACKAGE_MANAGER = \"pnpm@10.4.1\";\nconst SDK_PACKAGE_NAME = \"@dreamboard-games/sdk\";\nconst SDK_REQUIRED_DIST_FILES = [\n \"dist/index.d.ts\",\n \"dist/index.js\",\n \"dist/types.d.ts\",\n \"dist/types.js\",\n \"dist/ui.d.ts\",\n \"dist/ui.js\",\n \"dist/runtime.d.ts\",\n \"dist/runtime.js\",\n] as const;\nconst DEPENDENCY_INSTALL_METADATA_PATH_SEGMENTS = [\n \".dreamboard\",\n \"dependency-install.json\",\n] as const;\n\nclass LockfileGenerationError extends Error {\n constructor(\n readonly binary: string,\n readonly details: {\n code?: number | null;\n stdout: string;\n stderr: string;\n cause?: Error;\n },\n ) {\n super(buildLockfileGenerationErrorMessage(binary, details), {\n cause: details.cause,\n });\n this.name = \"LockfileGenerationError\";\n }\n}\n\nexport async function generatePnpmLockfile(\n projectRoot: string,\n _options: LockfileGenerationOptions = {},\n): Promise<boolean> {\n await ensurePackageManagerNormalized(projectRoot);\n await assertNoNpmLockfileConflict(projectRoot);\n await runPackageManagerCommand(projectRoot, {\n args: [\n \"install\",\n \"--ignore-workspace\",\n \"--lockfile-only\",\n \"--config.shared-workspace-lockfile=false\",\n ],\n });\n await assertPnpmLockfilePresent(projectRoot);\n return true;\n}\n\nexport async function installWorkspaceDependencies(\n projectRoot: string,\n _options: LockfileGenerationOptions = {},\n): Promise<boolean> {\n const result = await reconcileWorkspaceDependencies(projectRoot);\n return result.required;\n}\n\nexport async function reconcileWorkspaceDependencies(\n projectRoot: string,\n): Promise<WorkspaceDependencyReconciliationResult> {\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n if (!(await pathExists(packageJsonPath))) {\n return {\n required: false,\n installed: false,\n lockfileGenerated: false,\n packageManagerNormalized: false,\n fingerprint: null,\n };\n }\n\n await assertNoNpmLockfileConflict(projectRoot);\n const packageManagerNormalized =\n await ensurePackageManagerNormalized(projectRoot);\n const pnpmLockfilePath = path.join(projectRoot, \"pnpm-lock.yaml\");\n const nodeModulesPath = path.join(projectRoot, \"node_modules\");\n const metadataPath = path.join(\n projectRoot,\n ...DEPENDENCY_INSTALL_METADATA_PATH_SEGMENTS,\n );\n\n let lockfileGenerated = false;\n let installed = false;\n const metadata = await readJsonFile<DependencyInstallMetadata>(metadataPath);\n const lockfileExists = await pathExists(pnpmLockfilePath);\n\n if (!lockfileExists) {\n await runPackageManagerCommand(projectRoot, {\n args: [\n \"install\",\n \"--ignore-workspace\",\n \"--config.shared-workspace-lockfile=false\",\n ],\n });\n lockfileGenerated = true;\n installed = true;\n }\n\n await assertPnpmLockfilePresent(projectRoot);\n let fingerprint = await fingerprintInstallManifest({\n packageJsonPath,\n lockfilePath: pnpmLockfilePath,\n });\n const hasValidInstalledDeps =\n (await pathExists(nodeModulesPath)) &&\n (await hasValidInstalledDependencies({\n packageJsonPath,\n nodeModulesPath,\n }));\n const shouldInstall =\n !installed &&\n (metadata?.dependencyFingerprint !== fingerprint || !hasValidInstalledDeps);\n\n if (shouldInstall) {\n await rm(nodeModulesPath, { recursive: true, force: true });\n await runPackageManagerCommand(projectRoot, {\n args: [\n \"install\",\n \"--ignore-workspace\",\n \"--config.shared-workspace-lockfile=false\",\n ],\n });\n installed = true;\n fingerprint = await fingerprintInstallManifest({\n packageJsonPath,\n lockfilePath: pnpmLockfilePath,\n });\n }\n\n if (installed || packageManagerNormalized || !metadata) {\n await mkdir(path.dirname(metadataPath), { recursive: true });\n await writeJsonFile(metadataPath, {\n dependencyFingerprint: fingerprint,\n installedAt: new Date().toISOString(),\n packageManager: await readRepoPackageManager(),\n } satisfies DependencyInstallMetadata);\n }\n\n return {\n required: true,\n installed,\n lockfileGenerated,\n packageManagerNormalized,\n fingerprint,\n };\n}\n\nasync function assertNoNpmLockfileConflict(projectRoot: string): Promise<void> {\n const packageLockPath = path.join(projectRoot, \"package-lock.json\");\n const pnpmLockPath = path.join(projectRoot, \"pnpm-lock.yaml\");\n if (\n (await pathExists(packageLockPath)) &&\n !(await pathExists(pnpmLockPath))\n ) {\n throw new Error(buildPackageLockConflictMessage());\n }\n}\n\nasync function assertPnpmLockfilePresent(projectRoot: string): Promise<void> {\n const pnpmLockfilePath = path.join(projectRoot, \"pnpm-lock.yaml\");\n if (!(await pathExists(pnpmLockfilePath))) {\n throw new Error(buildMissingGeneratedLockfileMessage());\n }\n}\n\nasync function ensurePackageManagerNormalized(\n projectRoot: string,\n): Promise<boolean> {\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n const packageJsonContent = await readFile(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(packageJsonContent) as PackageJsonShape;\n const packageManager = await readRepoPackageManager();\n const nextPackageJson: PackageJsonShape = {\n ...packageJson,\n packageManager,\n pnpm: mergePnpmConfig(packageJson.pnpm),\n };\n const normalizedPackageJson = `${JSON.stringify(nextPackageJson, null, 2)}\\n`;\n if (normalizedPackageJson === packageJsonContent) {\n return false;\n }\n await writeFile(packageJsonPath, normalizedPackageJson, \"utf8\");\n return true;\n}\n\nfunction mergePnpmConfig(\n existingPnpm: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const existingOverrides =\n existingPnpm?.overrides &&\n typeof existingPnpm.overrides === \"object\" &&\n !Array.isArray(existingPnpm.overrides)\n ? (existingPnpm.overrides as Record<string, unknown>)\n : {};\n return {\n ...(existingPnpm ?? {}),\n overrides: {\n ...existingOverrides,\n ...FRAMEWORK_PNPM_OVERRIDES,\n },\n };\n}\n\nasync function fingerprintInstallManifest(options: {\n packageJsonPath: string;\n lockfilePath: string;\n}): Promise<string> {\n const packageJson = await readFile(options.packageJsonPath, \"utf8\");\n const lockfile = await readFile(options.lockfilePath, \"utf8\");\n const packageManager = await readRepoPackageManager();\n return fingerprintContent([\n packageJson,\n lockfile,\n `packageManager:${packageManager}`,\n ]);\n}\n\nasync function hasValidInstalledDependencies(options: {\n packageJsonPath: string;\n nodeModulesPath: string;\n}): Promise<boolean> {\n const packageJson = await readJsonFile<PackageJsonShape>(\n options.packageJsonPath,\n );\n if (!packageJson) {\n return false;\n }\n\n const directDependencyNames = new Set<string>();\n for (const field of [\n \"dependencies\",\n \"devDependencies\",\n \"optionalDependencies\",\n ] as const) {\n for (const packageName of Object.keys(packageJson[field] ?? {})) {\n directDependencyNames.add(packageName);\n }\n }\n\n if (directDependencyNames.size === 0) {\n return true;\n }\n\n for (const packageName of directDependencyNames) {\n const packageRoot = path.join(\n options.nodeModulesPath,\n ...packageName.split(\"/\"),\n );\n if (!(await pathExists(path.join(packageRoot, \"package.json\")))) {\n return false;\n }\n if (\n packageName === SDK_PACKAGE_NAME &&\n !(await hasInstalledSdkDistFiles(packageRoot))\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nasync function hasInstalledSdkDistFiles(packageRoot: string): Promise<boolean> {\n for (const relativePath of SDK_REQUIRED_DIST_FILES) {\n if (!(await pathExists(path.join(packageRoot, relativePath)))) {\n return false;\n }\n }\n return true;\n}\n\nfunction hasExactPnpmVersion(value?: string): boolean {\n return /^pnpm@\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(value ?? \"\");\n}\n\nasync function readRepoPackageManager(): Promise<string> {\n const packageJson = await readJsonFile<PackageJsonShape>(\n REPO_PACKAGE_JSON_PATH,\n );\n const packageManager = packageJson?.packageManager?.trim();\n return hasExactPnpmVersion(packageManager)\n ? packageManager!\n : DEFAULT_PACKAGE_MANAGER;\n}\n\nfunction fingerprintContent(parts: string[]): string {\n return crypto\n .createHash(\"sha256\")\n .update(parts.join(\"\\n---\\n\"))\n .digest(\"hex\");\n}\n\nfunction resolvePnpmInstallInvocation(installArgs: readonly string[]): {\n command: string;\n args: string[];\n} {\n const corepackPath = path.join(path.dirname(process.execPath), \"corepack\");\n if (existsSync(corepackPath)) {\n return { command: corepackPath, args: [\"pnpm\", ...installArgs] };\n }\n return { command: \"pnpm\", args: [...installArgs] };\n}\n\nasync function runPackageManagerCommand(\n projectRoot: string,\n command: { args: string[] },\n): Promise<void> {\n const invocation = resolvePnpmInstallInvocation(command.args);\n await runLockfileCommand(projectRoot, {\n binary: invocation.command,\n args: invocation.args,\n });\n}\n\nasync function runLockfileCommand(\n projectRoot: string,\n command: LockfileCommand,\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command.binary, command.args, {\n cwd: projectRoot,\n env: process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n bindStream(child.stdout, (chunk) => {\n stdout += chunk.toString();\n });\n bindStream(child.stderr, (chunk) => {\n stderr += chunk.toString();\n });\n\n child.on(\"error\", (cause) => {\n reject(\n new LockfileGenerationError(command.binary, {\n stdout,\n stderr,\n cause,\n }),\n );\n });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n reject(\n new LockfileGenerationError(command.binary, {\n code,\n stdout,\n stderr,\n }),\n );\n });\n });\n}\n\nfunction buildLockfileGenerationErrorMessage(\n binary: string,\n details: {\n code?: number | null;\n stdout: string;\n stderr: string;\n cause?: Error;\n },\n): string {\n if (details.cause) {\n const errnoError = details.cause as NodeJS.ErrnoException;\n const binaryName = path.basename(binary).toLowerCase();\n if (\n errnoError.code === \"ENOENT\" &&\n (binaryName === \"pnpm\" ||\n binaryName === \"pnpm.cmd\" ||\n binaryName === \"corepack\" ||\n binaryName === \"corepack.exe\")\n ) {\n return buildMissingDependencyToolingMessage();\n }\n return `Failed to start ${binary} for Dreamboard dependency reconciliation. ${details.cause.message}`;\n }\n\n const output = [details.stdout.trim(), details.stderr.trim()]\n .filter((chunk) => chunk.length > 0)\n .join(\"\\n\");\n\n return buildDependencyPreparationFailureMessage({\n exitCode: details.code,\n output,\n });\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await lstat(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readJsonFile<T>(filePath: string): Promise<T | null> {\n try {\n return JSON.parse(await readFile(filePath, \"utf8\")) as T;\n } catch {\n return null;\n }\n}\n\nasync function writeJsonFile(filePath: string, value: unknown): Promise<void> {\n await writeFile(filePath, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nfunction bindStream(\n stream: Readable | EventEmitter | null | undefined,\n onData: (chunk: Buffer | string) => void,\n): void {\n stream?.on(\"data\", onData);\n}\n","import { DEFAULT_WEB_BASE_URL } from \"../../constants.js\";\n\nexport const DEPENDENCY_SETUP_DOCS_PATH = \"/docs/reference/dependency-setup\";\nexport const DEPENDENCY_SETUP_DOCS_URL = `${DEFAULT_WEB_BASE_URL}${DEPENDENCY_SETUP_DOCS_PATH}`;\n\nexport function buildMissingDependencyToolingMessage(): string {\n return [\n \"Dreamboard needs dependency tooling to finish `dreamboard sync`.\",\n \"Use Node 24+ with Corepack enabled, then run `dreamboard sync` again.\",\n \"If Corepack is unavailable on this machine, install pnpm globally with `npm install -g pnpm`.\",\n `Help: ${DEPENDENCY_SETUP_DOCS_URL}`,\n ].join(\"\\n\");\n}\n\nexport function buildPackageLockConflictMessage(): string {\n return [\n \"Dreamboard manages workspace dependencies during `dreamboard sync`.\",\n \"This workspace has an npm lockfile that conflicts with Dreamboard-managed dependencies.\",\n \"Remove `package-lock.json` and run `dreamboard sync` again.\",\n `Help: ${DEPENDENCY_SETUP_DOCS_URL}`,\n ].join(\"\\n\");\n}\n\nexport function buildMissingGeneratedLockfileMessage(): string {\n return [\n \"Dreamboard could not finish preparing workspace dependencies during `dreamboard sync`.\",\n \"Diagnostic: `pnpm-lock.yaml` was not created.\",\n `Help: ${DEPENDENCY_SETUP_DOCS_URL}`,\n ].join(\"\\n\");\n}\n\nexport function buildDependencyPreparationFailureMessage(options: {\n output?: string;\n exitCode?: number | null;\n}): string {\n const details = options.output?.trim();\n return [\n `Dreamboard could not finish preparing workspace dependencies during \\`dreamboard sync\\`${options.exitCode != null ? ` (exit code ${options.exitCode})` : \"\"}.`,\n details ? `Diagnostic output:\\n${details}` : null,\n `Help: ${DEPENDENCY_SETUP_DOCS_URL}`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/project/project-state.ts"],"sourcesContent":["import type {\n LocalMaintainerRegistryConfig,\n LocalMaintainerRegistryPackages,\n LocalMaintainerSdkPackageName,\n ProjectAuthoringState,\n ProjectCompileAttempt,\n ProjectCompileState,\n ProjectConfig,\n ProjectPendingAuthoringSync,\n} from \"../../types.js\";\n\nconst LOCAL_MAINTAINER_SDK_PACKAGE_NAMES = [\n \"@dreamboard-games/api-client\",\n \"@dreamboard-games/sdk\",\n] as const satisfies readonly LocalMaintainerSdkPackageName[];\n\nexport function getProjectAuthoringState(\n projectConfig: ProjectConfig,\n): ProjectAuthoringState {\n return projectConfig.authoring ?? {};\n}\n\nexport function getProjectPendingAuthoringSync(\n projectConfig: ProjectConfig,\n): ProjectPendingAuthoringSync | undefined {\n return getProjectAuthoringState(projectConfig).pendingSync;\n}\n\nexport function getProjectCompileState(\n projectConfig: ProjectConfig,\n): ProjectCompileState {\n return projectConfig.compile ?? {};\n}\n\nexport function getProjectLocalMaintainerRegistry(\n projectConfig: ProjectConfig,\n): LocalMaintainerRegistryConfig | undefined {\n return projectConfig.localMaintainerRegistry;\n}\n\nexport function updateProjectAuthoringState(\n projectConfig: ProjectConfig,\n authoring: ProjectAuthoringState,\n): ProjectConfig {\n return {\n ...projectConfig,\n authoring: {\n ...getProjectAuthoringState(projectConfig),\n ...authoring,\n },\n };\n}\n\nexport function setProjectPendingAuthoringSync(\n projectConfig: ProjectConfig,\n pendingSync: ProjectPendingAuthoringSync,\n): ProjectConfig {\n return updateProjectAuthoringState(projectConfig, {\n pendingSync,\n });\n}\n\nexport function clearProjectPendingAuthoringSync(\n projectConfig: ProjectConfig,\n): ProjectConfig {\n const authoring = getProjectAuthoringState(projectConfig);\n if (!authoring.pendingSync) {\n return projectConfig;\n }\n\n const { pendingSync: _pendingSync, ...rest } = authoring;\n return {\n ...projectConfig,\n authoring: rest,\n };\n}\n\nexport function finalizeProjectPendingAuthoringSync(\n projectConfig: ProjectConfig,\n): ProjectConfig {\n const authoring = getProjectAuthoringState(projectConfig);\n const pendingSync = authoring.pendingSync;\n if (!pendingSync) {\n return projectConfig;\n }\n\n return updateProjectAuthoringState(\n clearProjectPendingAuthoringSync(projectConfig),\n {\n authoringStateId:\n pendingSync.phase === \"authoring_state_created\"\n ? pendingSync.authoringStateId\n : authoring.authoringStateId,\n revisionDigest: pendingSync.revisionDigest ?? authoring.revisionDigest,\n sourceRevisionId: pendingSync.sourceRevisionId,\n sourceTreeHash: pendingSync.sourceTreeHash,\n manifestId: pendingSync.manifestId,\n manifestContentHash: pendingSync.manifestContentHash,\n localManifestContentHash: pendingSync.localManifestContentHash,\n ruleId: pendingSync.ruleId,\n },\n );\n}\n\nexport function updateProjectCompileState(\n projectConfig: ProjectConfig,\n compile: ProjectCompileState,\n): ProjectConfig {\n return {\n ...projectConfig,\n compile: {\n ...getProjectCompileState(projectConfig),\n ...compile,\n },\n };\n}\n\nexport function setLatestCompileAttempt(\n projectConfig: ProjectConfig,\n attempt: ProjectCompileAttempt,\n): ProjectConfig {\n return updateProjectCompileState(projectConfig, {\n ...getProjectCompileState(projectConfig),\n latestAttempt: attempt,\n latestSuccessful:\n attempt.status === \"successful\" && attempt.resultId\n ? {\n resultId: attempt.resultId,\n authoringStateId: attempt.authoringStateId,\n revisionDigest: attempt.revisionDigest,\n }\n : getProjectCompileState(projectConfig).latestSuccessful,\n });\n}\n\nexport function clearProjectCompileState(\n projectConfig: ProjectConfig,\n): ProjectConfig {\n return {\n ...projectConfig,\n compile: {},\n };\n}\n\nexport function updateProjectLocalMaintainerRegistry(\n projectConfig: ProjectConfig,\n localMaintainerRegistry: LocalMaintainerRegistryConfig | undefined,\n): ProjectConfig {\n return {\n ...projectConfig,\n localMaintainerRegistry: sanitizeProjectLocalMaintainerRegistry(\n localMaintainerRegistry,\n ),\n };\n}\n\nexport function sanitizeProjectLocalMaintainerRegistry(\n localMaintainerRegistry: LocalMaintainerRegistryConfig | undefined,\n): LocalMaintainerRegistryConfig | undefined {\n if (!localMaintainerRegistry) return undefined;\n\n const packages: Partial<LocalMaintainerRegistryPackages> = {};\n for (const packageName of LOCAL_MAINTAINER_SDK_PACKAGE_NAMES) {\n const version = localMaintainerRegistry.packages[packageName];\n if (version) {\n packages[packageName] = version;\n }\n }\n\n return {\n ...localMaintainerRegistry,\n packages: packages as LocalMaintainerRegistryPackages,\n };\n}\n"],"mappings":";;;AAWA,IAAM,qCAAqC;AAAA,EACzC;AAAA,EACA;AACF;AAEO,SAAS,yBACd,eACuB;AACvB,SAAO,cAAc,aAAa,CAAC;AACrC;AAEO,SAAS,+BACd,eACyC;AACzC,SAAO,yBAAyB,aAAa,EAAE;AACjD;AAEO,SAAS,uBACd,eACqB;AACrB,SAAO,cAAc,WAAW,CAAC;AACnC;AAEO,SAAS,kCACd,eAC2C;AAC3C,SAAO,cAAc;AACvB;AAEO,SAAS,4BACd,eACA,WACe;AACf,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW;AAAA,MACT,GAAG,yBAAyB,aAAa;AAAA,MACzC,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAEO,SAAS,+BACd,eACA,aACe;AACf,SAAO,4BAA4B,eAAe;AAAA,IAChD;AAAA,EACF,CAAC;AACH;AAEO,SAAS,iCACd,eACe;AACf,QAAM,YAAY,yBAAyB,aAAa;AACxD,MAAI,CAAC,UAAU,aAAa;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,aAAa,cAAc,GAAG,KAAK,IAAI;AAC/C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW;AAAA,EACb;AACF;AAEO,SAAS,oCACd,eACe;AACf,QAAM,YAAY,yBAAyB,aAAa;AACxD,QAAM,cAAc,UAAU;AAC9B,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,iCAAiC,aAAa;AAAA,IAC9C;AAAA,MACE,kBACE,YAAY,UAAU,4BAClB,YAAY,mBACZ,UAAU;AAAA,MAChB,gBAAgB,YAAY,kBAAkB,UAAU;AAAA,MACxD,kBAAkB,YAAY;AAAA,MAC9B,gBAAgB,YAAY;AAAA,MAC5B,YAAY,YAAY;AAAA,MACxB,qBAAqB,YAAY;AAAA,MACjC,0BAA0B,YAAY;AAAA,MACtC,QAAQ,YAAY;AAAA,IACtB;AAAA,EACF;AACF;AAEO,SAAS,0BACd,eACA,SACe;AACf,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,uBAAuB,aAAa;AAAA,MACvC,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAEO,SAAS,wBACd,eACA,SACe;AACf,SAAO,0BAA0B,eAAe;AAAA,IAC9C,GAAG,uBAAuB,aAAa;AAAA,IACvC,eAAe;AAAA,IACf,kBACE,QAAQ,WAAW,gBAAgB,QAAQ,WACvC;AAAA,MACE,UAAU,QAAQ;AAAA,MAClB,kBAAkB,QAAQ;AAAA,MAC1B,gBAAgB,QAAQ;AAAA,IAC1B,IACA,uBAAuB,aAAa,EAAE;AAAA,EAC9C,CAAC;AACH;AAEO,SAAS,yBACd,eACe;AACf,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,CAAC;AAAA,EACZ;AACF;AAEO,SAAS,qCACd,eACA,yBACe;AACf,SAAO;AAAA,IACL,GAAG;AAAA,IACH,yBAAyB;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,uCACd,yBAC2C;AAC3C,MAAI,CAAC,wBAAyB,QAAO;AAErC,QAAM,WAAqD,CAAC;AAC5D,aAAW,eAAe,oCAAoC;AAC5D,UAAM,UAAU,wBAAwB,SAAS,WAAW;AAC5D,QAAI,SAAS;AACX,eAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
|