@forgeax/engine-import 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 +91 -3
- package/dist/__tests__/ies-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/ies-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ies-producer.unit.test.d.ts +2 -0
- package/dist/__tests__/ies-producer.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-lod-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-lod-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-lod-reimport.integration.test.d.ts +2 -0
- package/dist/__tests__/mesh-lod-reimport.integration.test.d.ts.map +1 -0
- package/dist/__tests__/parameterized-scriptable-pack.unit.test.d.ts +2 -0
- package/dist/__tests__/parameterized-scriptable-pack.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scriptable-pack-file-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-file-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/source-package-publication-lod.integration.test.d.ts +2 -0
- package/dist/__tests__/source-package-publication-lod.integration.test.d.ts.map +1 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.mjs +230 -3
- package/dist/browser.mjs.map +1 -1
- package/dist/build-production.d.ts +1 -8
- package/dist/build-production.d.ts.map +1 -1
- package/dist/ies/ies-importer.d.ts +4 -0
- package/dist/ies/ies-importer.d.ts.map +1 -0
- package/dist/ies/parse-lm63.d.ts +13 -0
- package/dist/ies/parse-lm63.d.ts.map +1 -0
- package/dist/ies/resample-type-c.d.ts +4 -0
- package/dist/ies/resample-type-c.d.ts.map +1 -0
- package/dist/import-runner.d.ts.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +2550 -1029
- package/dist/index.mjs.map +1 -1
- package/dist/mesh-bin.d.ts.map +1 -1
- package/dist/mesh-bin.mjs +29 -1
- package/dist/mesh-bin.mjs.map +1 -1
- package/dist/mesh-lod.d.ts +60 -0
- package/dist/mesh-lod.d.ts.map +1 -0
- package/dist/parameterized-scriptable-pack.d.ts +68 -0
- package/dist/parameterized-scriptable-pack.d.ts.map +1 -0
- package/dist/scriptable-pack-file-snapshot.d.ts +71 -0
- package/dist/scriptable-pack-file-snapshot.d.ts.map +1 -0
- package/dist/scriptable-pack-host.d.ts +70 -39
- package/dist/scriptable-pack-host.d.ts.map +1 -1
- package/dist/scriptable-pack-output-producers.d.ts +1 -0
- package/dist/scriptable-pack-output-producers.d.ts.map +1 -1
- package/dist/scriptable-pack-staged-snapshot.d.ts +2 -2
- package/dist/scriptable-pack-staged-snapshot.d.ts.map +1 -1
- package/dist/scriptable-pack.d.ts +13 -26
- package/dist/scriptable-pack.d.ts.map +1 -1
- package/dist/source-package-errors.d.ts.map +1 -1
- package/dist/source-package-publication.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/__tests__/ies-contract.unit.test.ts +31 -0
- package/src/__tests__/ies-producer.unit.test.ts +104 -0
- package/src/__tests__/mesh-bin.test.ts +69 -0
- package/src/__tests__/mesh-lod-contract.unit.test.ts +92 -0
- package/src/__tests__/mesh-lod-reimport.integration.test.ts +15 -0
- package/src/__tests__/parameterized-scriptable-pack.unit.test.ts +270 -0
- package/src/__tests__/scriptable-pack-file-snapshot.unit.test.ts +177 -0
- package/src/__tests__/scriptable-pack-host.unit.test.ts +196 -4
- package/src/__tests__/scriptable-pack-production-producers.unit.test.ts +7 -1
- package/src/__tests__/scriptable-pack-staged-snapshot.unit.test.ts +43 -12
- package/src/__tests__/source-package-publication-lod.integration.test.ts +29 -0
- package/src/__tests__/source-package-publication.integration.test.ts +26 -1
- package/src/browser.ts +5 -0
- package/src/build-production.ts +498 -141
- package/src/ies/ies-importer.ts +126 -0
- package/src/ies/parse-lm63.ts +98 -0
- package/src/ies/resample-type-c.ts +108 -0
- package/src/import-runner.ts +58 -0
- package/src/index.ts +49 -19
- package/src/mesh-bin.ts +38 -0
- package/src/mesh-lod.ts +265 -0
- package/src/parameterized-scriptable-pack.ts +725 -0
- package/src/scriptable-pack-file-snapshot.ts +346 -0
- package/src/scriptable-pack-host.ts +790 -343
- package/src/scriptable-pack-output-producers.ts +58 -1
- package/src/scriptable-pack-staged-snapshot.ts +12 -11
- package/src/scriptable-pack.ts +16 -485
- package/src/source-package-errors.ts +6 -0
- package/src/source-package-publication.ts +32 -2
- package/dist/.tsbuildinfo +0 -1
- package/dist/__tests__/scriptable-pack-product.contract.test.d.ts +0 -2
- package/dist/__tests__/scriptable-pack-product.contract.test.d.ts.map +0 -1
- package/dist/__tests__/scriptable-pack.integration.test.d.ts +0 -2
- package/dist/__tests__/scriptable-pack.integration.test.d.ts.map +0 -1
- package/dist/scriptable-source-package.d.ts +0 -14
- package/dist/scriptable-source-package.d.ts.map +0 -1
- package/src/__tests__/scriptable-pack-product.contract.test.ts +0 -46
- package/src/__tests__/scriptable-pack.integration.test.ts +0 -435
- package/src/scriptable-source-package.ts +0 -88
package/src/build-production.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
1
|
+
import { isAbsolute, relative, resolve } from 'node:path';
|
|
2
2
|
import {
|
|
3
3
|
type CatalogBuildResult,
|
|
4
4
|
createRuntimePackPublication,
|
|
5
5
|
finalizePackageTransportSource,
|
|
6
|
-
loadAssetConfig,
|
|
7
6
|
metaPathForGuid,
|
|
8
|
-
|
|
7
|
+
projectPackageCatalog,
|
|
9
8
|
} from '@forgeax/engine-pack/build';
|
|
9
|
+
import { AssetGuid } from '@forgeax/engine-pack/guid';
|
|
10
10
|
import type { NativeCooker } from '@forgeax/engine-pack/native-cooker';
|
|
11
|
+
import type { LegacyPackInventoryDocument } from '@forgeax/engine-pack/scanner';
|
|
12
|
+
import {
|
|
13
|
+
PackageId,
|
|
14
|
+
parseParameterizedPackJson,
|
|
15
|
+
projectDirectPackJson,
|
|
16
|
+
resolvePackParameterInheritance,
|
|
17
|
+
} from '@forgeax/engine-pack/source';
|
|
18
|
+
import { loadParameterizedScriptablePack } from '@forgeax/engine-pack/source-node';
|
|
11
19
|
import type {
|
|
12
20
|
AssetPublicationEnvelope,
|
|
21
|
+
AssetPublicationOutput,
|
|
22
|
+
CookReceipt,
|
|
13
23
|
Importer,
|
|
14
24
|
PackIndexEntry,
|
|
15
|
-
ResourceRevision,
|
|
16
25
|
RuntimeAssetBinding,
|
|
17
26
|
} from '@forgeax/engine-types';
|
|
18
27
|
import type { ImportRunnerFs } from './import-runner.js';
|
|
@@ -21,10 +30,11 @@ import { projectImportProductForBuild } from './pack-projection.js';
|
|
|
21
30
|
import {
|
|
22
31
|
canonicalScriptableSourcePath,
|
|
23
32
|
declaredPackExternalOutputs,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
type ParameterizedScriptablePackInput,
|
|
34
|
+
type PreparedParameterizedScriptablePack,
|
|
35
|
+
prepareDirectPackTransport,
|
|
36
|
+
prepareLegacyPackTransport,
|
|
37
|
+
produceParameterizedScriptablePackProducts,
|
|
28
38
|
} from './scriptable-pack-host.js';
|
|
29
39
|
import {
|
|
30
40
|
finalizeSourcePackage,
|
|
@@ -71,14 +81,6 @@ export interface BuildProductionOptions {
|
|
|
71
81
|
readonly fail: (failure: BuildProductionFailure) => Error;
|
|
72
82
|
}
|
|
73
83
|
|
|
74
|
-
export interface ScriptableBuildPackage {
|
|
75
|
-
readonly packageUrl: string;
|
|
76
|
-
readonly receiptUrls: ReadonlyMap<string, string>;
|
|
77
|
-
readonly refs: ReadonlyMap<string, readonly string[]>;
|
|
78
|
-
readonly revision: ResourceRevision;
|
|
79
|
-
readonly publication: AssetPublicationEnvelope;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
84
|
function scriptableArtifactPath(guid: string, key: string): string {
|
|
83
85
|
return `${guid.toLowerCase()}/${key.includes('.') ? key : `${key}.bin`}`;
|
|
84
86
|
}
|
|
@@ -91,114 +93,327 @@ function runtimePublicationFor(
|
|
|
91
93
|
readonly sourceRevision: string;
|
|
92
94
|
readonly packageUrl: string;
|
|
93
95
|
readonly digest?: string;
|
|
96
|
+
readonly inputFingerprint?: string;
|
|
97
|
+
/** Preserve producer-declared semantic keys on generic publication output rows. */
|
|
98
|
+
readonly sourceKeys?: ReadonlyMap<string, string>;
|
|
99
|
+
readonly outputs?: readonly AssetPublicationOutput[];
|
|
100
|
+
readonly externalEvidence?: readonly import('@forgeax/engine-types').AssetPublicationExternalEvidence[];
|
|
94
101
|
},
|
|
95
102
|
) {
|
|
96
|
-
|
|
103
|
+
const publicationInput = {
|
|
97
104
|
pack: input.pack,
|
|
98
105
|
scopeId: context.runtimeBinding?.scopeId ?? 'asset-runtime',
|
|
99
106
|
sourcePath: input.sourcePath,
|
|
100
107
|
sourceRevision: input.sourceRevision,
|
|
101
108
|
packageUrl: input.packageUrl,
|
|
102
109
|
...(input.digest === undefined ? {} : { digest: input.digest }),
|
|
110
|
+
...(input.inputFingerprint === undefined ? {} : { inputFingerprint: input.inputFingerprint }),
|
|
111
|
+
...(input.outputs === undefined ? {} : { outputs: input.outputs }),
|
|
112
|
+
...(input.externalEvidence === undefined ? {} : { externalEvidence: input.externalEvidence }),
|
|
103
113
|
generation: context.runtimeBinding?.generation ?? context.generation,
|
|
114
|
+
};
|
|
115
|
+
if (input.sourceKeys === undefined) return createRuntimePackPublication(publicationInput);
|
|
116
|
+
const derived = createRuntimePackPublication(publicationInput);
|
|
117
|
+
const outputs = derived.publication.outputs.map((output) => ({
|
|
118
|
+
...output,
|
|
119
|
+
sourceKey: input.sourceKeys?.get(output.guid.toLowerCase()) ?? output.sourceKey,
|
|
120
|
+
}));
|
|
121
|
+
return createRuntimePackPublication({ ...publicationInput, outputs });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function sourceKeysFor(
|
|
125
|
+
declarations: readonly { readonly guid: string; readonly sourceKey?: string }[],
|
|
126
|
+
): ReadonlyMap<string, string> {
|
|
127
|
+
return new Map(
|
|
128
|
+
declarations.flatMap((declaration) =>
|
|
129
|
+
declaration.sourceKey === undefined
|
|
130
|
+
? []
|
|
131
|
+
: [[declaration.guid.toLowerCase(), declaration.sourceKey] as const],
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface ParameterizedBuildBundle {
|
|
137
|
+
readonly input: ParameterizedScriptablePackInput;
|
|
138
|
+
readonly prepared: PreparedParameterizedScriptablePack;
|
|
139
|
+
readonly entries: readonly PackIndexEntry[];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
type ParameterizedSourceSubject = {
|
|
143
|
+
readonly kind: 'source';
|
|
144
|
+
readonly packageId: PackageId;
|
|
145
|
+
readonly sourcePath: string;
|
|
146
|
+
readonly definition: import('@forgeax/engine-pack/source').AnyParameterizedPackDefinition;
|
|
147
|
+
readonly sourceClosure: readonly import('@forgeax/engine-pack/source').ScriptablePackSourceClosureEntry[];
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
type ParameterizedInstanceSubject = {
|
|
151
|
+
readonly kind: 'instance';
|
|
152
|
+
readonly packageId: PackageId;
|
|
153
|
+
readonly parent: PackageId;
|
|
154
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
155
|
+
readonly sourcePath: string;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
type ParameterizedDirectSubject = {
|
|
159
|
+
readonly kind: 'direct';
|
|
160
|
+
readonly packageId: PackageId;
|
|
161
|
+
readonly sourcePath: string;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
type ParameterizedSourceIndexSubject =
|
|
165
|
+
| ParameterizedSourceSubject
|
|
166
|
+
| ParameterizedInstanceSubject
|
|
167
|
+
| ParameterizedDirectSubject;
|
|
168
|
+
|
|
169
|
+
function dynamicFailure(context: BuildProductionOptions, value: unknown): never {
|
|
170
|
+
const candidate = value !== null && typeof value === 'object' ? value : {};
|
|
171
|
+
const error = candidate as {
|
|
172
|
+
readonly code?: unknown;
|
|
173
|
+
readonly expected?: unknown;
|
|
174
|
+
readonly hint?: unknown;
|
|
175
|
+
readonly detail?: unknown;
|
|
176
|
+
};
|
|
177
|
+
throw context.fail({
|
|
178
|
+
code: typeof error.code === 'string' ? error.code : 'parameterized-pack-build-failed',
|
|
179
|
+
expected:
|
|
180
|
+
typeof error.expected === 'string'
|
|
181
|
+
? error.expected
|
|
182
|
+
: 'the parameterized Pack generation to produce a valid terminal result',
|
|
183
|
+
hint:
|
|
184
|
+
typeof error.hint === 'string'
|
|
185
|
+
? error.hint
|
|
186
|
+
: 'inspect the parameterized Pack subject and rebuild the current generation',
|
|
187
|
+
...(error.detail === undefined ? {} : { detail: error.detail }),
|
|
104
188
|
});
|
|
105
189
|
}
|
|
106
190
|
|
|
107
|
-
|
|
191
|
+
function parameterizedCatalogSourcePath(
|
|
108
192
|
context: BuildProductionOptions,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
193
|
+
sourcePath: string,
|
|
194
|
+
): string {
|
|
195
|
+
const projected = context.fsForImport.sourceIdentityFor?.(sourcePath);
|
|
196
|
+
const logical =
|
|
197
|
+
projected === undefined || isAbsolute(projected)
|
|
198
|
+
? relative(context.cwd, sourcePath)
|
|
199
|
+
: projected;
|
|
200
|
+
return canonicalScriptableSourcePath(logical).replaceAll('\\', '/');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** Build parameterized roots and JSON instances before normal Build emission. */
|
|
204
|
+
async function buildParameterizedPackages(
|
|
205
|
+
context: BuildProductionOptions,
|
|
206
|
+
): Promise<readonly ParameterizedBuildBundle[]> {
|
|
207
|
+
const subjects = new Map<string, ParameterizedSourceIndexSubject>();
|
|
208
|
+
for (const [sourcePath, declaration] of context.inventory.sourceDeclarations) {
|
|
209
|
+
if (declaration.format === 'pack.ts-parameterized') {
|
|
210
|
+
const key = PackageId.format(declaration.definition.packageId).toLowerCase();
|
|
211
|
+
subjects.set(key, {
|
|
212
|
+
kind: 'source',
|
|
213
|
+
packageId: declaration.definition.packageId,
|
|
214
|
+
sourcePath,
|
|
215
|
+
definition: declaration.definition,
|
|
216
|
+
sourceClosure: declaration.sourceClosure,
|
|
217
|
+
});
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (declaration.format !== 'pack.json' || declaration.value.schemaVersion !== '3.0.0') {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const parsed = parseParameterizedPackJson(declaration.value);
|
|
224
|
+
if (!parsed.ok) dynamicFailure(context, parsed.error);
|
|
225
|
+
if (parsed.value.format === 'direct') {
|
|
226
|
+
subjects.set(PackageId.format(parsed.value.packageId).toLowerCase(), {
|
|
227
|
+
kind: 'direct',
|
|
228
|
+
packageId: parsed.value.packageId,
|
|
229
|
+
sourcePath,
|
|
230
|
+
});
|
|
231
|
+
} else {
|
|
232
|
+
subjects.set(PackageId.format(parsed.value.packageId).toLowerCase(), {
|
|
233
|
+
kind: 'instance',
|
|
234
|
+
packageId: parsed.value.packageId,
|
|
235
|
+
parent: parsed.value.parent,
|
|
236
|
+
values: parsed.value.values,
|
|
237
|
+
sourcePath,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const sourceSubject = (packageId: PackageId): ParameterizedSourceSubject | undefined => {
|
|
242
|
+
const subject = subjects.get(PackageId.format(packageId).toLowerCase());
|
|
243
|
+
return subject?.kind === 'source' ? subject : undefined;
|
|
244
|
+
};
|
|
245
|
+
const readSubject = async (packageId: PackageId) => {
|
|
246
|
+
const subject = subjects.get(PackageId.format(packageId).toLowerCase());
|
|
247
|
+
if (subject === undefined) return undefined;
|
|
248
|
+
if (subject.kind === 'source') {
|
|
249
|
+
return {
|
|
250
|
+
format: 'source' as const,
|
|
251
|
+
packageId: subject.packageId,
|
|
252
|
+
parameters: 'parameters' in subject.definition ? subject.definition.parameters : [],
|
|
253
|
+
} satisfies import('@forgeax/engine-pack/source').PackParameterRootSubject;
|
|
254
|
+
}
|
|
255
|
+
if (subject.kind === 'instance') {
|
|
256
|
+
return {
|
|
257
|
+
format: 'instance' as const,
|
|
258
|
+
packageId: subject.packageId,
|
|
259
|
+
parent: subject.parent,
|
|
260
|
+
values: subject.values,
|
|
261
|
+
} satisfies import('@forgeax/engine-pack/source').PackParameterInstanceSubject;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
format: 'direct' as const,
|
|
265
|
+
packageId: subject.packageId,
|
|
266
|
+
} satisfies import('@forgeax/engine-pack/source').PackDirectSubject;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const orderedSubjects = [...subjects.values()].sort((left, right) =>
|
|
270
|
+
left.sourcePath.localeCompare(right.sourcePath),
|
|
125
271
|
);
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
272
|
+
const inputs: ParameterizedScriptablePackInput[] = [];
|
|
273
|
+
for (const subject of orderedSubjects) {
|
|
274
|
+
if (subject.kind === 'source') {
|
|
275
|
+
const packageId = PackageId.format(subject.packageId);
|
|
276
|
+
const loaded = await loadParameterizedScriptablePack(subject.sourcePath);
|
|
277
|
+
if (!loaded.ok) dynamicFailure(context, loaded.error);
|
|
278
|
+
if (PackageId.format(loaded.value.packageId) !== packageId) {
|
|
279
|
+
dynamicFailure(context, {
|
|
280
|
+
code: 'pack-source-revision-conflict',
|
|
281
|
+
expected: 'the parameterized source packageId to remain fixed during production',
|
|
282
|
+
hint: 'retry after source writes settle and rebuild the current generation',
|
|
283
|
+
detail: {
|
|
284
|
+
sourcePath: subject.sourcePath,
|
|
285
|
+
scannedPackageId: packageId,
|
|
286
|
+
loadedPackageId: PackageId.format(loaded.value.packageId),
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
inputs.push({
|
|
291
|
+
sourcePath: subject.sourcePath,
|
|
292
|
+
displaySourcePath: parameterizedCatalogSourcePath(context, subject.sourcePath),
|
|
293
|
+
definition: loaded.value,
|
|
294
|
+
sourceClosure: subject.sourceClosure,
|
|
295
|
+
publicationGeneration: context.generation,
|
|
296
|
+
policy: {
|
|
297
|
+
base: context.basePrefix === '' ? '/' : context.basePrefix,
|
|
298
|
+
packagePath: `assets/${packageId}.pack.json`,
|
|
299
|
+
artifactPath: scriptableArtifactPath,
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
for (const subject of orderedSubjects) {
|
|
305
|
+
if (subject.kind !== 'instance') continue;
|
|
306
|
+
const resolved = await resolvePackParameterInheritance(
|
|
132
307
|
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
308
|
+
format: 'instance',
|
|
309
|
+
packageId: subject.packageId,
|
|
310
|
+
parent: subject.parent,
|
|
311
|
+
values: subject.values,
|
|
136
312
|
},
|
|
137
|
-
|
|
313
|
+
readSubject,
|
|
314
|
+
);
|
|
315
|
+
if (!resolved.ok) dynamicFailure(context, resolved.error);
|
|
316
|
+
const root = sourceSubject(resolved.value.rootPackageId);
|
|
317
|
+
if (root === undefined) {
|
|
318
|
+
dynamicFailure(context, {
|
|
319
|
+
code: 'pack-parent-not-parameterized',
|
|
320
|
+
expected: 'the instance parent chain to terminate at a parameterized source',
|
|
321
|
+
hint: 'point the instance at a parameterized pack.ts source',
|
|
322
|
+
detail: { packageId: PackageId.format(subject.packageId) },
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
const loaded = await loadParameterizedScriptablePack(root.sourcePath);
|
|
326
|
+
if (!loaded.ok) dynamicFailure(context, loaded.error);
|
|
327
|
+
if (PackageId.format(loaded.value.packageId) !== PackageId.format(root.packageId)) {
|
|
328
|
+
dynamicFailure(context, {
|
|
329
|
+
code: 'pack-source-revision-conflict',
|
|
330
|
+
expected: 'the parameterized parent packageId to remain fixed during production',
|
|
331
|
+
hint: 'retry after source writes settle and rebuild the current generation',
|
|
332
|
+
detail: {
|
|
333
|
+
sourcePath: root.sourcePath,
|
|
334
|
+
scannedPackageId: PackageId.format(root.packageId),
|
|
335
|
+
loadedPackageId: PackageId.format(loaded.value.packageId),
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
const packageId = PackageId.format(subject.packageId);
|
|
340
|
+
inputs.push({
|
|
341
|
+
sourcePath: subject.sourcePath,
|
|
342
|
+
displaySourcePath: parameterizedCatalogSourcePath(context, subject.sourcePath),
|
|
343
|
+
definition: loaded.value,
|
|
344
|
+
sourceClosure: root.sourceClosure,
|
|
345
|
+
subjectPackageId: subject.packageId,
|
|
346
|
+
values: resolved.value.values,
|
|
347
|
+
publicationGeneration: context.generation,
|
|
348
|
+
policy: {
|
|
349
|
+
base: context.basePrefix === '' ? '/' : context.basePrefix,
|
|
350
|
+
packagePath: `assets/${packageId}.pack.json`,
|
|
351
|
+
artifactPath: scriptableArtifactPath,
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
if (inputs.length === 0) return [];
|
|
356
|
+
|
|
357
|
+
const requiredGuids = context.inventory.entries.flatMap((entry) => {
|
|
358
|
+
const parsed = AssetGuid.parse(entry.guid);
|
|
359
|
+
if (!parsed.ok) dynamicFailure(context, parsed.error);
|
|
360
|
+
return [parsed.value];
|
|
361
|
+
});
|
|
362
|
+
const externalOutputs = await declaredPackExternalOutputs(
|
|
363
|
+
context.inventory.sourceDeclarations,
|
|
364
|
+
context.cookers,
|
|
365
|
+
requiredGuids,
|
|
366
|
+
{
|
|
367
|
+
importerRegistry: context.importerRegistry,
|
|
368
|
+
fsForImport: context.fsForImport,
|
|
369
|
+
},
|
|
138
370
|
);
|
|
139
|
-
|
|
371
|
+
const availableGuids = new Set(requiredGuids.map((guid) => AssetGuid.format(guid).toLowerCase()));
|
|
372
|
+
const built = await produceParameterizedScriptablePackProducts({
|
|
373
|
+
sources: inputs,
|
|
374
|
+
declaredExternalOutputs: externalOutputs,
|
|
375
|
+
availableGuids,
|
|
376
|
+
});
|
|
377
|
+
if (!built.ok) dynamicFailure(context, built.error);
|
|
140
378
|
|
|
141
|
-
const
|
|
142
|
-
for (const
|
|
143
|
-
|
|
144
|
-
const prepared = preparedResult.value.get(canonicalScriptableSourcePath(entry.sourcePath));
|
|
379
|
+
const bundles: ParameterizedBuildBundle[] = [];
|
|
380
|
+
for (const input of inputs) {
|
|
381
|
+
const prepared = built.value.get(input.displaySourcePath);
|
|
145
382
|
if (prepared === undefined) {
|
|
146
|
-
|
|
147
|
-
code: '
|
|
148
|
-
expected: 'the
|
|
149
|
-
hint: 'rerun the
|
|
150
|
-
detail: {
|
|
383
|
+
dynamicFailure(context, {
|
|
384
|
+
code: 'parameterized-pack-build-failed',
|
|
385
|
+
expected: 'the worklist to return one prepared result per source subject',
|
|
386
|
+
hint: 'rerun the parameterized Pack generation from a clean inventory',
|
|
387
|
+
detail: { sourcePath: input.sourcePath },
|
|
151
388
|
});
|
|
152
389
|
}
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
sourceRevision: publication.sourceRevision,
|
|
160
|
-
packageUrl: finalized.packageUrl,
|
|
161
|
-
inputFingerprint: publication.receipt.inputFingerprint,
|
|
162
|
-
digest: finalized.digest,
|
|
163
|
-
generation: context.runtimeBinding?.generation ?? publication.generation,
|
|
164
|
-
outputs: facts.outputs,
|
|
165
|
-
externalEvidence: publication.externalEvidence,
|
|
166
|
-
});
|
|
167
|
-
const receiptPaths = await materializePreparedScriptablePack(
|
|
168
|
-
prepared,
|
|
169
|
-
{
|
|
170
|
-
packagePath,
|
|
171
|
-
artifactPath: (path) => `assets/${path}`,
|
|
172
|
-
receiptPath: (guid) => `assets/${guid}.receipt.json`,
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
writePackage: (path) => {
|
|
176
|
-
context.sink.emitFile({
|
|
177
|
-
type: 'asset',
|
|
178
|
-
fileName: path,
|
|
179
|
-
originalFileName: `${context.cwd}/${entry.sourcePath}`,
|
|
180
|
-
source: JSON.stringify(runtimePublication.pack),
|
|
181
|
-
});
|
|
182
|
-
},
|
|
183
|
-
writeArtifact: (path, bytes) => {
|
|
184
|
-
context.sink.emitFile({ type: 'asset', fileName: path, source: bytes });
|
|
185
|
-
},
|
|
186
|
-
writeReceipt: (path, source) => {
|
|
187
|
-
context.sink.emitFile({ type: 'asset', fileName: path, source });
|
|
188
|
-
},
|
|
189
|
-
},
|
|
390
|
+
const packageId = PackageId.format(input.subjectPackageId ?? input.definition.packageId);
|
|
391
|
+
const stagedByGuid = new Map(
|
|
392
|
+
prepared.product.stagedOutputs.map((output) => [
|
|
393
|
+
AssetGuid.format(output.guid).toLowerCase(),
|
|
394
|
+
output,
|
|
395
|
+
]),
|
|
190
396
|
);
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
397
|
+
const entries = projectPackageCatalog(
|
|
398
|
+
prepared.product.product.assets.map((asset, sourceIndex) => {
|
|
399
|
+
const staged = stagedByGuid.get(asset.guid.toLowerCase());
|
|
400
|
+
return {
|
|
401
|
+
guid: asset.guid,
|
|
402
|
+
kind: asset.kind,
|
|
403
|
+
sourcePath: input.displaySourcePath,
|
|
404
|
+
sourceIndex,
|
|
405
|
+
...(staged?.sourceKey === undefined ? {} : { sourceKey: staged.sourceKey }),
|
|
406
|
+
refs: asset.refs.map((reference) => reference.guid),
|
|
407
|
+
execution: 'cooked' as const,
|
|
408
|
+
packageId,
|
|
409
|
+
provenance: { provider: 'pack-ts', version: '2.0.0' },
|
|
410
|
+
};
|
|
411
|
+
}),
|
|
412
|
+
`${context.basePrefix === '/' ? '' : context.basePrefix}/${input.displaySourcePath}`,
|
|
413
|
+
);
|
|
414
|
+
bundles.push({ input, prepared, entries });
|
|
200
415
|
}
|
|
201
|
-
return
|
|
416
|
+
return bundles;
|
|
202
417
|
}
|
|
203
418
|
|
|
204
419
|
function updateImportedEntries(
|
|
@@ -209,12 +424,15 @@ function updateImportedEntries(
|
|
|
209
424
|
refsByGuid?: ReadonlyMap<string, readonly string[]>,
|
|
210
425
|
publication?: AssetPublicationEnvelope,
|
|
211
426
|
sourcePath?: string,
|
|
427
|
+
receiptUrls?: ReadonlyMap<string, string>,
|
|
428
|
+
revision?: PackIndexEntry['revision'],
|
|
212
429
|
): void {
|
|
213
430
|
const selected = new Set(guids.map((guid) => guid.toLowerCase()));
|
|
214
431
|
for (let index = 0; index < entries.length; index += 1) {
|
|
215
432
|
const entry = entries[index];
|
|
216
433
|
if (entry === undefined || !selected.has(entry.guid.toLowerCase())) continue;
|
|
217
434
|
const refs = refsByGuid?.get(entry.guid.toLowerCase());
|
|
435
|
+
const cookReceiptUrl = receiptUrls?.get(entry.guid.toLowerCase());
|
|
218
436
|
entries[index] = {
|
|
219
437
|
...entry,
|
|
220
438
|
packageUrl,
|
|
@@ -222,6 +440,8 @@ function updateImportedEntries(
|
|
|
222
440
|
...(sourcePath === undefined ? {} : { sourcePath }),
|
|
223
441
|
...(publication === undefined ? {} : { publication }),
|
|
224
442
|
...(refs === undefined ? {} : { refs }),
|
|
443
|
+
...(cookReceiptUrl === undefined ? {} : { cookReceiptUrl }),
|
|
444
|
+
...(revision === undefined ? {} : { revision }),
|
|
225
445
|
};
|
|
226
446
|
}
|
|
227
447
|
}
|
|
@@ -239,8 +459,11 @@ interface PackEmissionOptions {
|
|
|
239
459
|
readonly guids: readonly string[];
|
|
240
460
|
readonly projection?: Record<string, unknown>;
|
|
241
461
|
readonly refsByGuid?: ReadonlyMap<string, readonly string[]>;
|
|
462
|
+
readonly receipts?: readonly CookReceipt[];
|
|
463
|
+
readonly receiptOutputDigest?: string;
|
|
242
464
|
readonly publication?: AssetPublicationEnvelope;
|
|
243
465
|
readonly sourcePath?: string;
|
|
466
|
+
readonly revision?: PackIndexEntry['revision'];
|
|
244
467
|
}
|
|
245
468
|
|
|
246
469
|
async function emitPackDocument(
|
|
@@ -256,11 +479,34 @@ async function emitPackDocument(
|
|
|
256
479
|
}
|
|
257
480
|
const referenceId = work.context.sink.emitFile({
|
|
258
481
|
type: 'asset',
|
|
482
|
+
fileName: options.packageName.startsWith('assets/')
|
|
483
|
+
? options.packageName
|
|
484
|
+
: `assets/${options.packageName}`,
|
|
259
485
|
name: options.packageName,
|
|
260
486
|
originalFileName: options.originalFileName,
|
|
261
487
|
source: JSON.stringify(options.pack),
|
|
262
488
|
});
|
|
263
489
|
const packageUrl = work.context.sink.fileUrl(work.context.sink.getFileName(referenceId));
|
|
490
|
+
const receiptUrls = new Map<string, string>();
|
|
491
|
+
for (const receipt of options.receipts ?? []) {
|
|
492
|
+
const guid = receipt.guid.toLowerCase();
|
|
493
|
+
const receiptReferenceId = work.context.sink.emitFile({
|
|
494
|
+
type: 'asset',
|
|
495
|
+
fileName: `assets/${guid}.receipt.json`,
|
|
496
|
+
name: `${guid}.receipt.json`,
|
|
497
|
+
originalFileName: options.originalFileName,
|
|
498
|
+
source: JSON.stringify({
|
|
499
|
+
...receipt,
|
|
500
|
+
...(receipt.outputDigest === undefined && options.receiptOutputDigest === undefined
|
|
501
|
+
? {}
|
|
502
|
+
: { outputDigest: receipt.outputDigest ?? options.receiptOutputDigest }),
|
|
503
|
+
}),
|
|
504
|
+
});
|
|
505
|
+
receiptUrls.set(
|
|
506
|
+
guid,
|
|
507
|
+
work.context.sink.fileUrl(work.context.sink.getFileName(receiptReferenceId)),
|
|
508
|
+
);
|
|
509
|
+
}
|
|
264
510
|
updateImportedEntries(
|
|
265
511
|
work.importedEntries,
|
|
266
512
|
options.guids,
|
|
@@ -269,6 +515,8 @@ async function emitPackDocument(
|
|
|
269
515
|
options.refsByGuid,
|
|
270
516
|
options.publication,
|
|
271
517
|
options.sourcePath,
|
|
518
|
+
receiptUrls,
|
|
519
|
+
options.revision,
|
|
272
520
|
);
|
|
273
521
|
return packageUrl;
|
|
274
522
|
}
|
|
@@ -277,6 +525,7 @@ async function emitAuthoredPack(
|
|
|
277
525
|
work: BuildEmissionWork,
|
|
278
526
|
guidSeen: Set<string>,
|
|
279
527
|
entry: PackIndexEntry,
|
|
528
|
+
availableGuids: ReadonlySet<string>,
|
|
280
529
|
): Promise<void> {
|
|
281
530
|
const sourceDeclaration = sourceDeclarationForCatalogPath(
|
|
282
531
|
entry.sourcePath,
|
|
@@ -294,50 +543,158 @@ async function emitAuthoredPack(
|
|
|
294
543
|
detail: { stage: 'scan', sourcePath: packPath },
|
|
295
544
|
});
|
|
296
545
|
}
|
|
297
|
-
|
|
298
|
-
declaration.value
|
|
546
|
+
if (declaration.value.schemaVersion === '3.0.0') {
|
|
547
|
+
const parsed = parseParameterizedPackJson(declaration.value);
|
|
548
|
+
if (!parsed.ok) dynamicFailure(work.context, parsed.error);
|
|
549
|
+
if (parsed.value.format !== 'direct') {
|
|
550
|
+
dynamicFailure(work.context, {
|
|
551
|
+
code: 'catalog-declaration-missing',
|
|
552
|
+
expected: 'a direct v3 Pack declaration for an indexed authored output',
|
|
553
|
+
hint: 'instances are built from their parameterized parent and do not have direct Catalog rows',
|
|
554
|
+
detail: { stage: 'scan', sourcePath: packPath },
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const projected = projectDirectPackJson(parsed.value);
|
|
558
|
+
if (!projected.ok) dynamicFailure(work.context, projected.error);
|
|
559
|
+
const prepared = await prepareDirectPackTransport({
|
|
560
|
+
projected: projected.value,
|
|
561
|
+
sourcePath: packPath,
|
|
562
|
+
sourceRevision: declaration.sourceRevision,
|
|
563
|
+
availableGuids,
|
|
564
|
+
cookers: work.context.cookers,
|
|
565
|
+
policy: {
|
|
566
|
+
base: work.context.basePrefix === '' ? '/' : work.context.basePrefix,
|
|
567
|
+
packagePath: `assets/${projected.value.packageId}.pack.json`,
|
|
568
|
+
artifactPath: (assetGuid, key) => `${assetGuid}/${key}.bin`,
|
|
569
|
+
sink: () => {},
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
if (!prepared.ok) dynamicFailure(work.context, prepared.error);
|
|
573
|
+
const { product, finalized, facts, revision } = prepared.value;
|
|
574
|
+
const publication = runtimePublicationFor(work.context, {
|
|
575
|
+
pack: finalized.pack,
|
|
576
|
+
sourcePath: entry.sourcePath,
|
|
577
|
+
sourceRevision: product.inputFingerprint,
|
|
578
|
+
packageUrl: finalized.packageUrl,
|
|
579
|
+
digest: finalized.digest,
|
|
580
|
+
inputFingerprint: product.inputFingerprint,
|
|
581
|
+
outputs: facts.outputs,
|
|
582
|
+
externalEvidence: product.externalEvidence,
|
|
583
|
+
});
|
|
584
|
+
await emitPackDocument(work, {
|
|
585
|
+
pack: publication.pack,
|
|
586
|
+
artifacts: finalized.artifacts,
|
|
587
|
+
packageName: `${prepared.value.projected.packageId}.pack.json`,
|
|
588
|
+
originalFileName: packPath,
|
|
589
|
+
guids: product.product.assets.map((asset) => asset.guid),
|
|
590
|
+
projection: work.context.authoredCookedCurrentProjection,
|
|
591
|
+
refsByGuid: facts.refs,
|
|
592
|
+
receipts: product.product.receipts,
|
|
593
|
+
receiptOutputDigest: finalized.digest,
|
|
594
|
+
publication: publication.publication,
|
|
595
|
+
sourcePath: entry.sourcePath,
|
|
596
|
+
revision,
|
|
597
|
+
});
|
|
598
|
+
for (const asset of product.product.assets) guidSeen.add(asset.guid.toLowerCase());
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
// Legacy array-shaped documents are runtime Pack transport, not an
|
|
602
|
+
// authoring input anymore. Preserve the explicit v2 native-cooker seam for
|
|
603
|
+
// cooked transport while keeping source evaluation out of this path.
|
|
604
|
+
const legacy = declaration.value as LegacyPackInventoryDocument;
|
|
605
|
+
const prepared = await prepareLegacyPackTransport(
|
|
606
|
+
legacy,
|
|
299
607
|
work.context.cookers,
|
|
300
608
|
(guid) => ({
|
|
301
609
|
base: work.context.basePrefix === '' ? '/' : work.context.basePrefix,
|
|
302
610
|
packagePath: `assets/${guid}.pack.json`,
|
|
303
|
-
artifactPath: (
|
|
611
|
+
artifactPath: (assetGuid, key) => `${assetGuid}/${key}.bin`,
|
|
304
612
|
}),
|
|
305
613
|
packPath,
|
|
306
614
|
);
|
|
307
615
|
const outputGuid = prepared.firstGuid ?? entry.guid;
|
|
308
|
-
const authoredPack = prepared.finalized?.pack ??
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
616
|
+
const authoredPack = prepared.finalized?.pack ?? {
|
|
617
|
+
schemaVersion: '2.0.0' as const,
|
|
618
|
+
kind: 'internal-text-package' as const,
|
|
619
|
+
assets: legacy.assets.map((asset) => ({
|
|
620
|
+
guid: asset.guid,
|
|
621
|
+
kind: asset.kind,
|
|
622
|
+
...(asset.name === undefined ? {} : { name: asset.name }),
|
|
623
|
+
payload: asset.payload,
|
|
624
|
+
refs: asset.refs,
|
|
625
|
+
artifacts: asset.artifacts ?? {},
|
|
626
|
+
})),
|
|
627
|
+
};
|
|
628
|
+
const runtimePublication = runtimePublicationFor(work.context, {
|
|
629
|
+
pack: authoredPack,
|
|
630
|
+
sourcePath: entry.sourcePath,
|
|
631
|
+
sourceRevision: declaration.sourceRevision,
|
|
632
|
+
packageUrl:
|
|
633
|
+
prepared.finalized?.packageUrl ??
|
|
634
|
+
`${work.context.basePrefix === '/' ? '' : work.context.basePrefix}/assets/${outputGuid}.pack.json`,
|
|
635
|
+
...(prepared.finalized?.digest === undefined ? {} : { digest: prepared.finalized.digest }),
|
|
636
|
+
});
|
|
323
637
|
await emitPackDocument(work, {
|
|
324
|
-
pack: runtimePublication
|
|
638
|
+
pack: runtimePublication.pack,
|
|
325
639
|
artifacts: prepared.finalized?.artifacts ?? [],
|
|
326
640
|
packageName: `${outputGuid}.pack.json`,
|
|
327
641
|
originalFileName: packPath,
|
|
328
|
-
guids:
|
|
642
|
+
guids: authoredPack.assets.map((asset) => asset.guid),
|
|
329
643
|
projection:
|
|
330
644
|
prepared.finalized === undefined
|
|
331
645
|
? work.context.directCurrentProjection
|
|
332
646
|
: work.context.authoredCookedCurrentProjection,
|
|
333
|
-
|
|
334
|
-
...(
|
|
647
|
+
refsByGuid: new Map(authoredPack.assets.map((asset) => [asset.guid.toLowerCase(), asset.refs])),
|
|
648
|
+
...(prepared.finalized?.receipts === undefined
|
|
649
|
+
? {}
|
|
650
|
+
: {
|
|
651
|
+
receipts: prepared.finalized.receipts,
|
|
652
|
+
receiptOutputDigest: prepared.finalized.digest,
|
|
653
|
+
}),
|
|
654
|
+
publication: runtimePublication.publication,
|
|
655
|
+
sourcePath: entry.sourcePath,
|
|
335
656
|
});
|
|
336
|
-
for (const guid of
|
|
657
|
+
for (const guid of authoredPack.assets.map((asset) => asset.guid)) {
|
|
337
658
|
guidSeen.add(guid.toLowerCase());
|
|
338
659
|
}
|
|
339
660
|
}
|
|
340
661
|
|
|
662
|
+
async function emitParameterizedPack(
|
|
663
|
+
work: BuildEmissionWork,
|
|
664
|
+
guidSeen: Set<string>,
|
|
665
|
+
bundle: ParameterizedBuildBundle,
|
|
666
|
+
): Promise<void> {
|
|
667
|
+
const { input, prepared } = bundle;
|
|
668
|
+
const packageId = PackageId.format(input.subjectPackageId ?? input.definition.packageId);
|
|
669
|
+
const runtimePublication = createRuntimePackPublication({
|
|
670
|
+
pack: { assets: prepared.finalized.pack.assets },
|
|
671
|
+
scopeId: work.context.runtimeBinding?.scopeId ?? 'asset-runtime',
|
|
672
|
+
sourcePath: input.displaySourcePath,
|
|
673
|
+
sourceRevision: prepared.product.inputFingerprint,
|
|
674
|
+
packageUrl: prepared.finalized.packageUrl,
|
|
675
|
+
inputFingerprint: prepared.product.inputFingerprint,
|
|
676
|
+
digest: prepared.finalized.digest,
|
|
677
|
+
generation: work.context.runtimeBinding?.generation ?? prepared.publication.generation,
|
|
678
|
+
outputs: prepared.facts.outputs,
|
|
679
|
+
externalEvidence: prepared.product.externalEvidence,
|
|
680
|
+
});
|
|
681
|
+
await emitPackDocument(work, {
|
|
682
|
+
pack: runtimePublication.pack,
|
|
683
|
+
artifacts: prepared.finalized.artifacts,
|
|
684
|
+
packageName: `${packageId}.pack.json`,
|
|
685
|
+
originalFileName: input.sourcePath,
|
|
686
|
+
guids: prepared.product.product.assets.map((asset) => asset.guid),
|
|
687
|
+
projection: work.context.authoredCookedCurrentProjection,
|
|
688
|
+
refsByGuid: prepared.facts.refs,
|
|
689
|
+
receipts: prepared.product.product.receipts,
|
|
690
|
+
receiptOutputDigest: prepared.finalized.digest,
|
|
691
|
+
publication: runtimePublication.publication,
|
|
692
|
+
sourcePath: input.displaySourcePath,
|
|
693
|
+
revision: prepared.revision,
|
|
694
|
+
});
|
|
695
|
+
for (const asset of prepared.product.product.assets) guidSeen.add(asset.guid.toLowerCase());
|
|
696
|
+
}
|
|
697
|
+
|
|
341
698
|
async function emitFinalizedOwner(
|
|
342
699
|
work: BuildEmissionWork,
|
|
343
700
|
metaPath: string,
|
|
@@ -418,11 +775,13 @@ async function emitBuildEntry(
|
|
|
418
775
|
work: BuildEmissionWork,
|
|
419
776
|
guidSeen: Set<string>,
|
|
420
777
|
entry: PackIndexEntry,
|
|
778
|
+
availableGuids: ReadonlySet<string>,
|
|
421
779
|
): Promise<void> {
|
|
422
780
|
const guid = entry.guid.toLowerCase();
|
|
423
781
|
const metaPath = metaPathForGuid(work.context.inventory.declarations, guid);
|
|
424
782
|
if (metaPath === undefined) {
|
|
425
|
-
if (entry.sourcePath.endsWith('.pack.json'))
|
|
783
|
+
if (entry.sourcePath.endsWith('.pack.json'))
|
|
784
|
+
await emitAuthoredPack(work, guidSeen, entry, availableGuids);
|
|
426
785
|
else guidSeen.add(guid);
|
|
427
786
|
return;
|
|
428
787
|
}
|
|
@@ -436,7 +795,7 @@ async function emitBuildEntry(
|
|
|
436
795
|
});
|
|
437
796
|
}
|
|
438
797
|
const runMeta = { ...declaration, buildPack: false };
|
|
439
|
-
const subAssets
|
|
798
|
+
const subAssets = runMeta.subAssets;
|
|
440
799
|
for (const sub of subAssets) guidSeen.add(sub.guid.toLowerCase());
|
|
441
800
|
const sourcePackage = await produceSourcePackage({
|
|
442
801
|
meta: runMeta,
|
|
@@ -475,6 +834,7 @@ async function emitBuildEntry(
|
|
|
475
834
|
sourceRevision: finalized.sourceRevision,
|
|
476
835
|
packageUrl: finalized.packageUrl,
|
|
477
836
|
digest: finalized.digest,
|
|
837
|
+
sourceKeys: sourceKeysFor(subAssets),
|
|
478
838
|
});
|
|
479
839
|
await emitPackDocument(work, {
|
|
480
840
|
pack: runtimePublication.pack,
|
|
@@ -494,24 +854,21 @@ async function emitBuildEntry(
|
|
|
494
854
|
export async function produceBuildAssets(
|
|
495
855
|
context: BuildProductionOptions,
|
|
496
856
|
): Promise<PackIndexEntry[]> {
|
|
497
|
-
const
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
packageUrl: scriptable.packageUrl,
|
|
505
|
-
revision: scriptable.revision,
|
|
506
|
-
refs: scriptable.refs.get(entry.guid.toLowerCase()) ?? [],
|
|
507
|
-
...(cookReceiptUrl === undefined ? {} : { cookReceiptUrl }),
|
|
508
|
-
publication: scriptable.publication,
|
|
509
|
-
});
|
|
510
|
-
});
|
|
857
|
+
const dynamicBundles = await buildParameterizedPackages(context);
|
|
858
|
+
const entries = [
|
|
859
|
+
...context.inventory.entries,
|
|
860
|
+
...dynamicBundles.flatMap((bundle) => bundle.entries),
|
|
861
|
+
];
|
|
862
|
+
const availableGuids = new Set(entries.map((entry) => entry.guid.toLowerCase()));
|
|
863
|
+
const importedEntries = [...entries];
|
|
511
864
|
const guidSeen = new Set<string>();
|
|
512
865
|
const work: BuildEmissionWork = { importedEntries, context };
|
|
866
|
+
for (const bundle of dynamicBundles) {
|
|
867
|
+
await emitParameterizedPack(work, guidSeen, bundle);
|
|
868
|
+
}
|
|
513
869
|
for (const entry of importedEntries) {
|
|
514
|
-
if (!guidSeen.has(entry.guid.toLowerCase()))
|
|
870
|
+
if (!guidSeen.has(entry.guid.toLowerCase()))
|
|
871
|
+
await emitBuildEntry(work, guidSeen, entry, availableGuids);
|
|
515
872
|
}
|
|
516
873
|
return importedEntries;
|
|
517
874
|
}
|