@forgeax/engine-pack 0.1.30 → 0.1.32

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.
Files changed (40) hide show
  1. package/README.md +2 -2
  2. package/dist/build.d.ts +1 -1
  3. package/dist/build.d.ts.map +1 -1
  4. package/dist/build.mjs +237 -17
  5. package/dist/build.mjs.map +1 -1
  6. package/dist/cli-asset.d.ts +63 -0
  7. package/dist/cli-asset.d.ts.map +1 -1
  8. package/dist/cli-asset.mjs +142 -4
  9. package/dist/cli-asset.mjs.map +1 -1
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/native-cooker-registry.d.ts.map +1 -1
  12. package/dist/native-cooker.mjs +13 -1
  13. package/dist/native-cooker.mjs.map +1 -1
  14. package/dist/pack-authoring-node.d.ts +6 -0
  15. package/dist/pack-authoring-node.d.ts.map +1 -1
  16. package/dist/pack-authoring-node.mjs +215 -11
  17. package/dist/pack-authoring-node.mjs.map +1 -1
  18. package/dist/pack-authoring.d.ts +26 -0
  19. package/dist/pack-authoring.d.ts.map +1 -1
  20. package/dist/pack-authoring.mjs.map +1 -1
  21. package/dist/runtime-publication.d.ts +8 -0
  22. package/dist/runtime-publication.d.ts.map +1 -1
  23. package/dist/scanner.d.ts +1 -1
  24. package/dist/scanner.mjs +5 -5
  25. package/dist/scanner.mjs.map +1 -1
  26. package/dist/scriptable-pack-node.mjs.map +1 -1
  27. package/dist/scriptable-pack.mjs.map +1 -1
  28. package/package.json +2 -2
  29. package/src/__tests__/cli.unit.test.ts +87 -0
  30. package/src/__tests__/native-cooker-registry.test.ts +16 -0
  31. package/src/__tests__/pack-authoring-gateway.unit.test.ts +49 -0
  32. package/src/__tests__/pack.unit.test.ts +6 -6
  33. package/src/__tests__/runtime-publication.unit.test.ts +27 -1
  34. package/src/build.ts +2 -0
  35. package/src/cli-asset.ts +227 -5
  36. package/src/native-cooker-registry.ts +14 -1
  37. package/src/pack-authoring-node.ts +258 -9
  38. package/src/pack-authoring.ts +26 -0
  39. package/src/runtime-publication.ts +44 -0
  40. 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":"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"}
