@forgeax/engine-pack 0.1.31 → 0.1.33
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 +2 -2
- package/dist/build.d.ts +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.mjs +252 -22
- package/dist/build.mjs.map +1 -1
- package/dist/cli-asset.d.ts +63 -0
- package/dist/cli-asset.d.ts.map +1 -1
- package/dist/cli-asset.mjs +142 -4
- package/dist/cli-asset.mjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/native-cooker-registry.d.ts.map +1 -1
- package/dist/native-cooker.mjs +13 -1
- package/dist/native-cooker.mjs.map +1 -1
- package/dist/pack-authoring-node.d.ts +6 -0
- package/dist/pack-authoring-node.d.ts.map +1 -1
- package/dist/pack-authoring-node.mjs +230 -16
- package/dist/pack-authoring-node.mjs.map +1 -1
- package/dist/pack-authoring.d.ts +26 -0
- package/dist/pack-authoring.d.ts.map +1 -1
- package/dist/pack-authoring.mjs.map +1 -1
- package/dist/runtime-publication.d.ts +8 -0
- package/dist/runtime-publication.d.ts.map +1 -1
- package/dist/scanner.d.ts +1 -1
- package/dist/scanner.mjs +5 -5
- package/dist/scanner.mjs.map +1 -1
- package/dist/scriptable-pack-node.mjs.map +1 -1
- package/dist/scriptable-pack.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/cli.unit.test.ts +87 -0
- package/src/__tests__/native-cooker-registry.test.ts +16 -0
- package/src/__tests__/pack-authoring-gateway.unit.test.ts +120 -1
- package/src/__tests__/pack.unit.test.ts +6 -6
- package/src/__tests__/runtime-publication.unit.test.ts +27 -1
- package/src/build.ts +2 -0
- package/src/cli-asset.ts +227 -5
- package/src/native-cooker-registry.ts +14 -1
- package/src/pack-authoring-node.ts +278 -13
- package/src/pack-authoring.ts +26 -0
- package/src/runtime-publication.ts +44 -0
- package/src/scanner.ts +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-cooker-registry.d.ts","sourceRoot":"","sources":["../src/native-cooker-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,UAAU,EACV,eAAe,EACf,WAAW,EACX,MAAM,EACP,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACjE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACpD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,6BAA6B,CAAC,CAAC,GAAG,OAAO;IACxD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACpE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,QAAQ,CAAC,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5F;AAED,MAAM,WAAW,2BAA2B,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,6BAA6B,CAAC,CAAC,CAAC;IAChG,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;IAC3C,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"native-cooker-registry.d.ts","sourceRoot":"","sources":["../src/native-cooker-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/native-cooker.mjs
CHANGED
|
@@ -34,6 +34,18 @@ function failure(key, detail) {
|
|
|
34
34
|
function transactionFailure(key, reason) {
|
|
35
35
|
return failure(key, { guid: "unknown", producer: reason });
|
|
36
36
|
}
|
|
37
|
+
function thrownProducer(error) {
|
|
38
|
+
if (error instanceof Error) return error.message;
|
|
39
|
+
if (typeof error === "string") return error;
|
|
40
|
+
if (error !== null && typeof error === "object") {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.stringify(error);
|
|
43
|
+
} catch {
|
|
44
|
+
return Object.prototype.toString.call(error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return String(error);
|
|
48
|
+
}
|
|
37
49
|
function recovered(key, previous) {
|
|
38
50
|
return {
|
|
39
51
|
...previous,
|
|
@@ -71,7 +83,7 @@ var NativeCookerRegistry = class {
|
|
|
71
83
|
const typedInput = cooker.discover === void 0 ? input : await cooker.discover(input);
|
|
72
84
|
draft = await cooker.cook(typedInput);
|
|
73
85
|
} catch (error) {
|
|
74
|
-
return failure(key, { guid: "unknown", producer:
|
|
86
|
+
return failure(key, { guid: "unknown", producer: thrownProducer(error) });
|
|
75
87
|
}
|
|
76
88
|
if (draft.guid.length === 0 || draft.inputFingerprint.length === 0 || !Array.isArray(draft.refs) || typeof draft.payload !== "object" || draft.payload === null || typeof draft.artifacts !== "object" || draft.artifacts === null || Object.entries(draft.artifacts).some(
|
|
77
89
|
([, artifact]) => artifact === null || typeof artifact !== "object" || typeof artifact.mediaType !== "string" || artifact.mediaType.length === 0 || !(artifact.bytes instanceof Uint8Array)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/native-cooker-registry.ts"],"names":[],"mappings":"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","file":"native-cooker.mjs","sourcesContent":["import { createHash } from 'node:crypto';\nimport type {\n ArtifactDescriptor,\n AssetCodec,\n AssetStageError,\n CookProduct,\n Result,\n} from '@forgeax/engine-types';\nimport { err, ok } from '@forgeax/engine-types';\n\nexport interface NativeCookArtifact {\n readonly mediaType: string;\n readonly assetCodec?: AssetCodec;\n readonly bytes: Uint8Array;\n}\n\nexport interface NativeCookDraft<P = unknown> {\n readonly guid: string;\n readonly payload: P;\n readonly refs: readonly string[];\n readonly artifacts: Readonly<Record<string, NativeCookArtifact>>;\n readonly inputFingerprint: string;\n readonly sourceDependencies?: readonly string[];\n}\n\nexport interface NativeCooker<P = unknown, I = unknown> {\n readonly key: string;\n readonly discover?: (input: unknown) => I | Promise<I>;\n cook(input: I): NativeCookDraft<P> | Promise<NativeCookDraft<P>>;\n}\n\nexport interface NativeCookTransactionSnapshot<P = unknown> {\n readonly draft: NativeCookDraft<P>;\n readonly generation: number;\n}\n\nexport interface NativeCookTransactionOptions<P = unknown, I = unknown> {\n readonly key: string;\n readonly input: I;\n readonly previous?: NativeCookTransactionSnapshot<P>;\n readonly validate?: (draft: NativeCookDraft<P>) => string | undefined;\n readonly publish?: (draft: NativeCookDraft<P>, generation: number) => void | Promise<void>;\n}\n\nexport interface NativeCookTransactionResult<P = unknown> extends NativeCookTransactionSnapshot<P> {\n readonly status: 'committed' | 'recovered';\n readonly lastKnownGood: NativeCookDraft<P>;\n readonly candidateGeneration: number;\n readonly lastKnownGoodGeneration: number;\n readonly recoveryHint?: string;\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value instanceof Uint8Array) return Buffer.from(value).toString('base64');\n if (Array.isArray(value)) return value.map(canonicalize);\n if (typeof value !== 'object' || value === null) return value;\n return Object.fromEntries(\n Object.entries(value)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, canonicalize(nested)]),\n );\n}\n\nfunction digestDraft<P>(draft: NativeCookDraft<P>): string {\n const bytes = JSON.stringify(\n canonicalize({\n guid: draft.guid,\n payload: draft.payload,\n refs: draft.refs,\n artifacts: draft.artifacts,\n }),\n );\n return `sha256:${createHash('sha256').update(bytes).digest('hex')}`;\n}\n\ntype NativeCookErrorDetail = Extract<\n AssetStageError['detail'],\n { readonly guid: string; readonly producer: string }\n>;\n\nfunction failure(key: string, detail: NativeCookErrorDetail): Result<never, AssetStageError> {\n return err({\n stage: 'native-cook',\n code: 'native-cook-failed',\n expected: 'a registered native cooker to produce a complete draft',\n hint: 'register the cooker or repair its draft, then rerun recovery',\n detail,\n recovery: { action: `rerun native cooker ${key}`, retryable: true },\n });\n}\n\nfunction transactionFailure(key: string, reason: string): Result<never, AssetStageError> {\n return failure(key, { guid: 'unknown', producer: reason });\n}\n\nfunction recovered<P>(\n key: string,\n previous: NativeCookTransactionSnapshot<P>,\n): NativeCookTransactionResult<P> {\n return {\n ...previous,\n status: 'recovered',\n lastKnownGood: previous.draft,\n candidateGeneration: previous.generation + 1,\n lastKnownGoodGeneration: previous.generation,\n recoveryHint: `repair ${key} and submit a new candidate generation`,\n };\n}\n\n/** Injectable build-time table for native authored Pack producers. */\nexport class NativeCookerRegistry {\n private readonly cookers = new Map<string, NativeCooker>();\n\n register(cooker: NativeCooker): void {\n if (typeof cooker.key !== 'string' || cooker.key.length === 0) {\n throw new TypeError('NativeCookerRegistry.register: key must be a non-empty string');\n }\n if (typeof cooker.cook !== 'function') {\n throw new TypeError(`NativeCookerRegistry.register: cooker ${cooker.key} must expose cook`);\n }\n this.cookers.set(cooker.key, cooker);\n }\n\n get(key: string): NativeCooker | undefined {\n return this.cookers.get(key);\n }\n\n registeredCookers(): readonly string[] {\n return [...this.cookers.keys()];\n }\n\n async runDraft<P = unknown, I = unknown>(\n key: string,\n input: I,\n ): Promise<Result<NativeCookDraft<P>, AssetStageError>> {\n const cooker = this.cookers.get(key) as NativeCooker<P, I> | undefined;\n if (cooker === undefined) {\n return failure(key, { guid: 'unknown', producer: key });\n }\n let draft: NativeCookDraft<P>;\n try {\n const typedInput = cooker.discover === undefined ? input : await cooker.discover(input);\n draft = await cooker.cook(typedInput);\n } catch (error) {\n return failure(key, { guid: 'unknown', producer: String(error) });\n }\n if (\n draft.guid.length === 0 ||\n draft.inputFingerprint.length === 0 ||\n !Array.isArray(draft.refs) ||\n typeof draft.payload !== 'object' ||\n draft.payload === null ||\n typeof draft.artifacts !== 'object' ||\n draft.artifacts === null ||\n Object.entries(draft.artifacts).some(\n ([, artifact]) =>\n artifact === null ||\n typeof artifact !== 'object' ||\n typeof artifact.mediaType !== 'string' ||\n artifact.mediaType.length === 0 ||\n !(artifact.bytes instanceof Uint8Array),\n )\n ) {\n return failure(key, { guid: draft.guid || 'unknown', producer: key });\n }\n return ok(draft);\n }\n\n async run<P = unknown, I = unknown>(\n key: string,\n input: I,\n ): Promise<Result<CookProduct<P>, AssetStageError>> {\n const draftResult = await this.runDraft<P, I>(key, input);\n if (!draftResult.ok) return draftResult;\n const draft = draftResult.value;\n const digest = digestDraft(draft);\n const artifacts: Record<string, ArtifactDescriptor> = {};\n for (const [path, artifact] of Object.entries(draft.artifacts)) {\n artifacts[path] = {\n path,\n mediaType: artifact.mediaType,\n ...(artifact.assetCodec === undefined ? {} : { assetCodec: artifact.assetCodec }),\n byteLength: artifact.bytes.byteLength,\n };\n }\n const receipt = {\n guid: draft.guid,\n origin: 'authoredPack' as const,\n status: 'succeeded' as const,\n inputFingerprint: draft.inputFingerprint,\n outputDigest: digest,\n };\n const product: CookProduct<P> = {\n guid: draft.guid,\n payload: draft.payload,\n refs: draft.refs,\n artifacts,\n digest,\n receipt,\n };\n return ok(product);\n }\n\n async runTransaction<P = unknown, I = unknown>(\n options: NativeCookTransactionOptions<P, I>,\n ): Promise<Result<NativeCookTransactionResult<P>, AssetStageError>> {\n const candidate = await this.runDraft<P, I>(options.key, options.input);\n if (!candidate.ok) {\n return options.previous === undefined\n ? candidate\n : ok(recovered(options.key, options.previous));\n }\n const invalidReason = options.validate?.(candidate.value);\n if (invalidReason !== undefined) {\n return options.previous === undefined\n ? transactionFailure(options.key, invalidReason)\n : ok(recovered(options.key, options.previous));\n }\n const generation = (options.previous?.generation ?? 0) + 1;\n try {\n await options.publish?.(candidate.value, generation);\n } catch {\n return options.previous === undefined\n ? transactionFailure(options.key, 'atomic producer publication failed')\n : ok(recovered(options.key, options.previous));\n }\n return ok({\n draft: candidate.value,\n generation,\n status: 'committed',\n lastKnownGood: candidate.value,\n candidateGeneration: generation,\n lastKnownGoodGeneration: generation,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/native-cooker-registry.ts"],"names":[],"mappings":"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","file":"native-cooker.mjs","sourcesContent":["import { createHash } from 'node:crypto';\nimport type {\n ArtifactDescriptor,\n AssetCodec,\n AssetStageError,\n CookProduct,\n Result,\n} from '@forgeax/engine-types';\nimport { err, ok } from '@forgeax/engine-types';\n\nexport interface NativeCookArtifact {\n readonly mediaType: string;\n readonly assetCodec?: AssetCodec;\n readonly bytes: Uint8Array;\n}\n\nexport interface NativeCookDraft<P = unknown> {\n readonly guid: string;\n readonly payload: P;\n readonly refs: readonly string[];\n readonly artifacts: Readonly<Record<string, NativeCookArtifact>>;\n readonly inputFingerprint: string;\n readonly sourceDependencies?: readonly string[];\n}\n\nexport interface NativeCooker<P = unknown, I = unknown> {\n readonly key: string;\n readonly discover?: (input: unknown) => I | Promise<I>;\n cook(input: I): NativeCookDraft<P> | Promise<NativeCookDraft<P>>;\n}\n\nexport interface NativeCookTransactionSnapshot<P = unknown> {\n readonly draft: NativeCookDraft<P>;\n readonly generation: number;\n}\n\nexport interface NativeCookTransactionOptions<P = unknown, I = unknown> {\n readonly key: string;\n readonly input: I;\n readonly previous?: NativeCookTransactionSnapshot<P>;\n readonly validate?: (draft: NativeCookDraft<P>) => string | undefined;\n readonly publish?: (draft: NativeCookDraft<P>, generation: number) => void | Promise<void>;\n}\n\nexport interface NativeCookTransactionResult<P = unknown> extends NativeCookTransactionSnapshot<P> {\n readonly status: 'committed' | 'recovered';\n readonly lastKnownGood: NativeCookDraft<P>;\n readonly candidateGeneration: number;\n readonly lastKnownGoodGeneration: number;\n readonly recoveryHint?: string;\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value instanceof Uint8Array) return Buffer.from(value).toString('base64');\n if (Array.isArray(value)) return value.map(canonicalize);\n if (typeof value !== 'object' || value === null) return value;\n return Object.fromEntries(\n Object.entries(value)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, canonicalize(nested)]),\n );\n}\n\nfunction digestDraft<P>(draft: NativeCookDraft<P>): string {\n const bytes = JSON.stringify(\n canonicalize({\n guid: draft.guid,\n payload: draft.payload,\n refs: draft.refs,\n artifacts: draft.artifacts,\n }),\n );\n return `sha256:${createHash('sha256').update(bytes).digest('hex')}`;\n}\n\ntype NativeCookErrorDetail = Extract<\n AssetStageError['detail'],\n { readonly guid: string; readonly producer: string }\n>;\n\nfunction failure(key: string, detail: NativeCookErrorDetail): Result<never, AssetStageError> {\n return err({\n stage: 'native-cook',\n code: 'native-cook-failed',\n expected: 'a registered native cooker to produce a complete draft',\n hint: 'register the cooker or repair its draft, then rerun recovery',\n detail,\n recovery: { action: `rerun native cooker ${key}`, retryable: true },\n });\n}\n\nfunction transactionFailure(key: string, reason: string): Result<never, AssetStageError> {\n return failure(key, { guid: 'unknown', producer: reason });\n}\n\nfunction thrownProducer(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (typeof error === 'string') return error;\n if (error !== null && typeof error === 'object') {\n try {\n return JSON.stringify(error);\n } catch {\n return Object.prototype.toString.call(error);\n }\n }\n return String(error);\n}\n\nfunction recovered<P>(\n key: string,\n previous: NativeCookTransactionSnapshot<P>,\n): NativeCookTransactionResult<P> {\n return {\n ...previous,\n status: 'recovered',\n lastKnownGood: previous.draft,\n candidateGeneration: previous.generation + 1,\n lastKnownGoodGeneration: previous.generation,\n recoveryHint: `repair ${key} and submit a new candidate generation`,\n };\n}\n\n/** Injectable build-time table for native authored Pack producers. */\nexport class NativeCookerRegistry {\n private readonly cookers = new Map<string, NativeCooker>();\n\n register(cooker: NativeCooker): void {\n if (typeof cooker.key !== 'string' || cooker.key.length === 0) {\n throw new TypeError('NativeCookerRegistry.register: key must be a non-empty string');\n }\n if (typeof cooker.cook !== 'function') {\n throw new TypeError(`NativeCookerRegistry.register: cooker ${cooker.key} must expose cook`);\n }\n this.cookers.set(cooker.key, cooker);\n }\n\n get(key: string): NativeCooker | undefined {\n return this.cookers.get(key);\n }\n\n registeredCookers(): readonly string[] {\n return [...this.cookers.keys()];\n }\n\n async runDraft<P = unknown, I = unknown>(\n key: string,\n input: I,\n ): Promise<Result<NativeCookDraft<P>, AssetStageError>> {\n const cooker = this.cookers.get(key) as NativeCooker<P, I> | undefined;\n if (cooker === undefined) {\n return failure(key, { guid: 'unknown', producer: key });\n }\n let draft: NativeCookDraft<P>;\n try {\n const typedInput = cooker.discover === undefined ? input : await cooker.discover(input);\n draft = await cooker.cook(typedInput);\n } catch (error) {\n return failure(key, { guid: 'unknown', producer: thrownProducer(error) });\n }\n if (\n draft.guid.length === 0 ||\n draft.inputFingerprint.length === 0 ||\n !Array.isArray(draft.refs) ||\n typeof draft.payload !== 'object' ||\n draft.payload === null ||\n typeof draft.artifacts !== 'object' ||\n draft.artifacts === null ||\n Object.entries(draft.artifacts).some(\n ([, artifact]) =>\n artifact === null ||\n typeof artifact !== 'object' ||\n typeof artifact.mediaType !== 'string' ||\n artifact.mediaType.length === 0 ||\n !(artifact.bytes instanceof Uint8Array),\n )\n ) {\n return failure(key, { guid: draft.guid || 'unknown', producer: key });\n }\n return ok(draft);\n }\n\n async run<P = unknown, I = unknown>(\n key: string,\n input: I,\n ): Promise<Result<CookProduct<P>, AssetStageError>> {\n const draftResult = await this.runDraft<P, I>(key, input);\n if (!draftResult.ok) return draftResult;\n const draft = draftResult.value;\n const digest = digestDraft(draft);\n const artifacts: Record<string, ArtifactDescriptor> = {};\n for (const [path, artifact] of Object.entries(draft.artifacts)) {\n artifacts[path] = {\n path,\n mediaType: artifact.mediaType,\n ...(artifact.assetCodec === undefined ? {} : { assetCodec: artifact.assetCodec }),\n byteLength: artifact.bytes.byteLength,\n };\n }\n const receipt = {\n guid: draft.guid,\n origin: 'authoredPack' as const,\n status: 'succeeded' as const,\n inputFingerprint: draft.inputFingerprint,\n outputDigest: digest,\n };\n const product: CookProduct<P> = {\n guid: draft.guid,\n payload: draft.payload,\n refs: draft.refs,\n artifacts,\n digest,\n receipt,\n };\n return ok(product);\n }\n\n async runTransaction<P = unknown, I = unknown>(\n options: NativeCookTransactionOptions<P, I>,\n ): Promise<Result<NativeCookTransactionResult<P>, AssetStageError>> {\n const candidate = await this.runDraft<P, I>(options.key, options.input);\n if (!candidate.ok) {\n return options.previous === undefined\n ? candidate\n : ok(recovered(options.key, options.previous));\n }\n const invalidReason = options.validate?.(candidate.value);\n if (invalidReason !== undefined) {\n return options.previous === undefined\n ? transactionFailure(options.key, invalidReason)\n : ok(recovered(options.key, options.previous));\n }\n const generation = (options.previous?.generation ?? 0) + 1;\n try {\n await options.publish?.(candidate.value, generation);\n } catch {\n return options.previous === undefined\n ? transactionFailure(options.key, 'atomic producer publication failed')\n : ok(recovered(options.key, options.previous));\n }\n return ok({\n draft: candidate.value,\n generation,\n status: 'committed',\n lastKnownGood: candidate.value,\n candidateGeneration: generation,\n lastKnownGoodGeneration: generation,\n });\n }\n}\n"]}
|
|
@@ -16,6 +16,12 @@ export interface FileSystemPackAuthoringOptions {
|
|
|
16
16
|
readonly scanRoots?: readonly string[];
|
|
17
17
|
/** Current-generation rows only; this callback is never called by mutations. */
|
|
18
18
|
readonly materialized?: () => readonly PackAuthoringMaterializedAsset[] | Promise<readonly PackAuthoringMaterializedAsset[]>;
|
|
19
|
+
/**
|
|
20
|
+
* GUIDs published by non-Pack producers in the same Catalog projection.
|
|
21
|
+
* They are accepted as dependency identities but never exposed as Pack
|
|
22
|
+
* authoring assets.
|
|
23
|
+
*/
|
|
24
|
+
readonly additionalKnownGuids?: () => readonly string[] | Promise<readonly string[]>;
|
|
19
25
|
/** Build owner callback; the gateway itself does not own DDC or Catalog state. */
|
|
20
26
|
readonly rebuild?: (sourcePath: string, mode: 'rebuild' | 'cold-cook') => Promise<Result<unknown, PackAuthoringError>>;
|
|
21
27
|
/** Injection point for hosts that already own a validated Source Index. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-authoring-node.d.ts","sourceRoot":"","sources":["../src/pack-authoring-node.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgC,MAAM,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"pack-authoring-node.d.ts","sourceRoot":"","sources":["../src/pack-authoring-node.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgC,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIlF,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,wBAAwB,EAE7B,KAAK,4BAA4B,EASlC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,gFAAgF;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,MACpB,SAAS,8BAA8B,EAAE,GACzC,OAAO,CAAC,SAAS,8BAA8B,EAAE,CAAC,CAAC;IACvD;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACrF,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,GAAG,WAAW,KAC1B,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAClD,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;CACpE;AAknED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,8BAA8B,GACtC,wBAAwB,CAAC,4BAA4B,CAAC,CAExD;AAED,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,8BAA8B,GACtC,wBAAwB,CAAC,4BAA4B,CAAC,CAExD"}
|
|
@@ -9499,6 +9499,7 @@ async function scanInventory(roots, opts = {}) {
|
|
|
9499
9499
|
}
|
|
9500
9500
|
|
|
9501
9501
|
// src/pack-authoring-node.ts
|
|
9502
|
+
var VERIFY_PROVENANCE_LIMIT = 256;
|
|
9502
9503
|
function isRecord3(value) {
|
|
9503
9504
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9504
9505
|
}
|
|
@@ -9795,6 +9796,54 @@ async function readMaterialized(options, operation) {
|
|
|
9795
9796
|
);
|
|
9796
9797
|
return ok(materialized);
|
|
9797
9798
|
}
|
|
9799
|
+
async function readAdditionalKnownGuids(options, operation) {
|
|
9800
|
+
let rawGuids;
|
|
9801
|
+
try {
|
|
9802
|
+
rawGuids = await options.additionalKnownGuids?.() ?? [];
|
|
9803
|
+
} catch (cause) {
|
|
9804
|
+
return err(
|
|
9805
|
+
makeError(
|
|
9806
|
+
"pack-parameter-invalid",
|
|
9807
|
+
"the additionalKnownGuids callback to return current Catalog GUIDs",
|
|
9808
|
+
"repair the build-owner Catalog projection callback, then retry the Pack operation",
|
|
9809
|
+
{
|
|
9810
|
+
requestId: operation.requestId,
|
|
9811
|
+
cause: cause instanceof Error ? cause.message : String(cause)
|
|
9812
|
+
}
|
|
9813
|
+
)
|
|
9814
|
+
);
|
|
9815
|
+
}
|
|
9816
|
+
if (!Array.isArray(rawGuids)) {
|
|
9817
|
+
return err(
|
|
9818
|
+
makeError(
|
|
9819
|
+
"pack-parameter-invalid",
|
|
9820
|
+
"additionalKnownGuids to be an array of AssetGuid strings",
|
|
9821
|
+
"repair the build-owner Catalog projection before querying Pack authoring",
|
|
9822
|
+
{ requestId: operation.requestId, actual: typeof rawGuids }
|
|
9823
|
+
)
|
|
9824
|
+
);
|
|
9825
|
+
}
|
|
9826
|
+
const guids = [];
|
|
9827
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9828
|
+
for (const candidate of rawGuids) {
|
|
9829
|
+
if (typeof candidate !== "string" || !isValidAssetGuidString(candidate)) {
|
|
9830
|
+
return err(
|
|
9831
|
+
makeError(
|
|
9832
|
+
"pack-parameter-invalid",
|
|
9833
|
+
"additionalKnownGuids to contain valid AssetGuid strings",
|
|
9834
|
+
"repair the build-owner Catalog projection before querying Pack authoring",
|
|
9835
|
+
{ requestId: operation.requestId, guid: candidate }
|
|
9836
|
+
)
|
|
9837
|
+
);
|
|
9838
|
+
}
|
|
9839
|
+
const guid = candidate.toLowerCase();
|
|
9840
|
+
if (!seen.has(guid)) {
|
|
9841
|
+
seen.add(guid);
|
|
9842
|
+
guids.push(guid);
|
|
9843
|
+
}
|
|
9844
|
+
}
|
|
9845
|
+
return ok(guids);
|
|
9846
|
+
}
|
|
9798
9847
|
async function createSnapshot(options, operation) {
|
|
9799
9848
|
const scanned = options.inventory === void 0 ? await scanInventory(scanRoots(options)) : await options.inventory();
|
|
9800
9849
|
if (!scanned.ok) return err(scanFailure(operation, scanned.error));
|
|
@@ -9850,6 +9899,8 @@ async function createSnapshot(options, operation) {
|
|
|
9850
9899
|
}
|
|
9851
9900
|
const materializedResult = await readMaterialized(options, operation);
|
|
9852
9901
|
if (!materializedResult.ok) return materializedResult;
|
|
9902
|
+
const additionalKnownGuidsResult = await readAdditionalKnownGuids(options, operation);
|
|
9903
|
+
if (!additionalKnownGuidsResult.ok) return additionalKnownGuidsResult;
|
|
9853
9904
|
const materialized = materializedResult.value;
|
|
9854
9905
|
const guidOwners = /* @__PURE__ */ new Map();
|
|
9855
9906
|
const directPairs = /* @__PURE__ */ new Set();
|
|
@@ -9901,7 +9952,8 @@ async function createSnapshot(options, operation) {
|
|
|
9901
9952
|
const knownGuids = /* @__PURE__ */ new Set([
|
|
9902
9953
|
...scanned.value.inventory.map((entry) => entry.guid.toLowerCase()),
|
|
9903
9954
|
...directAssets.map((asset) => asset.guid),
|
|
9904
|
-
...materialized.map((asset) => asset.guid)
|
|
9955
|
+
...materialized.map((asset) => asset.guid),
|
|
9956
|
+
...additionalKnownGuidsResult.value
|
|
9905
9957
|
]);
|
|
9906
9958
|
return ok({ inventory: scanned.value, subjects, directAssets, materialized, knownGuids });
|
|
9907
9959
|
}
|
|
@@ -10042,6 +10094,15 @@ async function inspectAsset(gameRoot, snapshot, operation) {
|
|
|
10042
10094
|
const selected = subjectFor(gameRoot, snapshot, operation);
|
|
10043
10095
|
if (!selected.ok) return selected;
|
|
10044
10096
|
const subject = selected.value;
|
|
10097
|
+
const source = await readConfined({ gameRoot }, operation, subject.relativePath);
|
|
10098
|
+
if (!source.ok) return source;
|
|
10099
|
+
const inspectedSource = {
|
|
10100
|
+
...sourceResult(subject, operation),
|
|
10101
|
+
revision: source.value.revision,
|
|
10102
|
+
...subject.format === "source" ? {
|
|
10103
|
+
assets: snapshot.materialized.filter((asset) => asset.packageId === packageKey(subject.packageId)).map((asset) => ({ ...asset }))
|
|
10104
|
+
} : {}
|
|
10105
|
+
};
|
|
10045
10106
|
if (operation.sourceKey !== void 0) {
|
|
10046
10107
|
if (!isValidPackSourceKey(operation.sourceKey)) {
|
|
10047
10108
|
return err(
|
|
@@ -10074,7 +10135,7 @@ async function inspectAsset(gameRoot, snapshot, operation) {
|
|
|
10074
10135
|
(candidate) => candidate.packageId === packageKey(subject.packageId) && candidate.sourceKey === operation.sourceKey
|
|
10075
10136
|
);
|
|
10076
10137
|
return ok({
|
|
10077
|
-
...
|
|
10138
|
+
...inspectedSource,
|
|
10078
10139
|
sourceKey: asset.sourceKey,
|
|
10079
10140
|
guid: asset.guid,
|
|
10080
10141
|
kind: asset.kind,
|
|
@@ -10087,7 +10148,7 @@ async function inspectAsset(gameRoot, snapshot, operation) {
|
|
|
10087
10148
|
(candidate) => candidate.packageId === packageKey(subject.packageId) && candidate.sourceKey === operation.sourceKey
|
|
10088
10149
|
);
|
|
10089
10150
|
return ok({
|
|
10090
|
-
...
|
|
10151
|
+
...inspectedSource,
|
|
10091
10152
|
sourceKey: operation.sourceKey,
|
|
10092
10153
|
guid,
|
|
10093
10154
|
...materialized === void 0 ? { status: "identity" } : {
|
|
@@ -10111,7 +10172,7 @@ async function inspectAsset(gameRoot, snapshot, operation) {
|
|
|
10111
10172
|
const resolved = await resolveInstance(snapshot, subject);
|
|
10112
10173
|
if (!resolved.ok) return resolved;
|
|
10113
10174
|
return ok({
|
|
10114
|
-
...
|
|
10175
|
+
...inspectedSource,
|
|
10115
10176
|
parameters: resolved.value.parameters.map((parameter) => ({
|
|
10116
10177
|
name: parameter.name,
|
|
10117
10178
|
type: parameter.type,
|
|
@@ -10125,7 +10186,7 @@ async function inspectAsset(gameRoot, snapshot, operation) {
|
|
|
10125
10186
|
parentChain: resolved.value.parentChain
|
|
10126
10187
|
});
|
|
10127
10188
|
}
|
|
10128
|
-
return ok(
|
|
10189
|
+
return ok(inspectedSource);
|
|
10129
10190
|
}
|
|
10130
10191
|
function listAssets(snapshot, operation) {
|
|
10131
10192
|
const assets = snapshotAssets(snapshot).map((asset) => ({
|
|
@@ -10408,7 +10469,164 @@ async function resolveAsset(gameRoot, snapshot, operation) {
|
|
|
10408
10469
|
}
|
|
10409
10470
|
});
|
|
10410
10471
|
}
|
|
10411
|
-
|
|
10472
|
+
function verificationSourceFormat(gameRoot, sourcePath, fallback = "pack.ts") {
|
|
10473
|
+
if (sourcePath === void 0) return fallback;
|
|
10474
|
+
const absolute = resolve(gameRoot, sourcePath);
|
|
10475
|
+
if (absolute.endsWith(".meta.json")) return "meta.json";
|
|
10476
|
+
if (absolute.endsWith(".pack.json")) return "pack.json";
|
|
10477
|
+
if (absolute.endsWith(".pack.ts")) return "pack.ts";
|
|
10478
|
+
return fallback;
|
|
10479
|
+
}
|
|
10480
|
+
function verificationAuthorFacts(snapshot, entry) {
|
|
10481
|
+
const declaration = snapshot.inventory.declarations.get(entry.sourcePath);
|
|
10482
|
+
if (declaration?.format === "meta.json") {
|
|
10483
|
+
const asset = declaration.value.subAssets.find(
|
|
10484
|
+
(candidate) => candidate.guid.toLowerCase() === entry.guid.toLowerCase()
|
|
10485
|
+
);
|
|
10486
|
+
return {
|
|
10487
|
+
...asset?.name === void 0 && asset?.sourceKey === void 0 ? {} : { name: asset.name ?? asset.sourceKey },
|
|
10488
|
+
dependencies: []
|
|
10489
|
+
};
|
|
10490
|
+
}
|
|
10491
|
+
if (declaration?.format === "pack.json") {
|
|
10492
|
+
if (declaration.value.schemaVersion === "3.0.0") {
|
|
10493
|
+
const parsed = parsePackSourceJson(declaration.value);
|
|
10494
|
+
if (parsed.ok && parsed.value.format === "direct" && entry.sourceKey !== void 0) {
|
|
10495
|
+
const asset = parsed.value.assets[entry.sourceKey];
|
|
10496
|
+
return {
|
|
10497
|
+
...asset?.name === void 0 ? {} : { name: asset.name },
|
|
10498
|
+
dependencies: asset?.refs ?? []
|
|
10499
|
+
};
|
|
10500
|
+
}
|
|
10501
|
+
} else {
|
|
10502
|
+
const asset = declaration.value.assets.find(
|
|
10503
|
+
(candidate) => candidate.guid.toLowerCase() === entry.guid.toLowerCase()
|
|
10504
|
+
);
|
|
10505
|
+
return {
|
|
10506
|
+
...asset?.name === void 0 ? {} : { name: asset.name },
|
|
10507
|
+
dependencies: asset?.refs ?? []
|
|
10508
|
+
};
|
|
10509
|
+
}
|
|
10510
|
+
}
|
|
10511
|
+
return { dependencies: [] };
|
|
10512
|
+
}
|
|
10513
|
+
function verificationOutput(materialized, legacyPublished = false) {
|
|
10514
|
+
if (materialized !== void 0) {
|
|
10515
|
+
return {
|
|
10516
|
+
status: materialized.ready ? "produced" : "unknown",
|
|
10517
|
+
availability: materialized.ready ? "available" : "unknown",
|
|
10518
|
+
freshness: "unknown"
|
|
10519
|
+
};
|
|
10520
|
+
}
|
|
10521
|
+
if (legacyPublished) {
|
|
10522
|
+
return {
|
|
10523
|
+
status: "produced",
|
|
10524
|
+
availability: "unknown",
|
|
10525
|
+
freshness: "unknown"
|
|
10526
|
+
// A legacy Pack row is a validated published declaration. The bytes
|
|
10527
|
+
// remain outside this read-only gateway, so availability is unknown.
|
|
10528
|
+
};
|
|
10529
|
+
}
|
|
10530
|
+
return { status: "unproduced", availability: "unknown", freshness: "unknown" };
|
|
10531
|
+
}
|
|
10532
|
+
function createGatewayVerificationReport(gameRoot, snapshot) {
|
|
10533
|
+
const materializedByGuid = new Map(
|
|
10534
|
+
snapshot.materialized.map((asset) => [asset.guid.toLowerCase(), asset])
|
|
10535
|
+
);
|
|
10536
|
+
const rows = /* @__PURE__ */ new Map();
|
|
10537
|
+
for (const entry of snapshot.inventory.inventory) {
|
|
10538
|
+
const declaration = snapshot.inventory.declarations.get(entry.sourcePath);
|
|
10539
|
+
const format = declaration?.format ?? verificationSourceFormat(gameRoot, entry.sourcePath);
|
|
10540
|
+
const facts = verificationAuthorFacts(snapshot, entry);
|
|
10541
|
+
const materialized = materializedByGuid.get(entry.guid.toLowerCase());
|
|
10542
|
+
const legacyPublished = declaration?.format === "pack.json" && declaration.value.schemaVersion !== "3.0.0";
|
|
10543
|
+
rows.set(entry.guid.toLowerCase(), {
|
|
10544
|
+
guid: entry.guid,
|
|
10545
|
+
type: entry.kind,
|
|
10546
|
+
source: {
|
|
10547
|
+
path: entry.sourcePath,
|
|
10548
|
+
format,
|
|
10549
|
+
role: "author",
|
|
10550
|
+
...entry.sourceRevision === void 0 ? {} : { revision: entry.sourceRevision }
|
|
10551
|
+
},
|
|
10552
|
+
output: verificationOutput(materialized, legacyPublished),
|
|
10553
|
+
dependencies: facts.dependencies,
|
|
10554
|
+
producer: {
|
|
10555
|
+
state: materialized !== void 0 ? "published" : legacyPublished ? "published" : "not-run"
|
|
10556
|
+
},
|
|
10557
|
+
...facts.name === void 0 ? {} : { name: facts.name },
|
|
10558
|
+
...entry.sourceKey === void 0 ? {} : { sourceKey: entry.sourceKey },
|
|
10559
|
+
...entry.sourceIndex === void 0 ? {} : { sourceIndex: entry.sourceIndex }
|
|
10560
|
+
});
|
|
10561
|
+
}
|
|
10562
|
+
for (const asset of snapshot.materialized) {
|
|
10563
|
+
const key = asset.guid.toLowerCase();
|
|
10564
|
+
if (rows.has(key)) continue;
|
|
10565
|
+
const sourcePath = asset.sourcePath === void 0 ? void 0 : resolve(gameRoot, asset.sourcePath);
|
|
10566
|
+
const declaration = sourcePath === void 0 ? void 0 : snapshot.inventory.declarations.get(sourcePath);
|
|
10567
|
+
const format = declaration?.format ?? verificationSourceFormat(gameRoot, asset.sourcePath);
|
|
10568
|
+
rows.set(key, {
|
|
10569
|
+
guid: asset.guid,
|
|
10570
|
+
type: asset.kind,
|
|
10571
|
+
source: {
|
|
10572
|
+
path: sourcePath ?? `${asset.packageId}/${asset.sourceKey}`,
|
|
10573
|
+
format,
|
|
10574
|
+
role: "author",
|
|
10575
|
+
...declaration === void 0 ? {} : { revision: declaration.sourceRevision }
|
|
10576
|
+
},
|
|
10577
|
+
output: verificationOutput(asset),
|
|
10578
|
+
dependencies: asset.refs ?? [],
|
|
10579
|
+
producer: { state: "published" },
|
|
10580
|
+
sourceKey: asset.sourceKey
|
|
10581
|
+
});
|
|
10582
|
+
}
|
|
10583
|
+
const assets = [...rows.values()].sort(
|
|
10584
|
+
(left, right) => `${left.source.path}:${left.guid}`.localeCompare(`${right.source.path}:${right.guid}`)
|
|
10585
|
+
);
|
|
10586
|
+
const emitted = assets.slice(0, VERIFY_PROVENANCE_LIMIT);
|
|
10587
|
+
const sourcePaths = [...snapshot.inventory.declarations.keys()].sort();
|
|
10588
|
+
const scriptablePackSources = [...snapshot.inventory.declarations.values()].filter((declaration) => declaration.format === "pack.ts").sort((left, right) => left.sourcePath.localeCompare(right.sourcePath));
|
|
10589
|
+
const unmaterializedScriptable = scriptablePackSources.filter(
|
|
10590
|
+
(source) => !snapshot.materialized.some(
|
|
10591
|
+
(asset) => asset.packageId === source.value.packageId.toLowerCase() || asset.sourcePath !== void 0 && resolve(gameRoot, asset.sourcePath) === source.sourcePath
|
|
10592
|
+
)
|
|
10593
|
+
);
|
|
10594
|
+
return {
|
|
10595
|
+
schemaVersion: "asset-verification-v1",
|
|
10596
|
+
root: resolve(gameRoot),
|
|
10597
|
+
operation: "asset.verify",
|
|
10598
|
+
requestId: "gateway",
|
|
10599
|
+
scope: {
|
|
10600
|
+
sourceCount: sourcePaths.length,
|
|
10601
|
+
assetCount: assets.length,
|
|
10602
|
+
sourcePaths: sourcePaths.slice(0, VERIFY_PROVENANCE_LIMIT),
|
|
10603
|
+
omittedSourceCount: Math.max(0, sourcePaths.length - VERIFY_PROVENANCE_LIMIT),
|
|
10604
|
+
assetLimit: VERIFY_PROVENANCE_LIMIT,
|
|
10605
|
+
truncated: assets.length > VERIFY_PROVENANCE_LIMIT,
|
|
10606
|
+
scriptablePackSourceCount: scriptablePackSources.length,
|
|
10607
|
+
scriptablePackSources: unmaterializedScriptable.slice(0, VERIFY_PROVENANCE_LIMIT).map((source) => ({
|
|
10608
|
+
sourcePath: source.sourcePath,
|
|
10609
|
+
packageId: source.value.packageId,
|
|
10610
|
+
output: "unproduced",
|
|
10611
|
+
reason: "producer-not-run"
|
|
10612
|
+
})),
|
|
10613
|
+
omittedScriptablePackSourceCount: Math.max(
|
|
10614
|
+
0,
|
|
10615
|
+
unmaterializedScriptable.length - VERIFY_PROVENANCE_LIMIT
|
|
10616
|
+
)
|
|
10617
|
+
},
|
|
10618
|
+
assets: emitted,
|
|
10619
|
+
summary: {
|
|
10620
|
+
assetCount: assets.length,
|
|
10621
|
+
emittedAssetCount: emitted.length,
|
|
10622
|
+
materialCount: assets.filter((asset) => asset.type === "material").length,
|
|
10623
|
+
unproducedAssetCount: assets.filter((asset) => asset.output.status === "unproduced").length,
|
|
10624
|
+
unknownAssetCount: assets.filter((asset) => asset.output.status === "unknown").length,
|
|
10625
|
+
unmaterializedScriptablePackCount: unmaterializedScriptable.length
|
|
10626
|
+
}
|
|
10627
|
+
};
|
|
10628
|
+
}
|
|
10629
|
+
async function verify(gameRoot, snapshot, operation) {
|
|
10412
10630
|
for (const subject of snapshot.subjects.values()) {
|
|
10413
10631
|
if (subject.format === "instance") {
|
|
10414
10632
|
const resolved = await resolveInstance(snapshot, subject);
|
|
@@ -10453,14 +10671,8 @@ async function verify(snapshot, operation) {
|
|
|
10453
10671
|
);
|
|
10454
10672
|
}
|
|
10455
10673
|
}
|
|
10456
|
-
|
|
10457
|
-
|
|
10458
|
-
requestId: operation.requestId,
|
|
10459
|
-
snapshot: {
|
|
10460
|
-
sourceCount: snapshot.subjects.size,
|
|
10461
|
-
assetCount: snapshotAssets(snapshot).length
|
|
10462
|
-
}
|
|
10463
|
-
});
|
|
10674
|
+
const report = createGatewayVerificationReport(gameRoot, snapshot);
|
|
10675
|
+
return ok({ ...report, operation: operation.operation, requestId: operation.requestId });
|
|
10464
10676
|
}
|
|
10465
10677
|
function packageIdFromOperation(snapshot, operation) {
|
|
10466
10678
|
const value = operation.packageId === void 0 ? ok(PackageId.random()) : PackageId.parse(operation.packageId);
|
|
@@ -10560,7 +10772,8 @@ async function executeRaw(options, operation) {
|
|
|
10560
10772
|
if (!snapshot.ok) return snapshot;
|
|
10561
10773
|
if (operation.operation === "asset.resolve")
|
|
10562
10774
|
return resolveAsset(options.gameRoot, snapshot.value, operation);
|
|
10563
|
-
if (operation.operation === "asset.verify")
|
|
10775
|
+
if (operation.operation === "asset.verify")
|
|
10776
|
+
return verify(options.gameRoot, snapshot.value, operation);
|
|
10564
10777
|
if (operation.operation === "asset-source.create") {
|
|
10565
10778
|
const path = confinedPath(
|
|
10566
10779
|
options.gameRoot,
|
|
@@ -11073,7 +11286,8 @@ async function executeRaw(options, operation) {
|
|
|
11073
11286
|
refreshed.value.source,
|
|
11074
11287
|
selected.value.packageId,
|
|
11075
11288
|
{
|
|
11076
|
-
format: refreshed.value.relative.endsWith(".pack.json") ? "pack.json" : "pack.ts"
|
|
11289
|
+
format: refreshed.value.relative.endsWith(".pack.json") ? "pack.json" : "pack.ts",
|
|
11290
|
+
assets: refreshedSnapshot.value.materialized.filter((asset) => asset.packageId === packageKey(selected.value.packageId)).map((asset) => ({ ...asset }))
|
|
11077
11291
|
}
|
|
11078
11292
|
);
|
|
11079
11293
|
}
|