@adcp/sdk 16.5.0 → 16.6.0
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/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
- package/dist/lib/adapters/version/3.0/index.js +6 -0
- package/dist/lib/adapters/version/3.0/index.mjs +7 -1
- package/dist/lib/adapters/version/3.1/bidding.js +1 -1
- package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
- package/dist/lib/adapters/version/types.d.mts +5 -0
- package/dist/lib/adapters/version/types.d.ts +5 -0
- package/dist/lib/canonical-references/index.js +2 -0
- package/dist/lib/canonical-references/index.mjs +2 -0
- package/dist/lib/client/account-changes.d.mts +3 -1
- package/dist/lib/client/account-changes.d.ts +3 -1
- package/dist/lib/client/account-changes.js +22 -2
- package/dist/lib/client/account-changes.mjs +22 -2
- package/dist/lib/conformance/oracle.js +3 -2
- package/dist/lib/conformance/oracle.mjs +3 -2
- package/dist/lib/core/AgentClient.d.mts +165 -1
- package/dist/lib/core/AgentClient.d.ts +165 -1
- package/dist/lib/core/AgentClient.js +446 -8
- package/dist/lib/core/AgentClient.mjs +446 -8
- package/dist/lib/core/ConversationTypes.d.mts +8 -0
- package/dist/lib/core/ConversationTypes.d.ts +8 -0
- package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
- package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
- package/dist/lib/core/ProtocolResponseParser.js +28 -18
- package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
- package/dist/lib/core/ResponseValidator.js +1 -1
- package/dist/lib/core/ResponseValidator.mjs +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +116 -6
- package/dist/lib/core/SingleAgentClient.d.ts +116 -6
- package/dist/lib/core/SingleAgentClient.js +556 -84
- package/dist/lib/core/SingleAgentClient.mjs +545 -72
- package/dist/lib/core/TaskExecutor.d.mts +7 -0
- package/dist/lib/core/TaskExecutor.d.ts +7 -0
- package/dist/lib/core/TaskExecutor.js +23 -8
- package/dist/lib/core/TaskExecutor.mjs +23 -8
- package/dist/lib/core/task-status.d.mts +2 -0
- package/dist/lib/core/task-status.d.ts +2 -0
- package/dist/lib/core/task-status.js +11 -2
- package/dist/lib/core/task-status.mjs +9 -1
- package/dist/lib/errors/index.d.mts +22 -0
- package/dist/lib/errors/index.d.ts +22 -0
- package/dist/lib/errors/index.js +43 -0
- package/dist/lib/errors/index.mjs +42 -0
- package/dist/lib/identity-3.3/trust.d.mts +1 -4
- package/dist/lib/identity-3.3/trust.d.ts +1 -4
- package/dist/lib/identity-3.3/trust.js +34 -21
- package/dist/lib/identity-3.3/trust.mjs +34 -21
- package/dist/lib/identity-3.3/validation.js +5 -3
- package/dist/lib/identity-3.3/validation.mjs +6 -4
- package/dist/lib/index.d.mts +8 -54
- package/dist/lib/index.d.ts +8 -54
- package/dist/lib/index.js +15 -0
- package/dist/lib/index.mjs +11 -0
- package/dist/lib/media-buy/action-assessment.js +29 -3
- package/dist/lib/media-buy/action-assessment.mjs +32 -4
- package/dist/lib/media-buy/action-contracts.d.mts +3 -0
- package/dist/lib/media-buy/action-contracts.d.ts +3 -0
- package/dist/lib/media-buy/action-contracts.js +24 -1
- package/dist/lib/media-buy/action-contracts.mjs +22 -1
- package/dist/lib/media-buy/compatibility.js +6 -1
- package/dist/lib/media-buy/compatibility.mjs +6 -1
- package/dist/lib/media-buy/preflight.js +1 -1
- package/dist/lib/media-buy/preflight.mjs +3 -2
- package/dist/lib/media-buy/types.d.mts +6 -1
- package/dist/lib/media-buy/types.d.ts +6 -1
- package/dist/lib/protocols/mcp-modern.d.mts +2 -0
- package/dist/lib/protocols/mcp-modern.d.ts +2 -0
- package/dist/lib/protocols/mcp-modern.js +31 -5
- package/dist/lib/protocols/mcp-modern.mjs +31 -5
- package/dist/lib/protocols/mcp-scope.d.mts +6 -1
- package/dist/lib/protocols/mcp-scope.d.ts +6 -1
- package/dist/lib/protocols/mcp-scope.js +25 -3
- package/dist/lib/protocols/mcp-scope.mjs +24 -3
- package/dist/lib/protocols/mcp.js +12 -6
- package/dist/lib/protocols/mcp.mjs +13 -6
- package/dist/lib/reporting/inspection.js +1 -0
- package/dist/lib/reporting/inspection.mjs +1 -0
- package/dist/lib/schemas/browser.d.mts +2 -0
- package/dist/lib/schemas/browser.d.ts +2 -0
- package/dist/lib/schemas/browser.js +3 -0
- package/dist/lib/schemas/browser.mjs +2 -0
- package/dist/lib/schemas/index.d.mts +5 -2
- package/dist/lib/schemas/index.d.ts +5 -2
- package/dist/lib/schemas/index.js +5 -0
- package/dist/lib/schemas/index.mjs +4 -0
- package/dist/lib/server/account-response-identity.d.mts +17 -0
- package/dist/lib/server/account-response-identity.d.ts +17 -0
- package/dist/lib/server/account-response-identity.js +52 -0
- package/dist/lib/server/account-response-identity.mjs +28 -0
- package/dist/lib/server/account-sync-contract.js +1 -0
- package/dist/lib/server/account-sync-contract.mjs +1 -0
- package/dist/lib/server/create-adcp-server.js +32 -19
- package/dist/lib/server/create-adcp-server.mjs +36 -12
- package/dist/lib/server/decisioning/account.d.mts +13 -6
- package/dist/lib/server/decisioning/account.d.ts +13 -6
- package/dist/lib/server/decisioning/account.js +37 -15
- package/dist/lib/server/decisioning/account.mjs +37 -15
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.js +6 -6
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +6 -6
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.mjs +2 -0
- package/dist/lib/server/media-buy-action-resolver.d.mts +3 -0
- package/dist/lib/server/media-buy-action-resolver.d.ts +3 -0
- package/dist/lib/server/media-buy-action-resolver.js +32 -0
- package/dist/lib/server/media-buy-action-resolver.mjs +32 -0
- package/dist/lib/server/media-buy-store.d.mts +26 -12
- package/dist/lib/server/media-buy-store.d.ts +26 -12
- package/dist/lib/server/media-buy-store.js +69 -21
- package/dist/lib/server/media-buy-store.mjs +69 -21
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.mjs +9 -1
- package/dist/lib/server/state-machine.d.mts +10 -11
- package/dist/lib/server/state-machine.d.ts +10 -11
- package/dist/lib/server/state-machine.js +20 -5
- package/dist/lib/server/state-machine.mjs +19 -5
- package/dist/lib/signing/agent-fetch.d.mts +1 -1
- package/dist/lib/signing/agent-fetch.d.ts +1 -1
- package/dist/lib/signing/agent-fetch.js +3 -3
- package/dist/lib/signing/agent-fetch.mjs +3 -3
- package/dist/lib/testing/client.d.mts +1 -0
- package/dist/lib/testing/client.d.ts +1 -0
- package/dist/lib/testing/client.js +6 -5
- package/dist/lib/testing/client.mjs +6 -5
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
- package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
- package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
- package/dist/lib/testing/storyboard/compliance.js +62 -13
- package/dist/lib/testing/storyboard/compliance.mjs +63 -14
- package/dist/lib/testing/storyboard/context.d.mts +13 -3
- package/dist/lib/testing/storyboard/context.d.ts +13 -3
- package/dist/lib/testing/storyboard/context.js +15 -10
- package/dist/lib/testing/storyboard/context.mjs +15 -10
- package/dist/lib/testing/storyboard/default-invariants.js +10 -8
- package/dist/lib/testing/storyboard/default-invariants.mjs +11 -9
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
- package/dist/lib/testing/storyboard/runner.js +23 -10
- package/dist/lib/testing/storyboard/runner.mjs +23 -10
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.js +4 -1
- package/dist/lib/testing/storyboard/validations.mjs +4 -1
- package/dist/lib/testing/test-controller.js +3 -0
- package/dist/lib/testing/test-controller.mjs +3 -0
- package/dist/lib/types/asset-instances.d.mts +1 -1
- package/dist/lib/types/asset-instances.d.ts +1 -1
- package/dist/lib/types/index.d.mts +5 -0
- package/dist/lib/types/index.d.ts +5 -0
- package/dist/lib/types/index.js +6 -1
- package/dist/lib/types/index.mjs +4 -1
- package/dist/lib/types/inline-enums.generated.d.mts +30 -4
- package/dist/lib/types/inline-enums.generated.d.ts +30 -4
- package/dist/lib/types/inline-enums.generated.js +41 -2
- package/dist/lib/types/inline-enums.generated.mjs +28 -2
- package/dist/lib/types/media-buy-delivery-report.d.mts +4 -0
- package/dist/lib/types/media-buy-delivery-report.d.ts +4 -0
- package/dist/lib/types/media-buy-delivery-report.js +16 -0
- package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
- package/dist/lib/types/schemas.generated.d.ts +20 -69
- package/dist/lib/types/schemas.generated.js +29 -46
- package/dist/lib/types/schemas.generated.mjs +29 -46
- package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
- package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
- package/dist/lib/types/targeting-keys.generated.js +105 -0
- package/dist/lib/types/targeting-keys.generated.mjs +80 -0
- package/dist/lib/utils/adcp-version-config.js +5 -2
- package/dist/lib/utils/adcp-version-config.mjs +5 -2
- package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
- package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
- package/dist/lib/utils/envelope-status-compat.js +11 -5
- package/dist/lib/utils/envelope-status-compat.mjs +11 -5
- package/dist/lib/utils/response-unwrapper.js +18 -10
- package/dist/lib/utils/response-unwrapper.mjs +18 -10
- package/dist/lib/v2/format-schema/resolver.js +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +1 -1
- package/dist/lib/v2/projection/creative-delivery.js +123 -30
- package/dist/lib/v2/projection/creative-delivery.mjs +127 -30
- package/dist/lib/v2/projection/index.d.mts +1 -0
- package/dist/lib/v2/projection/index.d.ts +1 -0
- package/dist/lib/v2/projection/index.js +3 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.js +91 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
- package/dist/lib/validation/compact-schema.d.mts +27 -0
- package/dist/lib/validation/compact-schema.d.ts +27 -0
- package/dist/lib/validation/compact-schema.js +276 -0
- package/dist/lib/validation/compact-schema.mjs +250 -0
- package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.js +31 -0
- package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
- package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
- package/dist/lib/validation/schema-loader.js +86 -16
- package/dist/lib/validation/schema-loader.mjs +82 -16
- package/dist/lib/validation/schema-validator.d.mts +10 -19
- package/dist/lib/validation/schema-validator.d.ts +10 -19
- package/dist/lib/validation/schema-validator.js +136 -43
- package/dist/lib/validation/schema-validator.mjs +140 -44
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/webhooks/index.d.mts +3 -0
- package/dist/lib/webhooks/index.d.ts +3 -0
- package/dist/lib/webhooks/index.js +3 -0
- package/dist/lib/webhooks/index.mjs +2 -0
- package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.js +119 -0
- package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/BUILD-AN-AGENT.md +9 -1
- package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +135 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
- package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
- package/docs/llms.txt +3 -3
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-6.6-to-6.7.md +14 -0
- package/docs/migration-account-change-feed.md +19 -0
- package/docs/releases/sdk-16.6-adoption-fixes.md +33 -0
- package/package.json +2 -2
|
@@ -208,17 +208,41 @@ function evaluatePackage(pkg, pointer, index, products) {
|
|
|
208
208
|
actual: productId ?? null
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
|
+
const routes = [];
|
|
211
212
|
const formatOptionRefs = Array.isArray(pkg.format_option_refs) ? pkg.format_option_refs : [];
|
|
212
213
|
if (formatOptionRefs.length > 0) {
|
|
213
|
-
|
|
214
|
+
routes.push({ name: "format_option_refs", verdict: evaluateFormatOptionRefs(formatOptionRefs, product, pointer) });
|
|
214
215
|
}
|
|
215
216
|
const formatIds = Array.isArray(pkg.format_ids) ? pkg.format_ids : [];
|
|
216
217
|
if (formatIds.length > 0) {
|
|
217
|
-
|
|
218
|
+
routes.push({ name: "format_ids", verdict: evaluateLegacyFormatIds(formatIds, product, pointer, productId) });
|
|
218
219
|
}
|
|
219
220
|
const canonicalSelectors = extractCanonicalSelectors(pkg, pointer);
|
|
220
221
|
if (canonicalSelectors.length > 0) {
|
|
221
|
-
|
|
222
|
+
routes.push({ name: "canonical selectors", verdict: evaluateCanonicalSelectors(canonicalSelectors, product) });
|
|
223
|
+
}
|
|
224
|
+
const failed = routes.find((route) => !route.verdict.satisfied);
|
|
225
|
+
if (failed) return failed.verdict;
|
|
226
|
+
const primary = routes[0];
|
|
227
|
+
if (primary) {
|
|
228
|
+
const selected = new Set(primary.verdict.selectedDeclarations);
|
|
229
|
+
const conflicting = routes.slice(1).find((route) => {
|
|
230
|
+
const other = new Set(route.verdict.selectedDeclarations);
|
|
231
|
+
return selected.size !== other.size || [...selected].some((index2) => !other.has(index2));
|
|
232
|
+
});
|
|
233
|
+
if (conflicting) {
|
|
234
|
+
return {
|
|
235
|
+
satisfied: false,
|
|
236
|
+
bug_class: "directionality",
|
|
237
|
+
detail: `Conflicting selector routes ${primary.name} and ${conflicting.name} select different product format_options[] sets`,
|
|
238
|
+
json_pointer: pointer,
|
|
239
|
+
observations: routes.map((route) => ({
|
|
240
|
+
route: route.name,
|
|
241
|
+
selected_declarations: route.verdict.selectedDeclarations
|
|
242
|
+
}))
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return primary.verdict;
|
|
222
246
|
}
|
|
223
247
|
return {
|
|
224
248
|
satisfied: true,
|
|
@@ -238,6 +262,7 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
|
|
|
238
262
|
actual: refs
|
|
239
263
|
};
|
|
240
264
|
}
|
|
265
|
+
const selected = /* @__PURE__ */ new Set();
|
|
241
266
|
for (let i = 0; i < refs.length; i++) {
|
|
242
267
|
const ref = refs[i];
|
|
243
268
|
if (!isRecord(ref)) {
|
|
@@ -267,13 +292,13 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
|
|
|
267
292
|
actual: ref
|
|
268
293
|
};
|
|
269
294
|
}
|
|
270
|
-
const match = declarations.
|
|
295
|
+
const match = declarations.findIndex((decl) => {
|
|
271
296
|
if (ref.scope === "publisher") {
|
|
272
297
|
return decl.publisher_domain === ref.publisher_domain && decl.format_option_id === ref.format_option_id && typeof ref.publisher_domain === "string";
|
|
273
298
|
}
|
|
274
299
|
return decl.format_option_id === ref.format_option_id && !decl.publisher_domain;
|
|
275
300
|
});
|
|
276
|
-
if (
|
|
301
|
+
if (match < 0) {
|
|
277
302
|
return {
|
|
278
303
|
satisfied: false,
|
|
279
304
|
bug_class: "closed_set",
|
|
@@ -283,16 +308,19 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
|
|
|
283
308
|
observations: [{ available_format_option_ids: declarations.map(declarationLabel).filter(Boolean) }]
|
|
284
309
|
};
|
|
285
310
|
}
|
|
311
|
+
selected.add(match);
|
|
286
312
|
}
|
|
287
313
|
return {
|
|
288
314
|
satisfied: true,
|
|
289
315
|
bug_class: "directionality",
|
|
290
316
|
detail: "Every format_option_refs[] entry resolved to the target product format_options[] closed set",
|
|
291
|
-
json_pointer: `${packagePointer}/format_option_refs
|
|
317
|
+
json_pointer: `${packagePointer}/format_option_refs`,
|
|
318
|
+
selectedDeclarations: [...selected]
|
|
292
319
|
};
|
|
293
320
|
}
|
|
294
321
|
function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
|
|
295
322
|
const declarations = productFormatOptions(product);
|
|
323
|
+
const selected = /* @__PURE__ */ new Set();
|
|
296
324
|
for (let i = 0; i < refs.length; i++) {
|
|
297
325
|
const ref = refs[i];
|
|
298
326
|
if (!isFormatId(ref)) {
|
|
@@ -304,12 +332,22 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
|
|
|
304
332
|
actual: ref
|
|
305
333
|
};
|
|
306
334
|
}
|
|
307
|
-
const direct = declarations.
|
|
308
|
-
|
|
335
|
+
const direct = declarations.flatMap(
|
|
336
|
+
(decl, index) => (decl.v1_format_ref ?? []).some((v1) => sameFormatId(v1, ref)) ? [index] : []
|
|
337
|
+
);
|
|
338
|
+
if (direct.length > 0) {
|
|
339
|
+
for (const index of direct) selected.add(index);
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
309
342
|
const projected = projectLegacyRef(ref, productId, `${packagePointer}/format_ids/${i}`);
|
|
310
343
|
if (projected) {
|
|
311
|
-
const
|
|
312
|
-
|
|
344
|
+
const matches = declarations.flatMap(
|
|
345
|
+
(decl, index) => canonicalSelectorSatisfiesDeclaration(projected, decl).ok ? [index] : []
|
|
346
|
+
);
|
|
347
|
+
if (matches.length > 0) {
|
|
348
|
+
for (const index of matches) selected.add(index);
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
313
351
|
}
|
|
314
352
|
if (declarations.length === 0 && Array.isArray(product.format_ids) && product.format_ids.some((fid) => isFormatId(fid) && sameFormatId(fid, ref))) {
|
|
315
353
|
continue;
|
|
@@ -327,7 +365,8 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
|
|
|
327
365
|
satisfied: true,
|
|
328
366
|
bug_class: "normalization",
|
|
329
367
|
detail: "Every legacy format_id normalized to a product canonical declaration or product legacy format_id",
|
|
330
|
-
json_pointer: `${packagePointer}/format_ids
|
|
368
|
+
json_pointer: `${packagePointer}/format_ids`,
|
|
369
|
+
selectedDeclarations: [...selected]
|
|
331
370
|
};
|
|
332
371
|
}
|
|
333
372
|
function evaluateCanonicalSelectors(selectors, product) {
|
|
@@ -341,6 +380,7 @@ function evaluateCanonicalSelectors(selectors, product) {
|
|
|
341
380
|
actual: selectors
|
|
342
381
|
};
|
|
343
382
|
}
|
|
383
|
+
const selected = /* @__PURE__ */ new Set();
|
|
344
384
|
for (const selector of selectors) {
|
|
345
385
|
const candidates = declarations.filter((decl) => decl.format_kind === selector.format_kind);
|
|
346
386
|
if (candidates.length === 0) {
|
|
@@ -353,7 +393,12 @@ function evaluateCanonicalSelectors(selectors, product) {
|
|
|
353
393
|
};
|
|
354
394
|
}
|
|
355
395
|
const checks = candidates.map((decl) => canonicalSelectorSatisfiesDeclaration(selector, decl));
|
|
356
|
-
if (checks.some((c) => c.ok))
|
|
396
|
+
if (checks.some((c) => c.ok)) {
|
|
397
|
+
for (const [index, decl] of declarations.entries()) {
|
|
398
|
+
if (canonicalSelectorSatisfiesDeclaration(selector, decl).ok) selected.add(index);
|
|
399
|
+
}
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
357
402
|
const primary = checks.find((c) => c.bug_class === "range_containment") ?? checks[0];
|
|
358
403
|
return {
|
|
359
404
|
satisfied: false,
|
|
@@ -368,7 +413,8 @@ function evaluateCanonicalSelectors(selectors, product) {
|
|
|
368
413
|
satisfied: true,
|
|
369
414
|
bug_class: "directionality",
|
|
370
415
|
detail: "Every canonical selector satisfies at least one product format_options[] declaration",
|
|
371
|
-
json_pointer: selectors[0]?.pointer ?? null
|
|
416
|
+
json_pointer: selectors[0]?.pointer ?? null,
|
|
417
|
+
selectedDeclarations: [...selected]
|
|
372
418
|
};
|
|
373
419
|
}
|
|
374
420
|
function canonicalSelectorSatisfiesDeclaration(selector, decl) {
|
|
@@ -737,7 +783,7 @@ function collectRejectionInfo(value, codes, fields, messages, depth = 0) {
|
|
|
737
783
|
}
|
|
738
784
|
function rejectionSupportsFormatFailure(rejection) {
|
|
739
785
|
if (!rejection) return false;
|
|
740
|
-
if (rejection.codes.some((code) => code.startsWith("FORMAT_"))) return true;
|
|
786
|
+
if (rejection.codes.some((code) => code.startsWith("FORMAT_") || code === "CONFLICTING_SELECTORS")) return true;
|
|
741
787
|
return [...rejection.fields, ...rejection.messages].some(
|
|
742
788
|
(text) => /format|format_option|format_id|selector/i.test(text)
|
|
743
789
|
);
|
|
@@ -184,17 +184,41 @@ function evaluatePackage(pkg, pointer, index, products) {
|
|
|
184
184
|
actual: productId ?? null
|
|
185
185
|
};
|
|
186
186
|
}
|
|
187
|
+
const routes = [];
|
|
187
188
|
const formatOptionRefs = Array.isArray(pkg.format_option_refs) ? pkg.format_option_refs : [];
|
|
188
189
|
if (formatOptionRefs.length > 0) {
|
|
189
|
-
|
|
190
|
+
routes.push({ name: "format_option_refs", verdict: evaluateFormatOptionRefs(formatOptionRefs, product, pointer) });
|
|
190
191
|
}
|
|
191
192
|
const formatIds = Array.isArray(pkg.format_ids) ? pkg.format_ids : [];
|
|
192
193
|
if (formatIds.length > 0) {
|
|
193
|
-
|
|
194
|
+
routes.push({ name: "format_ids", verdict: evaluateLegacyFormatIds(formatIds, product, pointer, productId) });
|
|
194
195
|
}
|
|
195
196
|
const canonicalSelectors = extractCanonicalSelectors(pkg, pointer);
|
|
196
197
|
if (canonicalSelectors.length > 0) {
|
|
197
|
-
|
|
198
|
+
routes.push({ name: "canonical selectors", verdict: evaluateCanonicalSelectors(canonicalSelectors, product) });
|
|
199
|
+
}
|
|
200
|
+
const failed = routes.find((route) => !route.verdict.satisfied);
|
|
201
|
+
if (failed) return failed.verdict;
|
|
202
|
+
const primary = routes[0];
|
|
203
|
+
if (primary) {
|
|
204
|
+
const selected = new Set(primary.verdict.selectedDeclarations);
|
|
205
|
+
const conflicting = routes.slice(1).find((route) => {
|
|
206
|
+
const other = new Set(route.verdict.selectedDeclarations);
|
|
207
|
+
return selected.size !== other.size || [...selected].some((index2) => !other.has(index2));
|
|
208
|
+
});
|
|
209
|
+
if (conflicting) {
|
|
210
|
+
return {
|
|
211
|
+
satisfied: false,
|
|
212
|
+
bug_class: "directionality",
|
|
213
|
+
detail: `Conflicting selector routes ${primary.name} and ${conflicting.name} select different product format_options[] sets`,
|
|
214
|
+
json_pointer: pointer,
|
|
215
|
+
observations: routes.map((route) => ({
|
|
216
|
+
route: route.name,
|
|
217
|
+
selected_declarations: route.verdict.selectedDeclarations
|
|
218
|
+
}))
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return primary.verdict;
|
|
198
222
|
}
|
|
199
223
|
return {
|
|
200
224
|
satisfied: true,
|
|
@@ -214,6 +238,7 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
|
|
|
214
238
|
actual: refs
|
|
215
239
|
};
|
|
216
240
|
}
|
|
241
|
+
const selected = /* @__PURE__ */ new Set();
|
|
217
242
|
for (let i = 0; i < refs.length; i++) {
|
|
218
243
|
const ref = refs[i];
|
|
219
244
|
if (!isRecord(ref)) {
|
|
@@ -243,13 +268,13 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
|
|
|
243
268
|
actual: ref
|
|
244
269
|
};
|
|
245
270
|
}
|
|
246
|
-
const match = declarations.
|
|
271
|
+
const match = declarations.findIndex((decl) => {
|
|
247
272
|
if (ref.scope === "publisher") {
|
|
248
273
|
return decl.publisher_domain === ref.publisher_domain && decl.format_option_id === ref.format_option_id && typeof ref.publisher_domain === "string";
|
|
249
274
|
}
|
|
250
275
|
return decl.format_option_id === ref.format_option_id && !decl.publisher_domain;
|
|
251
276
|
});
|
|
252
|
-
if (
|
|
277
|
+
if (match < 0) {
|
|
253
278
|
return {
|
|
254
279
|
satisfied: false,
|
|
255
280
|
bug_class: "closed_set",
|
|
@@ -259,16 +284,19 @@ function evaluateFormatOptionRefs(refs, product, packagePointer) {
|
|
|
259
284
|
observations: [{ available_format_option_ids: declarations.map(declarationLabel).filter(Boolean) }]
|
|
260
285
|
};
|
|
261
286
|
}
|
|
287
|
+
selected.add(match);
|
|
262
288
|
}
|
|
263
289
|
return {
|
|
264
290
|
satisfied: true,
|
|
265
291
|
bug_class: "directionality",
|
|
266
292
|
detail: "Every format_option_refs[] entry resolved to the target product format_options[] closed set",
|
|
267
|
-
json_pointer: `${packagePointer}/format_option_refs
|
|
293
|
+
json_pointer: `${packagePointer}/format_option_refs`,
|
|
294
|
+
selectedDeclarations: [...selected]
|
|
268
295
|
};
|
|
269
296
|
}
|
|
270
297
|
function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
|
|
271
298
|
const declarations = productFormatOptions(product);
|
|
299
|
+
const selected = /* @__PURE__ */ new Set();
|
|
272
300
|
for (let i = 0; i < refs.length; i++) {
|
|
273
301
|
const ref = refs[i];
|
|
274
302
|
if (!isFormatId(ref)) {
|
|
@@ -280,12 +308,22 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
|
|
|
280
308
|
actual: ref
|
|
281
309
|
};
|
|
282
310
|
}
|
|
283
|
-
const direct = declarations.
|
|
284
|
-
|
|
311
|
+
const direct = declarations.flatMap(
|
|
312
|
+
(decl, index) => (decl.v1_format_ref ?? []).some((v1) => sameFormatId(v1, ref)) ? [index] : []
|
|
313
|
+
);
|
|
314
|
+
if (direct.length > 0) {
|
|
315
|
+
for (const index of direct) selected.add(index);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
285
318
|
const projected = projectLegacyRef(ref, productId, `${packagePointer}/format_ids/${i}`);
|
|
286
319
|
if (projected) {
|
|
287
|
-
const
|
|
288
|
-
|
|
320
|
+
const matches = declarations.flatMap(
|
|
321
|
+
(decl, index) => canonicalSelectorSatisfiesDeclaration(projected, decl).ok ? [index] : []
|
|
322
|
+
);
|
|
323
|
+
if (matches.length > 0) {
|
|
324
|
+
for (const index of matches) selected.add(index);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
289
327
|
}
|
|
290
328
|
if (declarations.length === 0 && Array.isArray(product.format_ids) && product.format_ids.some((fid) => isFormatId(fid) && sameFormatId(fid, ref))) {
|
|
291
329
|
continue;
|
|
@@ -303,7 +341,8 @@ function evaluateLegacyFormatIds(refs, product, packagePointer, productId) {
|
|
|
303
341
|
satisfied: true,
|
|
304
342
|
bug_class: "normalization",
|
|
305
343
|
detail: "Every legacy format_id normalized to a product canonical declaration or product legacy format_id",
|
|
306
|
-
json_pointer: `${packagePointer}/format_ids
|
|
344
|
+
json_pointer: `${packagePointer}/format_ids`,
|
|
345
|
+
selectedDeclarations: [...selected]
|
|
307
346
|
};
|
|
308
347
|
}
|
|
309
348
|
function evaluateCanonicalSelectors(selectors, product) {
|
|
@@ -317,6 +356,7 @@ function evaluateCanonicalSelectors(selectors, product) {
|
|
|
317
356
|
actual: selectors
|
|
318
357
|
};
|
|
319
358
|
}
|
|
359
|
+
const selected = /* @__PURE__ */ new Set();
|
|
320
360
|
for (const selector of selectors) {
|
|
321
361
|
const candidates = declarations.filter((decl) => decl.format_kind === selector.format_kind);
|
|
322
362
|
if (candidates.length === 0) {
|
|
@@ -329,7 +369,12 @@ function evaluateCanonicalSelectors(selectors, product) {
|
|
|
329
369
|
};
|
|
330
370
|
}
|
|
331
371
|
const checks = candidates.map((decl) => canonicalSelectorSatisfiesDeclaration(selector, decl));
|
|
332
|
-
if (checks.some((c) => c.ok))
|
|
372
|
+
if (checks.some((c) => c.ok)) {
|
|
373
|
+
for (const [index, decl] of declarations.entries()) {
|
|
374
|
+
if (canonicalSelectorSatisfiesDeclaration(selector, decl).ok) selected.add(index);
|
|
375
|
+
}
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
333
378
|
const primary = checks.find((c) => c.bug_class === "range_containment") ?? checks[0];
|
|
334
379
|
return {
|
|
335
380
|
satisfied: false,
|
|
@@ -344,7 +389,8 @@ function evaluateCanonicalSelectors(selectors, product) {
|
|
|
344
389
|
satisfied: true,
|
|
345
390
|
bug_class: "directionality",
|
|
346
391
|
detail: "Every canonical selector satisfies at least one product format_options[] declaration",
|
|
347
|
-
json_pointer: selectors[0]?.pointer ?? null
|
|
392
|
+
json_pointer: selectors[0]?.pointer ?? null,
|
|
393
|
+
selectedDeclarations: [...selected]
|
|
348
394
|
};
|
|
349
395
|
}
|
|
350
396
|
function canonicalSelectorSatisfiesDeclaration(selector, decl) {
|
|
@@ -713,7 +759,7 @@ function collectRejectionInfo(value, codes, fields, messages, depth = 0) {
|
|
|
713
759
|
}
|
|
714
760
|
function rejectionSupportsFormatFailure(rejection) {
|
|
715
761
|
if (!rejection) return false;
|
|
716
|
-
if (rejection.codes.some((code) => code.startsWith("FORMAT_"))) return true;
|
|
762
|
+
if (rejection.codes.some((code) => code.startsWith("FORMAT_") || code === "CONFLICTING_SELECTORS")) return true;
|
|
717
763
|
return [...rejection.fields, ...rejection.messages].some(
|
|
718
764
|
(text) => /format|format_option|format_id|selector/i.test(text)
|
|
719
765
|
);
|
|
@@ -181,12 +181,9 @@ export declare function getExternalSchemaRootForCompliance(options: ResolveOptio
|
|
|
181
181
|
export declare function loadBundleStoryboards(ref: BundleRef): Storyboard[];
|
|
182
182
|
/** Enumerate every bundle present in the cache (universal + protocols + specialisms). */
|
|
183
183
|
export declare function listBundles(options?: ResolveOptions): BundleRef[];
|
|
184
|
-
/** List every storyboard the
|
|
184
|
+
/** List every storyboard the selected immutable bundle can produce, as detached records. */
|
|
185
185
|
export declare function listAllComplianceStoryboards(options?: ResolveOptions): Storyboard[];
|
|
186
|
-
/**
|
|
187
|
-
* Find a storyboard by its internal `id` (the YAML's `id:` field).
|
|
188
|
-
* Scans every bundle in the cache. Returns undefined if no match.
|
|
189
|
-
*/
|
|
186
|
+
/** Find a storyboard by its internal YAML id without reparsing a warm bundle. */
|
|
190
187
|
export declare function getComplianceStoryboardById(id: string, options?: ResolveOptions): Storyboard | undefined;
|
|
191
188
|
/** Find a bundle by its directory/file id (`media-buy`, `sales-guaranteed`, `capability-discovery`). */
|
|
192
189
|
export declare function findBundleById(id: string, options?: ResolveOptions): BundleRef | undefined;
|
|
@@ -181,12 +181,9 @@ export declare function getExternalSchemaRootForCompliance(options: ResolveOptio
|
|
|
181
181
|
export declare function loadBundleStoryboards(ref: BundleRef): Storyboard[];
|
|
182
182
|
/** Enumerate every bundle present in the cache (universal + protocols + specialisms). */
|
|
183
183
|
export declare function listBundles(options?: ResolveOptions): BundleRef[];
|
|
184
|
-
/** List every storyboard the
|
|
184
|
+
/** List every storyboard the selected immutable bundle can produce, as detached records. */
|
|
185
185
|
export declare function listAllComplianceStoryboards(options?: ResolveOptions): Storyboard[];
|
|
186
|
-
/**
|
|
187
|
-
* Find a storyboard by its internal `id` (the YAML's `id:` field).
|
|
188
|
-
* Scans every bundle in the cache. Returns undefined if no match.
|
|
189
|
-
*/
|
|
186
|
+
/** Find a storyboard by its internal YAML id without reparsing a warm bundle. */
|
|
190
187
|
export declare function getComplianceStoryboardById(id: string, options?: ResolveOptions): Storyboard | undefined;
|
|
191
188
|
/** Find a bundle by its directory/file id (`media-buy`, `sales-guaranteed`, `capability-discovery`). */
|
|
192
189
|
export declare function findBundleById(id: string, options?: ResolveOptions): BundleRef | undefined;
|
|
@@ -47,6 +47,7 @@ var import_errors = require('../../errors/index.js');
|
|
|
47
47
|
var import_adcp_version_config = require('../../utils/adcp-version-config.js');
|
|
48
48
|
var import_schema_loader = require('../../validation/schema-loader.js');
|
|
49
49
|
var import_synthesize = require('./request-signing/synthesize.js');
|
|
50
|
+
var import_vector_loader = require('./request-signing/vector-loader.js');
|
|
50
51
|
var import_provenance = require('./provenance.js');
|
|
51
52
|
class CapabilityResolutionError extends import_errors.ADCPError {
|
|
52
53
|
code;
|
|
@@ -434,23 +435,71 @@ function listBundles(options = {}) {
|
|
|
434
435
|
}
|
|
435
436
|
return bundles;
|
|
436
437
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
438
|
+
const STORYBOARD_INDEX_CACHE_LIMIT = 8;
|
|
439
|
+
const storyboardIndexes = /* @__PURE__ */ new Map();
|
|
440
|
+
function customComplianceInventory(dir) {
|
|
441
|
+
if (!(0, import_fs.existsSync)(dir)) return "missing";
|
|
442
|
+
const entries = [];
|
|
443
|
+
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
444
|
+
const visit = (file, relative) => {
|
|
445
|
+
const stat = (0, import_fs.statSync)(file, { bigint: true });
|
|
446
|
+
entries.push([relative, String(stat.mtimeNs), String(stat.ctimeNs), String(stat.size), String(stat.ino)]);
|
|
447
|
+
if (!stat.isDirectory()) return;
|
|
448
|
+
const identity = `${stat.dev}:${stat.ino}`;
|
|
449
|
+
if (visitedDirectories.has(identity)) return;
|
|
450
|
+
visitedDirectories.add(identity);
|
|
451
|
+
for (const child of (0, import_fs.readdirSync)(file).sort()) visit((0, import_path.join)(file, child), `${relative}/${child}`);
|
|
452
|
+
};
|
|
453
|
+
visit(dir, "");
|
|
454
|
+
return JSON.stringify(entries);
|
|
455
|
+
}
|
|
456
|
+
function complianceStoryboardIndex(options) {
|
|
457
|
+
const dir = (0, import_path.resolve)(getComplianceCacheDir(options));
|
|
458
|
+
const indexPath = (0, import_path.join)(dir, "index.json");
|
|
459
|
+
const stamp = (0, import_fs.existsSync)(indexPath) ? (0, import_fs.statSync)(indexPath) : void 0;
|
|
460
|
+
const schemaRoot = getConfiguredSchemaRoot(options);
|
|
461
|
+
const customRoot = Boolean(getConfiguredComplianceDir(options));
|
|
462
|
+
const inventory = customRoot ? customComplianceInventory(dir) : null;
|
|
463
|
+
const key = JSON.stringify([
|
|
464
|
+
dir,
|
|
465
|
+
options.version ?? import_version.ADCP_VERSION,
|
|
466
|
+
schemaRoot ? (0, import_path.resolve)(schemaRoot) : null,
|
|
467
|
+
options.hostedStableLineAlias ?? null,
|
|
468
|
+
stamp?.mtimeMs ?? null,
|
|
469
|
+
stamp?.size ?? null,
|
|
470
|
+
inventory
|
|
471
|
+
]);
|
|
472
|
+
const cached = storyboardIndexes.get(key);
|
|
473
|
+
if (cached) {
|
|
474
|
+
storyboardIndexes.delete(key);
|
|
475
|
+
storyboardIndexes.set(key, cached);
|
|
476
|
+
return cached;
|
|
477
|
+
}
|
|
478
|
+
if (customRoot) (0, import_vector_loader.invalidateRequestSigningVectorCache)(dir);
|
|
479
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
480
|
+
for (const ref of listBundles({ ...options, complianceDir: dir })) {
|
|
481
|
+
for (const storyboard of loadBundleStoryboards(ref)) {
|
|
482
|
+
if (!indexed.has(storyboard.id)) indexed.set(storyboard.id, storyboard);
|
|
445
483
|
}
|
|
446
484
|
}
|
|
447
|
-
|
|
485
|
+
storyboardIndexes.set(key, indexed);
|
|
486
|
+
while (storyboardIndexes.size > STORYBOARD_INDEX_CACHE_LIMIT) {
|
|
487
|
+
const oldest = storyboardIndexes.keys().next().value;
|
|
488
|
+
if (oldest !== void 0) storyboardIndexes.delete(oldest);
|
|
489
|
+
}
|
|
490
|
+
return indexed;
|
|
491
|
+
}
|
|
492
|
+
function cloneComplianceStoryboard(storyboard) {
|
|
493
|
+
const copy = structuredClone(storyboard);
|
|
494
|
+
const trustedRoot = (0, import_provenance.trustedStoryboardComplianceRoot)(storyboard);
|
|
495
|
+
return trustedRoot ? (0, import_provenance.markStoryboardComplianceRoot)(copy, trustedRoot) : copy;
|
|
496
|
+
}
|
|
497
|
+
function listAllComplianceStoryboards(options = {}) {
|
|
498
|
+
return [...complianceStoryboardIndex(options).values()].map(cloneComplianceStoryboard);
|
|
448
499
|
}
|
|
449
500
|
function getComplianceStoryboardById(id, options = {}) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
}
|
|
453
|
-
return void 0;
|
|
501
|
+
const storyboard = complianceStoryboardIndex(options).get(id);
|
|
502
|
+
return storyboard ? cloneComplianceStoryboard(storyboard) : void 0;
|
|
454
503
|
}
|
|
455
504
|
function findBundleById(id, options = {}) {
|
|
456
505
|
return listBundles(options).find((b) => b.id === id);
|
|
@@ -12,7 +12,8 @@ import { ADCPError } from "../../errors/index.mjs";
|
|
|
12
12
|
import { isAdcpVersionSupported } from "../../utils/adcp-version-config.mjs";
|
|
13
13
|
import { hasSchemaBundle, resolveBundleKey } from "../../validation/schema-loader.mjs";
|
|
14
14
|
import { synthesizeRequestSigningSteps } from "./request-signing/synthesize.mjs";
|
|
15
|
-
import {
|
|
15
|
+
import { invalidateRequestSigningVectorCache } from "./request-signing/vector-loader.mjs";
|
|
16
|
+
import { markStoryboardComplianceRoot, trustedStoryboardComplianceRoot } from "./provenance.mjs";
|
|
16
17
|
class CapabilityResolutionError extends ADCPError {
|
|
17
18
|
code;
|
|
18
19
|
specialism;
|
|
@@ -399,23 +400,71 @@ function listBundles(options = {}) {
|
|
|
399
400
|
}
|
|
400
401
|
return bundles;
|
|
401
402
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
403
|
+
const STORYBOARD_INDEX_CACHE_LIMIT = 8;
|
|
404
|
+
const storyboardIndexes = /* @__PURE__ */ new Map();
|
|
405
|
+
function customComplianceInventory(dir) {
|
|
406
|
+
if (!existsSync(dir)) return "missing";
|
|
407
|
+
const entries = [];
|
|
408
|
+
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
409
|
+
const visit = (file, relative) => {
|
|
410
|
+
const stat = statSync(file, { bigint: true });
|
|
411
|
+
entries.push([relative, String(stat.mtimeNs), String(stat.ctimeNs), String(stat.size), String(stat.ino)]);
|
|
412
|
+
if (!stat.isDirectory()) return;
|
|
413
|
+
const identity = `${stat.dev}:${stat.ino}`;
|
|
414
|
+
if (visitedDirectories.has(identity)) return;
|
|
415
|
+
visitedDirectories.add(identity);
|
|
416
|
+
for (const child of readdirSync(file).sort()) visit(join(file, child), `${relative}/${child}`);
|
|
417
|
+
};
|
|
418
|
+
visit(dir, "");
|
|
419
|
+
return JSON.stringify(entries);
|
|
420
|
+
}
|
|
421
|
+
function complianceStoryboardIndex(options) {
|
|
422
|
+
const dir = resolve(getComplianceCacheDir(options));
|
|
423
|
+
const indexPath = join(dir, "index.json");
|
|
424
|
+
const stamp = existsSync(indexPath) ? statSync(indexPath) : void 0;
|
|
425
|
+
const schemaRoot = getConfiguredSchemaRoot(options);
|
|
426
|
+
const customRoot = Boolean(getConfiguredComplianceDir(options));
|
|
427
|
+
const inventory = customRoot ? customComplianceInventory(dir) : null;
|
|
428
|
+
const key = JSON.stringify([
|
|
429
|
+
dir,
|
|
430
|
+
options.version ?? ADCP_VERSION,
|
|
431
|
+
schemaRoot ? resolve(schemaRoot) : null,
|
|
432
|
+
options.hostedStableLineAlias ?? null,
|
|
433
|
+
stamp?.mtimeMs ?? null,
|
|
434
|
+
stamp?.size ?? null,
|
|
435
|
+
inventory
|
|
436
|
+
]);
|
|
437
|
+
const cached = storyboardIndexes.get(key);
|
|
438
|
+
if (cached) {
|
|
439
|
+
storyboardIndexes.delete(key);
|
|
440
|
+
storyboardIndexes.set(key, cached);
|
|
441
|
+
return cached;
|
|
442
|
+
}
|
|
443
|
+
if (customRoot) invalidateRequestSigningVectorCache(dir);
|
|
444
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
445
|
+
for (const ref of listBundles({ ...options, complianceDir: dir })) {
|
|
446
|
+
for (const storyboard of loadBundleStoryboards(ref)) {
|
|
447
|
+
if (!indexed.has(storyboard.id)) indexed.set(storyboard.id, storyboard);
|
|
410
448
|
}
|
|
411
449
|
}
|
|
412
|
-
|
|
450
|
+
storyboardIndexes.set(key, indexed);
|
|
451
|
+
while (storyboardIndexes.size > STORYBOARD_INDEX_CACHE_LIMIT) {
|
|
452
|
+
const oldest = storyboardIndexes.keys().next().value;
|
|
453
|
+
if (oldest !== void 0) storyboardIndexes.delete(oldest);
|
|
454
|
+
}
|
|
455
|
+
return indexed;
|
|
456
|
+
}
|
|
457
|
+
function cloneComplianceStoryboard(storyboard) {
|
|
458
|
+
const copy = structuredClone(storyboard);
|
|
459
|
+
const trustedRoot = trustedStoryboardComplianceRoot(storyboard);
|
|
460
|
+
return trustedRoot ? markStoryboardComplianceRoot(copy, trustedRoot) : copy;
|
|
461
|
+
}
|
|
462
|
+
function listAllComplianceStoryboards(options = {}) {
|
|
463
|
+
return [...complianceStoryboardIndex(options).values()].map(cloneComplianceStoryboard);
|
|
413
464
|
}
|
|
414
465
|
function getComplianceStoryboardById(id, options = {}) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
return void 0;
|
|
466
|
+
const storyboard = complianceStoryboardIndex(options).get(id);
|
|
467
|
+
return storyboard ? cloneComplianceStoryboard(storyboard) : void 0;
|
|
419
468
|
}
|
|
420
469
|
function findBundleById(id, options = {}) {
|
|
421
470
|
return listBundles(options).find((b) => b.id === id);
|
|
@@ -10,12 +10,22 @@
|
|
|
10
10
|
* (context_outputs/context_inputs) while still enabling stateful flows.
|
|
11
11
|
*/
|
|
12
12
|
import type { StoryboardContext, ContextOutput, ContextInput, ContextProvenanceEntry } from './types.mjs';
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* `adcpVersion` is the release the step was requested at. Media-buy mutation
|
|
15
|
+
* extractors use it to tell a 3.1+ task-envelope `status` from a 3.0
|
|
16
|
+
* lifecycle `status` when the response does not echo its version.
|
|
17
|
+
*/
|
|
18
|
+
type ContextExtractor = (data: unknown, adcpVersion?: string) => Record<string, unknown>;
|
|
14
19
|
export declare const CONTEXT_EXTRACTORS: Record<string, ContextExtractor>;
|
|
15
20
|
/**
|
|
16
21
|
* Extract context values from a task response.
|
|
22
|
+
*
|
|
23
|
+
* @param adcpVersion - Optional AdCP release the request was sent at. Used
|
|
24
|
+
* only when the response does not echo `adcp_version`, to read a
|
|
25
|
+
* create/update top-level `status` as the 3.1+ task status rather than a
|
|
26
|
+
* 3.0 media-buy lifecycle.
|
|
17
27
|
*/
|
|
18
|
-
export declare function extractContext(taskName: string, data: unknown): Record<string, unknown>;
|
|
28
|
+
export declare function extractContext(taskName: string, data: unknown, adcpVersion?: string): Record<string, unknown>;
|
|
19
29
|
/**
|
|
20
30
|
* Propagate the alias cache from one context to another — call after
|
|
21
31
|
* shallow-cloning context between storyboard steps so replay tests
|
|
@@ -132,7 +142,7 @@ export interface ContextWriteResult {
|
|
|
132
142
|
* tagging it as a convention-based extraction. `response_path` is absent
|
|
133
143
|
* for convention extractors — they're hardcoded functions, not YAML paths.
|
|
134
144
|
*/
|
|
135
|
-
export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string): ContextWriteResult;
|
|
145
|
+
export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string, adcpVersion?: string): ContextWriteResult;
|
|
136
146
|
/**
|
|
137
147
|
* Like `applyContextOutputs`, but also returns provenance for each written
|
|
138
148
|
* key carrying the YAML `response_path` so diagnostics can cite it verbatim.
|
|
@@ -10,12 +10,22 @@
|
|
|
10
10
|
* (context_outputs/context_inputs) while still enabling stateful flows.
|
|
11
11
|
*/
|
|
12
12
|
import type { StoryboardContext, ContextOutput, ContextInput, ContextProvenanceEntry } from './types';
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* `adcpVersion` is the release the step was requested at. Media-buy mutation
|
|
15
|
+
* extractors use it to tell a 3.1+ task-envelope `status` from a 3.0
|
|
16
|
+
* lifecycle `status` when the response does not echo its version.
|
|
17
|
+
*/
|
|
18
|
+
type ContextExtractor = (data: unknown, adcpVersion?: string) => Record<string, unknown>;
|
|
14
19
|
export declare const CONTEXT_EXTRACTORS: Record<string, ContextExtractor>;
|
|
15
20
|
/**
|
|
16
21
|
* Extract context values from a task response.
|
|
22
|
+
*
|
|
23
|
+
* @param adcpVersion - Optional AdCP release the request was sent at. Used
|
|
24
|
+
* only when the response does not echo `adcp_version`, to read a
|
|
25
|
+
* create/update top-level `status` as the 3.1+ task status rather than a
|
|
26
|
+
* 3.0 media-buy lifecycle.
|
|
17
27
|
*/
|
|
18
|
-
export declare function extractContext(taskName: string, data: unknown): Record<string, unknown>;
|
|
28
|
+
export declare function extractContext(taskName: string, data: unknown, adcpVersion?: string): Record<string, unknown>;
|
|
19
29
|
/**
|
|
20
30
|
* Propagate the alias cache from one context to another — call after
|
|
21
31
|
* shallow-cloning context between storyboard steps so replay tests
|
|
@@ -132,7 +142,7 @@ export interface ContextWriteResult {
|
|
|
132
142
|
* tagging it as a convention-based extraction. `response_path` is absent
|
|
133
143
|
* for convention extractors — they're hardcoded functions, not YAML paths.
|
|
134
144
|
*/
|
|
135
|
-
export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string): ContextWriteResult;
|
|
145
|
+
export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string, adcpVersion?: string): ContextWriteResult;
|
|
136
146
|
/**
|
|
137
147
|
* Like `applyContextOutputs`, but also returns provenance for each written
|
|
138
148
|
* key carrying the YAML `response_path` so diagnostics can cite it verbatim.
|