1
+ {"version":3,"file":"native-cooker-registry.d.ts","sourceRoot":"","sources":["../src/native-cooker-registry.ts"],"names":[],"mappings":"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"}
@@ -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: String(error) });
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":";;;;AAoDA,SAAS,aAAa,KAAA,EAAyB;AAC7C,EAAA,IAAI,KAAA,YAAiB,YAAY,OAAO,MAAA,CAAO,KAAK,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAC5E,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,YAAY,CAAA;AACvD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,MAAM,OAAO,KAAA;AACxD,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CACjB,IAAA,CAAK,CAAC,CAAC,IAAI,CAAA,EAAG,CAAC,KAAK,CAAA,KAAM,IAAA,CAAK,aAAA,CAAc,KAAK,CAAC,CAAA,CACnD,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,MAAM,CAAA,KAAM,CAAC,GAAA,EAAK,YAAA,CAAa,MAAM,CAAC,CAAC;AAAA,GACvD;AACF;AAEA,SAAS,YAAe,KAAA,EAAmC;AACzD,EAAA,MAAM,QAAQ,IAAA,CAAK,SAAA;AAAA,IACjB,YAAA,CAAa;AAAA,MACX,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,WAAW,KAAA,CAAM;AAAA,KAClB;AAAA,GACH;AACA,EAAA,OAAO,CAAA,OAAA,EAAU,WAAW,QAAQ,CAAA,CAAE,OAAO,KAAK,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AACnE;AAOA,SAAS,OAAA,CAAQ,KAAa,MAAA,EAA+D;AAC3F,EAAA,OAAO,GAAA,CAAI;AAAA,IACT,KAAA,EAAO,aAAA;AAAA,IACP,IAAA,EAAM,oBAAA;AAAA,IACN,QAAA,EAAU,wDAAA;AAAA,IACV,IAAA,EAAM,8DAAA;AAAA,IACN,MAAA;AAAA,IACA,UAAU,EAAE,MAAA,EAAQ,uBAAuB,GAAG,CAAA,CAAA,EAAI,WAAW,IAAA;AAAK,GACnE,CAAA;AACH;AAEA,SAAS,kBAAA,CAAmB,KAAa,MAAA,EAAgD;AACvF,EAAA,OAAO,QAAQ,GAAA,EAAK,EAAE,MAAM,SAAA,EAAW,QAAA,EAAU,QAAQ,CAAA;AAC3D;AAEA,SAAS,SAAA,CACP,KACA,QAAA,EACgC;AAChC,EAAA,OAAO;AAAA,IACL,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,WAAA;AAAA,IACR,eAAe,QAAA,CAAS,KAAA;AAAA,IACxB,mBAAA,EAAqB,SAAS,UAAA,GAAa,CAAA;AAAA,IAC3C,yBAAyB,QAAA,CAAS,UAAA;AAAA,IAClC,YAAA,EAAc,UAAU,GAAG,CAAA,sCAAA;AAAA,GAC7B;AACF;AAGO,IAAM,uBAAN,MAA2B;AAAA,EACf,OAAA,uBAAc,GAAA,EAA0B;AAAA,EAEzD,SAAS,MAAA,EAA4B;AACnC,IAAA,IAAI,OAAO,MAAA,CAAO,GAAA,KAAQ,YAAY,MAAA,CAAO,GAAA,CAAI,WAAW,CAAA,EAAG;AAC7D,MAAA,MAAM,IAAI,UAAU,+DAA+D,CAAA;AAAA,IACrF;AACA,IAAA,IAAI,OAAO,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACrC,MAAA,MAAM,IAAI,SAAA,CAAU,CAAA,sCAAA,EAAyC,MAAA,CAAO,GAAG,CAAA,iBAAA,CAAmB,CAAA;AAAA,IAC5F;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,EAAK,MAAM,CAAA;AAAA,EACrC;AAAA,EAEA,IAAI,GAAA,EAAuC;AACzC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAAA,EAC7B;AAAA,EAEA,iBAAA,GAAuC;AACrC,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA;AAAA,EAChC;AAAA,EAEA,MAAM,QAAA,CACJ,GAAA,EACA,KAAA,EACsD;AACtD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACnC,IAAA,IAAI,WAAW,MAAA,EAAW;AACxB,MAAA,OAAO,QAAQ,GAAA,EAAK,EAAE,MAAM,SAAA,EAAW,QAAA,EAAU,KAAK,CAAA;AAAA,IACxD;AACA,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,OAAO,QAAA,KAAa,KAAA,CAAA,GAAY,QAAQ,MAAM,MAAA,CAAO,SAAS,KAAK,CAAA;AACtF,MAAA,KAAA,GAAQ,MAAM,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA;AAAA,IACtC,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,WAAW,QAAA,EAAU,MAAA,CAAO,KAAK,CAAA,EAAG,CAAA;AAAA,IAClE;AACA,IAAA,IACE,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,CAAA,IACtB,MAAM,gBAAA,CAAiB,MAAA,KAAW,CAAA,IAClC,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,IAAI,KACzB,OAAO,KAAA,CAAM,OAAA,KAAY,QAAA,IACzB,KAAA,CAAM,OAAA,KAAY,IAAA,IAClB,OAAO,MAAM,SAAA,KAAc,QAAA,IAC3B,KAAA,CAAM,SAAA,KAAc,IAAA,IACpB,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAA,CAAE,IAAA;AAAA,MAC9B,CAAC,GAAG,QAAQ,MACV,QAAA,KAAa,IAAA,IACb,OAAO,QAAA,KAAa,QAAA,IACpB,OAAO,QAAA,CAAS,SAAA,KAAc,YAC9B,QAAA,CAAS,SAAA,CAAU,WAAW,CAAA,IAC9B,EAAE,SAAS,KAAA,YAAiB,UAAA;AAAA,KAChC,EACA;AACA,MAAA,OAAO,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,MAAM,IAAA,IAAQ,SAAA,EAAW,QAAA,EAAU,GAAA,EAAK,CAAA;AAAA,IACtE;AACA,IAAA,OAAO,GAAG,KAAK,CAAA;AAAA,EACjB;AAAA,EAEA,MAAM,GAAA,CACJ,GAAA,EACA,KAAA,EACkD;AAClD,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,QAAA,CAAe,KAAK,KAAK,CAAA;AACxD,IAAA,IAAI,CAAC,WAAA,CAAY,EAAA,EAAI,OAAO,WAAA;AAC5B,IAAA,MAAM,QAAQ,WAAA,CAAY,KAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,YAAY,KAAK,CAAA;AAChC,IAAA,MAAM,YAAgD,EAAC;AACvD,IAAA,KAAA,MAAW,CAAC,MAAM,QAAQ,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAA,EAAG;AAC9D,MAAA,SAAA,CAAU,IAAI,CAAA,GAAI;AAAA,QAChB,IAAA;AAAA,QACA,WAAW,QAAA,CAAS,SAAA;AAAA,QACpB,GAAI,SAAS,UAAA,KAAe,MAAA,GAAY,EAAC,GAAI,EAAE,UAAA,EAAY,QAAA,CAAS,UAAA,EAAW;AAAA,QAC/E,UAAA,EAAY,SAAS,KAAA,CAAM;AAAA,OAC7B;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,MAAA,EAAQ,cAAA;AAAA,MACR,MAAA,EAAQ,WAAA;AAAA,MACR,kBAAkB,KAAA,CAAM,gBAAA;AAAA,MACxB,YAAA,EAAc;AAAA,KAChB;AACA,IAAA,MAAM,OAAA,GAA0B;AAAA,MAC9B,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,GAAG,OAAO,CAAA;AAAA,EACnB;AAAA,EAEA,MAAM,eACJ,OAAA,EACkE;AAClE,IAAA,MAAM,YAAY,MAAM,IAAA,CAAK,SAAe,OAAA,CAAQ,GAAA,EAAK,QAAQ,KAAK,CAAA;AACtE,IAAA,IAAI,CAAC,UAAU,EAAA,EAAI;AACjB,MAAA,OAAO,OAAA,CAAQ,QAAA,KAAa,MAAA,GACxB,SAAA,GACA,EAAA,CAAG,UAAU,OAAA,CAAQ,GAAA,EAAK,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,IACjD;AACA,IAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,QAAA,GAAW,SAAA,CAAU,KAAK,CAAA;AACxD,IAAA,IAAI,kBAAkB,MAAA,EAAW;AAC/B,MAAA,OAAO,OAAA,CAAQ,QAAA,KAAa,MAAA,GACxB,kBAAA,CAAmB,QAAQ,GAAA,EAAK,aAAa,CAAA,GAC7C,EAAA,CAAG,SAAA,CAAU,OAAA,CAAQ,GAAA,EAAK,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,IACjD;AACA,IAAA,MAAM,UAAA,GAAA,CAAc,OAAA,CAAQ,QAAA,EAAU,UAAA,IAAc,CAAA,IAAK,CAAA;AACzD,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,OAAA,GAAU,SAAA,CAAU,KAAA,EAAO,UAAU,CAAA;AAAA,IACrD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,OAAA,CAAQ,QAAA,KAAa,MAAA,GACxB,kBAAA,CAAmB,QAAQ,GAAA,EAAK,oCAAoC,CAAA,GACpE,EAAA,CAAG,SAAA,CAAU,OAAA,CAAQ,GAAA,EAAK,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,EAAA,CAAG;AAAA,MACR,OAAO,SAAA,CAAU,KAAA;AAAA,MACjB,UAAA;AAAA,MACA,MAAA,EAAQ,WAAA;AAAA,MACR,eAAe,SAAA,CAAU,KAAA;AAAA,MACzB,mBAAA,EAAqB,UAAA;AAAA,MACrB,uBAAA,EAAyB;AAAA,KAC1B,CAAA;AAAA,EACH;AACF","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;AAGlF,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,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;AAg3DD,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"}
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;AAkmED,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
  }
