@adcp/sdk 16.0.0-beta.7 → 16.0.0-beta.8
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 +17 -0
- package/dist/lib/conformance/index.d.mts +2 -0
- package/dist/lib/conformance/index.d.ts +2 -0
- package/dist/lib/conformance/index.js +3 -0
- package/dist/lib/conformance/index.mjs +2 -0
- package/dist/lib/conformance/property-lists.d.mts +14 -0
- package/dist/lib/conformance/property-lists.d.ts +14 -0
- package/dist/lib/conformance/property-lists.js +45 -0
- package/dist/lib/conformance/property-lists.mjs +21 -0
- package/dist/lib/conformance/runConformance.js +20 -1
- package/dist/lib/conformance/runConformance.mjs +20 -1
- package/dist/lib/conformance/types.d.mts +3 -0
- package/dist/lib/conformance/types.d.ts +3 -0
- package/dist/lib/core/SingleAgentClient.d.mts +13 -3
- package/dist/lib/core/SingleAgentClient.d.ts +13 -3
- package/dist/lib/core/SingleAgentClient.js +109 -21
- package/dist/lib/core/SingleAgentClient.mjs +112 -22
- package/dist/lib/identifiers.d.mts +53 -0
- package/dist/lib/identifiers.d.ts +53 -0
- package/dist/lib/identifiers.js +212 -0
- package/dist/lib/identifiers.mjs +163 -0
- package/dist/lib/index.d.mts +3 -1
- package/dist/lib/index.d.ts +3 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.mjs +1 -0
- package/dist/lib/media-buy/index.d.mts +1 -1
- package/dist/lib/media-buy/index.d.ts +1 -1
- package/dist/lib/media-buy/property-policy.d.mts +15 -1
- package/dist/lib/media-buy/property-policy.d.ts +15 -1
- package/dist/lib/media-buy/property-policy.js +135 -3
- package/dist/lib/media-buy/property-policy.mjs +134 -3
- package/dist/lib/registry/index.d.mts +12 -0
- package/dist/lib/registry/index.d.ts +12 -0
- package/dist/lib/registry/index.js +159 -5
- package/dist/lib/registry/index.mjs +156 -4
- package/dist/lib/registry/types.d.mts +23 -0
- package/dist/lib/registry/types.d.ts +23 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/decisioning/specialisms/lists.d.mts +4 -4
- package/dist/lib/server/decisioning/specialisms/lists.d.ts +4 -4
- package/dist/lib/server/index.d.mts +3 -0
- package/dist/lib/server/index.d.ts +3 -0
- package/dist/lib/server/index.js +8 -1
- package/dist/lib/server/index.mjs +4 -0
- package/dist/lib/server/property-lists.d.mts +36 -0
- package/dist/lib/server/property-lists.d.ts +36 -0
- package/dist/lib/server/property-lists.js +154 -0
- package/dist/lib/server/property-lists.mjs +129 -0
- package/dist/lib/server/targeting-helpers.d.mts +2 -0
- package/dist/lib/server/targeting-helpers.d.ts +2 -0
- package/dist/lib/server/targeting-helpers.js +28 -1
- package/dist/lib/server/targeting-helpers.mjs +18 -1
- package/dist/lib/signing/parser.js +2 -2
- package/dist/lib/signing/parser.mjs +2 -2
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.mjs +5 -1
- package/dist/lib/signing/webhook-verifier.d.mts +11 -0
- package/dist/lib/signing/webhook-verifier.d.ts +11 -0
- package/dist/lib/signing/webhook-verifier.js +11 -3
- package/dist/lib/signing/webhook-verifier.mjs +11 -3
- package/dist/lib/supply-path/verify.js +12 -2
- package/dist/lib/supply-path/verify.mjs +2 -2
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- 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/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/PROPERTY-LISTS.md +264 -0
- package/docs/guides/SIGNING-GUIDE.md +25 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/package.json +1 -1
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { PropertyIdentifierTypesValues } from "../types/enums.generated.mjs";
|
|
2
|
+
function isSupportedPropertyIdentifierType(type) {
|
|
3
|
+
return PropertyIdentifierTypesValues.includes(type);
|
|
4
|
+
}
|
|
1
5
|
class ProductPropertyPolicyError extends Error {
|
|
2
6
|
constructor(result) {
|
|
3
7
|
super(
|
|
@@ -57,6 +61,8 @@ function compilePolicy(policy) {
|
|
|
57
61
|
}
|
|
58
62
|
return {
|
|
59
63
|
allowedDomains,
|
|
64
|
+
publisherCatalogsConfigured: policy.publisherProperties !== void 0,
|
|
65
|
+
publisherProperties: policy.publisherProperties ?? {},
|
|
60
66
|
allowedPropertyIdentifiers: [...policy.allowedPropertyIdentifiers ?? []],
|
|
61
67
|
requireAllowedPropertyMatch: policy.requireAllowedPropertyMatch ?? Boolean(policy.allowedDomains?.length || policy.allowedPropertyIdentifiers?.length),
|
|
62
68
|
excludedDomainsByComparable,
|
|
@@ -91,6 +97,18 @@ function diagnosticsForProduct(product, productIndex, policy) {
|
|
|
91
97
|
hasEligibleSubsetSelector = true;
|
|
92
98
|
}
|
|
93
99
|
});
|
|
100
|
+
if (requiresSubsetMatch) {
|
|
101
|
+
const scopes = publisherProperties.flatMap(
|
|
102
|
+
(selector) => selector && typeof selector === "object" && !Array.isArray(selector) ? [identifierScopeForSelector(selector, policy)] : []
|
|
103
|
+
);
|
|
104
|
+
if (scopes.some((scope) => scope?.hasNonMatch) && !scopes.some((scope) => scope?.hasMatch))
|
|
105
|
+
hasEligibleSubsetSelector = false;
|
|
106
|
+
}
|
|
107
|
+
if (requiresSubsetMatch && hasEligibleSubsetSelector) {
|
|
108
|
+
for (const diagnostic of diagnostics) {
|
|
109
|
+
if (diagnostic.code === "unresolved_property_identifiers") diagnostic.severity = "flagged";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
94
112
|
if (requiresSubsetMatch && !hasEligibleSubsetSelector) {
|
|
95
113
|
diagnostics.push({
|
|
96
114
|
code: "outside_property_list",
|
|
@@ -116,6 +134,7 @@ function diagnosticsForSelector(rawSelector, productIndex, selectorIndex, produc
|
|
|
116
134
|
});
|
|
117
135
|
}
|
|
118
136
|
const selector = rawSelector;
|
|
137
|
+
const identifierScope = identifierScopeForSelector(selector, policy);
|
|
119
138
|
const selectionType = typeof selector.selection_type === "string" ? selector.selection_type : void 0;
|
|
120
139
|
const domainCandidates = publisherDomainCandidates(selector, path);
|
|
121
140
|
const normalizedDomains = domainCandidates.map((candidate) => ({ candidate, normalized: normalizeDomainForPropertyPolicy(candidate.raw) })).filter(
|
|
@@ -167,7 +186,27 @@ function diagnosticsForSelector(rawSelector, productIndex, selectorIndex, produc
|
|
|
167
186
|
}
|
|
168
187
|
for (const { candidate, normalized: normalizedDomain } of normalizedDomains) {
|
|
169
188
|
const matchedAllowedDomain = matchedAllowedDomainForCandidate(normalizedDomain, policy);
|
|
170
|
-
|
|
189
|
+
const needsCatalogForExclusions = policy.publisherCatalogsConfigured && (policy.excludedDomainsByComparable.size > 0 || selectionType !== "by_id" && policy.excludedPropertyIds.size > 0);
|
|
190
|
+
if ((hasAllowedPropertyScope(policy) || selectionType === "by_tag" || needsCatalogForExclusions) && identifierScope?.unknown) {
|
|
191
|
+
diagnostics.push(
|
|
192
|
+
...diagnosticForBehavior(policy.unknownSelectorBehavior, {
|
|
193
|
+
code: "unresolved_property_identifiers",
|
|
194
|
+
identifier_types: [
|
|
195
|
+
...new Set(
|
|
196
|
+
policy.allowedPropertyIdentifiers.filter((identifier) => identifier.type !== "domain" && identifier.type !== "subdomain").map((identifier) => identifier.type)
|
|
197
|
+
)
|
|
198
|
+
],
|
|
199
|
+
message: "Publisher property identifiers could not be resolved; property-list membership is unknown.",
|
|
200
|
+
product_index: productIndex,
|
|
201
|
+
product_id: productId,
|
|
202
|
+
path,
|
|
203
|
+
publisher_property_index: selectorIndex,
|
|
204
|
+
selection_type: selectionType,
|
|
205
|
+
publisher_domain: candidate.raw
|
|
206
|
+
})
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
if (options.enforceEveryDomainInAllowedScope && hasAllowedPropertyScope(policy) && (identifierScope ? identifierScope.hasNonMatch : !matchedAllowedDomain)) {
|
|
171
210
|
diagnostics.push({
|
|
172
211
|
code: "outside_property_list",
|
|
173
212
|
severity: "rejected",
|
|
@@ -202,6 +241,19 @@ function diagnosticsForSelector(rawSelector, productIndex, selectorIndex, produc
|
|
|
202
241
|
});
|
|
203
242
|
}
|
|
204
243
|
}
|
|
244
|
+
if (options.enforceExclusions && identifierScope?.hasExcludedProperty) {
|
|
245
|
+
diagnostics.push({
|
|
246
|
+
code: "excluded_resolved_property",
|
|
247
|
+
severity: "rejected",
|
|
248
|
+
message: "Resolved publisher properties include a buyer-excluded property.",
|
|
249
|
+
product_index: productIndex,
|
|
250
|
+
product_id: productId,
|
|
251
|
+
path,
|
|
252
|
+
publisher_property_index: selectorIndex,
|
|
253
|
+
selection_type: selectionType,
|
|
254
|
+
publisher_domain: domainCandidates[0]?.raw
|
|
255
|
+
});
|
|
256
|
+
}
|
|
205
257
|
if (selectionType === "by_id") {
|
|
206
258
|
const propertyIds = stringArray(selector.property_ids);
|
|
207
259
|
const matchedPropertyIds = propertyIds.filter((id) => policy.excludedPropertyIds.has(id));
|
|
@@ -223,7 +275,7 @@ function diagnosticsForSelector(rawSelector, productIndex, selectorIndex, produc
|
|
|
223
275
|
matched_property_ids: matchedPropertyIds
|
|
224
276
|
});
|
|
225
277
|
}
|
|
226
|
-
} else if (selectionType === "by_tag") {
|
|
278
|
+
} else if (selectionType === "by_tag" && !identifierScope) {
|
|
227
279
|
diagnostics.push(
|
|
228
280
|
...diagnosticForBehavior(policy.unknownSelectorBehavior, {
|
|
229
281
|
code: "unresolved_tag_selector",
|
|
@@ -239,7 +291,7 @@ function diagnosticsForSelector(rawSelector, productIndex, selectorIndex, produc
|
|
|
239
291
|
normalized_domains: normalizedDomains.map((entry) => entry.normalized.host)
|
|
240
292
|
})
|
|
241
293
|
);
|
|
242
|
-
} else if (selectionType !== "all") {
|
|
294
|
+
} else if (selectionType !== "all" && selectionType !== "by_tag") {
|
|
243
295
|
diagnostics.push(
|
|
244
296
|
...diagnosticForBehavior(policy.unknownSelectorBehavior, {
|
|
245
297
|
code: "unknown_selector",
|
|
@@ -266,6 +318,14 @@ function selectorIsEligibleForSubsetTargeting(rawSelector, productIndex, selecto
|
|
|
266
318
|
if (!rawSelector || typeof rawSelector !== "object" || Array.isArray(rawSelector)) return false;
|
|
267
319
|
const selector = rawSelector;
|
|
268
320
|
if (selector.publisher_domains !== void 0) return false;
|
|
321
|
+
const identifierScope = identifierScopeForSelector(selector, policy);
|
|
322
|
+
if (identifierScope) {
|
|
323
|
+
const domain = typeof selector.publisher_domain === "string" ? normalizeDomainForPropertyPolicy(selector.publisher_domain) : void 0;
|
|
324
|
+
if (!domain || policy.excludedDomainsByComparable.has(domain.comparable)) return false;
|
|
325
|
+
if (selector.selection_type !== "all" && selector.selection_type !== "by_id" && selector.selection_type !== "by_tag")
|
|
326
|
+
return false;
|
|
327
|
+
return identifierScope.hasMatch || identifierScope.unknown && !identifierScope.hasNonMatch && policy.unknownSelectorBehavior !== "reject";
|
|
328
|
+
}
|
|
269
329
|
if (selector.selection_type === "by_tag") return false;
|
|
270
330
|
if (selector.selection_type !== "all" && selector.selection_type !== "by_id") return false;
|
|
271
331
|
const hasEligibleDomain = publisherDomainCandidates(selector, path).some((candidate) => {
|
|
@@ -292,6 +352,76 @@ function matchedAllowedDomainForCandidate(candidate, policy) {
|
|
|
292
352
|
}
|
|
293
353
|
return void 0;
|
|
294
354
|
}
|
|
355
|
+
function identifierScopeForSelector(selector, policy) {
|
|
356
|
+
if (!policy.allowedPropertyIdentifiers.some((id) => id.type !== "domain" && id.type !== "subdomain") && !policy.publisherCatalogsConfigured)
|
|
357
|
+
return void 0;
|
|
358
|
+
const propertyIds = selector.selection_type === "by_id" ? stringArray(selector.property_ids) : [];
|
|
359
|
+
const hasExcludedId = propertyIds.some((id) => policy.excludedPropertyIds.has(id));
|
|
360
|
+
const allIdsExcluded = propertyIds.length > 0 && propertyIds.every((id) => policy.excludedPropertyIds.has(id));
|
|
361
|
+
if (allIdsExcluded) return { allMatch: false, hasMatch: false, hasNonMatch: true, unknown: false };
|
|
362
|
+
const domain = typeof selector.publisher_domain === "string" ? normalizeDomainForPropertyPolicy(selector.publisher_domain) : void 0;
|
|
363
|
+
if (!domain) return { allMatch: false, hasMatch: false, hasNonMatch: hasExcludedId, unknown: true };
|
|
364
|
+
if (policy.excludedDomainsByComparable.has(domain.comparable))
|
|
365
|
+
return { allMatch: false, hasMatch: false, hasNonMatch: true, unknown: false };
|
|
366
|
+
const properties = Object.hasOwn(policy.publisherProperties, domain.host) ? policy.publisherProperties[domain.host] : void 0;
|
|
367
|
+
if (!properties && policy.publisherCatalogsConfigured)
|
|
368
|
+
return { allMatch: false, hasMatch: false, hasNonMatch: hasExcludedId, unknown: true };
|
|
369
|
+
if (!properties) {
|
|
370
|
+
const matchedDomain = !allIdsExcluded && Boolean(matchedAllowedDomainForCandidate(domain, policy));
|
|
371
|
+
const unknown2 = !matchedDomain && !allIdsExcluded || selector.selection_type === "by_tag";
|
|
372
|
+
return {
|
|
373
|
+
allMatch: matchedDomain && !unknown2 && !hasExcludedId,
|
|
374
|
+
hasMatch: matchedDomain && !unknown2,
|
|
375
|
+
hasNonMatch: hasExcludedId,
|
|
376
|
+
unknown: unknown2
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
if (!Array.isArray(properties) || properties.some(
|
|
380
|
+
(property) => !property || typeof property !== "object" || !Array.isArray(property.identifiers) || property.identifiers.some(
|
|
381
|
+
(identifier) => !identifier || typeof identifier.type !== "string" || typeof identifier.value !== "string"
|
|
382
|
+
) || property.tags !== void 0 && (!Array.isArray(property.tags) || property.tags.some((tag) => typeof tag !== "string"))
|
|
383
|
+
)) {
|
|
384
|
+
return { allMatch: false, hasMatch: false, hasNonMatch: hasExcludedId, unknown: true };
|
|
385
|
+
}
|
|
386
|
+
let selected = [...properties];
|
|
387
|
+
let missingIds = false;
|
|
388
|
+
if (selector.selection_type === "by_id") {
|
|
389
|
+
const ids = stringArray(selector.property_ids);
|
|
390
|
+
missingIds = !ids.length || ids.some((id) => !properties.some((property) => property.property_id === id));
|
|
391
|
+
selected = selected.filter((property) => property.property_id && ids.includes(property.property_id));
|
|
392
|
+
} else if (selector.selection_type === "by_tag") {
|
|
393
|
+
const tags = stringArray(selector.property_tags);
|
|
394
|
+
if (!tags.length) return { allMatch: false, hasMatch: false, hasNonMatch: false, unknown: true };
|
|
395
|
+
selected = selected.filter((property) => property.tags?.some((tag) => tags.includes(tag)));
|
|
396
|
+
} else if (selector.selection_type !== "all") {
|
|
397
|
+
return { allMatch: false, hasMatch: false, hasNonMatch: false, unknown: true };
|
|
398
|
+
}
|
|
399
|
+
const excluded = selected.map(
|
|
400
|
+
(property) => policy.excludedPropertyIds.has(property.property_id ?? "") || property.identifiers.some(
|
|
401
|
+
(identifier) => (identifier.type === "domain" || identifier.type === "subdomain") && policy.excludedDomainsByComparable.has(normalizeDomainForPropertyPolicy(identifier.value)?.comparable ?? "")
|
|
402
|
+
)
|
|
403
|
+
);
|
|
404
|
+
const matches = selected.map(
|
|
405
|
+
(property, index) => !excluded[index] && (!hasAllowedPropertyScope(policy) || property.identifiers.some(
|
|
406
|
+
(candidate) => policy.allowedPropertyIdentifiers.some(
|
|
407
|
+
(allowed) => allowed.type === "domain" || allowed.type === "subdomain" ? (candidate.type === "domain" || candidate.type === "subdomain") && propertyListDomainMatches(candidate.value, allowed.value, allowed.type) : isSupportedPropertyIdentifierType(allowed.type) && candidate.type === allowed.type && candidate.value === allowed.value
|
|
408
|
+
) || (candidate.type === "domain" || candidate.type === "subdomain") && policy.allowedDomains.some((allowed) => propertyListDomainMatches(candidate.value, allowed.input))
|
|
409
|
+
))
|
|
410
|
+
);
|
|
411
|
+
const undecidable = selected.map(
|
|
412
|
+
(property, index) => !excluded[index] && (property.identifiers.length === 0 || property.identifiers.some(
|
|
413
|
+
(candidate) => !isSupportedPropertyIdentifierType(candidate.type) && policy.allowedPropertyIdentifiers.some((allowed) => allowed.type === candidate.type)
|
|
414
|
+
))
|
|
415
|
+
);
|
|
416
|
+
const unknown = matches.some((match, index) => !match && undecidable[index]);
|
|
417
|
+
return {
|
|
418
|
+
allMatch: matches.length > 0 && matches.every(Boolean) && !unknown,
|
|
419
|
+
hasMatch: matches.some(Boolean),
|
|
420
|
+
hasNonMatch: missingIds || !selected.length || matches.some((match, index) => !match && !undecidable[index]),
|
|
421
|
+
hasExcludedProperty: excluded.some(Boolean),
|
|
422
|
+
unknown
|
|
423
|
+
};
|
|
424
|
+
}
|
|
295
425
|
function publisherDomainCandidates(selector, path) {
|
|
296
426
|
const candidates = [];
|
|
297
427
|
if (typeof selector.publisher_domain === "string") {
|
|
@@ -356,6 +486,7 @@ function isUsableHostname(host) {
|
|
|
356
486
|
}
|
|
357
487
|
export {
|
|
358
488
|
ProductPropertyPolicyError,
|
|
489
|
+
isSupportedPropertyIdentifierType,
|
|
359
490
|
normalizeDomainForPropertyPolicy,
|
|
360
491
|
validateProductsAgainstPropertyPolicy
|
|
361
492
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { SupplyPathRequest, RegistrySupplyPathResult } from '../supply-path/types.mjs';
|
|
2
|
+
export * from '../identifiers.mjs';
|
|
3
|
+
export type { ResolveIdentifiersAllOptions, ResolveIdentifierOutcome } from './types.mjs';
|
|
4
|
+
import type { ResolveIdentifiersAllOptions, ResolveIdentifierOutcome } from './types.mjs';
|
|
2
5
|
import type { ResolvedBrand, LookupBrandOptions, ResolvedProperty, RegistryClientConfig, SaveBrandRequest, SaveBrandResponse, ListBrandLogosOptions, ListBrandLogosResponse, SaveBrandLogoInput, SaveBrandLogoResponse, UploadBrandLogoInput, UploadBrandLogoResponse, SavePropertyRequest, SavePropertyResponse, ResolveIdentifiersRequest, ResolveIdentifiersResponse, FileCatalogDisputeRequest, FileCatalogDisputeResponse, GetCatalogDisputeResponse, ClaimHostedPropertyDomainResponse, VerifyHostedPropertyOriginResponse, PropertyRegistryItem, ValidationResult, DomainLookupResult, ListBrandsOptions, ListBrandsResponse, GetBrandJsonResponse, ListOptions, ListAgentsOptions, ListAgentsResponse, ListPublishersResponse, ValidateAdagentsResponse, CreateAdagentsRequest, CreateAdagentsResponse, CommunityMirrorAdagentsConfig, CreateCommunityMirrorAdagentsConfig, CommunityMirrorAdagentsCatalog, PublishCommunityMirrorAdagentsResponse, ListCommunityMirrorAdagentsResponse, DeleteCommunityMirrorAdagentsResponse, PublisherPropertySelector, FindCompanyResult, FeedQuery, FeedResponse, AgentSearchQuery, AgentSearchResponse, CrawlRequestResponse, ManagerRevalidationResponse, ListPoliciesQuery, ListPoliciesResponse, ResolvePolicyQuery, ResolvePolicyResponse, ResolvePoliciesBulkRequest, ResolvePoliciesBulkResponse, GetPolicyHistoryQuery, GetPolicyHistoryResponse, SavePolicyRequest, SavePolicyResponse, GetBrandHistoryQuery, GetBrandHistoryResponse, GetPropertyHistoryQuery, GetPropertyHistoryResponse, AgentComplianceDetail, OperatorLookupResult, PublisherLookupResult, GetAgentStoryboardStatusResponse, GetAgentStoryboardStatusBulkResponse } from './types.mjs';
|
|
3
6
|
import type { FeedStreamQuery, FeedStreamMessage } from './feed-stream.mjs';
|
|
4
7
|
export type { ResolvedBrand, LookupBrandOptions, ResolvedProperty, PropertyInfo, RegistryClientConfig, SaveBrandRequest, SaveBrandResponse, BrandLogoReviewStatus, ApprovedBrandLogoAsset, PendingBrandLogoAsset, ReviewedBrandLogoAsset, BrandLogoAsset, ListBrandLogosOptions, ListBrandLogosResponse, SaveBrandLogoInput, SaveBrandLogoResponse, UploadBrandLogoInput, UploadBrandLogoResponse, SavePropertyIdentity, RegistryPropertyIdentity, SavePropertyRequest, SavePropertyResponse, ResolveIdentifiersRequest, ResolveIdentifiersResponse, FileCatalogDisputeRequest, FileCatalogDisputeResponse, GetCatalogDisputeResponse, ClaimHostedPropertyDomainResponse, VerifyHostedPropertyOriginResponse, BrandRegistryItem, PropertyRegistryItem, ValidationResult, FederatedAgentWithDetails, FederatedPublisher, DomainLookupResult, ListBrandsOptions, ListBrandsResponse, GetBrandJsonResponse, ListOptions, ListAgentsOptions, ListAgentsResponse, ListPublishersResponse, ValidateAdagentsRequest, ValidateAdagentsResponse, CreateAdagentsRequest, CreateAdagentsResponse, AdagentsAuthorizedAgent, AdagentsCatalogFormat, AdagentsPlacementDefinition, AdagentsPlacementFormatReference, AdagentsPlacementFormatOption, AdagentsPlacementTag, CreatedAdagentsJson, CommunityMirrorAdagentsConfig, CreateCommunityMirrorAdagentsConfig, CommunityMirrorAdagentsCatalog, PublishCommunityMirrorAdagentsResponse, CommunityMirrorAdagentsSummary, ListCommunityMirrorAdagentsResponse, GetCommunityMirrorAdagentsResponse, PublishCommunityMirrorAdagentsRequest, PublishCommunityMirrorAdagentsError, DeleteCommunityMirrorAdagentsResponse, ValidateProductAuthorizationRequest, ExpandProductIdentifiersRequest, PublisherPropertySelector, CompanySearchResult, FindCompanyResult, FeedQuery, AgentSearchQuery, CrawlRequest, ManagerRevalidationRequest, ManagerRevalidationResponse, ListPoliciesQuery, ListPoliciesResponse, ResolvePolicyQuery, ResolvePolicyResponse, ResolvePoliciesBulkRequest, ResolvePoliciesBulkResponse, GetPolicyHistoryQuery, GetPolicyHistoryResponse, SavePolicyRequest, SavePolicyResponse, GetBrandHistoryQuery, GetBrandHistoryResponse, GetPropertyHistoryQuery, GetPropertyHistoryResponse, AgentComplianceDetail, StoryboardStatus, OperatorLookupResult, PublisherLookupResult, ComplianceChangedPayload, GetAgentStoryboardStatusResponse, GetAgentStoryboardStatusBulkResponse, } from './types.mjs';
|
|
@@ -151,6 +154,7 @@ export declare class RegistryClient {
|
|
|
151
154
|
concurrency?: number;
|
|
152
155
|
}): Promise<Record<string, SavePropertyResponse | {
|
|
153
156
|
error: string;
|
|
157
|
+
cause?: Error;
|
|
154
158
|
}>>;
|
|
155
159
|
/**
|
|
156
160
|
* Resolve catalog identifiers to stable property_rids.
|
|
@@ -158,6 +162,14 @@ export declare class RegistryClient {
|
|
|
158
162
|
* contribution; `lookup` mode is read-only.
|
|
159
163
|
*/
|
|
160
164
|
resolveIdentifiers(request: ResolveIdentifiersRequest): Promise<ResolveIdentifiersResponse>;
|
|
165
|
+
/**
|
|
166
|
+
* Bulk catalog registration (`resolve`, the default) or read-only `lookup`.
|
|
167
|
+
* Splits by identifier count and UTF-8 request bytes, bounds concurrency,
|
|
168
|
+
* and honors Retry-After on 429. Results retain input order and duplicates.
|
|
169
|
+
* Network/5xx failures are not retried: resolve contributions have additive
|
|
170
|
+
* activity logs even though identifier-to-RID mapping is idempotent.
|
|
171
|
+
*/
|
|
172
|
+
resolveIdentifiersAll(request: ResolveIdentifiersRequest, options?: ResolveIdentifiersAllOptions): Promise<ResolveIdentifierOutcome[]>;
|
|
161
173
|
/** File a catalog fact dispute. Requires authentication. */
|
|
162
174
|
fileCatalogDispute(request: FileCatalogDisputeRequest): Promise<FileCatalogDisputeResponse>;
|
|
163
175
|
/** Fetch a catalog dispute by id. */
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { SupplyPathRequest, RegistrySupplyPathResult } from '../supply-path/types';
|
|
2
|
+
export * from '../identifiers';
|
|
3
|
+
export type { ResolveIdentifiersAllOptions, ResolveIdentifierOutcome } from './types';
|
|
4
|
+
import type { ResolveIdentifiersAllOptions, ResolveIdentifierOutcome } from './types';
|
|
2
5
|
import type { ResolvedBrand, LookupBrandOptions, ResolvedProperty, RegistryClientConfig, SaveBrandRequest, SaveBrandResponse, ListBrandLogosOptions, ListBrandLogosResponse, SaveBrandLogoInput, SaveBrandLogoResponse, UploadBrandLogoInput, UploadBrandLogoResponse, SavePropertyRequest, SavePropertyResponse, ResolveIdentifiersRequest, ResolveIdentifiersResponse, FileCatalogDisputeRequest, FileCatalogDisputeResponse, GetCatalogDisputeResponse, ClaimHostedPropertyDomainResponse, VerifyHostedPropertyOriginResponse, PropertyRegistryItem, ValidationResult, DomainLookupResult, ListBrandsOptions, ListBrandsResponse, GetBrandJsonResponse, ListOptions, ListAgentsOptions, ListAgentsResponse, ListPublishersResponse, ValidateAdagentsResponse, CreateAdagentsRequest, CreateAdagentsResponse, CommunityMirrorAdagentsConfig, CreateCommunityMirrorAdagentsConfig, CommunityMirrorAdagentsCatalog, PublishCommunityMirrorAdagentsResponse, ListCommunityMirrorAdagentsResponse, DeleteCommunityMirrorAdagentsResponse, PublisherPropertySelector, FindCompanyResult, FeedQuery, FeedResponse, AgentSearchQuery, AgentSearchResponse, CrawlRequestResponse, ManagerRevalidationResponse, ListPoliciesQuery, ListPoliciesResponse, ResolvePolicyQuery, ResolvePolicyResponse, ResolvePoliciesBulkRequest, ResolvePoliciesBulkResponse, GetPolicyHistoryQuery, GetPolicyHistoryResponse, SavePolicyRequest, SavePolicyResponse, GetBrandHistoryQuery, GetBrandHistoryResponse, GetPropertyHistoryQuery, GetPropertyHistoryResponse, AgentComplianceDetail, OperatorLookupResult, PublisherLookupResult, GetAgentStoryboardStatusResponse, GetAgentStoryboardStatusBulkResponse } from './types';
|
|
3
6
|
import type { FeedStreamQuery, FeedStreamMessage } from './feed-stream';
|
|
4
7
|
export type { ResolvedBrand, LookupBrandOptions, ResolvedProperty, PropertyInfo, RegistryClientConfig, SaveBrandRequest, SaveBrandResponse, BrandLogoReviewStatus, ApprovedBrandLogoAsset, PendingBrandLogoAsset, ReviewedBrandLogoAsset, BrandLogoAsset, ListBrandLogosOptions, ListBrandLogosResponse, SaveBrandLogoInput, SaveBrandLogoResponse, UploadBrandLogoInput, UploadBrandLogoResponse, SavePropertyIdentity, RegistryPropertyIdentity, SavePropertyRequest, SavePropertyResponse, ResolveIdentifiersRequest, ResolveIdentifiersResponse, FileCatalogDisputeRequest, FileCatalogDisputeResponse, GetCatalogDisputeResponse, ClaimHostedPropertyDomainResponse, VerifyHostedPropertyOriginResponse, BrandRegistryItem, PropertyRegistryItem, ValidationResult, FederatedAgentWithDetails, FederatedPublisher, DomainLookupResult, ListBrandsOptions, ListBrandsResponse, GetBrandJsonResponse, ListOptions, ListAgentsOptions, ListAgentsResponse, ListPublishersResponse, ValidateAdagentsRequest, ValidateAdagentsResponse, CreateAdagentsRequest, CreateAdagentsResponse, AdagentsAuthorizedAgent, AdagentsCatalogFormat, AdagentsPlacementDefinition, AdagentsPlacementFormatReference, AdagentsPlacementFormatOption, AdagentsPlacementTag, CreatedAdagentsJson, CommunityMirrorAdagentsConfig, CreateCommunityMirrorAdagentsConfig, CommunityMirrorAdagentsCatalog, PublishCommunityMirrorAdagentsResponse, CommunityMirrorAdagentsSummary, ListCommunityMirrorAdagentsResponse, GetCommunityMirrorAdagentsResponse, PublishCommunityMirrorAdagentsRequest, PublishCommunityMirrorAdagentsError, DeleteCommunityMirrorAdagentsResponse, ValidateProductAuthorizationRequest, ExpandProductIdentifiersRequest, PublisherPropertySelector, CompanySearchResult, FindCompanyResult, FeedQuery, AgentSearchQuery, CrawlRequest, ManagerRevalidationRequest, ManagerRevalidationResponse, ListPoliciesQuery, ListPoliciesResponse, ResolvePolicyQuery, ResolvePolicyResponse, ResolvePoliciesBulkRequest, ResolvePoliciesBulkResponse, GetPolicyHistoryQuery, GetPolicyHistoryResponse, SavePolicyRequest, SavePolicyResponse, GetBrandHistoryQuery, GetBrandHistoryResponse, GetPropertyHistoryQuery, GetPropertyHistoryResponse, AgentComplianceDetail, StoryboardStatus, OperatorLookupResult, PublisherLookupResult, ComplianceChangedPayload, GetAgentStoryboardStatusResponse, GetAgentStoryboardStatusBulkResponse, } from './types';
|
|
@@ -151,6 +154,7 @@ export declare class RegistryClient {
|
|
|
151
154
|
concurrency?: number;
|
|
152
155
|
}): Promise<Record<string, SavePropertyResponse | {
|
|
153
156
|
error: string;
|
|
157
|
+
cause?: Error;
|
|
154
158
|
}>>;
|
|
155
159
|
/**
|
|
156
160
|
* Resolve catalog identifiers to stable property_rids.
|
|
@@ -158,6 +162,14 @@ export declare class RegistryClient {
|
|
|
158
162
|
* contribution; `lookup` mode is read-only.
|
|
159
163
|
*/
|
|
160
164
|
resolveIdentifiers(request: ResolveIdentifiersRequest): Promise<ResolveIdentifiersResponse>;
|
|
165
|
+
/**
|
|
166
|
+
* Bulk catalog registration (`resolve`, the default) or read-only `lookup`.
|
|
167
|
+
* Splits by identifier count and UTF-8 request bytes, bounds concurrency,
|
|
168
|
+
* and honors Retry-After on 429. Results retain input order and duplicates.
|
|
169
|
+
* Network/5xx failures are not retried: resolve contributions have additive
|
|
170
|
+
* activity logs even though identifier-to-RID mapping is idempotent.
|
|
171
|
+
*/
|
|
172
|
+
resolveIdentifiersAll(request: ResolveIdentifiersRequest, options?: ResolveIdentifiersAllOptions): Promise<ResolveIdentifierOutcome[]>;
|
|
161
173
|
/** File a catalog fact dispute. Requires authentication. */
|
|
162
174
|
fileCatalogDispute(request: FileCatalogDisputeRequest): Promise<FileCatalogDisputeResponse>;
|
|
163
175
|
/** Fetch a catalog dispute by id. */
|
|
@@ -15,6 +15,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
15
|
}
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
18
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
20
|
var registry_exports = {};
|
|
20
21
|
__export(registry_exports, {
|
|
@@ -37,6 +38,8 @@ __export(registry_exports, {
|
|
|
37
38
|
sanitizeStreamText: () => import_feed_stream2.sanitizeStreamText
|
|
38
39
|
});
|
|
39
40
|
module.exports = __toCommonJS(registry_exports);
|
|
41
|
+
var import_identifiers = require('../identifiers.js');
|
|
42
|
+
__reExport(registry_exports, require('../identifiers.js'), module.exports);
|
|
40
43
|
var import_validation = require('../supply-path/validation.js');
|
|
41
44
|
var import_feed_stream = require('./feed-stream.js');
|
|
42
45
|
var import_sync = require('./sync.js');
|
|
@@ -51,6 +54,9 @@ const ERROR_BODY_PREVIEW_CHARS = 200;
|
|
|
51
54
|
const MAX_BRAND_BULK_DOMAINS = 25;
|
|
52
55
|
const MAX_BULK_DOMAINS = 100;
|
|
53
56
|
const MAX_CHECK_DOMAINS = 1e4;
|
|
57
|
+
const MAX_RESOLVE_IDENTIFIERS = 1e4;
|
|
58
|
+
const DEFAULT_RESOLVE_REQUEST_BYTES = 1024 * 1024;
|
|
59
|
+
const DEFAULT_RESOLVE_RESPONSE_BYTES = 16 * 1024 * 1024;
|
|
54
60
|
const COMMUNITY_MIRROR_PLATFORM_RE = /^[a-z0-9_-]{1,64}$/;
|
|
55
61
|
const MAX_REGISTRY_ERROR_DETAILS_BYTES = 64 * 1024;
|
|
56
62
|
const MAX_RETRY_AFTER_MS = 2147483647;
|
|
@@ -303,7 +309,15 @@ class RegistryClient {
|
|
|
303
309
|
}
|
|
304
310
|
/** Save or update a hosted property. Requires authentication. */
|
|
305
311
|
async saveProperty(property) {
|
|
306
|
-
if (
|
|
312
|
+
if (typeof property?.publisher_domain !== "string" || !property.publisher_domain.trim()) {
|
|
313
|
+
throw new import_identifiers.IdentifierValidationError(
|
|
314
|
+
"invalid_publisher_domain",
|
|
315
|
+
"publisher_domain",
|
|
316
|
+
"publisher_domain is required"
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const domain = (0, import_identifiers.validatePublisherDomain)(property.publisher_domain);
|
|
320
|
+
if (!domain.ok) throw domain.error;
|
|
307
321
|
if (!this.apiKey) throw new Error("apiKey is required for save operations");
|
|
308
322
|
const payload = this.normalizeSavePropertyRequest(property);
|
|
309
323
|
return this.post(`${this.baseUrl}/api/properties/save`, payload);
|
|
@@ -335,17 +349,19 @@ class RegistryClient {
|
|
|
335
349
|
*/
|
|
336
350
|
async saveProperties(properties, options) {
|
|
337
351
|
const concurrency = options?.concurrency ?? 5;
|
|
338
|
-
|
|
352
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1)
|
|
353
|
+
throw new RangeError("concurrency must be a positive integer");
|
|
354
|
+
const results = /* @__PURE__ */ Object.create(null);
|
|
339
355
|
for (let i = 0; i < properties.length; i += concurrency) {
|
|
340
356
|
const batch = properties.slice(i, i + concurrency);
|
|
341
357
|
const settled = await Promise.allSettled(batch.map((p) => this.saveProperty(p)));
|
|
342
358
|
for (let j = 0; j < batch.length; j++) {
|
|
343
359
|
const domain = batch[j].publisher_domain;
|
|
344
360
|
const s = settled[j];
|
|
345
|
-
results[domain] = s.status === "fulfilled" ? s.value : { error: String(s.reason) };
|
|
361
|
+
results[domain] = s.status === "fulfilled" ? s.value : { error: String(s.reason), ...s.reason instanceof Error ? { cause: s.reason } : {} };
|
|
346
362
|
}
|
|
347
363
|
}
|
|
348
|
-
return results;
|
|
364
|
+
return Object.fromEntries(Object.entries(results));
|
|
349
365
|
}
|
|
350
366
|
/**
|
|
351
367
|
* Resolve catalog identifiers to stable property_rids.
|
|
@@ -354,11 +370,147 @@ class RegistryClient {
|
|
|
354
370
|
*/
|
|
355
371
|
async resolveIdentifiers(request) {
|
|
356
372
|
if (!request?.identifiers?.length) throw new Error("identifiers are required");
|
|
373
|
+
if (request.identifiers.length > MAX_RESOLVE_IDENTIFIERS) {
|
|
374
|
+
throw new RangeError("At most 10,000 identifiers are allowed; use resolveIdentifiersAll for larger lists");
|
|
375
|
+
}
|
|
357
376
|
if ((request.mode ?? "resolve") !== "lookup" && !this.apiKey) {
|
|
358
377
|
throw new Error("apiKey is required for resolveIdentifiers in resolve mode");
|
|
359
378
|
}
|
|
360
379
|
return this.post(`${this.baseUrl}/api/registry/resolve`, request);
|
|
361
380
|
}
|
|
381
|
+
/**
|
|
382
|
+
* Bulk catalog registration (`resolve`, the default) or read-only `lookup`.
|
|
383
|
+
* Splits by identifier count and UTF-8 request bytes, bounds concurrency,
|
|
384
|
+
* and honors Retry-After on 429. Results retain input order and duplicates.
|
|
385
|
+
* Network/5xx failures are not retried: resolve contributions have additive
|
|
386
|
+
* activity logs even though identifier-to-RID mapping is idempotent.
|
|
387
|
+
*/
|
|
388
|
+
async resolveIdentifiersAll(request, options = {}) {
|
|
389
|
+
const {
|
|
390
|
+
batchSize = MAX_RESOLVE_IDENTIFIERS,
|
|
391
|
+
maxRequestBytes = DEFAULT_RESOLVE_REQUEST_BYTES,
|
|
392
|
+
concurrency = 2,
|
|
393
|
+
maxRetries = 3,
|
|
394
|
+
maxRetryDelayMs = 6e4
|
|
395
|
+
} = options;
|
|
396
|
+
for (const [name, value, minimum] of [
|
|
397
|
+
["batchSize", batchSize, 1],
|
|
398
|
+
["maxRequestBytes", maxRequestBytes, 1],
|
|
399
|
+
["concurrency", concurrency, 1],
|
|
400
|
+
["maxRetries", maxRetries, 0],
|
|
401
|
+
["maxRetryDelayMs", maxRetryDelayMs, 0]
|
|
402
|
+
]) {
|
|
403
|
+
if (!Number.isSafeInteger(value) || value < minimum)
|
|
404
|
+
throw new RangeError(`${name} must be an integer >= ${minimum}`);
|
|
405
|
+
}
|
|
406
|
+
if (batchSize > MAX_RESOLVE_IDENTIFIERS) throw new RangeError("batchSize must not exceed 10,000");
|
|
407
|
+
if (!Array.isArray(request?.identifiers)) throw new TypeError("identifiers are required");
|
|
408
|
+
if ((request.mode ?? "resolve") !== "lookup" && !this.apiKey)
|
|
409
|
+
throw new Error("apiKey is required for resolveIdentifiers in resolve mode");
|
|
410
|
+
const { identifiers, ...envelope } = request;
|
|
411
|
+
const envelopeBytes = Buffer.byteLength(JSON.stringify({ ...envelope, identifiers: [] }), "utf8");
|
|
412
|
+
const outcomes = new Array(identifiers.length);
|
|
413
|
+
const batches = [];
|
|
414
|
+
let batch = { indexes: [], identifiers: [] };
|
|
415
|
+
let bytes = envelopeBytes;
|
|
416
|
+
for (const [index, identifier] of identifiers.entries()) {
|
|
417
|
+
if (!identifier || typeof identifier !== "object" || typeof identifier.type !== "string" || typeof identifier.value !== "string") {
|
|
418
|
+
outcomes[index] = {
|
|
419
|
+
index,
|
|
420
|
+
identifier,
|
|
421
|
+
success: false,
|
|
422
|
+
error: new TypeError("Identifier must contain string type and value")
|
|
423
|
+
};
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
const size = Buffer.byteLength(JSON.stringify(identifier), "utf8");
|
|
427
|
+
if (envelopeBytes + size > maxRequestBytes) {
|
|
428
|
+
outcomes[index] = {
|
|
429
|
+
index,
|
|
430
|
+
identifier,
|
|
431
|
+
success: false,
|
|
432
|
+
error: new RangeError("Identifier and provenance exceed maxRequestBytes")
|
|
433
|
+
};
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
if (batch.indexes.length && (batch.indexes.length >= batchSize || bytes + size + 1 > maxRequestBytes)) {
|
|
437
|
+
batches.push(batch);
|
|
438
|
+
batch = { indexes: [], identifiers: [] };
|
|
439
|
+
bytes = envelopeBytes;
|
|
440
|
+
}
|
|
441
|
+
bytes += size + (batch.indexes.length ? 1 : 0);
|
|
442
|
+
batch.indexes.push(index);
|
|
443
|
+
batch.identifiers.push(identifier);
|
|
444
|
+
}
|
|
445
|
+
if (batch.indexes.length) batches.push(batch);
|
|
446
|
+
let nextBatch = 0;
|
|
447
|
+
let retryNotBefore = 0;
|
|
448
|
+
let rateLimitFailure;
|
|
449
|
+
const worker = async () => {
|
|
450
|
+
while (nextBatch < batches.length) {
|
|
451
|
+
const current = batches[nextBatch++];
|
|
452
|
+
let response;
|
|
453
|
+
let failure;
|
|
454
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
455
|
+
if (rateLimitFailure) {
|
|
456
|
+
failure = rateLimitFailure;
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
while (!rateLimitFailure && retryNotBefore > Date.now())
|
|
460
|
+
await new Promise(
|
|
461
|
+
(resolve) => setTimeout(resolve, Math.min(retryNotBefore - Date.now(), MAX_RETRY_AFTER_MS))
|
|
462
|
+
);
|
|
463
|
+
if (rateLimitFailure) {
|
|
464
|
+
failure = rateLimitFailure;
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
try {
|
|
468
|
+
response = await this.resolveIdentifiers({ ...envelope, identifiers: current.identifiers });
|
|
469
|
+
if (!response || !Array.isArray(response.resolved)) {
|
|
470
|
+
throw new TypeError("Registry returned an invalid identifier resolution response");
|
|
471
|
+
}
|
|
472
|
+
break;
|
|
473
|
+
} catch (error) {
|
|
474
|
+
response = void 0;
|
|
475
|
+
failure = error instanceof Error ? error : new Error("Registry resolution failed");
|
|
476
|
+
if (!isRegistryRequestError(error) || error.status !== 429) break;
|
|
477
|
+
const delay = typeof error.retryAfterMs === "number" && Number.isFinite(error.retryAfterMs) && error.retryAfterMs >= 0 ? error.retryAfterMs : Math.min(1e3 * 2 ** attempt, 3e4);
|
|
478
|
+
if (delay > maxRetryDelayMs) {
|
|
479
|
+
rateLimitFailure = error;
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
retryNotBefore = Math.max(retryNotBefore, Date.now() + delay);
|
|
483
|
+
if (attempt === maxRetries) break;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const entries = /* @__PURE__ */ new Map();
|
|
487
|
+
let malformedEntries = false;
|
|
488
|
+
for (const entry of response?.resolved ?? []) {
|
|
489
|
+
if (!entry || typeof entry !== "object" || !entry.identifier || typeof entry.identifier.type !== "string" || typeof entry.identifier.value !== "string" || entry.property_rid !== null && typeof entry.property_rid !== "string" || !["existing", "created", "excluded"].includes(entry.status)) {
|
|
490
|
+
malformedEntries = true;
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
const key = JSON.stringify([entry.identifier.type, entry.identifier.value]);
|
|
494
|
+
const group = entries.get(key) ?? [];
|
|
495
|
+
group.push(entry);
|
|
496
|
+
entries.set(key, group);
|
|
497
|
+
}
|
|
498
|
+
for (const index of current.indexes) {
|
|
499
|
+
const identifier = identifiers[index];
|
|
500
|
+
const group = entries.get(JSON.stringify([identifier.type, identifier.value]));
|
|
501
|
+
const entry = group && (group.length > 1 ? group.shift() : group[0]);
|
|
502
|
+
outcomes[index] = entry ? { index, identifier, success: true, result: entry } : {
|
|
503
|
+
index,
|
|
504
|
+
identifier,
|
|
505
|
+
success: false,
|
|
506
|
+
error: response ? malformedEntries ? new TypeError("Registry returned an invalid identifier resolution response") : new Error("Registry response omitted identifier") : failure
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, batches.length) }, worker));
|
|
512
|
+
return outcomes;
|
|
513
|
+
}
|
|
362
514
|
/** File a catalog fact dispute. Requires authentication. */
|
|
363
515
|
async fileCatalogDispute(request) {
|
|
364
516
|
if (!request?.subject_type?.trim()) throw new Error("subject_type is required");
|
|
@@ -1130,6 +1282,7 @@ class RegistryClient {
|
|
|
1130
1282
|
bodyLimitForUrl(url) {
|
|
1131
1283
|
if (this.hasCustomMaxBodyBytes) return this.maxBodyBytes;
|
|
1132
1284
|
const path = new URL(url).pathname;
|
|
1285
|
+
if (path === "/api/registry/resolve") return DEFAULT_RESOLVE_RESPONSE_BYTES;
|
|
1133
1286
|
if (path === "/api/brands/registry" || path === "/api/brands/resolve/bulk" || path === "/api/properties/registry" || path === "/api/properties/resolve/bulk" || path === "/api/registry/agents" || path === "/api/registry/publishers" || path === "/api/registry/feed" || path === "/api/registry/mirrors" || path === "/api/registry/agents/search" || path === "/api/registry/authorizations" || path === "/api/registry/authorizations/snapshot" || path === "/api/search" || path === "/api/policies/registry" || path === "/api/policies/resolve/bulk" || path === "/api/public/discover-agent" || path === "/api/public/agent-formats" || path === "/api/public/agent-products" || path === "/api/public/validate-publisher" || path === "/api/registry/agents/storyboard-status" || path.startsWith("/api/registry/agents/") && path.endsWith("/storyboard-status") || path.startsWith("/api/registry/mirrors/") || path.startsWith("/api/properties/check")) {
|
|
1134
1287
|
return DEFAULT_LARGE_RESPONSE_MAX_BODY_BYTES;
|
|
1135
1288
|
}
|
|
@@ -1239,5 +1392,6 @@ class RegistryClient {
|
|
|
1239
1392
|
isRegistryRequestError,
|
|
1240
1393
|
openFeedStream,
|
|
1241
1394
|
parseSseStream,
|
|
1242
|
-
sanitizeStreamText
|
|
1395
|
+
sanitizeStreamText,
|
|
1396
|
+
...require('../identifiers.js')
|
|
1243
1397
|
});
|