@forgeax/engine-pack 0.1.20 → 0.1.23
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 +159 -46
- package/dist/__tests__/inventory-schema.test.d.ts +2 -0
- package/dist/__tests__/inventory-schema.test.d.ts.map +1 -0
- package/dist/__tests__/parameterized-pack-authoring-gateway.unit.test.d.ts +2 -0
- package/dist/__tests__/parameterized-pack-authoring-gateway.unit.test.d.ts.map +1 -0
- package/dist/__tests__/parameterized-pack-scanner.unit.test.d.ts +2 -0
- package/dist/__tests__/parameterized-pack-scanner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/parameterized-pack.unit.test.d.ts +2 -0
- package/dist/__tests__/parameterized-pack.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scanner-blacklist.test.d.ts +2 -0
- package/dist/__tests__/scanner-blacklist.test.d.ts.map +1 -0
- package/dist/build.d.ts +9 -4
- package/dist/build.d.ts.map +1 -1
- package/dist/build.mjs +3317 -804
- package/dist/build.mjs.map +1 -1
- package/dist/builtin.mjs +37 -4
- package/dist/builtin.mjs.map +1 -1
- package/dist/catalog-builder.d.ts.map +1 -1
- package/dist/cli-asset.d.ts.map +1 -1
- package/dist/cli-asset.mjs +1368 -850
- package/dist/cli-asset.mjs.map +1 -1
- package/dist/deriveAssetName.d.ts +11 -7
- package/dist/deriveAssetName.d.ts.map +1 -1
- package/dist/evidence/material-cook.d.ts.map +1 -1
- package/dist/evidence/source-inventory.d.ts.map +1 -1
- package/dist/guid.d.ts +15 -0
- package/dist/guid.d.ts.map +1 -1
- package/dist/guid.mjs +53 -5
- package/dist/guid.mjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +1255 -561
- package/dist/index.mjs.map +1 -1
- package/dist/inventory/binding.d.ts +6 -0
- package/dist/inventory/binding.d.ts.map +1 -0
- package/dist/inventory/declaration.d.ts +24 -0
- package/dist/inventory/declaration.d.ts.map +1 -0
- package/dist/inventory/index.d.ts +3 -0
- package/dist/inventory/index.d.ts.map +1 -0
- package/dist/inventory/sync.d.ts +5 -0
- package/dist/inventory/sync.d.ts.map +1 -0
- package/dist/material-cook.mjs +3 -1
- package/dist/material-cook.mjs.map +1 -1
- package/dist/name.mjs +4 -7
- package/dist/name.mjs.map +1 -1
- package/dist/package-finalizer.d.ts +2 -20
- package/dist/package-finalizer.d.ts.map +1 -1
- package/dist/parameterized-pack-node.d.ts +26 -0
- package/dist/parameterized-pack-node.d.ts.map +1 -0
- package/dist/parameterized-pack-node.mjs +11093 -0
- package/dist/parameterized-pack-node.mjs.map +1 -0
- package/dist/parameterized-pack.d.ts +233 -0
- package/dist/parameterized-pack.d.ts.map +1 -0
- package/dist/resolve-asset-source.d.ts +1 -3
- package/dist/resolve-asset-source.d.ts.map +1 -1
- package/dist/resolve-asset-source.mjs +6 -81
- package/dist/resolve-asset-source.mjs.map +1 -1
- package/dist/runtime.mjs +77 -7
- package/dist/runtime.mjs.map +1 -1
- package/dist/scanner.d.ts +19 -8
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.mjs +1169 -690
- package/dist/scanner.mjs.map +1 -1
- package/dist/schema-compiled.d.ts.map +1 -1
- package/dist/schema.mjs +79 -7
- package/dist/schema.mjs.map +1 -1
- package/dist/scriptable-pack-node.d.ts +8 -32
- package/dist/scriptable-pack-node.d.ts.map +1 -1
- package/dist/scriptable-pack-node.mjs +576 -1021
- package/dist/scriptable-pack-node.mjs.map +1 -1
- package/dist/scriptable-pack-worker.mjs +29 -11
- package/dist/scriptable-pack-worker.mjs.map +1 -1
- package/dist/scriptable-pack.d.ts +19 -532
- package/dist/scriptable-pack.d.ts.map +1 -1
- package/dist/scriptable-pack.mjs +1042 -527
- package/dist/scriptable-pack.mjs.map +1 -1
- package/package.json +7 -7
- package/schema/meta.schema.json +1 -1
- package/schema/pack.schema.json +76 -6
- package/src/__tests__/guid-collision.unit.test.ts +18 -9
- package/src/__tests__/inventory-schema.test.ts +109 -0
- package/src/__tests__/pack.unit.test.ts +1 -238
- package/src/__tests__/package-finalizer.contract.test.ts +55 -0
- package/src/__tests__/parameterized-pack-authoring-gateway.unit.test.ts +249 -0
- package/src/__tests__/parameterized-pack-scanner.unit.test.ts +123 -0
- package/src/__tests__/parameterized-pack.unit.test.ts +266 -0
- package/src/__tests__/resolve-asset-source.test.ts +15 -98
- package/src/__tests__/scanner-blacklist.test.ts +55 -0
- package/src/__tests__/scanner-inventory.contract.test.ts +14 -15
- package/src/__tests__/scanner-inventory.test.ts +24 -12
- package/src/__tests__/scriptable-pack-cli.integration.test.ts +4 -9
- package/src/__tests__/topology.unit.test.ts +23 -0
- package/src/build.ts +28 -18
- package/src/catalog-builder.ts +61 -34
- package/src/cli-asset.ts +70 -85
- package/src/deriveAssetName.ts +14 -13
- package/src/evidence/material-cook.ts +3 -1
- package/src/evidence/source-inventory.ts +34 -21
- package/src/guid.ts +65 -4
- package/src/index.ts +12 -11
- package/src/inventory/binding.ts +25 -0
- package/src/inventory/declaration.ts +168 -0
- package/src/inventory/index.ts +18 -0
- package/src/inventory/sync.ts +22 -0
- package/src/package-finalizer.ts +2 -42
- package/src/parameterized-pack-node.ts +1968 -0
- package/src/parameterized-pack.ts +1493 -0
- package/src/resolve-asset-source.ts +4 -76
- package/src/scanner.ts +241 -59
- package/src/schema-compiled.ts +2 -0
- package/src/scriptable-pack-node.ts +111 -722
- package/src/scriptable-pack-worker.ts +48 -16
- package/src/scriptable-pack.ts +27 -939
- package/dist/.tsbuildinfo +0 -1
- package/dist/__tests__/load-asset-config.test.d.ts +0 -2
- package/dist/__tests__/load-asset-config.test.d.ts.map +0 -1
- package/dist/__tests__/scriptable-pack.test-d.d.ts +0 -2
- package/dist/__tests__/scriptable-pack.test-d.d.ts.map +0 -1
- package/dist/__tests__/scriptable-pack.unit.test.d.ts +0 -2
- package/dist/__tests__/scriptable-pack.unit.test.d.ts.map +0 -1
- package/dist/config.d.ts +0 -6
- package/dist/config.d.ts.map +0 -1
- package/dist/config.mjs +0 -29
- package/dist/config.mjs.map +0 -1
- package/src/__tests__/load-asset-config.test.ts +0 -121
- package/src/__tests__/scriptable-pack.test-d.ts +0 -131
- package/src/__tests__/scriptable-pack.unit.test.ts +0 -789
- package/src/config.ts +0 -36
package/dist/cli-asset.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
3
|
import { realpath, readFile, mkdir, writeFile, mkdtemp, rm, stat, readdir } from 'fs/promises';
|
|
4
|
-
import { isAbsolute, resolve, sep, basename, extname, dirname, join
|
|
4
|
+
import { isAbsolute, resolve, sep, basename, extname, dirname, join } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { parseArgs } from 'util';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { err, ok, IMAGE_ERROR_HINTS, projectCookProductEvidence, projectAssetEvidence, AssetError, ImportError, PACK_ERROR_HINTS, validateSourceOverrideMap } from '@forgeax/engine-types';
|
|
8
|
+
import { sha1 } from '@noble/hashes/legacy.js';
|
|
9
9
|
import { uuidv7obj } from 'uuidv7';
|
|
10
|
+
import { existsSync } from 'fs';
|
|
10
11
|
import { tmpdir } from 'os';
|
|
11
12
|
import { Worker } from 'worker_threads';
|
|
12
13
|
import ts from 'typescript';
|
|
@@ -3627,49 +3628,49 @@ var require_fast_uri = __commonJS({
|
|
|
3627
3628
|
schemelessOptions.skipEscape = true;
|
|
3628
3629
|
return serialize(resolved, schemelessOptions);
|
|
3629
3630
|
}
|
|
3630
|
-
function resolveComponent(base,
|
|
3631
|
+
function resolveComponent(base, relative2, options, skipNormalization) {
|
|
3631
3632
|
const target = {};
|
|
3632
3633
|
if (!skipNormalization) {
|
|
3633
3634
|
base = parse(serialize(base, options), options);
|
|
3634
|
-
|
|
3635
|
+
relative2 = parse(serialize(relative2, options), options);
|
|
3635
3636
|
}
|
|
3636
3637
|
options = options || {};
|
|
3637
|
-
if (!options.tolerant &&
|
|
3638
|
-
target.scheme =
|
|
3639
|
-
target.userinfo =
|
|
3640
|
-
target.host =
|
|
3641
|
-
target.port =
|
|
3642
|
-
target.path = removeDotSegments(
|
|
3643
|
-
target.query =
|
|
3638
|
+
if (!options.tolerant && relative2.scheme) {
|
|
3639
|
+
target.scheme = relative2.scheme;
|
|
3640
|
+
target.userinfo = relative2.userinfo;
|
|
3641
|
+
target.host = relative2.host;
|
|
3642
|
+
target.port = relative2.port;
|
|
3643
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
3644
|
+
target.query = relative2.query;
|
|
3644
3645
|
} else {
|
|
3645
|
-
if (
|
|
3646
|
-
target.userinfo =
|
|
3647
|
-
target.host =
|
|
3648
|
-
target.port =
|
|
3649
|
-
target.path = removeDotSegments(
|
|
3650
|
-
target.query =
|
|
3646
|
+
if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
|
|
3647
|
+
target.userinfo = relative2.userinfo;
|
|
3648
|
+
target.host = relative2.host;
|
|
3649
|
+
target.port = relative2.port;
|
|
3650
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
3651
|
+
target.query = relative2.query;
|
|
3651
3652
|
} else {
|
|
3652
|
-
if (!
|
|
3653
|
+
if (!relative2.path) {
|
|
3653
3654
|
target.path = base.path;
|
|
3654
|
-
if (
|
|
3655
|
-
target.query =
|
|
3655
|
+
if (relative2.query !== void 0) {
|
|
3656
|
+
target.query = relative2.query;
|
|
3656
3657
|
} else {
|
|
3657
3658
|
target.query = base.query;
|
|
3658
3659
|
}
|
|
3659
3660
|
} else {
|
|
3660
|
-
if (
|
|
3661
|
-
target.path = removeDotSegments(
|
|
3661
|
+
if (relative2.path[0] === "/") {
|
|
3662
|
+
target.path = removeDotSegments(relative2.path);
|
|
3662
3663
|
} else {
|
|
3663
3664
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
3664
|
-
target.path = "/" +
|
|
3665
|
+
target.path = "/" + relative2.path;
|
|
3665
3666
|
} else if (!base.path) {
|
|
3666
|
-
target.path =
|
|
3667
|
+
target.path = relative2.path;
|
|
3667
3668
|
} else {
|
|
3668
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
3669
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
|
|
3669
3670
|
}
|
|
3670
3671
|
target.path = removeDotSegments(target.path);
|
|
3671
3672
|
}
|
|
3672
|
-
target.query =
|
|
3673
|
+
target.query = relative2.query;
|
|
3673
3674
|
}
|
|
3674
3675
|
target.userinfo = base.userinfo;
|
|
3675
3676
|
target.host = base.host;
|
|
@@ -3677,7 +3678,7 @@ var require_fast_uri = __commonJS({
|
|
|
3677
3678
|
}
|
|
3678
3679
|
target.scheme = base.scheme;
|
|
3679
3680
|
}
|
|
3680
|
-
target.fragment =
|
|
3681
|
+
target.fragment = relative2.fragment;
|
|
3681
3682
|
return target;
|
|
3682
3683
|
}
|
|
3683
3684
|
function equal(uriA, uriB, options) {
|
|
@@ -4716,8 +4717,8 @@ var require_multipleOf = __commonJS({
|
|
|
4716
4717
|
const { gen, data, schemaCode, it } = cxt;
|
|
4717
4718
|
const prec = it.opts.multipleOfPrecision;
|
|
4718
4719
|
const res = gen.let("res");
|
|
4719
|
-
const
|
|
4720
|
-
cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${
|
|
4720
|
+
const invalid = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
|
|
4721
|
+
cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid}))`);
|
|
4721
4722
|
}
|
|
4722
4723
|
};
|
|
4723
4724
|
exports.default = def;
|
|
@@ -7180,27 +7181,6 @@ function buildOfflineAssetEvidence(input) {
|
|
|
7180
7181
|
};
|
|
7181
7182
|
return Promise.resolve(projectAssetEvidence(evidenceInput));
|
|
7182
7183
|
}
|
|
7183
|
-
function loadAssetConfig(cwd) {
|
|
7184
|
-
let pkg;
|
|
7185
|
-
try {
|
|
7186
|
-
pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8"));
|
|
7187
|
-
} catch {
|
|
7188
|
-
return { roots: [join(cwd, "assets")], paths: {} };
|
|
7189
|
-
}
|
|
7190
|
-
const assets = pkg.forgeax?.assets;
|
|
7191
|
-
const rawRoots = assets?.roots;
|
|
7192
|
-
const roots = Array.isArray(rawRoots) && rawRoots.length > 0 ? rawRoots.map((r) => join(cwd, r)) : [join(cwd, "assets")];
|
|
7193
|
-
const rawPaths = assets?.paths;
|
|
7194
|
-
const paths = {};
|
|
7195
|
-
if (rawPaths !== void 0 && rawPaths !== null && typeof rawPaths === "object") {
|
|
7196
|
-
for (const [name, dir] of Object.entries(rawPaths)) {
|
|
7197
|
-
if (typeof dir === "string") {
|
|
7198
|
-
paths[name] = join(cwd, dir);
|
|
7199
|
-
}
|
|
7200
|
-
}
|
|
7201
|
-
}
|
|
7202
|
-
return { roots, paths };
|
|
7203
|
-
}
|
|
7204
7184
|
|
|
7205
7185
|
// src/errors.ts
|
|
7206
7186
|
var PackError = class extends Error {
|
|
@@ -7217,6 +7197,8 @@ var PackError = class extends Error {
|
|
|
7217
7197
|
this.detail = args.detail;
|
|
7218
7198
|
}
|
|
7219
7199
|
};
|
|
7200
|
+
|
|
7201
|
+
// src/guid.ts
|
|
7220
7202
|
function brand(bytes) {
|
|
7221
7203
|
return bytes;
|
|
7222
7204
|
}
|
|
@@ -7226,6 +7208,10 @@ function bytesToDashForm(bytes) {
|
|
|
7226
7208
|
return `${h[bytes[0]]}${h[bytes[1]]}${h[bytes[2]]}${h[bytes[3]]}-${h[bytes[4]]}${h[bytes[5]]}-${h[bytes[6]]}${h[bytes[7]]}-${h[bytes[8]]}${h[bytes[9]]}-${h[bytes[10]]}${h[bytes[11]]}${h[bytes[12]]}${h[bytes[13]]}${h[bytes[14]]}${h[bytes[15]]}`;
|
|
7227
7209
|
}
|
|
7228
7210
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7211
|
+
var PACK_SOURCE_KEY_RE = /^[a-z0-9][a-z0-9._-]*(\/[a-z0-9][a-z0-9._-]*)*$/;
|
|
7212
|
+
function isValidPackSourceKey(value) {
|
|
7213
|
+
return typeof value === "string" && PACK_SOURCE_KEY_RE.test(value);
|
|
7214
|
+
}
|
|
7229
7215
|
function isValidAssetGuidString(value) {
|
|
7230
7216
|
return typeof value === "string" && UUID_RE.test(value);
|
|
7231
7217
|
}
|
|
@@ -7237,6 +7223,48 @@ function dashFormToBytes(dashForm) {
|
|
|
7237
7223
|
}
|
|
7238
7224
|
return bytes;
|
|
7239
7225
|
}
|
|
7226
|
+
function randomUuidBytes() {
|
|
7227
|
+
const uuid = uuidv7obj();
|
|
7228
|
+
const bytes = new Uint8Array(16);
|
|
7229
|
+
bytes.set(uuid.bytes);
|
|
7230
|
+
return bytes;
|
|
7231
|
+
}
|
|
7232
|
+
function packageId(value) {
|
|
7233
|
+
return value;
|
|
7234
|
+
}
|
|
7235
|
+
var PackageId = {
|
|
7236
|
+
parse(dashForm) {
|
|
7237
|
+
const parsed = AssetGuid.parse(dashForm);
|
|
7238
|
+
return parsed.ok ? { ok: true, value: packageId(parsed.value) } : parsed;
|
|
7239
|
+
},
|
|
7240
|
+
format(value) {
|
|
7241
|
+
return bytesToDashForm(value);
|
|
7242
|
+
},
|
|
7243
|
+
random() {
|
|
7244
|
+
return packageId(randomUuidBytes());
|
|
7245
|
+
}
|
|
7246
|
+
};
|
|
7247
|
+
function derivedGuid(namespace, sourceKey) {
|
|
7248
|
+
if (!(namespace instanceof Uint8Array) || namespace.byteLength !== 16) {
|
|
7249
|
+
throw new TypeError("AssetGuid.derive requires a 16-byte PackageId");
|
|
7250
|
+
}
|
|
7251
|
+
if (!isValidPackSourceKey(sourceKey)) {
|
|
7252
|
+
const error = new TypeError(
|
|
7253
|
+
`AssetGuid.derive received invalid sourceKey ${JSON.stringify(sourceKey)}`
|
|
7254
|
+
);
|
|
7255
|
+
Object.defineProperty(error, "code", { value: "pack-source-key-invalid" });
|
|
7256
|
+
throw error;
|
|
7257
|
+
}
|
|
7258
|
+
const name = new TextEncoder().encode(sourceKey);
|
|
7259
|
+
const input = new Uint8Array(namespace.byteLength + name.byteLength);
|
|
7260
|
+
input.set(namespace, 0);
|
|
7261
|
+
input.set(name, namespace.byteLength);
|
|
7262
|
+
const digest = sha1(input);
|
|
7263
|
+
const result = digest.slice(0, 16);
|
|
7264
|
+
result[6] = (result[6] ?? 0) & 15 | 80;
|
|
7265
|
+
result[8] = (result[8] ?? 0) & 63 | 128;
|
|
7266
|
+
return brand(result);
|
|
7267
|
+
}
|
|
7240
7268
|
var AssetGuid = {
|
|
7241
7269
|
/**
|
|
7242
7270
|
* Parse a 36-char RFC 4122 dash-form UUID string into an AssetGuid.
|
|
@@ -7280,19 +7308,762 @@ var AssetGuid = {
|
|
|
7280
7308
|
* Works in both Node.js and browser environments.
|
|
7281
7309
|
*/
|
|
7282
7310
|
random() {
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7311
|
+
return brand(randomUuidBytes());
|
|
7312
|
+
},
|
|
7313
|
+
/** Derive the stable UUIDv5 projection for one Pack subject and sourceKey. */
|
|
7314
|
+
derive(namespace, sourceKey) {
|
|
7315
|
+
return derivedGuid(namespace, sourceKey);
|
|
7287
7316
|
}
|
|
7288
7317
|
};
|
|
7318
|
+
|
|
7319
|
+
// src/parameterized-pack.ts
|
|
7320
|
+
var PACK_PARAMETER_TYPES = [
|
|
7321
|
+
"bool",
|
|
7322
|
+
"u32",
|
|
7323
|
+
"i32",
|
|
7324
|
+
"f32",
|
|
7325
|
+
"f64",
|
|
7326
|
+
"string",
|
|
7327
|
+
"enum",
|
|
7328
|
+
"vec2",
|
|
7329
|
+
"vec3",
|
|
7330
|
+
"vec4",
|
|
7331
|
+
"color",
|
|
7332
|
+
"asset-guid"
|
|
7333
|
+
];
|
|
7334
|
+
function authoringError(code, expected, hint, detail = {}, actual) {
|
|
7335
|
+
return {
|
|
7336
|
+
code,
|
|
7337
|
+
expected,
|
|
7338
|
+
hint,
|
|
7339
|
+
...actual === void 0 ? {} : { actual },
|
|
7340
|
+
detail
|
|
7341
|
+
};
|
|
7342
|
+
}
|
|
7343
|
+
function failure(error) {
|
|
7344
|
+
return err(error);
|
|
7345
|
+
}
|
|
7289
7346
|
function isRecord(value) {
|
|
7347
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7348
|
+
}
|
|
7349
|
+
function validateSceneComponents(value) {
|
|
7350
|
+
if (value === void 0) return ok(void 0);
|
|
7351
|
+
if (!Array.isArray(value)) {
|
|
7352
|
+
return failure(
|
|
7353
|
+
parameterFailure(
|
|
7354
|
+
"$.sceneComponents",
|
|
7355
|
+
"an array of component schema records",
|
|
7356
|
+
value,
|
|
7357
|
+
"sceneComponents is not an array"
|
|
7358
|
+
)
|
|
7359
|
+
);
|
|
7360
|
+
}
|
|
7361
|
+
const components = [];
|
|
7362
|
+
const names = /* @__PURE__ */ new Set();
|
|
7363
|
+
for (const [componentIndex, candidate] of value.entries()) {
|
|
7364
|
+
if (!isRecord(candidate) || typeof candidate.name !== "string" || !isRecord(candidate.fields)) {
|
|
7365
|
+
return failure(
|
|
7366
|
+
parameterFailure(
|
|
7367
|
+
`$.sceneComponents[${componentIndex}]`,
|
|
7368
|
+
"a component record with name and fields",
|
|
7369
|
+
candidate,
|
|
7370
|
+
"scene component schema is malformed"
|
|
7371
|
+
)
|
|
7372
|
+
);
|
|
7373
|
+
}
|
|
7374
|
+
if (candidate.name.length === 0 || names.has(candidate.name)) {
|
|
7375
|
+
return failure(
|
|
7376
|
+
parameterFailure(
|
|
7377
|
+
`$.sceneComponents[${componentIndex}].name`,
|
|
7378
|
+
"a non-empty unique component name",
|
|
7379
|
+
candidate.name,
|
|
7380
|
+
"scene component names must be unique"
|
|
7381
|
+
)
|
|
7382
|
+
);
|
|
7383
|
+
}
|
|
7384
|
+
names.add(candidate.name);
|
|
7385
|
+
const fields = {};
|
|
7386
|
+
for (const [fieldName, field] of Object.entries(candidate.fields)) {
|
|
7387
|
+
if (typeof field === "string" && field.length === 0 || typeof field !== "string" && (!isRecord(field) || typeof field.type !== "string" || field.type.length === 0)) {
|
|
7388
|
+
return failure(
|
|
7389
|
+
parameterFailure(
|
|
7390
|
+
`$.sceneComponents[${componentIndex}].fields.${fieldName}`,
|
|
7391
|
+
"a field type string or { type: string }",
|
|
7392
|
+
field,
|
|
7393
|
+
"scene component field schema is malformed"
|
|
7394
|
+
)
|
|
7395
|
+
);
|
|
7396
|
+
}
|
|
7397
|
+
fields[fieldName] = field;
|
|
7398
|
+
}
|
|
7399
|
+
components.push({ name: candidate.name, fields });
|
|
7400
|
+
}
|
|
7401
|
+
return ok(components);
|
|
7402
|
+
}
|
|
7403
|
+
function isPackageId(value) {
|
|
7404
|
+
return value instanceof Uint8Array && value.byteLength === 16;
|
|
7405
|
+
}
|
|
7406
|
+
function cloneValue(value) {
|
|
7407
|
+
if (value instanceof Uint8Array) return value.slice();
|
|
7408
|
+
if (Array.isArray(value)) return value.map((item) => cloneValue(item));
|
|
7409
|
+
return value;
|
|
7410
|
+
}
|
|
7411
|
+
function sourceKeyFailure(sourceKey, propertyPath = "$.sourceKey") {
|
|
7412
|
+
return authoringError(
|
|
7413
|
+
"pack-source-key-invalid",
|
|
7414
|
+
"a sourceKey matching ^[a-z0-9][a-z0-9._-]*(/[a-z0-9][a-z0-9._-]*)*$",
|
|
7415
|
+
"use a stable lower-case semantic key; do not derive it from file paths or output order",
|
|
7416
|
+
{ propertyPath, sourceKey },
|
|
7417
|
+
typeof sourceKey === "string" ? sourceKey : void 0
|
|
7418
|
+
);
|
|
7419
|
+
}
|
|
7420
|
+
function parameterFailure(propertyPath, expected, actual, reason) {
|
|
7421
|
+
return authoringError(
|
|
7422
|
+
"pack-parameter-invalid",
|
|
7423
|
+
expected,
|
|
7424
|
+
"repair the parameter declaration or the instance values, then inspect and rebuild",
|
|
7425
|
+
{ propertyPath, reason, actual: typeof actual === "string" ? actual : JSON.stringify(actual) }
|
|
7426
|
+
);
|
|
7427
|
+
}
|
|
7428
|
+
function numericType(type) {
|
|
7429
|
+
return type === "u32" || type === "i32" || type === "f32" || type === "f64";
|
|
7430
|
+
}
|
|
7431
|
+
function vectorLength(type) {
|
|
7432
|
+
switch (type) {
|
|
7433
|
+
case "vec2":
|
|
7434
|
+
return 2;
|
|
7435
|
+
case "vec3":
|
|
7436
|
+
return 3;
|
|
7437
|
+
case "vec4":
|
|
7438
|
+
case "color":
|
|
7439
|
+
return 4;
|
|
7440
|
+
default:
|
|
7441
|
+
return void 0;
|
|
7442
|
+
}
|
|
7443
|
+
}
|
|
7444
|
+
function parameterValueError(parameter, value, propertyPath) {
|
|
7445
|
+
const { type } = parameter;
|
|
7446
|
+
if (type === "bool" && typeof value !== "boolean") {
|
|
7447
|
+
return parameterFailure(propertyPath, "a boolean", value, "bool value has the wrong type");
|
|
7448
|
+
}
|
|
7449
|
+
if (numericType(type)) {
|
|
7450
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
7451
|
+
return parameterFailure(
|
|
7452
|
+
propertyPath,
|
|
7453
|
+
"a finite number",
|
|
7454
|
+
value,
|
|
7455
|
+
"numeric value is not finite"
|
|
7456
|
+
);
|
|
7457
|
+
}
|
|
7458
|
+
if ((type === "u32" || type === "i32") && !Number.isInteger(value)) {
|
|
7459
|
+
return parameterFailure(
|
|
7460
|
+
propertyPath,
|
|
7461
|
+
"an integer",
|
|
7462
|
+
value,
|
|
7463
|
+
"integer parameter received a fraction"
|
|
7464
|
+
);
|
|
7465
|
+
}
|
|
7466
|
+
if (type === "u32" && (value < 0 || value > 4294967295)) {
|
|
7467
|
+
return parameterFailure(
|
|
7468
|
+
propertyPath,
|
|
7469
|
+
"an unsigned 32-bit integer",
|
|
7470
|
+
value,
|
|
7471
|
+
"u32 value is outside [0, 2^32 - 1]"
|
|
7472
|
+
);
|
|
7473
|
+
}
|
|
7474
|
+
if (type === "i32" && (value < -2147483648 || value > 2147483647)) {
|
|
7475
|
+
return parameterFailure(
|
|
7476
|
+
propertyPath,
|
|
7477
|
+
"a signed 32-bit integer",
|
|
7478
|
+
value,
|
|
7479
|
+
"i32 value is outside [-2^31, 2^31 - 1]"
|
|
7480
|
+
);
|
|
7481
|
+
}
|
|
7482
|
+
if (type === "f32" && !Number.isFinite(Math.fround(value))) {
|
|
7483
|
+
return parameterFailure(
|
|
7484
|
+
propertyPath,
|
|
7485
|
+
"a finite IEEE-754 32-bit float",
|
|
7486
|
+
value,
|
|
7487
|
+
"f32 value overflows binary32"
|
|
7488
|
+
);
|
|
7489
|
+
}
|
|
7490
|
+
if (parameter.minimum !== void 0 && value < parameter.minimum) {
|
|
7491
|
+
return parameterFailure(
|
|
7492
|
+
propertyPath,
|
|
7493
|
+
`a number >= ${parameter.minimum}`,
|
|
7494
|
+
value,
|
|
7495
|
+
"value is below minimum"
|
|
7496
|
+
);
|
|
7497
|
+
}
|
|
7498
|
+
if (parameter.maximum !== void 0 && value > parameter.maximum) {
|
|
7499
|
+
return parameterFailure(
|
|
7500
|
+
propertyPath,
|
|
7501
|
+
`a number <= ${parameter.maximum}`,
|
|
7502
|
+
value,
|
|
7503
|
+
"value is above maximum"
|
|
7504
|
+
);
|
|
7505
|
+
}
|
|
7506
|
+
return void 0;
|
|
7507
|
+
}
|
|
7508
|
+
if (type === "string" && typeof value !== "string") {
|
|
7509
|
+
return parameterFailure(propertyPath, "a string", value, "string parameter has the wrong type");
|
|
7510
|
+
}
|
|
7511
|
+
if (type === "enum") {
|
|
7512
|
+
if (typeof value !== "string") {
|
|
7513
|
+
return parameterFailure(
|
|
7514
|
+
propertyPath,
|
|
7515
|
+
"one of the declared enum strings",
|
|
7516
|
+
value,
|
|
7517
|
+
"enum value has the wrong type"
|
|
7518
|
+
);
|
|
7519
|
+
}
|
|
7520
|
+
if (parameter.values === void 0 || !parameter.values.includes(value)) {
|
|
7521
|
+
return parameterFailure(
|
|
7522
|
+
propertyPath,
|
|
7523
|
+
"one of the declared enum values",
|
|
7524
|
+
value,
|
|
7525
|
+
"enum value is not declared"
|
|
7526
|
+
);
|
|
7527
|
+
}
|
|
7528
|
+
return void 0;
|
|
7529
|
+
}
|
|
7530
|
+
const length = vectorLength(type);
|
|
7531
|
+
if (length !== void 0) {
|
|
7532
|
+
if (!Array.isArray(value) || value.length !== length || value.some((component) => typeof component !== "number" || !Number.isFinite(component))) {
|
|
7533
|
+
return parameterFailure(
|
|
7534
|
+
propertyPath,
|
|
7535
|
+
`a finite numeric vector with ${length} components`,
|
|
7536
|
+
value,
|
|
7537
|
+
"vector value has the wrong shape"
|
|
7538
|
+
);
|
|
7539
|
+
}
|
|
7540
|
+
if (type === "color" && value.some((component) => component < 0 || component > 1)) {
|
|
7541
|
+
return parameterFailure(
|
|
7542
|
+
propertyPath,
|
|
7543
|
+
"an RGBA color with components in [0, 1]",
|
|
7544
|
+
value,
|
|
7545
|
+
"color component is outside [0, 1]"
|
|
7546
|
+
);
|
|
7547
|
+
}
|
|
7548
|
+
return void 0;
|
|
7549
|
+
}
|
|
7550
|
+
if (type === "asset-guid") {
|
|
7551
|
+
const validString = typeof value === "string" && isValidAssetGuidString(value);
|
|
7552
|
+
if (!(value instanceof Uint8Array && value.byteLength === 16) && !validString) {
|
|
7553
|
+
return parameterFailure(
|
|
7554
|
+
propertyPath,
|
|
7555
|
+
"a 16-byte AssetGuid or UUID string",
|
|
7556
|
+
value,
|
|
7557
|
+
"asset GUID value is malformed"
|
|
7558
|
+
);
|
|
7559
|
+
}
|
|
7560
|
+
return void 0;
|
|
7561
|
+
}
|
|
7562
|
+
return parameterFailure(
|
|
7563
|
+
propertyPath,
|
|
7564
|
+
"a supported Pack parameter type",
|
|
7565
|
+
value,
|
|
7566
|
+
"unknown parameter type"
|
|
7567
|
+
);
|
|
7568
|
+
}
|
|
7569
|
+
function normalizeParameterValue(parameter, value, propertyPath) {
|
|
7570
|
+
const error = parameterValueError(parameter, value, propertyPath);
|
|
7571
|
+
if (error !== void 0) return failure(error);
|
|
7572
|
+
if (parameter.type === "asset-guid" && typeof value === "string") {
|
|
7573
|
+
const parsed = AssetGuid.parse(value);
|
|
7574
|
+
if (!parsed.ok) {
|
|
7575
|
+
return failure(
|
|
7576
|
+
parameterFailure(
|
|
7577
|
+
propertyPath,
|
|
7578
|
+
"a valid AssetGuid UUID string",
|
|
7579
|
+
value,
|
|
7580
|
+
"asset GUID parser rejected the value"
|
|
7581
|
+
)
|
|
7582
|
+
);
|
|
7583
|
+
}
|
|
7584
|
+
return ok(parsed.value);
|
|
7585
|
+
}
|
|
7586
|
+
return ok(cloneValue(value));
|
|
7587
|
+
}
|
|
7588
|
+
function validateParameterDefinitions(parameters, propertyPath = "$.parameters") {
|
|
7589
|
+
if (!Array.isArray(parameters) || parameters.length === 0) {
|
|
7590
|
+
return failure(
|
|
7591
|
+
parameterFailure(
|
|
7592
|
+
propertyPath,
|
|
7593
|
+
"a non-empty parameter descriptor array",
|
|
7594
|
+
parameters,
|
|
7595
|
+
"parameters must be explicit and non-empty"
|
|
7596
|
+
)
|
|
7597
|
+
);
|
|
7598
|
+
}
|
|
7599
|
+
const names = /* @__PURE__ */ new Set();
|
|
7600
|
+
const normalized = [];
|
|
7601
|
+
for (const [index, candidate] of parameters.entries()) {
|
|
7602
|
+
const path = `${propertyPath}[${index}]`;
|
|
7603
|
+
if (!isRecord(candidate))
|
|
7604
|
+
return failure(
|
|
7605
|
+
parameterFailure(
|
|
7606
|
+
path,
|
|
7607
|
+
"a parameter descriptor object",
|
|
7608
|
+
candidate,
|
|
7609
|
+
"descriptor is not an object"
|
|
7610
|
+
)
|
|
7611
|
+
);
|
|
7612
|
+
const name = candidate.name;
|
|
7613
|
+
if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_.-]*$/.test(name)) {
|
|
7614
|
+
return failure(
|
|
7615
|
+
parameterFailure(
|
|
7616
|
+
`${path}.name`,
|
|
7617
|
+
"a unique identifier-like parameter name",
|
|
7618
|
+
name,
|
|
7619
|
+
"parameter name is invalid"
|
|
7620
|
+
)
|
|
7621
|
+
);
|
|
7622
|
+
}
|
|
7623
|
+
if (names.has(name))
|
|
7624
|
+
return failure(
|
|
7625
|
+
parameterFailure(
|
|
7626
|
+
`${path}.name`,
|
|
7627
|
+
"a unique parameter name",
|
|
7628
|
+
name,
|
|
7629
|
+
"parameter name is duplicated"
|
|
7630
|
+
)
|
|
7631
|
+
);
|
|
7632
|
+
names.add(name);
|
|
7633
|
+
const unknown = Object.keys(candidate).find(
|
|
7634
|
+
(key) => !["name", "type", "default", "minimum", "maximum", "values", "kind"].includes(key)
|
|
7635
|
+
);
|
|
7636
|
+
if (unknown !== void 0) {
|
|
7637
|
+
return failure(
|
|
7638
|
+
parameterFailure(
|
|
7639
|
+
`${path}.${unknown}`,
|
|
7640
|
+
"only name, type, default, minimum, maximum, values, and kind fields",
|
|
7641
|
+
candidate[unknown],
|
|
7642
|
+
"parameter descriptors are a closed authoring schema"
|
|
7643
|
+
)
|
|
7644
|
+
);
|
|
7645
|
+
}
|
|
7646
|
+
const type = candidate.type;
|
|
7647
|
+
if (typeof type !== "string" || !PACK_PARAMETER_TYPES.includes(type)) {
|
|
7648
|
+
return failure(
|
|
7649
|
+
parameterFailure(
|
|
7650
|
+
`${path}.type`,
|
|
7651
|
+
PACK_PARAMETER_TYPES.join(" | "),
|
|
7652
|
+
type,
|
|
7653
|
+
"parameter type is not supported"
|
|
7654
|
+
)
|
|
7655
|
+
);
|
|
7656
|
+
}
|
|
7657
|
+
const typed = {
|
|
7658
|
+
...candidate,
|
|
7659
|
+
name,
|
|
7660
|
+
type
|
|
7661
|
+
};
|
|
7662
|
+
if (typed.values !== void 0) {
|
|
7663
|
+
if (typed.type !== "enum" || !Array.isArray(typed.values) || typed.values.length === 0 || typed.values.some((item) => typeof item !== "string") || new Set(typed.values).size !== typed.values.length) {
|
|
7664
|
+
return failure(
|
|
7665
|
+
parameterFailure(
|
|
7666
|
+
`${path}.values`,
|
|
7667
|
+
"unique non-empty strings for enum",
|
|
7668
|
+
typed.values,
|
|
7669
|
+
"enum values are malformed"
|
|
7670
|
+
)
|
|
7671
|
+
);
|
|
7672
|
+
}
|
|
7673
|
+
} else if (typed.type === "enum") {
|
|
7674
|
+
return failure(
|
|
7675
|
+
parameterFailure(
|
|
7676
|
+
`${path}.values`,
|
|
7677
|
+
"a non-empty enum choices array",
|
|
7678
|
+
typed.values,
|
|
7679
|
+
"enum has no choices"
|
|
7680
|
+
)
|
|
7681
|
+
);
|
|
7682
|
+
}
|
|
7683
|
+
if (typed.kind !== void 0 && (typed.type !== "asset-guid" || typeof typed.kind !== "string")) {
|
|
7684
|
+
return failure(
|
|
7685
|
+
parameterFailure(
|
|
7686
|
+
`${path}.kind`,
|
|
7687
|
+
"a kind constraint only on asset-guid parameters",
|
|
7688
|
+
typed.kind,
|
|
7689
|
+
"kind is misplaced"
|
|
7690
|
+
)
|
|
7691
|
+
);
|
|
7692
|
+
}
|
|
7693
|
+
for (const field of ["minimum", "maximum"]) {
|
|
7694
|
+
const bound = typed[field];
|
|
7695
|
+
if (bound !== void 0 && (typeof bound !== "number" || !Number.isFinite(bound))) {
|
|
7696
|
+
return failure(
|
|
7697
|
+
parameterFailure(
|
|
7698
|
+
`${path}.${field}`,
|
|
7699
|
+
"a finite numeric bound",
|
|
7700
|
+
bound,
|
|
7701
|
+
"numeric bound is invalid"
|
|
7702
|
+
)
|
|
7703
|
+
);
|
|
7704
|
+
}
|
|
7705
|
+
}
|
|
7706
|
+
if (!numericType(typed.type) && (typed.minimum !== void 0 || typed.maximum !== void 0)) {
|
|
7707
|
+
return failure(
|
|
7708
|
+
parameterFailure(
|
|
7709
|
+
path,
|
|
7710
|
+
"minimum/maximum only on numeric parameters",
|
|
7711
|
+
typed,
|
|
7712
|
+
"numeric bounds are not meaningful for this parameter type"
|
|
7713
|
+
)
|
|
7714
|
+
);
|
|
7715
|
+
}
|
|
7716
|
+
if (typed.minimum !== void 0 && typed.maximum !== void 0 && typed.minimum > typed.maximum) {
|
|
7717
|
+
return failure(
|
|
7718
|
+
parameterFailure(path, "minimum <= maximum", typed, "numeric bounds are reversed")
|
|
7719
|
+
);
|
|
7720
|
+
}
|
|
7721
|
+
const defaultResult = normalizeParameterValue(typed, typed.default, `${path}.default`);
|
|
7722
|
+
if (!defaultResult.ok) return defaultResult;
|
|
7723
|
+
normalized.push({
|
|
7724
|
+
...typed,
|
|
7725
|
+
default: defaultResult.value,
|
|
7726
|
+
...typed.values === void 0 ? {} : { values: Object.freeze([...typed.values]) }
|
|
7727
|
+
});
|
|
7728
|
+
}
|
|
7729
|
+
return ok(Object.freeze(normalized));
|
|
7730
|
+
}
|
|
7731
|
+
function projectParameterizedPackMeta(definition, sourcePath) {
|
|
7732
|
+
return {
|
|
7733
|
+
schemaVersion: "2.0.0",
|
|
7734
|
+
kind: "parameterized-pack-source",
|
|
7735
|
+
packageId: PackageId.format(definition.packageId),
|
|
7736
|
+
source: sourcePath,
|
|
7737
|
+
..."parameters" in definition ? {
|
|
7738
|
+
parameters: definition.parameters.map((parameter) => ({
|
|
7739
|
+
name: parameter.name,
|
|
7740
|
+
type: parameter.type,
|
|
7741
|
+
default: jsonParameterValue(parameter.default),
|
|
7742
|
+
...parameter.minimum === void 0 ? {} : { minimum: parameter.minimum },
|
|
7743
|
+
...parameter.maximum === void 0 ? {} : { maximum: parameter.maximum },
|
|
7744
|
+
...parameter.values === void 0 ? {} : { values: parameter.values },
|
|
7745
|
+
...parameter.kind === void 0 ? {} : { kind: parameter.kind }
|
|
7746
|
+
}))
|
|
7747
|
+
} : {}
|
|
7748
|
+
};
|
|
7749
|
+
}
|
|
7750
|
+
function jsonParameterValue(value) {
|
|
7751
|
+
return value instanceof Uint8Array ? AssetGuid.format(value) : value;
|
|
7752
|
+
}
|
|
7753
|
+
function validatePackDefinition(value, sourcePath) {
|
|
7754
|
+
if (!isRecord(value))
|
|
7755
|
+
return failure(
|
|
7756
|
+
parameterFailure("$", "a Pack definition object", value, "definition is not an object")
|
|
7757
|
+
);
|
|
7758
|
+
const unknown = Object.keys(value).find(
|
|
7759
|
+
(key) => !["schemaVersion", "packageId", "name", "parameters", "sceneComponents", "build"].includes(
|
|
7760
|
+
key
|
|
7761
|
+
)
|
|
7762
|
+
);
|
|
7763
|
+
if (unknown !== void 0) {
|
|
7764
|
+
return failure(
|
|
7765
|
+
parameterFailure(
|
|
7766
|
+
`$.${unknown}`,
|
|
7767
|
+
"only schemaVersion, packageId, name, parameters, sceneComponents, and build fields",
|
|
7768
|
+
value[unknown],
|
|
7769
|
+
"legacy static output declarations and external asset tables are not part of v2 authoring"
|
|
7770
|
+
)
|
|
7771
|
+
);
|
|
7772
|
+
}
|
|
7773
|
+
if (value.schemaVersion !== "2.0.0") {
|
|
7774
|
+
return failure(
|
|
7775
|
+
parameterFailure(
|
|
7776
|
+
"$.schemaVersion",
|
|
7777
|
+
"the literal '2.0.0'",
|
|
7778
|
+
value.schemaVersion,
|
|
7779
|
+
"authoring source schema is unsupported"
|
|
7780
|
+
)
|
|
7781
|
+
);
|
|
7782
|
+
}
|
|
7783
|
+
if (!isPackageId(value.packageId)) {
|
|
7784
|
+
return failure(
|
|
7785
|
+
authoringError(
|
|
7786
|
+
"pack-package-id-invalid",
|
|
7787
|
+
"a 16-byte PackageId",
|
|
7788
|
+
"use definePackageId() for the stable source identity",
|
|
7789
|
+
{ sourcePath, propertyPath: "$.packageId" },
|
|
7790
|
+
typeof value.packageId === "string" ? value.packageId : void 0
|
|
7791
|
+
)
|
|
7792
|
+
);
|
|
7793
|
+
}
|
|
7794
|
+
if (value.name !== void 0 && typeof value.name !== "string") {
|
|
7795
|
+
return failure(
|
|
7796
|
+
parameterFailure("$.name", "a string when present", value.name, "display name is malformed")
|
|
7797
|
+
);
|
|
7798
|
+
}
|
|
7799
|
+
if (typeof value.build !== "function") {
|
|
7800
|
+
return failure(
|
|
7801
|
+
parameterFailure("$.build", "a build function", value.build, "build is not callable")
|
|
7802
|
+
);
|
|
7803
|
+
}
|
|
7804
|
+
const sceneComponents = validateSceneComponents(value.sceneComponents);
|
|
7805
|
+
if (!sceneComponents.ok) return sceneComponents;
|
|
7806
|
+
const hasParameters = Object.hasOwn(value, "parameters");
|
|
7807
|
+
if (!hasParameters) {
|
|
7808
|
+
return ok(
|
|
7809
|
+
Object.freeze({
|
|
7810
|
+
schemaVersion: "2.0.0",
|
|
7811
|
+
packageId: value.packageId,
|
|
7812
|
+
...value.name === void 0 ? {} : { name: value.name },
|
|
7813
|
+
...sceneComponents.value === void 0 ? {} : { sceneComponents: sceneComponents.value },
|
|
7814
|
+
build: value.build
|
|
7815
|
+
})
|
|
7816
|
+
);
|
|
7817
|
+
}
|
|
7818
|
+
const parameters = validateParameterDefinitions(value.parameters);
|
|
7819
|
+
if (!parameters.ok) return parameters;
|
|
7820
|
+
return ok(
|
|
7821
|
+
Object.freeze({
|
|
7822
|
+
schemaVersion: "2.0.0",
|
|
7823
|
+
packageId: value.packageId,
|
|
7824
|
+
...value.name === void 0 ? {} : { name: value.name },
|
|
7825
|
+
...sceneComponents.value === void 0 ? {} : { sceneComponents: sceneComponents.value },
|
|
7826
|
+
parameters: parameters.value,
|
|
7827
|
+
build: value.build
|
|
7828
|
+
})
|
|
7829
|
+
);
|
|
7830
|
+
}
|
|
7831
|
+
function jsonError(propertyPath, expected, actual, reason) {
|
|
7832
|
+
return failure(
|
|
7833
|
+
authoringError(
|
|
7834
|
+
"pack-parameter-invalid",
|
|
7835
|
+
expected,
|
|
7836
|
+
"repair the v3 pack.json authoring data, then rerun scan or rebuild",
|
|
7837
|
+
{
|
|
7838
|
+
propertyPath,
|
|
7839
|
+
reason,
|
|
7840
|
+
actual: typeof actual === "string" ? actual : JSON.stringify(actual)
|
|
7841
|
+
}
|
|
7842
|
+
)
|
|
7843
|
+
);
|
|
7844
|
+
}
|
|
7845
|
+
function parsePackageId(value, propertyPath) {
|
|
7846
|
+
if (typeof value !== "string") {
|
|
7847
|
+
return failure(
|
|
7848
|
+
authoringError(
|
|
7849
|
+
"pack-package-id-invalid",
|
|
7850
|
+
"a UUID string",
|
|
7851
|
+
"repair packageId in the authoring file",
|
|
7852
|
+
{ propertyPath, value }
|
|
7853
|
+
)
|
|
7854
|
+
);
|
|
7855
|
+
}
|
|
7856
|
+
const parsed = PackageId.parse(value);
|
|
7857
|
+
if (!parsed.ok) {
|
|
7858
|
+
return failure(
|
|
7859
|
+
authoringError(
|
|
7860
|
+
"pack-package-id-invalid",
|
|
7861
|
+
"a 36-character RFC 4122 UUID",
|
|
7862
|
+
"repair packageId or use the authoring gateway to mint one",
|
|
7863
|
+
{ propertyPath, value },
|
|
7864
|
+
value
|
|
7865
|
+
)
|
|
7866
|
+
);
|
|
7867
|
+
}
|
|
7868
|
+
return ok(parsed.value);
|
|
7869
|
+
}
|
|
7870
|
+
function parsePackJsonAsset(value, sourceKey) {
|
|
7871
|
+
if (!isRecord(value))
|
|
7872
|
+
return jsonError(
|
|
7873
|
+
`$.assets.${sourceKey}`,
|
|
7874
|
+
"an asset entry object",
|
|
7875
|
+
value,
|
|
7876
|
+
"asset entry is not an object"
|
|
7877
|
+
);
|
|
7878
|
+
const allowed = /* @__PURE__ */ new Set(["kind", "payload", "refs", "name", "artifacts"]);
|
|
7879
|
+
const unknown = Object.keys(value).find((key) => !allowed.has(key));
|
|
7880
|
+
if (unknown !== void 0)
|
|
7881
|
+
return jsonError(
|
|
7882
|
+
`$.assets.${sourceKey}.${unknown}`,
|
|
7883
|
+
"no GUID or extra authoring field",
|
|
7884
|
+
value[unknown],
|
|
7885
|
+
"direct v3 entries derive identity from their object key"
|
|
7886
|
+
);
|
|
7887
|
+
if (typeof value.kind !== "string" || value.kind.length === 0)
|
|
7888
|
+
return jsonError(
|
|
7889
|
+
`$.assets.${sourceKey}.kind`,
|
|
7890
|
+
"a non-empty asset kind",
|
|
7891
|
+
value.kind,
|
|
7892
|
+
"asset kind is missing"
|
|
7893
|
+
);
|
|
7894
|
+
if (!isRecord(value.payload))
|
|
7895
|
+
return jsonError(
|
|
7896
|
+
`$.assets.${sourceKey}.payload`,
|
|
7897
|
+
"a JSON object payload",
|
|
7898
|
+
value.payload,
|
|
7899
|
+
"payload must be a plain object"
|
|
7900
|
+
);
|
|
7901
|
+
if (!Array.isArray(value.refs) || value.refs.some((ref) => typeof ref !== "string" || !isValidAssetGuidString(ref))) {
|
|
7902
|
+
return jsonError(
|
|
7903
|
+
`$.assets.${sourceKey}.refs`,
|
|
7904
|
+
"an array of UUID references",
|
|
7905
|
+
value.refs,
|
|
7906
|
+
"references must already be real AssetGuids"
|
|
7907
|
+
);
|
|
7908
|
+
}
|
|
7909
|
+
if (value.name !== void 0 && (typeof value.name !== "string" || value.name.length === 0))
|
|
7910
|
+
return jsonError(
|
|
7911
|
+
`$.assets.${sourceKey}.name`,
|
|
7912
|
+
"a non-empty display name when present",
|
|
7913
|
+
value.name,
|
|
7914
|
+
"asset name is malformed"
|
|
7915
|
+
);
|
|
7916
|
+
if (value.artifacts !== void 0 && !isRecord(value.artifacts))
|
|
7917
|
+
return jsonError(
|
|
7918
|
+
`$.assets.${sourceKey}.artifacts`,
|
|
7919
|
+
"an artifact descriptor object when present",
|
|
7920
|
+
value.artifacts,
|
|
7921
|
+
"artifacts are not an object"
|
|
7922
|
+
);
|
|
7923
|
+
const base = {
|
|
7924
|
+
kind: value.kind,
|
|
7925
|
+
payload: value.payload,
|
|
7926
|
+
refs: Object.freeze([...value.refs]),
|
|
7927
|
+
...value.name === void 0 ? {} : { name: value.name }
|
|
7928
|
+
};
|
|
7929
|
+
if (value.artifacts === void 0) return ok(base);
|
|
7930
|
+
const withArtifacts = {
|
|
7931
|
+
...base,
|
|
7932
|
+
artifacts: value.artifacts
|
|
7933
|
+
};
|
|
7934
|
+
return ok(withArtifacts);
|
|
7935
|
+
}
|
|
7936
|
+
function parseParameterizedPackJson(value) {
|
|
7937
|
+
if (!isRecord(value))
|
|
7938
|
+
return jsonError("$", "a v3 pack.json object", value, "document is not an object");
|
|
7939
|
+
if (value.schemaVersion !== "3.0.0")
|
|
7940
|
+
return jsonError(
|
|
7941
|
+
"$.schemaVersion",
|
|
7942
|
+
"the literal '3.0.0'",
|
|
7943
|
+
value.schemaVersion,
|
|
7944
|
+
"document schema is not v3"
|
|
7945
|
+
);
|
|
7946
|
+
const unknown = Object.keys(value).find(
|
|
7947
|
+
(key) => !["schemaVersion", "packageId", "assets", "parent", "values"].includes(key)
|
|
7948
|
+
);
|
|
7949
|
+
if (unknown !== void 0)
|
|
7950
|
+
return jsonError(
|
|
7951
|
+
`$.${unknown}`,
|
|
7952
|
+
"no extra top-level authoring fields",
|
|
7953
|
+
value[unknown],
|
|
7954
|
+
"keep the v3 document to packageId+assets or packageId+parent+values"
|
|
7955
|
+
);
|
|
7956
|
+
const packageResult = parsePackageId(value.packageId, "$.packageId");
|
|
7957
|
+
if (!packageResult.ok) return packageResult;
|
|
7958
|
+
const hasAssets = Object.hasOwn(value, "assets");
|
|
7959
|
+
const hasParent = Object.hasOwn(value, "parent");
|
|
7960
|
+
const hasValues = Object.hasOwn(value, "values");
|
|
7961
|
+
if (hasAssets && (hasParent || hasValues))
|
|
7962
|
+
return jsonError(
|
|
7963
|
+
"$",
|
|
7964
|
+
"assets or parent+values, never both",
|
|
7965
|
+
value,
|
|
7966
|
+
"direct and instance branches are mutually exclusive"
|
|
7967
|
+
);
|
|
7968
|
+
if (hasAssets) {
|
|
7969
|
+
if (!isRecord(value.assets))
|
|
7970
|
+
return jsonError(
|
|
7971
|
+
"$.assets",
|
|
7972
|
+
"a sourceKey to asset object",
|
|
7973
|
+
value.assets,
|
|
7974
|
+
"direct assets are not an object"
|
|
7975
|
+
);
|
|
7976
|
+
const assets = {};
|
|
7977
|
+
for (const [sourceKey, entry] of Object.entries(value.assets)) {
|
|
7978
|
+
if (!isValidPackSourceKey(sourceKey))
|
|
7979
|
+
return failure(sourceKeyFailure(sourceKey, `$.assets.${sourceKey}`));
|
|
7980
|
+
const parsed = parsePackJsonAsset(entry, sourceKey);
|
|
7981
|
+
if (!parsed.ok) return parsed;
|
|
7982
|
+
assets[sourceKey] = parsed.value;
|
|
7983
|
+
}
|
|
7984
|
+
return ok({
|
|
7985
|
+
format: "direct",
|
|
7986
|
+
schemaVersion: "3.0.0",
|
|
7987
|
+
packageId: packageResult.value,
|
|
7988
|
+
assets: Object.freeze(assets)
|
|
7989
|
+
});
|
|
7990
|
+
}
|
|
7991
|
+
if (!hasParent || !hasValues || hasAssets)
|
|
7992
|
+
return jsonError(
|
|
7993
|
+
"$",
|
|
7994
|
+
"parent and values for an instance document",
|
|
7995
|
+
value,
|
|
7996
|
+
"instance branch is incomplete"
|
|
7997
|
+
);
|
|
7998
|
+
const parentResult = parsePackageId(value.parent, "$.parent");
|
|
7999
|
+
if (!parentResult.ok) return parentResult;
|
|
8000
|
+
if (!isRecord(value.values))
|
|
8001
|
+
return jsonError(
|
|
8002
|
+
"$.values",
|
|
8003
|
+
"a sparse parameter object",
|
|
8004
|
+
value.values,
|
|
8005
|
+
"instance values are not an object"
|
|
8006
|
+
);
|
|
8007
|
+
return ok({
|
|
8008
|
+
format: "instance",
|
|
8009
|
+
schemaVersion: "3.0.0",
|
|
8010
|
+
packageId: packageResult.value,
|
|
8011
|
+
parent: parentResult.value,
|
|
8012
|
+
values: Object.freeze({ ...value.values })
|
|
8013
|
+
});
|
|
8014
|
+
}
|
|
8015
|
+
function projectDirectPackJson(value) {
|
|
8016
|
+
const parsed = "format" in value ? ok(value) : parseParameterizedPackJson(value);
|
|
8017
|
+
if (!parsed.ok) return parsed;
|
|
8018
|
+
if (parsed.value.format !== "direct") {
|
|
8019
|
+
return failure(
|
|
8020
|
+
authoringError(
|
|
8021
|
+
"pack-parameter-invalid",
|
|
8022
|
+
"a direct v3 pack.json",
|
|
8023
|
+
"projectDirectPackJson accepts the direct branch only",
|
|
8024
|
+
{ observed: parsed.value.format }
|
|
8025
|
+
)
|
|
8026
|
+
);
|
|
8027
|
+
}
|
|
8028
|
+
const assets = [];
|
|
8029
|
+
for (const [sourceKey, entry] of Object.entries(parsed.value.assets).sort(
|
|
8030
|
+
([left], [right]) => left.localeCompare(right)
|
|
8031
|
+
)) {
|
|
8032
|
+
assets.push({
|
|
8033
|
+
...entry,
|
|
8034
|
+
guid: AssetGuid.format(AssetGuid.derive(parsed.value.packageId, sourceKey)),
|
|
8035
|
+
sourceKey
|
|
8036
|
+
});
|
|
8037
|
+
}
|
|
8038
|
+
return ok({ packageId: PackageId.format(parsed.value.packageId), assets: Object.freeze(assets) });
|
|
8039
|
+
}
|
|
8040
|
+
var PARAMETERIZED_PACK_OPERATION_IDS = [
|
|
8041
|
+
"asset.list",
|
|
8042
|
+
"asset.inspect",
|
|
8043
|
+
"asset.resolve",
|
|
8044
|
+
"asset.verify",
|
|
8045
|
+
"asset-source.create",
|
|
8046
|
+
"asset-source.clone",
|
|
8047
|
+
"asset-source.create-instance",
|
|
8048
|
+
"asset-source.apply-values",
|
|
8049
|
+
"asset-source.rebuild",
|
|
8050
|
+
"asset-source.cold-cook"
|
|
8051
|
+
];
|
|
8052
|
+
PARAMETERIZED_PACK_OPERATION_IDS.map(
|
|
8053
|
+
(id) => ({
|
|
8054
|
+
id,
|
|
8055
|
+
domain: id.startsWith("asset-source.") ? "session" : "asset",
|
|
8056
|
+
readOnly: id.startsWith("asset."),
|
|
8057
|
+
requiresRevision: !id.startsWith("asset.") && id !== "asset-source.create"
|
|
8058
|
+
})
|
|
8059
|
+
);
|
|
8060
|
+
function isRecord2(value) {
|
|
7290
8061
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7291
8062
|
}
|
|
7292
8063
|
function hasText(value) {
|
|
7293
8064
|
return typeof value === "string" && value.length > 0;
|
|
7294
8065
|
}
|
|
7295
|
-
function issue(code, subjectId, expected, hint,
|
|
8066
|
+
function issue(code, subjectId, expected, hint, actual, authority = "producer") {
|
|
7296
8067
|
const subject = { type: "asset", id: subjectId };
|
|
7297
8068
|
return {
|
|
7298
8069
|
ok: false,
|
|
@@ -7300,7 +8071,7 @@ function issue(code, subjectId, expected, hint, actual2, authority = "producer")
|
|
|
7300
8071
|
code,
|
|
7301
8072
|
subject,
|
|
7302
8073
|
expected,
|
|
7303
|
-
...
|
|
8074
|
+
...actual === void 0 ? {} : { actual },
|
|
7304
8075
|
hint,
|
|
7305
8076
|
authority
|
|
7306
8077
|
}
|
|
@@ -7317,7 +8088,7 @@ function validateFacts(value, subjectId) {
|
|
|
7317
8088
|
}
|
|
7318
8089
|
if ("provenance" in value) {
|
|
7319
8090
|
const provenance = value.provenance;
|
|
7320
|
-
if (!
|
|
8091
|
+
if (!isRecord2(provenance) || !hasText(provenance.provider) || !hasText(provenance.version)) {
|
|
7321
8092
|
return issue(
|
|
7322
8093
|
"invalid-producer-fact",
|
|
7323
8094
|
subjectId,
|
|
@@ -7328,7 +8099,7 @@ function validateFacts(value, subjectId) {
|
|
|
7328
8099
|
}
|
|
7329
8100
|
if ("revision" in value) {
|
|
7330
8101
|
const revision = value.revision;
|
|
7331
|
-
if (!
|
|
8102
|
+
if (!isRecord2(revision) || !hasText(revision.digest) || !hasText(revision.rootId) || typeof revision.observedAt !== "number" || !Number.isFinite(revision.observedAt)) {
|
|
7332
8103
|
return issue(
|
|
7333
8104
|
"invalid-producer-fact",
|
|
7334
8105
|
subjectId,
|
|
@@ -7347,7 +8118,7 @@ function validateFacts(value, subjectId) {
|
|
|
7347
8118
|
);
|
|
7348
8119
|
}
|
|
7349
8120
|
for (const diagnostic of value.diagnostics) {
|
|
7350
|
-
if (!
|
|
8121
|
+
if (!isRecord2(diagnostic) || !hasText(diagnostic.code)) {
|
|
7351
8122
|
return issue(
|
|
7352
8123
|
"invalid-producer-fact",
|
|
7353
8124
|
subjectId,
|
|
@@ -7356,7 +8127,7 @@ function validateFacts(value, subjectId) {
|
|
|
7356
8127
|
);
|
|
7357
8128
|
}
|
|
7358
8129
|
if (diagnostic.severity === "blocking") {
|
|
7359
|
-
if (!
|
|
8130
|
+
if (!isRecord2(diagnostic.subject) || !hasText(diagnostic.subject.id)) {
|
|
7360
8131
|
return issue(
|
|
7361
8132
|
"invalid-producer-fact",
|
|
7362
8133
|
subjectId,
|
|
@@ -7380,7 +8151,7 @@ function validateFacts(value, subjectId) {
|
|
|
7380
8151
|
function validateMetaSourceOverrides(value, subjectId) {
|
|
7381
8152
|
if (!("sourceOverrides" in value)) return { ok: true, value };
|
|
7382
8153
|
const declaredSourceKeys = Array.isArray(value.subAssets) ? value.subAssets.flatMap(
|
|
7383
|
-
(subAsset) =>
|
|
8154
|
+
(subAsset) => isRecord2(subAsset) && hasText(subAsset.sourceKey) ? [subAsset.sourceKey] : []
|
|
7384
8155
|
) : [];
|
|
7385
8156
|
const result = validateSourceOverrideMap(value.sourceOverrides, declaredSourceKeys);
|
|
7386
8157
|
if (!result.ok) {
|
|
@@ -7399,7 +8170,7 @@ function validateMetaSourceOverrides(value, subjectId) {
|
|
|
7399
8170
|
};
|
|
7400
8171
|
}
|
|
7401
8172
|
function validateProducerContract(value) {
|
|
7402
|
-
if (!
|
|
8173
|
+
if (!isRecord2(value)) {
|
|
7403
8174
|
return issue(
|
|
7404
8175
|
"invalid-producer-fact",
|
|
7405
8176
|
"unknown",
|
|
@@ -7501,83 +8272,25 @@ function baseName(p) {
|
|
|
7501
8272
|
const idx = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
|
|
7502
8273
|
return idx === -1 ? trimmed : trimmed.slice(idx + 1);
|
|
7503
8274
|
}
|
|
7504
|
-
function deriveAssetName(packagePath2,
|
|
8275
|
+
function deriveAssetName(packagePath2, _assetCount, storedName) {
|
|
7505
8276
|
if (packagePath2 === null) {
|
|
7506
8277
|
return "";
|
|
7507
8278
|
}
|
|
7508
|
-
|
|
7509
|
-
return baseName(packagePath2);
|
|
7510
|
-
}
|
|
8279
|
+
return baseName(packagePath2);
|
|
7511
8280
|
}
|
|
7512
8281
|
|
|
7513
8282
|
// src/resolve-asset-source.ts
|
|
7514
8283
|
function deriveSourceName(metaFileName) {
|
|
7515
8284
|
return metaFileName.replace(/\.meta\.json$/, "");
|
|
7516
8285
|
}
|
|
7517
|
-
|
|
7518
|
-
function isPathEscape(pathDir, resolved) {
|
|
7519
|
-
const rel = posix.relative(pathDir, resolved);
|
|
7520
|
-
return rel.startsWith("..") || posix.isAbsolute(rel);
|
|
7521
|
-
}
|
|
7522
|
-
function resolveAssetSource(metaPath, source, paths) {
|
|
8286
|
+
function resolveAssetSource(metaPath, source) {
|
|
7523
8287
|
if (source === void 0) {
|
|
7524
8288
|
const metaDir = dirname(metaPath);
|
|
7525
8289
|
const metaName = deriveAssetName(metaPath);
|
|
7526
8290
|
const derived = deriveSourceName(metaName);
|
|
7527
|
-
return
|
|
8291
|
+
return resolve(metaDir, derived);
|
|
7528
8292
|
}
|
|
7529
|
-
|
|
7530
|
-
const match = source.match(PATH_REF_RE);
|
|
7531
|
-
if (!match) {
|
|
7532
|
-
return err(
|
|
7533
|
-
new PackError({
|
|
7534
|
-
code: "pack-malformed-path-ref",
|
|
7535
|
-
expected: "source in format @<name>/<rest>",
|
|
7536
|
-
hint: PACK_ERROR_HINTS["pack-malformed-path-ref"],
|
|
7537
|
-
detail: {
|
|
7538
|
-
code: "pack-malformed-path-ref",
|
|
7539
|
-
reason: "format",
|
|
7540
|
-
rawSource: source,
|
|
7541
|
-
expectedFormat: "@<name>/<rest>"
|
|
7542
|
-
}
|
|
7543
|
-
})
|
|
7544
|
-
);
|
|
7545
|
-
}
|
|
7546
|
-
const [, name, rest] = match;
|
|
7547
|
-
const pathDir = paths[name];
|
|
7548
|
-
if (pathDir === void 0) {
|
|
7549
|
-
return err(
|
|
7550
|
-
new PackError({
|
|
7551
|
-
code: "pack-unknown-path",
|
|
7552
|
-
expected: "path name found in package.json#forgeax.assets.paths",
|
|
7553
|
-
hint: PACK_ERROR_HINTS["pack-unknown-path"],
|
|
7554
|
-
detail: {
|
|
7555
|
-
code: "pack-unknown-path",
|
|
7556
|
-
pathName: name,
|
|
7557
|
-
knownNames: Object.keys(paths)
|
|
7558
|
-
}
|
|
7559
|
-
})
|
|
7560
|
-
);
|
|
7561
|
-
}
|
|
7562
|
-
const resolved = resolve(pathDir, rest);
|
|
7563
|
-
if (isPathEscape(pathDir, resolved)) {
|
|
7564
|
-
return err(
|
|
7565
|
-
new PackError({
|
|
7566
|
-
code: "pack-malformed-path-ref",
|
|
7567
|
-
expected: "rest path must not escape the declared path directory",
|
|
7568
|
-
hint: PACK_ERROR_HINTS["pack-malformed-path-ref"],
|
|
7569
|
-
detail: {
|
|
7570
|
-
code: "pack-malformed-path-ref",
|
|
7571
|
-
reason: "escape",
|
|
7572
|
-
rawSource: source,
|
|
7573
|
-
expectedFormat: "@<name>/<rest>"
|
|
7574
|
-
}
|
|
7575
|
-
})
|
|
7576
|
-
);
|
|
7577
|
-
}
|
|
7578
|
-
return ok(resolved);
|
|
7579
|
-
}
|
|
7580
|
-
return ok(resolve(dirname(metaPath), source));
|
|
8293
|
+
return resolve(dirname(metaPath), source);
|
|
7581
8294
|
}
|
|
7582
8295
|
|
|
7583
8296
|
// src/schema-compiled.ts
|
|
@@ -7627,7 +8340,7 @@ var meta_schema_default = {
|
|
|
7627
8340
|
source: {
|
|
7628
8341
|
type: "string",
|
|
7629
8342
|
minLength: 1,
|
|
7630
|
-
description: "Optional. Omit to derive the companion file in the same directory (strip .meta.json suffix from the meta filename).
|
|
8343
|
+
description: "Optional. Omit to derive the companion file in the same directory (strip .meta.json suffix from the meta filename). An explicit source is resolved relative to this sidecar."
|
|
7631
8344
|
},
|
|
7632
8345
|
importSettings: {
|
|
7633
8346
|
type: "object",
|
|
@@ -7768,11 +8481,11 @@ var pack_schema_default = {
|
|
|
7768
8481
|
$comment: "The ordinary durable consumer matrix is SCRIPTABLE_PACK_ASSET_KINDS in @forgeax/engine-pack/source. Pack kind fields remain open for registered producer extensions.",
|
|
7769
8482
|
type: "object",
|
|
7770
8483
|
additionalProperties: false,
|
|
7771
|
-
required: ["schemaVersion"
|
|
8484
|
+
required: ["schemaVersion"],
|
|
7772
8485
|
properties: {
|
|
7773
8486
|
schemaVersion: {
|
|
7774
8487
|
type: "string",
|
|
7775
|
-
enum: ["1.0.0", "2.0.0"]
|
|
8488
|
+
enum: ["1.0.0", "2.0.0", "3.0.0"]
|
|
7776
8489
|
},
|
|
7777
8490
|
kind: {
|
|
7778
8491
|
type: "string",
|
|
@@ -7794,12 +8507,58 @@ var pack_schema_default = {
|
|
|
7794
8507
|
items: { $ref: "#/$defs/diagnostic" }
|
|
7795
8508
|
},
|
|
7796
8509
|
assets: {
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
8510
|
+
oneOf: [
|
|
8511
|
+
{
|
|
8512
|
+
type: "array",
|
|
8513
|
+
items: { $ref: "#/$defs/asset" }
|
|
8514
|
+
},
|
|
8515
|
+
{ $ref: "#/$defs/authoringAssets" }
|
|
8516
|
+
]
|
|
8517
|
+
},
|
|
8518
|
+
parent: {
|
|
8519
|
+
$ref: "#/$defs/guid36",
|
|
8520
|
+
description: "Parent parameterized Pack packageId for one v3 instance."
|
|
8521
|
+
},
|
|
8522
|
+
values: {
|
|
8523
|
+
type: "object",
|
|
8524
|
+
additionalProperties: true,
|
|
8525
|
+
description: "Sparse shallow parameter overrides for one v3 instance."
|
|
7801
8526
|
}
|
|
7802
8527
|
},
|
|
8528
|
+
oneOf: [
|
|
8529
|
+
{
|
|
8530
|
+
required: ["kind", "assets"],
|
|
8531
|
+
properties: {
|
|
8532
|
+
schemaVersion: { enum: ["1.0.0", "2.0.0"] },
|
|
8533
|
+
kind: { const: "internal-text-package" },
|
|
8534
|
+
assets: { type: "array" },
|
|
8535
|
+
parent: false,
|
|
8536
|
+
values: false
|
|
8537
|
+
}
|
|
8538
|
+
},
|
|
8539
|
+
{
|
|
8540
|
+
required: ["packageId", "assets"],
|
|
8541
|
+
properties: {
|
|
8542
|
+
schemaVersion: { const: "3.0.0" },
|
|
8543
|
+
kind: false,
|
|
8544
|
+
packageId: { $ref: "#/$defs/guid36" },
|
|
8545
|
+
assets: { $ref: "#/$defs/authoringAssets" },
|
|
8546
|
+
parent: false,
|
|
8547
|
+
values: false
|
|
8548
|
+
}
|
|
8549
|
+
},
|
|
8550
|
+
{
|
|
8551
|
+
required: ["packageId", "parent", "values"],
|
|
8552
|
+
properties: {
|
|
8553
|
+
schemaVersion: { const: "3.0.0" },
|
|
8554
|
+
kind: false,
|
|
8555
|
+
packageId: { $ref: "#/$defs/guid36" },
|
|
8556
|
+
parent: { $ref: "#/$defs/guid36" },
|
|
8557
|
+
values: { type: "object" },
|
|
8558
|
+
assets: false
|
|
8559
|
+
}
|
|
8560
|
+
}
|
|
8561
|
+
],
|
|
7803
8562
|
allOf: [
|
|
7804
8563
|
{
|
|
7805
8564
|
if: {
|
|
@@ -7891,6 +8650,30 @@ var pack_schema_default = {
|
|
|
7891
8650
|
}
|
|
7892
8651
|
]
|
|
7893
8652
|
},
|
|
8653
|
+
authoringAssets: {
|
|
8654
|
+
type: "object",
|
|
8655
|
+
additionalProperties: false,
|
|
8656
|
+
patternProperties: {
|
|
8657
|
+
"^[a-z0-9][a-z0-9._-]*(/[a-z0-9][a-z0-9._-]*)*$": {
|
|
8658
|
+
$ref: "#/$defs/authoringAsset"
|
|
8659
|
+
}
|
|
8660
|
+
}
|
|
8661
|
+
},
|
|
8662
|
+
authoringAsset: {
|
|
8663
|
+
type: "object",
|
|
8664
|
+
additionalProperties: false,
|
|
8665
|
+
required: ["kind", "payload", "refs"],
|
|
8666
|
+
properties: {
|
|
8667
|
+
kind: { type: "string", minLength: 1 },
|
|
8668
|
+
name: { type: "string", minLength: 1 },
|
|
8669
|
+
payload: { type: "object" },
|
|
8670
|
+
refs: {
|
|
8671
|
+
type: "array",
|
|
8672
|
+
items: { $ref: "#/$defs/guid36" }
|
|
8673
|
+
},
|
|
8674
|
+
artifacts: { $ref: "#/$defs/artifacts" }
|
|
8675
|
+
}
|
|
8676
|
+
},
|
|
7894
8677
|
artifacts: {
|
|
7895
8678
|
type: "object",
|
|
7896
8679
|
additionalProperties: false,
|
|
@@ -7913,563 +8696,102 @@ var pack_schema_default = {
|
|
|
7913
8696
|
integrity: { $ref: "#/$defs/integrity" }
|
|
7914
8697
|
}
|
|
7915
8698
|
},
|
|
7916
|
-
assetCodec: {
|
|
7917
|
-
type: "object",
|
|
7918
|
-
additionalProperties: false,
|
|
7919
|
-
required: ["name"],
|
|
7920
|
-
properties: {
|
|
7921
|
-
name: { type: "string", minLength: 1 },
|
|
7922
|
-
profile: { type: "string", minLength: 1 },
|
|
7923
|
-
version: { type: "string", minLength: 1 }
|
|
7924
|
-
}
|
|
7925
|
-
},
|
|
7926
|
-
integrity: {
|
|
7927
|
-
type: "object",
|
|
7928
|
-
additionalProperties: false,
|
|
7929
|
-
required: ["algorithm", "digest"],
|
|
7930
|
-
properties: {
|
|
7931
|
-
algorithm: { const: "sha256" },
|
|
7932
|
-
digest: { type: "string", minLength: 1 }
|
|
7933
|
-
}
|
|
7934
|
-
},
|
|
7935
|
-
provenance: {
|
|
7936
|
-
type: "object",
|
|
7937
|
-
additionalProperties: false,
|
|
7938
|
-
required: ["provider", "version"],
|
|
7939
|
-
properties: {
|
|
7940
|
-
provider: { type: "string", minLength: 1 },
|
|
7941
|
-
version: { type: "string", minLength: 1 },
|
|
7942
|
-
source: { type: "string", minLength: 1 }
|
|
7943
|
-
}
|
|
7944
|
-
},
|
|
7945
|
-
revision: {
|
|
7946
|
-
type: "object",
|
|
7947
|
-
additionalProperties: false,
|
|
7948
|
-
required: ["digest", "observedAt", "rootId"],
|
|
7949
|
-
properties: {
|
|
7950
|
-
digest: { type: "string", minLength: 1 },
|
|
7951
|
-
observedAt: { type: "number" },
|
|
7952
|
-
rootId: { type: "string", minLength: 1 }
|
|
7953
|
-
}
|
|
7954
|
-
},
|
|
7955
|
-
diagnostic: {
|
|
7956
|
-
type: "object",
|
|
7957
|
-
additionalProperties: false,
|
|
7958
|
-
required: ["code", "severity"],
|
|
7959
|
-
properties: {
|
|
7960
|
-
code: { type: "string", minLength: 1 },
|
|
7961
|
-
severity: { type: "string", enum: ["info", "warning", "blocking"] },
|
|
7962
|
-
message: { type: "string" },
|
|
7963
|
-
subject: { $ref: "#/$defs/subject" },
|
|
7964
|
-
expected: { type: "string", minLength: 1 },
|
|
7965
|
-
actual: { type: "string" },
|
|
7966
|
-
hint: { type: "string", minLength: 1 },
|
|
7967
|
-
authority: { type: "string", enum: ["producer", "pack", "catalog"] },
|
|
7968
|
-
evidence: { type: "array", items: { type: "object" } },
|
|
7969
|
-
recoveryIntents: { type: "array", items: { type: "string", minLength: 1 } }
|
|
7970
|
-
}
|
|
7971
|
-
},
|
|
7972
|
-
subject: {
|
|
7973
|
-
type: "object",
|
|
7974
|
-
additionalProperties: false,
|
|
7975
|
-
required: ["type", "id"],
|
|
7976
|
-
properties: {
|
|
7977
|
-
type: { type: "string", enum: ["asset", "package", "resource"] },
|
|
7978
|
-
id: { type: "string", minLength: 1 }
|
|
7979
|
-
}
|
|
7980
|
-
},
|
|
7981
|
-
relation: {
|
|
7982
|
-
type: "object",
|
|
7983
|
-
additionalProperties: false,
|
|
7984
|
-
required: ["from", "to", "type", "provenance"],
|
|
7985
|
-
properties: {
|
|
7986
|
-
from: { $ref: "#/$defs/subject" },
|
|
7987
|
-
to: { $ref: "#/$defs/subject" },
|
|
7988
|
-
type: { type: "string", minLength: 1 },
|
|
7989
|
-
policy: { type: "object" },
|
|
7990
|
-
provenance: { $ref: "#/$defs/provenance" }
|
|
7991
|
-
}
|
|
7992
|
-
}
|
|
7993
|
-
}
|
|
7994
|
-
};
|
|
7995
|
-
|
|
7996
|
-
// src/schema-compiled.ts
|
|
7997
|
-
var ajv = new import_ajv.default({ strict: true, allErrors: false });
|
|
7998
|
-
(0, import_ajv_formats.default)(ajv, ["uuid"]);
|
|
7999
|
-
var validateMeta = ajv.compile(meta_schema_default);
|
|
8000
|
-
var validatePack = ajv.compile(pack_schema_default);
|
|
8001
|
-
function validatePackV2(value) {
|
|
8002
|
-
if (!validatePack(value) || !isPackV2Shape(value)) return false;
|
|
8003
|
-
const seenGuids = /* @__PURE__ */ new Set();
|
|
8004
|
-
for (const asset of value.assets) {
|
|
8005
|
-
if (seenGuids.has(asset.guid)) return false;
|
|
8006
|
-
seenGuids.add(asset.guid);
|
|
8007
|
-
}
|
|
8008
|
-
return true;
|
|
8009
|
-
}
|
|
8010
|
-
function isPackV2Shape(value) {
|
|
8011
|
-
return typeof value === "object" && value !== null && "schemaVersion" in value && value.schemaVersion === "2.0.0";
|
|
8012
|
-
}
|
|
8013
|
-
var SCRIPTABLE_PACK_ASSET_KINDS = [
|
|
8014
|
-
"mesh",
|
|
8015
|
-
"material",
|
|
8016
|
-
"scene",
|
|
8017
|
-
"texture",
|
|
8018
|
-
"equirect",
|
|
8019
|
-
"sampler",
|
|
8020
|
-
"font",
|
|
8021
|
-
"render-pipeline",
|
|
8022
|
-
"tileset",
|
|
8023
|
-
"video",
|
|
8024
|
-
"skeleton",
|
|
8025
|
-
"skin",
|
|
8026
|
-
"animation-clip",
|
|
8027
|
-
"animation-graph",
|
|
8028
|
-
"audio",
|
|
8029
|
-
"particle-effect"
|
|
8030
|
-
];
|
|
8031
|
-
function isScriptablePackAssetKind(value) {
|
|
8032
|
-
return SCRIPTABLE_PACK_ASSET_KINDS.includes(value);
|
|
8033
|
-
}
|
|
8034
|
-
function sceneComponentFieldType(value) {
|
|
8035
|
-
if (typeof value === "string") return value;
|
|
8036
|
-
if (isRecord2(value) && typeof value.type === "string") return value.type;
|
|
8037
|
-
return void 0;
|
|
8038
|
-
}
|
|
8039
|
-
function projectScriptablePackSceneComponents(components) {
|
|
8040
|
-
return (components ?? []).map((component) => ({
|
|
8041
|
-
name: component.name,
|
|
8042
|
-
fields: Object.fromEntries(
|
|
8043
|
-
Object.entries(component.fields).map(([fieldName, field]) => [
|
|
8044
|
-
fieldName,
|
|
8045
|
-
sceneComponentFieldType(field)
|
|
8046
|
-
])
|
|
8047
|
-
)
|
|
8048
|
-
}));
|
|
8049
|
-
}
|
|
8050
|
-
var SCRIPTABLE_PACK_REQUEST_ID_SCHEMA = {
|
|
8051
|
-
type: "string",
|
|
8052
|
-
minLength: 1,
|
|
8053
|
-
maxLength: 128,
|
|
8054
|
-
pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$",
|
|
8055
|
-
description: "Caller-minted identity for one idempotent ScriptablePack operation."
|
|
8056
|
-
};
|
|
8057
|
-
var SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA = {
|
|
8058
|
-
type: "string",
|
|
8059
|
-
minLength: 8,
|
|
8060
|
-
pattern: "^[^/].*\\.pack\\.ts$",
|
|
8061
|
-
description: "Game-root-relative ScriptablePack source path."
|
|
8062
|
-
};
|
|
8063
|
-
var SCRIPTABLE_PACK_OWNER_GUID_SCHEMA = {
|
|
8064
|
-
type: "string",
|
|
8065
|
-
format: "uuid",
|
|
8066
|
-
description: "Catalog GUID used to resolve the producer-owned source subject."
|
|
8067
|
-
};
|
|
8068
|
-
var SCRIPTABLE_PACK_REVISION_SCHEMA = {
|
|
8069
|
-
type: "string",
|
|
8070
|
-
minLength: 64,
|
|
8071
|
-
maxLength: 64,
|
|
8072
|
-
pattern: "^[a-f0-9]{64}$",
|
|
8073
|
-
description: "SHA-256 source revision returned by preflight."
|
|
8074
|
-
};
|
|
8075
|
-
var SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA = { type: "string", minLength: 1 };
|
|
8076
|
-
var SCRIPTABLE_PACK_ASSET_KIND_SCHEMA = {
|
|
8077
|
-
enum: SCRIPTABLE_PACK_ASSET_KINDS,
|
|
8078
|
-
description: "Ordinary Asset kind supported by the ScriptablePack producer/loader matrix."
|
|
8079
|
-
};
|
|
8080
|
-
var SCRIPTABLE_PACK_NAME_SCHEMA = { type: "string", minLength: 1 };
|
|
8081
|
-
function scriptablePackArgsSchema(properties, required, options = {}) {
|
|
8082
|
-
const subjectRequired = ["requestId", ...required];
|
|
8083
|
-
return {
|
|
8084
|
-
type: "object",
|
|
8085
|
-
properties: {
|
|
8086
|
-
sourcePath: SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA,
|
|
8087
|
-
ownerGuid: SCRIPTABLE_PACK_OWNER_GUID_SCHEMA,
|
|
8088
|
-
requestId: SCRIPTABLE_PACK_REQUEST_ID_SCHEMA,
|
|
8089
|
-
...properties
|
|
8090
|
-
},
|
|
8091
|
-
required: subjectRequired,
|
|
8092
|
-
...options.subject === false ? {} : {
|
|
8093
|
-
anyOf: [
|
|
8094
|
-
{ required: [...subjectRequired, "sourcePath"] },
|
|
8095
|
-
{ required: [...subjectRequired, "ownerGuid"] },
|
|
8096
|
-
...options.guidSubject === false ? [] : [{ required: [...subjectRequired, "guid"] }]
|
|
8097
|
-
]
|
|
8098
|
-
},
|
|
8099
|
-
additionalProperties: false
|
|
8100
|
-
};
|
|
8101
|
-
}
|
|
8102
|
-
[
|
|
8103
|
-
{
|
|
8104
|
-
id: "asset-source.create",
|
|
8105
|
-
kind: "create",
|
|
8106
|
-
domain: "session",
|
|
8107
|
-
title: "Create Asset Source",
|
|
8108
|
-
argsSchema: scriptablePackArgsSchema(
|
|
8109
|
-
{
|
|
8110
|
-
name: SCRIPTABLE_PACK_NAME_SCHEMA,
|
|
8111
|
-
initialOutput: {
|
|
8112
|
-
type: "object",
|
|
8113
|
-
properties: {
|
|
8114
|
-
sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
|
|
8115
|
-
kind: SCRIPTABLE_PACK_ASSET_KIND_SCHEMA,
|
|
8116
|
-
name: SCRIPTABLE_PACK_NAME_SCHEMA
|
|
8117
|
-
},
|
|
8118
|
-
required: ["sourceKey", "kind"],
|
|
8119
|
-
additionalProperties: false
|
|
8120
|
-
}
|
|
8121
|
-
},
|
|
8122
|
-
["sourcePath", "initialOutput"],
|
|
8123
|
-
{ subject: false }
|
|
8124
|
-
)
|
|
8125
|
-
},
|
|
8126
|
-
{
|
|
8127
|
-
id: "asset-source.add-output",
|
|
8128
|
-
kind: "add-output",
|
|
8129
|
-
domain: "session",
|
|
8130
|
-
title: "Add Asset Source Output",
|
|
8131
|
-
argsSchema: scriptablePackArgsSchema(
|
|
8132
|
-
{
|
|
8133
|
-
sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
|
|
8134
|
-
assetKind: SCRIPTABLE_PACK_ASSET_KIND_SCHEMA,
|
|
8135
|
-
name: SCRIPTABLE_PACK_NAME_SCHEMA,
|
|
8136
|
-
expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
|
|
8137
|
-
},
|
|
8138
|
-
["sourceKey", "assetKind", "expectedRevision"]
|
|
8139
|
-
)
|
|
8140
|
-
},
|
|
8141
|
-
{
|
|
8142
|
-
id: "asset-source.add-external-asset",
|
|
8143
|
-
kind: "add-external-asset",
|
|
8144
|
-
domain: "session",
|
|
8145
|
-
title: "Add Asset Source External Asset",
|
|
8146
|
-
argsSchema: scriptablePackArgsSchema(
|
|
8147
|
-
{
|
|
8148
|
-
alias: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
|
|
8149
|
-
guid: { type: "string", format: "uuid" },
|
|
8150
|
-
expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
|
|
8151
|
-
},
|
|
8152
|
-
["alias", "guid", "expectedRevision"],
|
|
8153
|
-
{ guidSubject: false }
|
|
8154
|
-
)
|
|
8155
|
-
},
|
|
8156
|
-
{
|
|
8157
|
-
id: "asset-source.rename",
|
|
8158
|
-
kind: "rename",
|
|
8159
|
-
domain: "session",
|
|
8160
|
-
title: "Rename Asset Source Display Name",
|
|
8161
|
-
argsSchema: scriptablePackArgsSchema(
|
|
8162
|
-
{
|
|
8163
|
-
target: {
|
|
8164
|
-
oneOf: [
|
|
8165
|
-
{
|
|
8166
|
-
type: "object",
|
|
8167
|
-
properties: { kind: { const: "package" } },
|
|
8168
|
-
required: ["kind"],
|
|
8169
|
-
additionalProperties: false
|
|
8170
|
-
},
|
|
8171
|
-
{
|
|
8172
|
-
type: "object",
|
|
8173
|
-
properties: {
|
|
8174
|
-
kind: { const: "output" },
|
|
8175
|
-
sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA
|
|
8176
|
-
},
|
|
8177
|
-
required: ["kind", "sourceKey"],
|
|
8178
|
-
additionalProperties: false
|
|
8179
|
-
}
|
|
8180
|
-
]
|
|
8181
|
-
},
|
|
8182
|
-
name: SCRIPTABLE_PACK_NAME_SCHEMA,
|
|
8183
|
-
expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
|
|
8184
|
-
},
|
|
8185
|
-
["target", "name", "expectedRevision"]
|
|
8186
|
-
)
|
|
8187
|
-
},
|
|
8188
|
-
{
|
|
8189
|
-
id: "asset-source.remove-output",
|
|
8190
|
-
kind: "remove-output",
|
|
8191
|
-
domain: "session",
|
|
8192
|
-
title: "Remove Asset Source Output",
|
|
8193
|
-
destructive: true,
|
|
8194
|
-
argsSchema: scriptablePackArgsSchema(
|
|
8195
|
-
{
|
|
8196
|
-
sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
|
|
8197
|
-
confirmIncomingRefs: { type: "array", items: { type: "string" } },
|
|
8198
|
-
expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
|
|
8199
|
-
},
|
|
8200
|
-
["sourceKey", "expectedRevision"]
|
|
8201
|
-
)
|
|
8202
|
-
},
|
|
8203
|
-
{
|
|
8204
|
-
id: "asset-source.clone",
|
|
8205
|
-
kind: "clone",
|
|
8206
|
-
domain: "session",
|
|
8207
|
-
title: "Clone Asset Source",
|
|
8208
|
-
argsSchema: scriptablePackArgsSchema(
|
|
8209
|
-
{
|
|
8210
|
-
targetPath: SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA,
|
|
8211
|
-
expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
|
|
8212
|
-
},
|
|
8213
|
-
["targetPath", "expectedRevision"]
|
|
8214
|
-
)
|
|
8215
|
-
},
|
|
8216
|
-
{
|
|
8217
|
-
id: "asset-source.rebuild",
|
|
8218
|
-
kind: "rebuild",
|
|
8219
|
-
domain: "session",
|
|
8220
|
-
title: "Rebuild Asset Source",
|
|
8221
|
-
argsSchema: scriptablePackArgsSchema({ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA }, [
|
|
8222
|
-
"expectedRevision"
|
|
8223
|
-
])
|
|
8224
|
-
},
|
|
8225
|
-
{
|
|
8226
|
-
id: "asset-source.cold-cook",
|
|
8227
|
-
kind: "cold-cook",
|
|
8228
|
-
domain: "session",
|
|
8229
|
-
title: "Cold Cook Asset Source",
|
|
8230
|
-
argsSchema: scriptablePackArgsSchema({ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA }, [
|
|
8231
|
-
"expectedRevision"
|
|
8232
|
-
])
|
|
8233
|
-
}
|
|
8234
|
-
];
|
|
8235
|
-
function actual(value) {
|
|
8236
|
-
if (value === null) return "null";
|
|
8237
|
-
if (Array.isArray(value)) return "array";
|
|
8238
|
-
if (ArrayBuffer.isView(value)) return value.constructor.name;
|
|
8239
|
-
return typeof value;
|
|
8240
|
-
}
|
|
8241
|
-
function invalid(propertyPath, expected, value, sourcePath) {
|
|
8242
|
-
return err({
|
|
8243
|
-
code: "pack-source-definition-invalid",
|
|
8244
|
-
expected,
|
|
8245
|
-
hint: "repair the default exported ScriptablePack definition, then inspect Meta again",
|
|
8246
|
-
detail: {
|
|
8247
|
-
...sourcePath === void 0 ? {} : { sourcePath },
|
|
8248
|
-
propertyPath,
|
|
8249
|
-
actual: actual(value)
|
|
8250
|
-
}
|
|
8251
|
-
});
|
|
8252
|
-
}
|
|
8253
|
-
function isRecord2(value) {
|
|
8254
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8255
|
-
}
|
|
8256
|
-
function isAssetGuid(value) {
|
|
8257
|
-
return value instanceof Uint8Array && value.byteLength === 16;
|
|
8258
|
-
}
|
|
8259
|
-
function guidKey(guid) {
|
|
8260
|
-
return AssetGuid.format(guid);
|
|
8261
|
-
}
|
|
8262
|
-
function freezeDefinition(definition) {
|
|
8263
|
-
const assets = Object.fromEntries(
|
|
8264
|
-
Object.entries(definition.assets).map(([sourceKey, descriptor]) => [
|
|
8265
|
-
sourceKey,
|
|
8266
|
-
Object.freeze({ ...descriptor, guid: descriptor.guid.slice() })
|
|
8267
|
-
])
|
|
8268
|
-
);
|
|
8269
|
-
const externalAssets = Object.fromEntries(
|
|
8270
|
-
Object.entries(definition.externalAssets).map(([alias, guid]) => [
|
|
8271
|
-
alias,
|
|
8272
|
-
guid.slice()
|
|
8273
|
-
])
|
|
8274
|
-
);
|
|
8275
|
-
const sceneComponents = definition.sceneComponents === void 0 ? void 0 : Object.freeze(
|
|
8276
|
-
projectScriptablePackSceneComponents(definition.sceneComponents).map(
|
|
8277
|
-
(component) => Object.freeze({
|
|
8278
|
-
...component,
|
|
8279
|
-
fields: Object.freeze({ ...component.fields })
|
|
8280
|
-
})
|
|
8281
|
-
)
|
|
8282
|
-
);
|
|
8283
|
-
return Object.freeze({
|
|
8284
|
-
...definition,
|
|
8285
|
-
packageId: definition.packageId.slice(),
|
|
8286
|
-
assets: Object.freeze(assets),
|
|
8287
|
-
externalAssets: Object.freeze(externalAssets),
|
|
8288
|
-
...sceneComponents === void 0 ? {} : { sceneComponents }
|
|
8289
|
-
});
|
|
8290
|
-
}
|
|
8291
|
-
function validateScriptablePackDefinition(value, sourcePath) {
|
|
8292
|
-
if (!isRecord2(value))
|
|
8293
|
-
return invalid("$", "a ScriptablePack definition object", value, sourcePath);
|
|
8294
|
-
if (value.schemaVersion !== "1.0.0") {
|
|
8295
|
-
return invalid("$.schemaVersion", "the literal '1.0.0'", value.schemaVersion, sourcePath);
|
|
8296
|
-
}
|
|
8297
|
-
if (!isAssetGuid(value.packageId)) {
|
|
8298
|
-
return invalid("$.packageId", "a 16-byte AssetGuid", value.packageId, sourcePath);
|
|
8299
|
-
}
|
|
8300
|
-
if (value.name !== void 0 && typeof value.name !== "string") {
|
|
8301
|
-
return invalid("$.name", "a string when present", value.name, sourcePath);
|
|
8302
|
-
}
|
|
8303
|
-
if (!isRecord2(value.assets) || Object.keys(value.assets).length === 0) {
|
|
8304
|
-
return invalid(
|
|
8305
|
-
"$.assets",
|
|
8306
|
-
"a non-empty sourceKey to descriptor object",
|
|
8307
|
-
value.assets,
|
|
8308
|
-
sourcePath
|
|
8309
|
-
);
|
|
8310
|
-
}
|
|
8311
|
-
if (!isRecord2(value.externalAssets)) {
|
|
8312
|
-
return invalid(
|
|
8313
|
-
"$.externalAssets",
|
|
8314
|
-
"an alias to AssetGuid object",
|
|
8315
|
-
value.externalAssets,
|
|
8316
|
-
sourcePath
|
|
8317
|
-
);
|
|
8318
|
-
}
|
|
8319
|
-
if (value.sceneComponents !== void 0) {
|
|
8320
|
-
if (!Array.isArray(value.sceneComponents)) {
|
|
8321
|
-
return invalid(
|
|
8322
|
-
"$.sceneComponents",
|
|
8323
|
-
"an array of component tokens or neutral schema rows when present",
|
|
8324
|
-
value.sceneComponents,
|
|
8325
|
-
sourcePath
|
|
8326
|
-
);
|
|
8327
|
-
}
|
|
8328
|
-
const componentNames = /* @__PURE__ */ new Set();
|
|
8329
|
-
for (const [componentIndex, component] of value.sceneComponents.entries()) {
|
|
8330
|
-
if (!isRecord2(component)) {
|
|
8331
|
-
return invalid(
|
|
8332
|
-
`$.sceneComponents[${componentIndex}]`,
|
|
8333
|
-
"a component token or neutral schema row",
|
|
8334
|
-
component,
|
|
8335
|
-
sourcePath
|
|
8336
|
-
);
|
|
8699
|
+
assetCodec: {
|
|
8700
|
+
type: "object",
|
|
8701
|
+
additionalProperties: false,
|
|
8702
|
+
required: ["name"],
|
|
8703
|
+
properties: {
|
|
8704
|
+
name: { type: "string", minLength: 1 },
|
|
8705
|
+
profile: { type: "string", minLength: 1 },
|
|
8706
|
+
version: { type: "string", minLength: 1 }
|
|
8337
8707
|
}
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8708
|
+
},
|
|
8709
|
+
integrity: {
|
|
8710
|
+
type: "object",
|
|
8711
|
+
additionalProperties: false,
|
|
8712
|
+
required: ["algorithm", "digest"],
|
|
8713
|
+
properties: {
|
|
8714
|
+
algorithm: { const: "sha256" },
|
|
8715
|
+
digest: { type: "string", minLength: 1 }
|
|
8345
8716
|
}
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8717
|
+
},
|
|
8718
|
+
provenance: {
|
|
8719
|
+
type: "object",
|
|
8720
|
+
additionalProperties: false,
|
|
8721
|
+
required: ["provider", "version"],
|
|
8722
|
+
properties: {
|
|
8723
|
+
provider: { type: "string", minLength: 1 },
|
|
8724
|
+
version: { type: "string", minLength: 1 },
|
|
8725
|
+
source: { type: "string", minLength: 1 }
|
|
8353
8726
|
}
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8727
|
+
},
|
|
8728
|
+
revision: {
|
|
8729
|
+
type: "object",
|
|
8730
|
+
additionalProperties: false,
|
|
8731
|
+
required: ["digest", "observedAt", "rootId"],
|
|
8732
|
+
properties: {
|
|
8733
|
+
digest: { type: "string", minLength: 1 },
|
|
8734
|
+
observedAt: { type: "number" },
|
|
8735
|
+
rootId: { type: "string", minLength: 1 }
|
|
8362
8736
|
}
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
}
|
|
8737
|
+
},
|
|
8738
|
+
diagnostic: {
|
|
8739
|
+
type: "object",
|
|
8740
|
+
additionalProperties: false,
|
|
8741
|
+
required: ["code", "severity"],
|
|
8742
|
+
properties: {
|
|
8743
|
+
code: { type: "string", minLength: 1 },
|
|
8744
|
+
severity: { type: "string", enum: ["info", "warning", "blocking"] },
|
|
8745
|
+
message: { type: "string" },
|
|
8746
|
+
subject: { $ref: "#/$defs/subject" },
|
|
8747
|
+
expected: { type: "string", minLength: 1 },
|
|
8748
|
+
actual: { type: "string" },
|
|
8749
|
+
hint: { type: "string", minLength: 1 },
|
|
8750
|
+
authority: { type: "string", enum: ["producer", "pack", "catalog"] },
|
|
8751
|
+
evidence: { type: "array", items: { type: "object" } },
|
|
8752
|
+
recoveryIntents: { type: "array", items: { type: "string", minLength: 1 } }
|
|
8753
|
+
}
|
|
8754
|
+
},
|
|
8755
|
+
subject: {
|
|
8756
|
+
type: "object",
|
|
8757
|
+
additionalProperties: false,
|
|
8758
|
+
required: ["type", "id"],
|
|
8759
|
+
properties: {
|
|
8760
|
+
type: { type: "string", enum: ["asset", "package", "resource"] },
|
|
8761
|
+
id: { type: "string", minLength: 1 }
|
|
8762
|
+
}
|
|
8763
|
+
},
|
|
8764
|
+
relation: {
|
|
8765
|
+
type: "object",
|
|
8766
|
+
additionalProperties: false,
|
|
8767
|
+
required: ["from", "to", "type", "provenance"],
|
|
8768
|
+
properties: {
|
|
8769
|
+
from: { $ref: "#/$defs/subject" },
|
|
8770
|
+
to: { $ref: "#/$defs/subject" },
|
|
8771
|
+
type: { type: "string", minLength: 1 },
|
|
8772
|
+
policy: { type: "object" },
|
|
8773
|
+
provenance: { $ref: "#/$defs/provenance" }
|
|
8373
8774
|
}
|
|
8374
8775
|
}
|
|
8375
8776
|
}
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
descriptor,
|
|
8390
|
-
sourcePath
|
|
8391
|
-
);
|
|
8392
|
-
}
|
|
8393
|
-
if (!isAssetGuid(descriptor.guid)) {
|
|
8394
|
-
return invalid(
|
|
8395
|
-
`$.assets[${JSON.stringify(sourceKey)}].guid`,
|
|
8396
|
-
"a 16-byte AssetGuid",
|
|
8397
|
-
descriptor.guid,
|
|
8398
|
-
sourcePath
|
|
8399
|
-
);
|
|
8400
|
-
}
|
|
8401
|
-
if (typeof descriptor.kind !== "string" || !isScriptablePackAssetKind(descriptor.kind)) {
|
|
8402
|
-
return invalid(
|
|
8403
|
-
`$.assets[${JSON.stringify(sourceKey)}].kind`,
|
|
8404
|
-
"one of SCRIPTABLE_PACK_ASSET_KINDS",
|
|
8405
|
-
descriptor.kind,
|
|
8406
|
-
sourcePath
|
|
8407
|
-
);
|
|
8408
|
-
}
|
|
8409
|
-
if (descriptor.name !== void 0 && typeof descriptor.name !== "string") {
|
|
8410
|
-
return invalid(
|
|
8411
|
-
`$.assets[${JSON.stringify(sourceKey)}].name`,
|
|
8412
|
-
"a string when present",
|
|
8413
|
-
descriptor.name,
|
|
8414
|
-
sourcePath
|
|
8415
|
-
);
|
|
8416
|
-
}
|
|
8417
|
-
const guid = guidKey(descriptor.guid);
|
|
8418
|
-
if (guid === packageGuid || localGuids.has(guid)) {
|
|
8419
|
-
return invalid(
|
|
8420
|
-
`$.assets[${JSON.stringify(sourceKey)}].guid`,
|
|
8421
|
-
"a GUID unique within the package and distinct from packageId",
|
|
8422
|
-
descriptor.guid,
|
|
8423
|
-
sourcePath
|
|
8424
|
-
);
|
|
8425
|
-
}
|
|
8426
|
-
localGuids.add(guid);
|
|
8427
|
-
}
|
|
8428
|
-
const externalGuids = /* @__PURE__ */ new Set();
|
|
8429
|
-
for (const [alias, guidValue] of Object.entries(value.externalAssets)) {
|
|
8430
|
-
if (alias.trim().length === 0) {
|
|
8431
|
-
return invalid("$.externalAssets", "non-empty alias object keys", alias, sourcePath);
|
|
8432
|
-
}
|
|
8433
|
-
if (!isAssetGuid(guidValue)) {
|
|
8434
|
-
return invalid(
|
|
8435
|
-
`$.externalAssets[${JSON.stringify(alias)}]`,
|
|
8436
|
-
"a 16-byte AssetGuid",
|
|
8437
|
-
guidValue,
|
|
8438
|
-
sourcePath
|
|
8439
|
-
);
|
|
8440
|
-
}
|
|
8441
|
-
const guid = guidKey(guidValue);
|
|
8442
|
-
if (guid === packageGuid || localGuids.has(guid) || externalGuids.has(guid)) {
|
|
8443
|
-
return invalid(
|
|
8444
|
-
`$.externalAssets[${JSON.stringify(alias)}]`,
|
|
8445
|
-
"a unique foreign GUID not owned by this package",
|
|
8446
|
-
guidValue,
|
|
8447
|
-
sourcePath
|
|
8448
|
-
);
|
|
8449
|
-
}
|
|
8450
|
-
externalGuids.add(guid);
|
|
8777
|
+
};
|
|
8778
|
+
|
|
8779
|
+
// src/schema-compiled.ts
|
|
8780
|
+
var ajv = new import_ajv.default({ strict: true, allErrors: false });
|
|
8781
|
+
(0, import_ajv_formats.default)(ajv, ["uuid"]);
|
|
8782
|
+
var validateMeta = ajv.compile(meta_schema_default);
|
|
8783
|
+
var validatePack = ajv.compile(pack_schema_default);
|
|
8784
|
+
function validatePackV2(value) {
|
|
8785
|
+
if (!validatePack(value) || !isPackV2Shape(value)) return false;
|
|
8786
|
+
const seenGuids = /* @__PURE__ */ new Set();
|
|
8787
|
+
for (const asset of value.assets) {
|
|
8788
|
+
if (seenGuids.has(asset.guid)) return false;
|
|
8789
|
+
seenGuids.add(asset.guid);
|
|
8451
8790
|
}
|
|
8452
|
-
return
|
|
8791
|
+
return true;
|
|
8453
8792
|
}
|
|
8454
|
-
function
|
|
8455
|
-
|
|
8456
|
-
guid: guidKey(descriptor.guid),
|
|
8457
|
-
sourceIndex,
|
|
8458
|
-
sourceKey,
|
|
8459
|
-
kind: descriptor.kind,
|
|
8460
|
-
...descriptor.name === void 0 ? {} : { name: descriptor.name }
|
|
8461
|
-
}));
|
|
8462
|
-
const externalAssets = Object.entries(definition.externalAssets).sort(([left], [right]) => left.localeCompare(right)).map(([alias, guid]) => ({ alias, guid: guidKey(guid) }));
|
|
8463
|
-
return {
|
|
8464
|
-
schemaVersion: "1.0.0",
|
|
8465
|
-
kind: "external-asset-package",
|
|
8466
|
-
packageId: guidKey(definition.packageId),
|
|
8467
|
-
...definition.name === void 0 ? {} : { name: definition.name },
|
|
8468
|
-
importer: "pack-ts",
|
|
8469
|
-
source,
|
|
8470
|
-
importSettings: { contractVersion: "1.0.0", externalAssets },
|
|
8471
|
-
subAssets
|
|
8472
|
-
};
|
|
8793
|
+
function isPackV2Shape(value) {
|
|
8794
|
+
return typeof value === "object" && value !== null && "schemaVersion" in value && value.schemaVersion === "2.0.0";
|
|
8473
8795
|
}
|
|
8474
8796
|
var IMPORT_META_RESOLVE_FLAG = "--experimental-import-meta-resolve";
|
|
8475
8797
|
function scriptablePackWorkerExecArgv() {
|
|
@@ -8518,50 +8840,51 @@ async function inventoryScriptablePackSource(sourcePath, initialSourceText) {
|
|
|
8518
8840
|
}
|
|
8519
8841
|
function serializeFailure(value) {
|
|
8520
8842
|
if (value !== null && typeof value === "object") {
|
|
8521
|
-
const
|
|
8843
|
+
const failure2 = value;
|
|
8522
8844
|
return {
|
|
8523
|
-
name:
|
|
8524
|
-
code:
|
|
8525
|
-
expected:
|
|
8526
|
-
actual:
|
|
8527
|
-
hint:
|
|
8528
|
-
detail:
|
|
8529
|
-
message:
|
|
8845
|
+
name: failure2.name,
|
|
8846
|
+
code: failure2.code,
|
|
8847
|
+
expected: failure2.expected,
|
|
8848
|
+
actual: failure2.actual,
|
|
8849
|
+
hint: failure2.hint,
|
|
8850
|
+
detail: failure2.detail,
|
|
8851
|
+
message: failure2.message
|
|
8530
8852
|
};
|
|
8531
8853
|
}
|
|
8532
8854
|
return { message: String(value) };
|
|
8533
8855
|
}
|
|
8534
8856
|
function hydrateFailure(value) {
|
|
8535
8857
|
if (value === null || typeof value !== "object") return value;
|
|
8536
|
-
const
|
|
8537
|
-
if (
|
|
8858
|
+
const failure2 = value;
|
|
8859
|
+
if (failure2.name === "AssetError" && typeof failure2.code === "string" && typeof failure2.expected === "string" && typeof failure2.hint === "string") {
|
|
8538
8860
|
const args = {
|
|
8539
|
-
code:
|
|
8540
|
-
expected:
|
|
8541
|
-
hint:
|
|
8861
|
+
code: failure2.code,
|
|
8862
|
+
expected: failure2.expected,
|
|
8863
|
+
hint: failure2.hint
|
|
8542
8864
|
};
|
|
8543
|
-
return
|
|
8865
|
+
return failure2.detail === void 0 ? new AssetError(args) : new AssetError({
|
|
8544
8866
|
...args,
|
|
8545
|
-
detail:
|
|
8867
|
+
detail: failure2.detail
|
|
8546
8868
|
});
|
|
8547
8869
|
}
|
|
8548
|
-
if (
|
|
8870
|
+
if (failure2.name === "ImportError" && typeof failure2.code === "string" && typeof failure2.expected === "string" && typeof failure2.hint === "string" && failure2.detail !== void 0) {
|
|
8549
8871
|
return new ImportError({
|
|
8550
|
-
code:
|
|
8551
|
-
expected:
|
|
8552
|
-
hint:
|
|
8553
|
-
detail:
|
|
8554
|
-
...typeof
|
|
8872
|
+
code: failure2.code,
|
|
8873
|
+
expected: failure2.expected,
|
|
8874
|
+
hint: failure2.hint,
|
|
8875
|
+
detail: failure2.detail,
|
|
8876
|
+
...typeof failure2.actual === "string" ? { actual: failure2.actual } : {}
|
|
8555
8877
|
});
|
|
8556
8878
|
}
|
|
8557
|
-
if (typeof
|
|
8558
|
-
const error = new Error(
|
|
8559
|
-
if (typeof
|
|
8879
|
+
if (typeof failure2.message === "string") {
|
|
8880
|
+
const error = new Error(failure2.message);
|
|
8881
|
+
if (typeof failure2.name === "string") error.name = failure2.name;
|
|
8560
8882
|
return error;
|
|
8561
8883
|
}
|
|
8562
8884
|
return value;
|
|
8563
8885
|
}
|
|
8564
8886
|
var WorkerScriptablePackExecutor = class {
|
|
8887
|
+
supportsParameterizedContext = true;
|
|
8565
8888
|
worker;
|
|
8566
8889
|
compileRoot;
|
|
8567
8890
|
nextBuildId = 0;
|
|
@@ -8589,7 +8912,7 @@ var WorkerScriptablePackExecutor = class {
|
|
|
8589
8912
|
resolveLoad({
|
|
8590
8913
|
default: value.definition === void 0 ? void 0 : {
|
|
8591
8914
|
...value.definition,
|
|
8592
|
-
build: (
|
|
8915
|
+
build: (readByGuid, context) => this.runBuild({ readByGuid }, context)
|
|
8593
8916
|
}
|
|
8594
8917
|
});
|
|
8595
8918
|
} else if (value.kind === "load-threw") {
|
|
@@ -8621,7 +8944,7 @@ var WorkerScriptablePackExecutor = class {
|
|
|
8621
8944
|
})();
|
|
8622
8945
|
return this.disposal;
|
|
8623
8946
|
}
|
|
8624
|
-
runBuild(reader) {
|
|
8947
|
+
runBuild(reader, context) {
|
|
8625
8948
|
const worker = this.worker;
|
|
8626
8949
|
if (worker === void 0) return Promise.reject(new Error("ScriptablePack worker is closed"));
|
|
8627
8950
|
if (this.build !== void 0)
|
|
@@ -8629,7 +8952,7 @@ var WorkerScriptablePackExecutor = class {
|
|
|
8629
8952
|
const id = this.nextBuildId++;
|
|
8630
8953
|
return new Promise((resolveBuild, rejectBuild) => {
|
|
8631
8954
|
this.build = { id, reader, resolve: resolveBuild, reject: rejectBuild };
|
|
8632
|
-
worker.postMessage({ kind: "build", buildId: id });
|
|
8955
|
+
worker.postMessage({ kind: "build", buildId: id, context });
|
|
8633
8956
|
});
|
|
8634
8957
|
}
|
|
8635
8958
|
onMessage(message) {
|
|
@@ -8662,11 +8985,11 @@ function scriptablePackWorkerUrl() {
|
|
|
8662
8985
|
const bundledWorker = new URL("./scriptable-pack-worker.mjs", import.meta.url);
|
|
8663
8986
|
return existsSync(fileURLToPath(bundledWorker)) ? bundledWorker : new URL("../dist/scriptable-pack-worker.mjs", import.meta.url);
|
|
8664
8987
|
}
|
|
8665
|
-
function
|
|
8666
|
-
return
|
|
8667
|
-
code: "pack-
|
|
8668
|
-
expected: "a trusted
|
|
8669
|
-
hint: "repair the module
|
|
8988
|
+
function parameterizedLoadFailure(sourcePath, reason, phase, diagnostic, timeoutMs) {
|
|
8989
|
+
return {
|
|
8990
|
+
code: "pack-parameter-invalid",
|
|
8991
|
+
expected: "a trusted Pack v2 authoring module with a valid default export",
|
|
8992
|
+
hint: "repair the source module or its build timeout, then inspect the Pack again",
|
|
8670
8993
|
detail: {
|
|
8671
8994
|
sourcePath,
|
|
8672
8995
|
reason,
|
|
@@ -8674,30 +8997,16 @@ function loadFailure(sourcePath, reason, phase, diagnostic, timeoutMs) {
|
|
|
8674
8997
|
diagnostic,
|
|
8675
8998
|
...timeoutMs === void 0 ? {} : { timeoutMs }
|
|
8676
8999
|
}
|
|
8677
|
-
});
|
|
8678
|
-
}
|
|
8679
|
-
function buildTimeoutFailure(sourcePath, timeoutMs) {
|
|
8680
|
-
return {
|
|
8681
|
-
code: "pack-source-load-failed",
|
|
8682
|
-
expected: "a ScriptablePack build to settle within the configured build timeout",
|
|
8683
|
-
hint: "repair the authored build, then retry through a fresh ScriptablePack generation",
|
|
8684
|
-
detail: {
|
|
8685
|
-
sourcePath,
|
|
8686
|
-
reason: "timeout",
|
|
8687
|
-
phase: "build",
|
|
8688
|
-
timeoutMs,
|
|
8689
|
-
diagnostic: `ScriptablePack build exceeded ${timeoutMs}ms`
|
|
8690
|
-
}
|
|
8691
9000
|
};
|
|
8692
9001
|
}
|
|
8693
|
-
async function
|
|
9002
|
+
async function loadParameterizedScriptablePack(sourcePath, options = {}) {
|
|
8694
9003
|
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
8695
9004
|
const buildTimeoutMs = options.buildTimeoutMs ?? 5e3;
|
|
8696
9005
|
const executor = options.executor ?? new WorkerScriptablePackExecutor();
|
|
8697
9006
|
let disposeReason;
|
|
8698
9007
|
let timeout;
|
|
8699
9008
|
try {
|
|
8700
|
-
const timeoutSignal = /* @__PURE__ */ Symbol("
|
|
9009
|
+
const timeoutSignal = /* @__PURE__ */ Symbol("parameterized-pack-module-timeout");
|
|
8701
9010
|
const loaded = await Promise.race([
|
|
8702
9011
|
executor.load(sourcePath),
|
|
8703
9012
|
new Promise((resolve6) => {
|
|
@@ -8706,34 +9015,49 @@ async function loadScriptablePack(sourcePath, options = {}) {
|
|
|
8706
9015
|
]);
|
|
8707
9016
|
if (loaded === timeoutSignal) {
|
|
8708
9017
|
disposeReason = "timeout";
|
|
8709
|
-
return
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
9018
|
+
return err(
|
|
9019
|
+
parameterizedLoadFailure(
|
|
9020
|
+
sourcePath,
|
|
9021
|
+
"timeout",
|
|
9022
|
+
"module-load",
|
|
9023
|
+
`Pack module initialization exceeded ${timeoutMs}ms`,
|
|
9024
|
+
timeoutMs
|
|
9025
|
+
)
|
|
8715
9026
|
);
|
|
8716
9027
|
}
|
|
8717
9028
|
const moduleValue = loaded !== null && typeof loaded === "object" && "default" in loaded ? loaded.default : void 0;
|
|
8718
|
-
const validated =
|
|
9029
|
+
const validated = validatePackDefinition(moduleValue, sourcePath);
|
|
8719
9030
|
if (!validated.ok) {
|
|
8720
9031
|
disposeReason = "failure";
|
|
8721
9032
|
return validated;
|
|
8722
9033
|
}
|
|
8723
9034
|
if (options.metadataOnly === true) {
|
|
8724
9035
|
disposeReason = "complete";
|
|
8725
|
-
return validated;
|
|
9036
|
+
return ok(validated.value);
|
|
8726
9037
|
}
|
|
8727
9038
|
const definition = validated.value;
|
|
9039
|
+
const build = definition.build;
|
|
8728
9040
|
return ok({
|
|
8729
9041
|
...definition,
|
|
8730
|
-
build: async (
|
|
9042
|
+
build: async (context) => {
|
|
8731
9043
|
let buildTimedOut = false;
|
|
8732
9044
|
let buildTimeout;
|
|
8733
|
-
const timeoutResult = err(
|
|
9045
|
+
const timeoutResult = err(
|
|
9046
|
+
parameterizedLoadFailure(
|
|
9047
|
+
sourcePath,
|
|
9048
|
+
"timeout",
|
|
9049
|
+
"build",
|
|
9050
|
+
`ScriptablePack build exceeded ${buildTimeoutMs}ms`,
|
|
9051
|
+
buildTimeoutMs
|
|
9052
|
+
)
|
|
9053
|
+
);
|
|
8734
9054
|
try {
|
|
9055
|
+
const invocation = "supportsParameterizedContext" in executor && executor.supportsParameterizedContext === true ? build(context.readByGuid, {
|
|
9056
|
+
packageId: [...context.packageId],
|
|
9057
|
+
..."values" in context && context.values !== void 0 ? { values: context.values } : {}
|
|
9058
|
+
}) : definition.build(context);
|
|
8735
9059
|
const built = await Promise.race([
|
|
8736
|
-
Promise.resolve(
|
|
9060
|
+
Promise.resolve(invocation),
|
|
8737
9061
|
new Promise((resolve6) => {
|
|
8738
9062
|
buildTimeout = setTimeout(() => {
|
|
8739
9063
|
buildTimedOut = true;
|
|
@@ -8756,9 +9080,15 @@ async function loadScriptablePack(sourcePath, options = {}) {
|
|
|
8756
9080
|
}
|
|
8757
9081
|
});
|
|
8758
9082
|
} catch (error) {
|
|
8759
|
-
const diagnostic = error instanceof Error ? error.message : String(error);
|
|
8760
9083
|
disposeReason = "failure";
|
|
8761
|
-
return
|
|
9084
|
+
return err(
|
|
9085
|
+
parameterizedLoadFailure(
|
|
9086
|
+
sourcePath,
|
|
9087
|
+
"module-load",
|
|
9088
|
+
"module-load",
|
|
9089
|
+
error instanceof Error ? error.message : String(error)
|
|
9090
|
+
)
|
|
9091
|
+
);
|
|
8762
9092
|
} finally {
|
|
8763
9093
|
if (timeout !== void 0) clearTimeout(timeout);
|
|
8764
9094
|
if (disposeReason !== void 0) await executor.dispose?.(disposeReason);
|
|
@@ -8772,8 +9102,12 @@ function ok4(value) {
|
|
|
8772
9102
|
function packErr(error) {
|
|
8773
9103
|
return { ok: false, error };
|
|
8774
9104
|
}
|
|
9105
|
+
function record(value) {
|
|
9106
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9107
|
+
}
|
|
8775
9108
|
var BLACKLIST = /* @__PURE__ */ new Set([
|
|
8776
9109
|
"node_modules",
|
|
9110
|
+
"__tests__",
|
|
8777
9111
|
".forgeax-harness",
|
|
8778
9112
|
".forgeax",
|
|
8779
9113
|
".git",
|
|
@@ -8877,10 +9211,87 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
8877
9211
|
const scriptablePaths = rawPaths.filter((p) => p.endsWith(".pack.ts"));
|
|
8878
9212
|
const guidToPath = /* @__PURE__ */ new Map();
|
|
8879
9213
|
const packRefs = /* @__PURE__ */ new Map();
|
|
9214
|
+
const packageIdToPath = /* @__PURE__ */ new Map();
|
|
9215
|
+
const packageKind = /* @__PURE__ */ new Map();
|
|
9216
|
+
const instanceParents = [];
|
|
9217
|
+
function registerPackage(packageId2, path, kind) {
|
|
9218
|
+
if (packageId2 === void 0) return void 0;
|
|
9219
|
+
const normalized = packageId2.toLowerCase();
|
|
9220
|
+
const existing = packageIdToPath.get(normalized);
|
|
9221
|
+
if (existing !== void 0) {
|
|
9222
|
+
return makePackError("pack-guid-collision", {
|
|
9223
|
+
paths: [existing, path],
|
|
9224
|
+
guid: normalized
|
|
9225
|
+
});
|
|
9226
|
+
}
|
|
9227
|
+
packageIdToPath.set(normalized, path);
|
|
9228
|
+
packageKind.set(normalized, kind);
|
|
9229
|
+
return void 0;
|
|
9230
|
+
}
|
|
8880
9231
|
for (const packPath of packPaths) {
|
|
8881
9232
|
const loaded = await readValidatedJson(packPath, "pack-malformed-pack", validatePack);
|
|
8882
9233
|
if (!loaded.ok) return loaded;
|
|
8883
9234
|
const { raw, parsed } = loaded.value;
|
|
9235
|
+
if (record(parsed) && parsed.schemaVersion === "3.0.0") {
|
|
9236
|
+
const authoring = parseParameterizedPackJson(parsed);
|
|
9237
|
+
if (!authoring.ok) {
|
|
9238
|
+
return packErr(
|
|
9239
|
+
makePackError("pack-malformed-pack", {
|
|
9240
|
+
path: packPath,
|
|
9241
|
+
ajvErrors: [{ instancePath: "", message: authoring.error.code }]
|
|
9242
|
+
})
|
|
9243
|
+
);
|
|
9244
|
+
}
|
|
9245
|
+
const packageId2 = authoring.value.packageId;
|
|
9246
|
+
const packageCollision2 = registerPackage(
|
|
9247
|
+
PackageId.format(packageId2),
|
|
9248
|
+
packPath,
|
|
9249
|
+
authoring.value.format
|
|
9250
|
+
);
|
|
9251
|
+
if (packageCollision2 !== void 0) return packErr(packageCollision2);
|
|
9252
|
+
if (authoring.value.format === "instance") {
|
|
9253
|
+
instanceParents.push({
|
|
9254
|
+
path: packPath,
|
|
9255
|
+
packageId: PackageId.format(authoring.value.packageId),
|
|
9256
|
+
parent: PackageId.format(authoring.value.parent)
|
|
9257
|
+
});
|
|
9258
|
+
} else {
|
|
9259
|
+
const projected = projectDirectPackJson(authoring.value);
|
|
9260
|
+
if (!projected.ok) {
|
|
9261
|
+
return packErr(
|
|
9262
|
+
makePackError("pack-malformed-pack", {
|
|
9263
|
+
path: packPath,
|
|
9264
|
+
ajvErrors: [{ instancePath: "/assets", message: projected.error.code }]
|
|
9265
|
+
})
|
|
9266
|
+
);
|
|
9267
|
+
}
|
|
9268
|
+
for (const asset of projected.value.assets) {
|
|
9269
|
+
const normalizedGuid = asset.guid.toLowerCase();
|
|
9270
|
+
const existing = guidToPath.get(normalizedGuid);
|
|
9271
|
+
if (existing !== void 0) {
|
|
9272
|
+
return packErr(
|
|
9273
|
+
makePackError("pack-guid-collision", {
|
|
9274
|
+
paths: [existing, packPath],
|
|
9275
|
+
guid: normalizedGuid
|
|
9276
|
+
})
|
|
9277
|
+
);
|
|
9278
|
+
}
|
|
9279
|
+
guidToPath.set(normalizedGuid, packPath);
|
|
9280
|
+
packRefs.set(normalizedGuid, [
|
|
9281
|
+
...asset.refs.map((ref) => ref.toLowerCase()),
|
|
9282
|
+
...extractMountSourceGuids(asset)
|
|
9283
|
+
]);
|
|
9284
|
+
}
|
|
9285
|
+
}
|
|
9286
|
+
capture?.declarations.set(packPath, {
|
|
9287
|
+
format: "pack.json",
|
|
9288
|
+
sourcePath: packPath,
|
|
9289
|
+
sourceRevision: `sha256:${createHash("sha256").update(raw).digest("hex")}`,
|
|
9290
|
+
sourceText: raw,
|
|
9291
|
+
value: parsed
|
|
9292
|
+
});
|
|
9293
|
+
continue;
|
|
9294
|
+
}
|
|
8884
9295
|
const packageContract = validateProducerContract(parsed);
|
|
8885
9296
|
if (!packageContract.ok) {
|
|
8886
9297
|
return packErr(
|
|
@@ -8891,6 +9302,8 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
8891
9302
|
);
|
|
8892
9303
|
}
|
|
8893
9304
|
const packObj = parsed;
|
|
9305
|
+
const packageCollision = registerPackage(packObj.packageId, packPath, "legacy");
|
|
9306
|
+
if (packageCollision !== void 0) return packErr(packageCollision);
|
|
8894
9307
|
for (const asset of packObj.assets) {
|
|
8895
9308
|
if (asset.kind === "particle-effect" && asset.execution === "direct" && (asset.refs.length > 0 || Object.keys(asset.artifacts ?? {}).length > 0)) {
|
|
8896
9309
|
return packErr(
|
|
@@ -8973,8 +9386,14 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
8973
9386
|
...extractMountSourceGuids(asset)
|
|
8974
9387
|
]);
|
|
8975
9388
|
}
|
|
9389
|
+
capture?.declarations.set(packPath, {
|
|
9390
|
+
format: "pack.json",
|
|
9391
|
+
sourcePath: packPath,
|
|
9392
|
+
sourceRevision: `sha256:${createHash("sha256").update(raw).digest("hex")}`,
|
|
9393
|
+
sourceText: raw,
|
|
9394
|
+
value: packObj
|
|
9395
|
+
});
|
|
8976
9396
|
}
|
|
8977
|
-
const { paths: assetPaths } = loadAssetConfig(process.cwd());
|
|
8978
9397
|
for (const metaPath of metaPaths) {
|
|
8979
9398
|
const loaded = await readValidatedJson(metaPath, "pack-malformed-meta", validateMeta);
|
|
8980
9399
|
if (!loaded.ok) return loaded;
|
|
@@ -8989,6 +9408,14 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
8989
9408
|
);
|
|
8990
9409
|
}
|
|
8991
9410
|
const metaObj = parsed;
|
|
9411
|
+
const packageCollision = registerPackage(metaObj.packageId, metaPath, "legacy");
|
|
9412
|
+
if (packageCollision !== void 0) return packErr(packageCollision);
|
|
9413
|
+
capture?.declarations.set(metaPath, {
|
|
9414
|
+
format: "meta.json",
|
|
9415
|
+
sourcePath: metaPath,
|
|
9416
|
+
sourceRevision: `sha256:${createHash("sha256").update(raw).digest("hex")}`,
|
|
9417
|
+
value: metaObj
|
|
9418
|
+
});
|
|
8992
9419
|
for (const sub of metaObj.subAssets) {
|
|
8993
9420
|
if (!isValidAssetGuidString(sub.guid)) {
|
|
8994
9421
|
return packErr(
|
|
@@ -9022,11 +9449,7 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
9022
9449
|
);
|
|
9023
9450
|
}
|
|
9024
9451
|
}
|
|
9025
|
-
const
|
|
9026
|
-
if (!sourceResolved.ok) {
|
|
9027
|
-
return packErr(sourceResolved.error);
|
|
9028
|
-
}
|
|
9029
|
-
const expectedSourcePath = sourceResolved.value;
|
|
9452
|
+
const expectedSourcePath = resolveAssetSource(metaPath, metaObj.source);
|
|
9030
9453
|
try {
|
|
9031
9454
|
await stat(expectedSourcePath);
|
|
9032
9455
|
} catch {
|
|
@@ -9046,23 +9469,24 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
9046
9469
|
return packErr(
|
|
9047
9470
|
makePackError("pack-malformed-meta", {
|
|
9048
9471
|
path: sourcePath,
|
|
9049
|
-
ajvErrors: [{ instancePath: "", message: "
|
|
9472
|
+
ajvErrors: [{ instancePath: "", message: "Pack source read failed" }]
|
|
9050
9473
|
})
|
|
9051
9474
|
);
|
|
9052
9475
|
}
|
|
9053
|
-
const
|
|
9476
|
+
const loaderOptions = {
|
|
9054
9477
|
...opts.scriptablePack ?? {},
|
|
9055
|
-
...{ metadataOnly: true }
|
|
9056
|
-
}
|
|
9478
|
+
...capture === void 0 ? { metadataOnly: true } : {}
|
|
9479
|
+
};
|
|
9480
|
+
const loaded = await loadParameterizedScriptablePack(sourcePath, loaderOptions);
|
|
9057
9481
|
if (!loaded.ok) {
|
|
9058
|
-
const diagnostic =
|
|
9482
|
+
const diagnostic = loaded.error.detail.diagnostic;
|
|
9059
9483
|
return packErr(
|
|
9060
9484
|
makePackError("pack-malformed-meta", {
|
|
9061
9485
|
path: sourcePath,
|
|
9062
9486
|
ajvErrors: [
|
|
9063
9487
|
{
|
|
9064
9488
|
instancePath: "",
|
|
9065
|
-
message: diagnostic ===
|
|
9489
|
+
message: typeof diagnostic === "string" ? `${loaded.error.code}: ${diagnostic}` : loaded.error.code
|
|
9066
9490
|
}
|
|
9067
9491
|
]
|
|
9068
9492
|
})
|
|
@@ -9075,32 +9499,81 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
9075
9499
|
return packErr(
|
|
9076
9500
|
makePackError("pack-malformed-meta", {
|
|
9077
9501
|
path: sourcePath,
|
|
9078
|
-
ajvErrors: [{ instancePath: "", message: "
|
|
9502
|
+
ajvErrors: [{ instancePath: "", message: "Pack source closure read failed" }]
|
|
9079
9503
|
})
|
|
9080
9504
|
);
|
|
9081
9505
|
}
|
|
9082
|
-
const
|
|
9083
|
-
|
|
9084
|
-
|
|
9506
|
+
const packageCollision = registerPackage(
|
|
9507
|
+
PackageId.format(loaded.value.packageId),
|
|
9508
|
+
sourcePath,
|
|
9509
|
+
"parameterized"
|
|
9510
|
+
);
|
|
9511
|
+
if (packageCollision !== void 0) return packErr(packageCollision);
|
|
9512
|
+
const meta = projectParameterizedPackMeta(loaded.value, sourcePath);
|
|
9513
|
+
capture?.declarations.set(sourcePath, {
|
|
9514
|
+
format: "pack.ts-parameterized",
|
|
9515
|
+
sourcePath,
|
|
9516
|
+
sourceRevision: `sha256:${createHash("sha256").update(source).digest("hex")}`,
|
|
9517
|
+
value: meta,
|
|
9518
|
+
definition: loaded.value,
|
|
9519
|
+
sourceClosure
|
|
9520
|
+
});
|
|
9521
|
+
}
|
|
9522
|
+
const parentByPackageId = new Map(
|
|
9523
|
+
instanceParents.map((instance) => [instance.packageId.toLowerCase(), instance])
|
|
9524
|
+
);
|
|
9525
|
+
for (const instance of instanceParents) {
|
|
9526
|
+
const parentId = instance.parent.toLowerCase();
|
|
9527
|
+
const parentPath = packageIdToPath.get(parentId);
|
|
9528
|
+
if (parentPath === void 0) {
|
|
9085
9529
|
return packErr(
|
|
9086
|
-
makePackError("pack-malformed-
|
|
9087
|
-
path:
|
|
9088
|
-
|
|
9530
|
+
makePackError("pack-malformed-pack", {
|
|
9531
|
+
path: instance.path,
|
|
9532
|
+
reason: "pack-parent-not-found",
|
|
9533
|
+
ajvErrors: [
|
|
9534
|
+
{
|
|
9535
|
+
instancePath: "/parent",
|
|
9536
|
+
message: `parent packageId ${instance.parent} was not found`
|
|
9537
|
+
}
|
|
9538
|
+
]
|
|
9089
9539
|
})
|
|
9090
9540
|
);
|
|
9091
9541
|
}
|
|
9092
|
-
(
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9542
|
+
const kind = packageKind.get(parentId);
|
|
9543
|
+
if (kind !== "parameterized" && kind !== "instance") {
|
|
9544
|
+
return packErr(
|
|
9545
|
+
makePackError("pack-malformed-pack", {
|
|
9546
|
+
path: instance.path,
|
|
9547
|
+
reason: "pack-parent-not-parameterized",
|
|
9548
|
+
ajvErrors: [
|
|
9549
|
+
{
|
|
9550
|
+
instancePath: "/parent",
|
|
9551
|
+
message: `parent ${instance.parent} is not a parameterized Pack`
|
|
9552
|
+
}
|
|
9553
|
+
]
|
|
9554
|
+
})
|
|
9555
|
+
);
|
|
9556
|
+
}
|
|
9557
|
+
}
|
|
9558
|
+
for (const instance of instanceParents) {
|
|
9559
|
+
const chain = /* @__PURE__ */ new Set();
|
|
9560
|
+
let current = instance.packageId.toLowerCase();
|
|
9561
|
+
while (true) {
|
|
9562
|
+
if (chain.has(current)) {
|
|
9099
9563
|
return packErr(
|
|
9100
|
-
makePackError("pack-
|
|
9564
|
+
makePackError("pack-malformed-pack", {
|
|
9565
|
+
path: instance.path,
|
|
9566
|
+
reason: "pack-parent-cycle",
|
|
9567
|
+
ajvErrors: [
|
|
9568
|
+
{ instancePath: "/parent", message: `parent chain repeats packageId ${current}` }
|
|
9569
|
+
]
|
|
9570
|
+
})
|
|
9101
9571
|
);
|
|
9102
9572
|
}
|
|
9103
|
-
|
|
9573
|
+
chain.add(current);
|
|
9574
|
+
const next = parentByPackageId.get(current);
|
|
9575
|
+
if (next === void 0) break;
|
|
9576
|
+
current = next.parent.toLowerCase();
|
|
9104
9577
|
}
|
|
9105
9578
|
}
|
|
9106
9579
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -9139,6 +9612,59 @@ async function scanValidated(roots, opts = {}, capture) {
|
|
|
9139
9612
|
async function scan(roots, opts = {}) {
|
|
9140
9613
|
return scanValidated(roots, opts);
|
|
9141
9614
|
}
|
|
9615
|
+
async function scanInventory(roots, opts = {}) {
|
|
9616
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
9617
|
+
const scanned = await scanValidated(roots, opts, { declarations });
|
|
9618
|
+
if (!scanned.ok) return scanned;
|
|
9619
|
+
const inventory = [];
|
|
9620
|
+
for (const sourcePath of scanned.value) {
|
|
9621
|
+
const declaration = declarations.get(sourcePath);
|
|
9622
|
+
if (declaration?.format !== "pack.json") continue;
|
|
9623
|
+
if (declaration.value.schemaVersion === "3.0.0") {
|
|
9624
|
+
const parsed = parseParameterizedPackJson(declaration.value);
|
|
9625
|
+
if (!parsed.ok) {
|
|
9626
|
+
return packErr(
|
|
9627
|
+
makePackError("pack-malformed-pack", {
|
|
9628
|
+
path: sourcePath,
|
|
9629
|
+
ajvErrors: [{ instancePath: "", message: parsed.error.code }]
|
|
9630
|
+
})
|
|
9631
|
+
);
|
|
9632
|
+
}
|
|
9633
|
+
if (parsed.value.format !== "direct") continue;
|
|
9634
|
+
const projected = projectDirectPackJson(parsed.value);
|
|
9635
|
+
if (!projected.ok) {
|
|
9636
|
+
return packErr(
|
|
9637
|
+
makePackError("pack-malformed-pack", {
|
|
9638
|
+
path: sourcePath,
|
|
9639
|
+
ajvErrors: [{ instancePath: "/assets", message: projected.error.code }]
|
|
9640
|
+
})
|
|
9641
|
+
);
|
|
9642
|
+
}
|
|
9643
|
+
for (const [index, asset] of projected.value.assets.entries()) {
|
|
9644
|
+
inventory.push({
|
|
9645
|
+
guid: asset.guid,
|
|
9646
|
+
kind: asset.kind,
|
|
9647
|
+
sourcePath,
|
|
9648
|
+
sourceRevision: declaration.sourceRevision,
|
|
9649
|
+
sourceKey: asset.sourceKey,
|
|
9650
|
+
sourceIndex: index
|
|
9651
|
+
});
|
|
9652
|
+
}
|
|
9653
|
+
continue;
|
|
9654
|
+
}
|
|
9655
|
+
for (const [index, asset] of declaration.value.assets.entries()) {
|
|
9656
|
+
inventory.push({
|
|
9657
|
+
guid: asset.guid,
|
|
9658
|
+
kind: asset.kind,
|
|
9659
|
+
sourcePath,
|
|
9660
|
+
sourceRevision: declaration.sourceRevision,
|
|
9661
|
+
...asset.sourceKey === void 0 ? {} : { sourceKey: asset.sourceKey },
|
|
9662
|
+
...asset.sourceIndex === void 0 ? { sourceIndex: index } : { sourceIndex: asset.sourceIndex }
|
|
9663
|
+
});
|
|
9664
|
+
}
|
|
9665
|
+
}
|
|
9666
|
+
return ok4({ paths: scanned.value, inventory, declarations });
|
|
9667
|
+
}
|
|
9142
9668
|
|
|
9143
9669
|
// src/evidence/source-inventory.ts
|
|
9144
9670
|
function fingerprint(meta, source) {
|
|
@@ -9181,32 +9707,41 @@ async function readSourceInventory(request) {
|
|
|
9181
9707
|
let authored;
|
|
9182
9708
|
for (const path of paths) {
|
|
9183
9709
|
if (path.endsWith(".pack.ts")) {
|
|
9184
|
-
const loaded = await loadScriptablePack(path, { metadataOnly: true });
|
|
9185
|
-
if (!loaded.ok) continue;
|
|
9186
|
-
const meta = projectScriptablePackMeta(loaded.value, path);
|
|
9187
|
-
if (meta.subAssets.some((asset) => asset.guid.toLowerCase() === guid)) {
|
|
9188
|
-
return { origin: "sourceMeta", sourcePath: path };
|
|
9189
|
-
}
|
|
9190
9710
|
continue;
|
|
9191
9711
|
}
|
|
9192
9712
|
const raw = await readFile(path, "utf8").catch(() => void 0);
|
|
9193
9713
|
if (raw === void 0) continue;
|
|
9194
9714
|
let parsed;
|
|
9195
9715
|
try {
|
|
9196
|
-
|
|
9716
|
+
const value = JSON.parse(raw);
|
|
9717
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) continue;
|
|
9718
|
+
parsed = value;
|
|
9197
9719
|
} catch {
|
|
9198
9720
|
continue;
|
|
9199
9721
|
}
|
|
9200
9722
|
if (path.endsWith(".pack.json")) {
|
|
9201
|
-
if (parsed.
|
|
9202
|
-
|
|
9723
|
+
if (parsed.schemaVersion === "3.0.0") {
|
|
9724
|
+
const direct = parseParameterizedPackJson(parsed);
|
|
9725
|
+
if (direct.ok && direct.value.format === "direct") {
|
|
9726
|
+
const projected = projectDirectPackJson(direct.value);
|
|
9727
|
+
if (projected.ok && projected.value.assets.some((asset) => asset.guid.toLowerCase() === guid)) {
|
|
9728
|
+
authored = { origin: "authoredPack", sourcePath: path };
|
|
9729
|
+
}
|
|
9730
|
+
}
|
|
9731
|
+
} else if (Array.isArray(parsed.assets) && parsed.assets.some(
|
|
9732
|
+
(asset) => asset !== null && typeof asset === "object" && !Array.isArray(asset) && typeof asset.guid === "string" && (asset.guid === request.guid || asset.guid.toLowerCase() === guid)
|
|
9203
9733
|
)) {
|
|
9204
9734
|
authored = { origin: "authoredPack", sourcePath: path };
|
|
9205
9735
|
}
|
|
9206
9736
|
continue;
|
|
9207
9737
|
}
|
|
9208
9738
|
if (path.endsWith(".meta.json")) {
|
|
9209
|
-
const source = sourceFromMeta(
|
|
9739
|
+
const source = sourceFromMeta(
|
|
9740
|
+
path,
|
|
9741
|
+
parsed,
|
|
9742
|
+
request.guid,
|
|
9743
|
+
raw
|
|
9744
|
+
);
|
|
9210
9745
|
if (source !== void 0) return source;
|
|
9211
9746
|
}
|
|
9212
9747
|
}
|
|
@@ -9225,6 +9760,9 @@ function parsePackV2(value) {
|
|
|
9225
9760
|
}
|
|
9226
9761
|
|
|
9227
9762
|
// src/cli-asset.ts
|
|
9763
|
+
function isRecord3(value) {
|
|
9764
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9765
|
+
}
|
|
9228
9766
|
function emitError2(ctx, err5) {
|
|
9229
9767
|
const payload = {
|
|
9230
9768
|
code: err5.code,
|
|
@@ -9236,7 +9774,7 @@ function emitError2(ctx, err5) {
|
|
|
9236
9774
|
return 1;
|
|
9237
9775
|
}
|
|
9238
9776
|
async function scanEntries(roots, ctx) {
|
|
9239
|
-
const result = await
|
|
9777
|
+
const result = await scanInventory(roots);
|
|
9240
9778
|
if (!result.ok) {
|
|
9241
9779
|
emitError2(ctx, {
|
|
9242
9780
|
code: result.error.code,
|
|
@@ -9247,77 +9785,55 @@ async function scanEntries(roots, ctx) {
|
|
|
9247
9785
|
return { ok: false };
|
|
9248
9786
|
}
|
|
9249
9787
|
const entries = [];
|
|
9250
|
-
const
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
} catch {
|
|
9258
|
-
continue;
|
|
9259
|
-
}
|
|
9260
|
-
const packObj = parsed;
|
|
9261
|
-
if (!Array.isArray(packObj.assets)) continue;
|
|
9262
|
-
for (const asset of packObj.assets) {
|
|
9263
|
-
if (typeof asset.guid === "string" && typeof asset.kind === "string") {
|
|
9264
|
-
entries.push({
|
|
9265
|
-
guid: asset.guid,
|
|
9266
|
-
kind: asset.kind,
|
|
9267
|
-
sourcePath: packPath,
|
|
9268
|
-
...typeof asset.name === "string" ? { name: asset.name } : {}
|
|
9269
|
-
});
|
|
9788
|
+
for (const declaration of result.value.declarations.values()) {
|
|
9789
|
+
if (declaration.format !== "meta.json") continue;
|
|
9790
|
+
const sourcePath = declaration.sourcePath;
|
|
9791
|
+
const assets = declaration.value.subAssets;
|
|
9792
|
+
for (const asset of assets) {
|
|
9793
|
+
if (!isRecord3(asset) || typeof asset.guid !== "string" || typeof asset.kind !== "string") {
|
|
9794
|
+
continue;
|
|
9270
9795
|
}
|
|
9796
|
+
const name = typeof asset.name === "string" ? asset.name : typeof asset.sourceKey === "string" ? asset.sourceKey : void 0;
|
|
9797
|
+
entries.push({
|
|
9798
|
+
guid: asset.guid,
|
|
9799
|
+
kind: asset.kind,
|
|
9800
|
+
sourcePath,
|
|
9801
|
+
...name === void 0 ? {} : { name }
|
|
9802
|
+
});
|
|
9271
9803
|
}
|
|
9272
9804
|
}
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
|
|
9805
|
+
const names = /* @__PURE__ */ new Map();
|
|
9806
|
+
for (const declaration of result.value.declarations.values()) {
|
|
9807
|
+
if (declaration.format !== "pack.json") continue;
|
|
9808
|
+
if (declaration.value.schemaVersion === "3.0.0") {
|
|
9809
|
+
for (const [sourceKey, asset] of Object.entries(declaration.value.assets ?? {})) {
|
|
9810
|
+
if (isRecord3(asset) && typeof asset.name === "string") {
|
|
9811
|
+
names.set(`${declaration.sourcePath}:${sourceKey}`, asset.name);
|
|
9812
|
+
}
|
|
9813
|
+
}
|
|
9279
9814
|
continue;
|
|
9280
9815
|
}
|
|
9281
|
-
const
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
if (typeof sub.guid === "string" && typeof sub.kind === "string") {
|
|
9285
|
-
const name = typeof sub.name === "string" ? sub.name : typeof sub.sourceKey === "string" ? sub.sourceKey : void 0;
|
|
9286
|
-
entries.push({
|
|
9287
|
-
guid: sub.guid,
|
|
9288
|
-
kind: sub.kind,
|
|
9289
|
-
sourcePath: metaPath,
|
|
9290
|
-
...name === void 0 ? {} : { name }
|
|
9291
|
-
});
|
|
9816
|
+
for (const asset of declaration.value.assets) {
|
|
9817
|
+
if (typeof asset.name === "string") {
|
|
9818
|
+
names.set(`${declaration.sourcePath}:${asset.guid.toLowerCase()}`, asset.name);
|
|
9292
9819
|
}
|
|
9293
9820
|
}
|
|
9294
9821
|
}
|
|
9295
|
-
for (const
|
|
9296
|
-
const
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9305
|
-
|
|
9306
|
-
const firstByGuid = /* @__PURE__ */ new Map();
|
|
9307
|
-
for (const entry of entries) {
|
|
9308
|
-
const guid = entry.guid.toLowerCase();
|
|
9309
|
-
const first = firstByGuid.get(guid);
|
|
9310
|
-
if (first !== void 0) {
|
|
9311
|
-
emitError2(ctx, {
|
|
9312
|
-
code: "pack-guid-collision",
|
|
9313
|
-
expected: "one author declaration per GUID across Meta, Pack v2, and ScriptablePack sources",
|
|
9314
|
-
hint: "allocate a new durable GUID through the asset authoring gateway, then rerun verify",
|
|
9315
|
-
detail: { guid, paths: [first.sourcePath, entry.sourcePath] }
|
|
9316
|
-
});
|
|
9317
|
-
return { ok: false };
|
|
9318
|
-
}
|
|
9319
|
-
firstByGuid.set(guid, entry);
|
|
9822
|
+
for (const inventoryEntry of result.value.inventory) {
|
|
9823
|
+
const declaration = result.value.declarations.get(inventoryEntry.sourcePath);
|
|
9824
|
+
const namedByKey = inventoryEntry.sourceKey === void 0 ? names.get(`${inventoryEntry.sourcePath}:${inventoryEntry.guid.toLowerCase()}`) : names.get(`${inventoryEntry.sourcePath}:${inventoryEntry.sourceKey}`);
|
|
9825
|
+
const name = namedByKey ?? names.get(`${inventoryEntry.sourcePath}:${inventoryEntry.guid.toLowerCase()}`);
|
|
9826
|
+
entries.push({
|
|
9827
|
+
guid: inventoryEntry.guid,
|
|
9828
|
+
kind: inventoryEntry.kind,
|
|
9829
|
+
sourcePath: inventoryEntry.sourcePath,
|
|
9830
|
+
...name === void 0 ? {} : { name },
|
|
9831
|
+
...declaration?.format === "pack.json" && declaration.value.schemaVersion === "3.0.0" && inventoryEntry.sourceKey !== void 0 && name === void 0 ? { name: inventoryEntry.sourceKey } : {}
|
|
9832
|
+
});
|
|
9320
9833
|
}
|
|
9834
|
+
entries.sort(
|
|
9835
|
+
(left, right) => `${left.sourcePath}:${left.guid}`.localeCompare(`${right.sourcePath}:${right.guid}`)
|
|
9836
|
+
);
|
|
9321
9837
|
return { ok: true, value: entries };
|
|
9322
9838
|
}
|
|
9323
9839
|
function helpBody() {
|
|
@@ -9400,9 +9916,11 @@ async function runMeta(rest, ctx) {
|
|
|
9400
9916
|
});
|
|
9401
9917
|
}
|
|
9402
9918
|
const cwd = ctx.cwd ?? process.cwd();
|
|
9403
|
-
const loaded = await
|
|
9919
|
+
const loaded = await loadParameterizedScriptablePack(absolutePath(source, cwd), {
|
|
9920
|
+
metadataOnly: true
|
|
9921
|
+
});
|
|
9404
9922
|
if (!loaded.ok) return emitError2(ctx, loaded.error);
|
|
9405
|
-
ctx.stdoutWrite(JSON.stringify(
|
|
9923
|
+
ctx.stdoutWrite(JSON.stringify(projectParameterizedPackMeta(loaded.value, source)));
|
|
9406
9924
|
return 0;
|
|
9407
9925
|
}
|
|
9408
9926
|
async function runRecoveryCommand(operation, rest, ctx) {
|
|
@@ -9569,13 +10087,13 @@ async function readJson(path, ctx) {
|
|
|
9569
10087
|
}
|
|
9570
10088
|
}
|
|
9571
10089
|
function catalogRows(value) {
|
|
9572
|
-
if (Array.isArray(value)) return value.filter(
|
|
9573
|
-
if (!
|
|
9574
|
-
return value.entries.filter(
|
|
10090
|
+
if (Array.isArray(value)) return value.filter(isRecord3);
|
|
10091
|
+
if (!isRecord3(value) || !Array.isArray(value.entries)) return void 0;
|
|
10092
|
+
return value.entries.filter(isRecord3);
|
|
9575
10093
|
}
|
|
9576
10094
|
function packagePath(projectRoot, packageUrl) {
|
|
9577
|
-
const
|
|
9578
|
-
return resolve(projectRoot,
|
|
10095
|
+
const relative2 = packageUrl.replace(/^\/+/, "");
|
|
10096
|
+
return resolve(projectRoot, relative2);
|
|
9579
10097
|
}
|
|
9580
10098
|
function artifactInputs(pack, packagePathValue) {
|
|
9581
10099
|
return Promise.all(
|