@@ -10408,7 +10460,164 @@ async function resolveAsset(gameRoot, snapshot, operation) {
10408
10460
  }
10409
10461
  });
10410
10462
  }
10411
- async function verify(snapshot, operation) {
10463
+ function verificationSourceFormat(gameRoot, sourcePath, fallback = "pack.ts") {
10464
+ if (sourcePath === void 0) return fallback;
10465
+ const absolute = resolve(gameRoot, sourcePath);
10466
+ if (absolute.endsWith(".meta.json")) return "meta.json";
10467
+ if (absolute.endsWith(".pack.json")) return "pack.json";
10468
+ if (absolute.endsWith(".pack.ts")) return "pack.ts";
10469
+ return fallback;
10470
+ }
10471
+ function verificationAuthorFacts(snapshot, entry) {
10472
+ const declaration = snapshot.inventory.declarations.get(entry.sourcePath);
10473
+ if (declaration?.format === "meta.json") {
10474
+ const asset = declaration.value.subAssets.find(
10475
+ (candidate) => candidate.guid.toLowerCase() === entry.guid.toLowerCase()
10476
+ );
10477
+ return {
10478
+ ...asset?.name === void 0 && asset?.sourceKey === void 0 ? {} : { name: asset.name ?? asset.sourceKey },
10479
+ dependencies: []
10480
+ };
10481
+ }
10482
+ if (declaration?.format === "pack.json") {
10483
+ if (declaration.value.schemaVersion === "3.0.0") {
10484
+ const parsed = parsePackSourceJson(declaration.value);
10485
+ if (parsed.ok && parsed.value.format === "direct" && entry.sourceKey !== void 0) {
10486
+ const asset = parsed.value.assets[entry.sourceKey];
10487
+ return {
10488
+ ...asset?.name === void 0 ? {} : { name: asset.name },
10489
+ dependencies: asset?.refs ?? []
10490
+ };
10491
+ }
10492
+ } else {
10493
+ const asset = declaration.value.assets.find(
10494
+ (candidate) => candidate.guid.toLowerCase() === entry.guid.toLowerCase()
10495
+ );
10496
+ return {
10497
+ ...asset?.name === void 0 ? {} : { name: asset.name },
10498
+ dependencies: asset?.refs ?? []
10499
+ };
10500
+ }
10501
+ }
10502
+ return { dependencies: [] };
10503
+ }
10504
+ function verificationOutput(materialized, legacyPublished = false) {
10505
+ if (materialized !== void 0) {
10506
+ return {
10507
+ status: materialized.ready ? "produced" : "unknown",
10508
+ availability: materialized.ready ? "available" : "unknown",
10509
+ freshness: "unknown"
10510
+ };
10511
+ }
10512
+ if (legacyPublished) {
10513
+ return {
10514
+ status: "produced",
10515
+ availability: "unknown",
10516
+ freshness: "unknown"
10517
+ // A legacy Pack row is a validated published declaration. The bytes
10518
+ // remain outside this read-only gateway, so availability is unknown.
10519
+ };
10520
+ }
10521
+ return { status: "unproduced", availability: "unknown", freshness: "unknown" };
10522
+ }
10523
+ function createGatewayVerificationReport(gameRoot, snapshot) {
10524
+ const materializedByGuid = new Map(
10525
+ snapshot.materialized.map((asset) => [asset.guid.toLowerCase(), asset])
10526
+ );
10527
+ const rows = /* @__PURE__ */ new Map();
10528
+ for (const entry of snapshot.inventory.inventory) {
10529
+ const declaration = snapshot.inventory.declarations.get(entry.sourcePath);
10530
+ const format = declaration?.format ?? verificationSourceFormat(gameRoot, entry.sourcePath);
10531
+ const facts = verificationAuthorFacts(snapshot, entry);
10532
+ const materialized = materializedByGuid.get(entry.guid.toLowerCase());
10533
+ const legacyPublished = declaration?.format === "pack.json" && declaration.value.schemaVersion !== "3.0.0";
10534
+ rows.set(entry.guid.toLowerCase(), {
10535
+ guid: entry.guid,
10536
+ type: entry.kind,
10537
+ source: {
10538
+ path: entry.sourcePath,
10539
+ format,
10540
+ role: "author",
10541
+ ...entry.sourceRevision === void 0 ? {} : { revision: entry.sourceRevision }
10542
+ },
10543
+ output: verificationOutput(materialized, legacyPublished),
10544
+ dependencies: facts.dependencies,
10545
+ producer: {
10546
+ state: materialized !== void 0 ? "published" : legacyPublished ? "published" : "not-run"
10547
+ },
10548
+ ...facts.name === void 0 ? {} : { name: facts.name },
10549
+ ...entry.sourceKey === void 0 ? {} : { sourceKey: entry.sourceKey },
10550
+ ...entry.sourceIndex === void 0 ? {} : { sourceIndex: entry.sourceIndex }
10551
+ });
10552
+ }
10553
+ for (const asset of snapshot.materialized) {
10554
+ const key = asset.guid.toLowerCase();
10555
+ if (rows.has(key)) continue;
10556
+ const sourcePath = asset.sourcePath === void 0 ? void 0 : resolve(gameRoot, asset.sourcePath);
10557
+ const declaration = sourcePath === void 0 ? void 0 : snapshot.inventory.declarations.get(sourcePath);
10558
+ const format = declaration?.format ?? verificationSourceFormat(gameRoot, asset.sourcePath);
10559
+ rows.set(key, {
10560
+ guid: asset.guid,
10561
+ type: asset.kind,
10562
+ source: {
10563
+ path: sourcePath ?? `${asset.packageId}/${asset.sourceKey}`,
10564
+ format,
10565
+ role: "author",
10566
+ ...declaration === void 0 ? {} : { revision: declaration.sourceRevision }
10567
+ },
10568
+ output: verificationOutput(asset),
10569
+ dependencies: asset.refs ?? [],
10570
+ producer: { state: "published" },
10571
+ sourceKey: asset.sourceKey
10572
+ });
10573
+ }
10574
+ const assets = [...rows.values()].sort(
10575
+ (left, right) => `${left.source.path}:${left.guid}`.localeCompare(`${right.source.path}:${right.guid}`)
10576
+ );
10577
+ const emitted = assets.slice(0, VERIFY_PROVENANCE_LIMIT);
10578
+ const sourcePaths = [...snapshot.inventory.declarations.keys()].sort();
10579
+ const scriptablePackSources = [...snapshot.inventory.declarations.values()].filter((declaration) => declaration.format === "pack.ts").sort((left, right) => left.sourcePath.localeCompare(right.sourcePath));
10580
+ const unmaterializedScriptable = scriptablePackSources.filter(
10581
+ (source) => !snapshot.materialized.some(
10582
+ (asset) => asset.packageId === source.value.packageId.toLowerCase() || asset.sourcePath !== void 0 && resolve(gameRoot, asset.sourcePath) === source.sourcePath
10583
+ )
10584
+ );
10585
+ return {
10586
+ schemaVersion: "asset-verification-v1",
10587
+ root: resolve(gameRoot),
10588
+ operation: "asset.verify",
10589
+ requestId: "gateway",
10590
+ scope: {
10591
+ sourceCount: sourcePaths.length,
10592
+ assetCount: assets.length,
10593
+ sourcePaths: sourcePaths.slice(0, VERIFY_PROVENANCE_LIMIT),
10594
+ omittedSourceCount: Math.max(0, sourcePaths.length - VERIFY_PROVENANCE_LIMIT),
10595
+ assetLimit: VERIFY_PROVENANCE_LIMIT,
10596
+ truncated: assets.length > VERIFY_PROVENANCE_LIMIT,
10597
+ scriptablePackSourceCount: scriptablePackSources.length,
10598
+ scriptablePackSources: unmaterializedScriptable.slice(0, VERIFY_PROVENANCE_LIMIT).map((source) => ({
10599
+ sourcePath: source.sourcePath,
10600
+ packageId: source.value.packageId,
10601
+ output: "unproduced",
10602
+ reason: "producer-not-run"
10603
+ })),
10604
+ omittedScriptablePackSourceCount: Math.max(
10605
+ 0,
10606
+ unmaterializedScriptable.length - VERIFY_PROVENANCE_LIMIT
10607
+ )
10608
+ },
10609
+ assets: emitted,
10610
+ summary: {
10611
+ assetCount: assets.length,
10612
+ emittedAssetCount: emitted.length,
10613
+ materialCount: assets.filter((asset) => asset.type === "material").length,
10614
+ unproducedAssetCount: assets.filter((asset) => asset.output.status === "unproduced").length,
10615
+ unknownAssetCount: assets.filter((asset) => asset.output.status === "unknown").length,
10616
+ unmaterializedScriptablePackCount: unmaterializedScriptable.length
10617
+ }
10618
+ };
10619
+ }
10620
+ async function verify(gameRoot, snapshot, operation) {
10412
10621
  for (const subject of snapshot.subjects.values()) {
10413
10622
  if (subject.format === "instance") {
10414
10623
  const resolved = await resolveInstance(snapshot, subject);
@@ -10453,14 +10662,8 @@ async function verify(snapshot, operation) {
10453
10662
  );
10454
10663
  }
10455
10664
  }
10456
- return ok({
10457
- operation: operation.operation,
10458
- requestId: operation.requestId,
10459
- snapshot: {
10460
- sourceCount: snapshot.subjects.size,
10461
- assetCount: snapshotAssets(snapshot).length
10462
- }
10463
- });
10665
+ const report = createGatewayVerificationReport(gameRoot, snapshot);
10666
+ return ok({ ...report, operation: operation.operation, requestId: operation.requestId });
10464
10667
  }
10465
10668
  function packageIdFromOperation(snapshot, operation) {
10466
10669
  const value = operation.packageId === void 0 ? ok(PackageId.random()) : PackageId.parse(operation.packageId);
@@ -10560,7 +10763,8 @@ async function executeRaw(options, operation) {
10560
10763
  if (!snapshot.ok) return snapshot;
10561
10764
  if (operation.operation === "asset.resolve")
10562
10765
  return resolveAsset(options.gameRoot, snapshot.value, operation);
10563
- if (operation.operation === "asset.verify") return verify(snapshot.value, operation);
10766
+ if (operation.operation === "asset.verify")
10767
+ return verify(options.gameRoot, snapshot.value, operation);
10564
10768
  if (operation.operation === "asset-source.create") {
10565
10769
  const path = confinedPath(
10566
10770
  options.gameRoot,