@authorizedretailers/spec 0.1.1 → 0.2.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.
Files changed (208) hide show
  1. package/README.md +66 -47
  2. package/dist/constants.d.ts +25 -6
  3. package/dist/constants.js +41 -7
  4. package/dist/identity.d.ts +29 -14
  5. package/dist/identity.js +79 -39
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +2 -0
  8. package/dist/jws.d.ts +36 -5
  9. package/dist/jws.js +48 -14
  10. package/dist/match.d.ts +21 -0
  11. package/dist/match.js +89 -0
  12. package/dist/product.d.ts +34 -0
  13. package/dist/product.js +75 -0
  14. package/dist/published.d.ts +14 -8
  15. package/dist/published.js +32 -10
  16. package/dist/schemas.d.ts +366 -91
  17. package/dist/schemas.js +802 -181
  18. package/dist/types.d.ts +121 -47
  19. package/dist/types.js +2 -2
  20. package/dist/validate.d.ts +24 -10
  21. package/dist/validate.js +300 -107
  22. package/fixtures/list/invalid/list-all-mixed.json +53 -0
  23. package/fixtures/list/invalid/list-amazon-missing-seller-id.json +51 -0
  24. package/fixtures/list/invalid/list-amazon-on-walmart-domain.json +52 -0
  25. package/fixtures/{file/invalid/full-attached-jws.json → list/invalid/list-attached-jws.json} +14 -12
  26. package/fixtures/list/invalid/list-bad-asin.json +102 -0
  27. package/fixtures/list/invalid/list-bad-gtin.json +102 -0
  28. package/fixtures/list/invalid/list-brand-exclusion-no-catalog.json +57 -0
  29. package/fixtures/list/invalid/list-duplicate-asin.json +102 -0
  30. package/fixtures/{file/invalid/full-duplicate-authorization-id.json → list/invalid/list-duplicate-authorization-id.json} +23 -18
  31. package/fixtures/list/invalid/list-duplicate-gtin.json +102 -0
  32. package/fixtures/list/invalid/list-duplicate-product-id.json +102 -0
  33. package/fixtures/{file/invalid/full-empty-territories.json → list/invalid/list-empty-territories.json} +17 -10
  34. package/fixtures/list/invalid/list-exclude-unknown-product.json +105 -0
  35. package/fixtures/list/invalid/list-expires-field.json +53 -0
  36. package/fixtures/list/invalid/list-extra-property.json +53 -0
  37. package/fixtures/list/invalid/list-generic-web-no-territories.json +39 -0
  38. package/fixtures/list/invalid/list-gtin-11-digits.json +102 -0
  39. package/fixtures/list/invalid/list-impossible-date.json +53 -0
  40. package/fixtures/list/invalid/list-lowercase-territory.json +52 -0
  41. package/fixtures/{file/invalid/full-signature-missing-kid.json → list/invalid/list-marketplace-field.json} +14 -11
  42. package/fixtures/list/invalid/list-marketplace-territory-mismatch.json +52 -0
  43. package/fixtures/list/invalid/list-missing-revocation-id.json +51 -0
  44. package/fixtures/list/invalid/list-missing-scope.json +44 -0
  45. package/fixtures/list/invalid/list-missing-stale-until.json +51 -0
  46. package/fixtures/list/invalid/list-name-only-retailer.json +36 -0
  47. package/fixtures/list/invalid/list-no-channels.json +37 -0
  48. package/fixtures/list/invalid/list-non-utc-timestamp.json +52 -0
  49. package/fixtures/list/invalid/list-not-public-with-authorizations.json +18 -0
  50. package/fixtures/list/invalid/list-not-public-with-catalog.json +18 -0
  51. package/fixtures/{file/invalid/full-physical-only.json → list/invalid/list-physical.json} +16 -10
  52. package/fixtures/list/invalid/list-product-no-identifier.json +98 -0
  53. package/fixtures/list/invalid/list-scope-no-products.json +49 -0
  54. package/fixtures/{file/valid/full-signed.json → list/invalid/list-single-domain.json} +12 -12
  55. package/fixtures/list/invalid/list-stale-over-24-hours.json +52 -0
  56. package/fixtures/list/invalid/list-territory-uk.json +52 -0
  57. package/fixtures/{file/invalid/full-unknown-channel-type.json → list/invalid/list-unknown-channel-type.json} +18 -12
  58. package/fixtures/list/invalid/list-unknown-line.json +102 -0
  59. package/fixtures/list/invalid/list-unknown-product.json +105 -0
  60. package/fixtures/{file/invalid/full-missing-authorization-expires.json → list/invalid/list-unsigned.json} +12 -9
  61. package/fixtures/list/invalid/list-valid-over-15-minutes.json +52 -0
  62. package/fixtures/{file/invalid/full-web-domain-is-url.json → list/invalid/list-web-domain-is-url.json} +18 -12
  63. package/fixtures/list/invalid/list-web-on-marketplace-domain.json +52 -0
  64. package/fixtures/{file/invalid/full-wildcard-mixed.json → list/invalid/list-wildcard-mixed.json} +17 -10
  65. package/fixtures/list/valid/list-catalog-line-scope.json +102 -0
  66. package/fixtures/list/valid/list-cctld-web.json +39 -0
  67. package/fixtures/list/valid/list-fractional-seconds.json +52 -0
  68. package/fixtures/{file/invalid/full-amazon-missing-seller-id.json → list/valid/list-generic-web-territories.json} +15 -17
  69. package/fixtures/list/valid/list-marketplace-no-territories.json +40 -0
  70. package/fixtures/list/valid/list-no-authorizations.json +18 -0
  71. package/fixtures/list/valid/list-no-catalog.json +52 -0
  72. package/fixtures/list/valid/list-no-expires.json +52 -0
  73. package/fixtures/list/valid/list-not-public.json +17 -0
  74. package/fixtures/list/valid/list-product-scope.json +103 -0
  75. package/fixtures/list/valid/list-proposed-by.json +55 -0
  76. package/fixtures/list/valid/list-with-expires.json +53 -0
  77. package/fixtures/list/valid/list-worldwide.json +52 -0
  78. package/fixtures/manifest.json +606 -158
  79. package/fixtures/match/all-scope-excluded-line.json +194 -0
  80. package/fixtures/match/all-scope-not-in-catalog.json +194 -0
  81. package/fixtures/match/as-of-before-end-date.json +194 -0
  82. package/fixtures/match/brand-exclusion-beats-named-product.json +194 -0
  83. package/fixtures/match/duplicate-asin-authorized-seller.json +192 -0
  84. package/fixtures/match/duplicate-asin-unauthorized-seller.json +191 -0
  85. package/fixtures/match/expired-end-date.json +193 -0
  86. package/fixtures/match/marketplace-territory-default.json +186 -0
  87. package/fixtures/match/marketplace-territory-mismatch.json +187 -0
  88. package/fixtures/match/match-by-channel-key.json +186 -0
  89. package/fixtures/match/product-excluded-by-authorization.json +194 -0
  90. package/fixtures/match/product-line-request.json +186 -0
  91. package/fixtures/match/product-not-in-scope.json +194 -0
  92. package/fixtures/match/seller-authorized-by-gtin.json +194 -0
  93. package/fixtures/match/seller-authorized-for-line.json +194 -0
  94. package/fixtures/match/worldwide-web.json +186 -0
  95. package/fixtures/pointer/invalid/full-form.json +11 -0
  96. package/fixtures/pointer/invalid/pointer-domain-mismatch.json +10 -0
  97. package/fixtures/{file → pointer}/invalid/pointer-http-url.json +2 -1
  98. package/fixtures/pointer/invalid/pointer-missing-verify-token.json +9 -0
  99. package/fixtures/pointer/invalid/pointer-other-host.json +10 -0
  100. package/fixtures/{file/valid/pointer.json → pointer/invalid/pointer-wrong-spec.json} +1 -0
  101. package/fixtures/pointer/invalid/private-form.json +10 -0
  102. package/fixtures/pointer/invalid/unknown-form.json +10 -0
  103. package/fixtures/pointer/valid/pointer-fetched-via-www.json +10 -0
  104. package/fixtures/pointer/valid/pointer.json +10 -0
  105. package/fixtures/revocation-feed/invalid/feed-hashed-entry.json +17 -0
  106. package/fixtures/revocation-feed/invalid/feed-valid-over-15-minutes.json +17 -0
  107. package/fixtures/revocation-feed/valid/feed-empty.json +12 -0
  108. package/fixtures/revocation-feed/valid/feed.json +17 -0
  109. package/fixtures/verify-request/invalid/bad-as-of.json +9 -0
  110. package/fixtures/verify-request/invalid/bad-gtin.json +11 -0
  111. package/fixtures/verify-request/invalid/domain-with-scheme.json +2 -4
  112. package/fixtures/verify-request/{valid/web-no-product-line.json → invalid/generic-web-no-territory.json} +1 -2
  113. package/fixtures/verify-request/invalid/gtin-and-asin.json +12 -0
  114. package/fixtures/verify-request/{valid/amazon.json → invalid/marketplace-field.json} +1 -3
  115. package/fixtures/verify-request/invalid/missing-channel.json +1 -3
  116. package/fixtures/verify-request/invalid/physical-channel.json +1 -3
  117. package/fixtures/verify-request/invalid/retailer-name-only.json +0 -2
  118. package/fixtures/verify-request/invalid/territory-uk.json +9 -0
  119. package/fixtures/verify-request/invalid/wildcard-territory.json +2 -3
  120. package/fixtures/verify-request/valid/as-of-datetime.json +9 -0
  121. package/fixtures/verify-request/valid/full.json +13 -0
  122. package/fixtures/verify-request/valid/gtin.json +11 -0
  123. package/fixtures/verify-request/valid/minimal-marketplace.json +8 -0
  124. package/fixtures/verify-request/valid/web-cctld-no-territory.json +7 -0
  125. package/fixtures/verify-request/valid/web-generic-with-territory.json +9 -0
  126. package/fixtures/verify-response/invalid/authorized-missing-revocation-id.json +18 -0
  127. package/fixtures/verify-response/invalid/authorized-with-reason.json +20 -0
  128. package/fixtures/verify-response/invalid/brand-unverified.json +13 -0
  129. package/fixtures/verify-response/invalid/expired-without-expires.json +18 -0
  130. package/fixtures/verify-response/invalid/missing-observed.json +11 -5
  131. package/fixtures/verify-response/invalid/missing-signature.json +9 -3
  132. package/fixtures/verify-response/invalid/missing-stale-until.json +18 -0
  133. package/fixtures/verify-response/invalid/not-in-catalog-with-id.json +17 -0
  134. package/fixtures/verify-response/invalid/not-registered-with-unlisted-reason.json +13 -0
  135. package/fixtures/verify-response/invalid/stale-until-over-24-hours.json +19 -0
  136. package/fixtures/verify-response/invalid/unlisted-observed.json +5 -4
  137. package/fixtures/verify-response/invalid/unlisted-with-authorization-id.json +5 -4
  138. package/fixtures/verify-response/invalid/unlisted-with-not-registered-reason.json +13 -0
  139. package/fixtures/verify-response/invalid/unlisted-with-revocation-id.json +13 -0
  140. package/fixtures/verify-response/invalid/valid-until-before-checked.json +11 -5
  141. package/fixtures/verify-response/invalid/valid-until-over-15-minutes.json +19 -0
  142. package/fixtures/verify-response/invalid/with-stale-flag.json +20 -0
  143. package/fixtures/verify-response/invalid/with-tier.json +11 -5
  144. package/fixtures/verify-response/valid/authorized-no-product.json +14 -0
  145. package/fixtures/verify-response/valid/authorized-not-in-catalog.json +22 -0
  146. package/fixtures/verify-response/valid/authorized-observed.json +11 -5
  147. package/fixtures/verify-response/valid/authorized-private-product.json +17 -0
  148. package/fixtures/verify-response/valid/authorized-with-end-date.json +20 -0
  149. package/fixtures/verify-response/valid/authorized.json +11 -5
  150. package/fixtures/verify-response/valid/disputed.json +10 -5
  151. package/fixtures/verify-response/valid/expired.json +12 -6
  152. package/fixtures/verify-response/valid/not-registered-no-reason.json +12 -0
  153. package/fixtures/verify-response/valid/not-registered-reason.json +13 -0
  154. package/fixtures/verify-response/valid/unlisted-product-excluded.json +18 -0
  155. package/fixtures/verify-response/valid/unlisted-product-not-in-catalog.json +16 -0
  156. package/fixtures/verify-response/valid/unlisted-territory-mismatch.json +13 -0
  157. package/fixtures/verify-response/valid/unlisted.json +5 -4
  158. package/fixtures/verify-response/valid/with-as-of.json +20 -0
  159. package/fixtures/verify-response/valid/with-signal.json +11 -5
  160. package/package.json +5 -4
  161. package/schemas/0.2/common.json +761 -0
  162. package/schemas/0.2/list.json +87 -0
  163. package/schemas/0.2/pointer.json +33 -0
  164. package/schemas/0.2/revocation-feed.json +55 -0
  165. package/schemas/0.2/verify-request.json +65 -0
  166. package/schemas/0.2/verify-response.json +284 -0
  167. package/spec/spec-v0.2.md +531 -0
  168. package/fixtures/file/invalid/full-all-mixed.json +0 -47
  169. package/fixtures/file/invalid/full-authorization-expires-after-file.json +0 -46
  170. package/fixtures/file/invalid/full-expires-before-issued.json +0 -46
  171. package/fixtures/file/invalid/full-expiry-over-180-days.json +0 -46
  172. package/fixtures/file/invalid/full-extra-property.json +0 -47
  173. package/fixtures/file/invalid/full-impossible-date.json +0 -46
  174. package/fixtures/file/invalid/full-lowercase-territory.json +0 -45
  175. package/fixtures/file/invalid/full-missing-file-expires.json +0 -45
  176. package/fixtures/file/invalid/full-missing-product-lines.json +0 -43
  177. package/fixtures/file/invalid/full-missing-scope.json +0 -37
  178. package/fixtures/file/invalid/full-missing-territories.json +0 -42
  179. package/fixtures/file/invalid/full-name-only-retailer.json +0 -30
  180. package/fixtures/file/invalid/full-no-channels.json +0 -31
  181. package/fixtures/file/invalid/full-non-utc-timestamp.json +0 -46
  182. package/fixtures/file/invalid/full-physical-missing-country.json +0 -50
  183. package/fixtures/file/invalid/full-web-missing-domain.json +0 -45
  184. package/fixtures/file/invalid/full-wrong-spec.json +0 -46
  185. package/fixtures/file/invalid/private-missing-verify.json +0 -8
  186. package/fixtures/file/invalid/private-with-authorizations.json +0 -45
  187. package/fixtures/file/invalid/unknown-form.json +0 -9
  188. package/fixtures/file/valid/full-fractional-seconds.json +0 -46
  189. package/fixtures/file/valid/full-max-expiry.json +0 -46
  190. package/fixtures/file/valid/full-no-authorizations.json +0 -11
  191. package/fixtures/file/valid/full-unsigned-handwritten.json +0 -46
  192. package/fixtures/file/valid/full-worldwide-physical-proposed.json +0 -82
  193. package/fixtures/file/valid/private.json +0 -9
  194. package/fixtures/verify-response/invalid/authorized-missing-authorization-id.json +0 -12
  195. package/fixtures/verify-response/invalid/missing-valid-until.json +0 -12
  196. package/fixtures/verify-response/invalid/observed-without-last-seen.json +0 -13
  197. package/fixtures/verify-response/invalid/unknown-status.json +0 -13
  198. package/fixtures/verify-response/invalid/unlisted-with-reason.json +0 -12
  199. package/fixtures/verify-response/invalid/valid-until-over-24h.json +0 -13
  200. package/fixtures/verify-response/valid/brand-unverified-no-reason.json +0 -11
  201. package/fixtures/verify-response/valid/brand-unverified-reason.json +0 -12
  202. /package/schemas/{common.json → 0.1/common.json} +0 -0
  203. /package/schemas/{file-full.json → 0.1/file-full.json} +0 -0
  204. /package/schemas/{file-pointer.json → 0.1/file-pointer.json} +0 -0
  205. /package/schemas/{file-private.json → 0.1/file-private.json} +0 -0
  206. /package/schemas/{file.json → 0.1/file.json} +0 -0
  207. /package/schemas/{verify-request.json → 0.1/verify-request.json} +0 -0
  208. /package/schemas/{verify-response.json → 0.1/verify-response.json} +0 -0
package/dist/types.d.ts CHANGED
@@ -1,85 +1,124 @@
1
- export declare const SPEC_VERSION: "authorized-retailers/0.1";
1
+ export declare const SPEC_VERSION: "authorized-retailers/0.2";
2
2
  export type SpecVersion = typeof SPEC_VERSION;
3
- /** RFC 3339 UTC timestamp, e.g. "2026-09-23T00:00:00Z". */
3
+ /** RFC 3339 UTC timestamp, e.g. "2026-09-28T00:00:00Z". */
4
4
  export type Timestamp = string;
5
- export interface Brand {
6
- name: string;
7
- domain: string;
8
- }
9
5
  export type MarketplaceChannelType = "amazon" | "walmart" | "ebay";
6
+ /** Section 6: a marketplace seller, identified by the marketplace domain and seller ID. */
10
7
  export interface MarketplaceChannel {
11
8
  type: MarketplaceChannelType;
12
- marketplace: string;
9
+ /** One of that type's marketplace domains, e.g. "amazon.com" (see MARKETPLACE_DOMAINS). */
10
+ domain: string;
13
11
  seller_id: string;
14
12
  }
15
13
  export interface WebChannel {
16
14
  type: "web";
17
15
  domain: string;
18
16
  }
19
- export interface PhysicalChannel {
20
- type: "physical";
21
- address: string;
22
- country: string;
23
- }
24
- /** A channel an agent can see and match on (section 6). */
25
- export type VerifiableChannel = MarketplaceChannel | WebChannel;
26
- export type Channel = VerifiableChannel | PhysicalChannel;
17
+ /** Section 6: every channel is identified by a domain. */
18
+ export type Channel = MarketplaceChannel | WebChannel;
27
19
  export type ChannelType = Channel["type"];
28
20
  export interface Party {
29
21
  name: string;
30
22
  entity_id?: string;
31
23
  }
24
+ /** Section 3.1: one product in a brand's catalog. Has a gtin, asins or both. */
25
+ export interface Product {
26
+ id: string;
27
+ name: string;
28
+ product_line?: string;
29
+ attributes?: Record<string, string>;
30
+ gtin?: string;
31
+ asins?: string[];
32
+ }
32
33
  export interface Scope {
33
- /** ISO 3166-1 alpha-2 codes, or exactly ["*"]. */
34
- territories: string[];
34
+ /** ISO 3166-1 alpha-2 codes, or exactly ["*"]. Optional: most channels take territory from their domain (section 6.2). */
35
+ territories?: string[];
35
36
  /** Named product lines, or exactly ["all"]. */
36
- product_lines: string[];
37
+ product_lines?: string[];
38
+ /** Catalog product IDs. */
39
+ products?: string[];
40
+ exclude_product_lines?: string[];
41
+ exclude_products?: string[];
42
+ }
43
+ export interface Exclusions {
44
+ product_lines?: string[];
45
+ products?: string[];
37
46
  }
38
47
  export interface Authorization {
39
48
  id: string;
49
+ /** Section 10.3: random, replaced whenever the authorization's coverage shrinks. */
50
+ revocation_id: string;
40
51
  retailer: Party;
41
52
  channels: Channel[];
42
53
  scope: Scope;
43
54
  proposed_by?: Party | null;
44
- expires: Timestamp;
55
+ /** Optional end date set by the brand (section 10). */
56
+ expires?: Timestamp;
45
57
  }
46
58
  export interface Signature {
47
59
  kid: string;
48
60
  /** Detached compact JWS: "<header>..<signature>". */
49
61
  jws: string;
50
62
  }
51
- export interface FullFile {
52
- spec: SpecVersion;
53
- form: "full";
54
- brand: Brand;
55
- issued: Timestamp;
56
- expires: Timestamp;
57
- authorizations: Authorization[];
58
- signature?: Signature;
59
- }
63
+ /** Section 5.1: the optional, unsigned file at /.well-known/authorized-retailers.json. */
60
64
  export interface PointerFile {
61
65
  spec: SpecVersion;
62
66
  form: "pointer";
63
- brand: Brand;
67
+ brand: {
68
+ name: string;
69
+ domain: string;
70
+ };
71
+ verify_token: string;
72
+ /** Always an https://authorizedretailers.ai/ URL. */
64
73
  list: string;
65
74
  }
66
- export interface PrivateFile {
75
+ /** The only file form in v0.2. */
76
+ export type AuthorizedRetailersFile = PointerFile;
77
+ export type FileForm = PointerFile["form"];
78
+ interface ListBase {
67
79
  spec: SpecVersion;
68
- form: "private";
69
- brand: Brand;
70
- verify: string;
80
+ brand: {
81
+ name: string;
82
+ domains: string[];
83
+ };
84
+ issued: Timestamp;
85
+ /** At most 15 minutes after issued (section 10.1). */
86
+ valid_until: Timestamp;
87
+ /** At most 24 hours after issued (section 10.2). */
88
+ stale_until: Timestamp;
89
+ signature: Signature;
90
+ }
91
+ /** Section 5.2: a brand's signed list, as published by the registry. */
92
+ export interface PublicList extends ListBase {
93
+ public: true;
94
+ catalog?: Product[];
95
+ exclusions?: Exclusions;
96
+ authorizations: Authorization[];
71
97
  }
72
- export type AuthorizedRetailersFile = FullFile | PointerFile | PrivateFile;
73
- export type FileForm = AuthorizedRetailersFile["form"];
98
+ /** Section 5.2: the signed response for a brand whose list is not public. */
99
+ export interface NotPublicList extends ListBase {
100
+ public: false;
101
+ }
102
+ export type SignedList = PublicList | NotPublicList;
103
+ /** Exactly one of gtin or asin. */
104
+ export type ProductRef = {
105
+ gtin: string;
106
+ } | {
107
+ asin: string;
108
+ };
74
109
  export interface VerifyRequest {
75
110
  brand_domain: string;
76
- channel: VerifiableChannel;
77
- territory: string;
78
- /** Defaults to "all". */
111
+ channel: Channel;
112
+ /** Defaults to the channel domain's country. Required for web stores on generic domains. */
113
+ territory?: string;
79
114
  product_line?: string;
115
+ product?: ProductRef;
116
+ /** ISO 8601 date or UTC date-time. Defaults to now. */
117
+ as_of?: string;
80
118
  }
81
- export type VerifyStatus = "authorized" | "unlisted" | "expired" | "brand_unverified" | "disputed";
82
- export type UnverifiedReason = "not_registered" | "domain_unlinked" | "verification_lapsed";
119
+ export type VerifyStatus = "authorized" | "unlisted" | "expired" | "brand_not_registered" | "disputed";
120
+ export type NotRegisteredReason = "not_registered" | "domain_unlinked" | "verification_lapsed";
121
+ export type UnlistedReason = "territory_mismatch" | "product_excluded" | "product_not_in_scope" | "product_not_in_catalog";
83
122
  export interface Signal {
84
123
  type: string;
85
124
  observed: Timestamp;
@@ -89,28 +128,63 @@ export interface Signal {
89
128
  export interface Observation {
90
129
  last_seen: Timestamp;
91
130
  }
131
+ /** Section 9: present when the request named a product. id and product_line only for public lists. */
132
+ export interface ProductResult {
133
+ in_catalog: boolean;
134
+ id?: string;
135
+ product_line?: string;
136
+ }
92
137
  interface VerifyResponseBase {
93
138
  checked: Timestamp;
94
- /** At most 24 hours after `checked` (section 9). */
139
+ as_of?: Timestamp;
140
+ /** At most 15 minutes after `checked` (section 9). */
95
141
  valid_until: Timestamp;
142
+ /** At most 24 hours after `checked` (section 10.2). */
143
+ stale_until: Timestamp;
144
+ product?: ProductResult;
96
145
  /** Non-null only on `authorized` answers (section 7). */
97
146
  observed: Observation | null;
98
147
  signals: Signal[];
99
148
  signature: Signature;
100
149
  }
101
- export interface VerifyResponseWithAuthorization extends VerifyResponseBase {
102
- status: "authorized" | "expired" | "disputed";
150
+ export interface VerifyResponseAuthorized extends VerifyResponseBase {
151
+ status: "authorized";
152
+ authorization_id: string;
153
+ revocation_id: string;
154
+ expires?: Timestamp;
155
+ }
156
+ export interface VerifyResponseExpired extends VerifyResponseBase {
157
+ status: "expired";
103
158
  authorization_id: string;
104
159
  expires: Timestamp;
105
160
  }
161
+ export interface VerifyResponseDisputed extends VerifyResponseBase {
162
+ status: "disputed";
163
+ authorization_id: string;
164
+ expires?: Timestamp;
165
+ }
106
166
  export interface VerifyResponseUnlisted extends VerifyResponseBase {
107
167
  status: "unlisted";
168
+ reason?: UnlistedReason;
108
169
  }
109
- export interface VerifyResponseBrandUnverified extends VerifyResponseBase {
110
- status: "brand_unverified";
111
- reason?: UnverifiedReason;
170
+ export interface VerifyResponseNotRegistered extends VerifyResponseBase {
171
+ status: "brand_not_registered";
172
+ reason?: NotRegisteredReason;
112
173
  }
113
- export type VerifyResponse = VerifyResponseWithAuthorization | VerifyResponseUnlisted | VerifyResponseBrandUnverified;
174
+ export type VerifyResponse = VerifyResponseAuthorized | VerifyResponseExpired | VerifyResponseDisputed | VerifyResponseUnlisted | VerifyResponseNotRegistered;
114
175
  /** A verify response before the registry attaches its signature. */
115
176
  export type UnsignedVerifyResponse = VerifyResponse extends infer R ? R extends VerifyResponseBase ? Omit<R, "signature"> : never : never;
177
+ /** Section 10.3: the signed feed of revocation IDs from the last 24 hours. */
178
+ export interface RevocationFeed {
179
+ spec: SpecVersion;
180
+ feed: "revocations";
181
+ issued: Timestamp;
182
+ valid_until: Timestamp;
183
+ stale_until: Timestamp;
184
+ entries: {
185
+ revocation_id: string;
186
+ revoked: Timestamp;
187
+ }[];
188
+ signature: Signature;
189
+ }
116
190
  export {};
package/dist/types.js CHANGED
@@ -1,2 +1,2 @@
1
- // Types mirror schemas/*.json. The schemas are canonical; if the two disagree, the schema wins.
2
- export const SPEC_VERSION = "authorized-retailers/0.1";
1
+ // Types mirror schemas/0.2/*.json. The schemas are canonical; if the two disagree, the schema wins.
2
+ export const SPEC_VERSION = "authorized-retailers/0.2";
@@ -1,8 +1,14 @@
1
- import type { AuthorizedRetailersFile, Channel, Scope, FullFile, PointerFile, PrivateFile, VerifyRequest, VerifyResponse } from "./types.js";
2
- export type ErrorCode = "schema" | "no_online_channel" | "invalid_timestamp" | "expires_not_after_issued" | "file_expiry_exceeds_max" | "authorization_expires_after_file" | "duplicate_authorization_id" | "valid_until_not_after_checked" | "valid_until_exceeds_max";
1
+ import type { Channel, PointerFile, RevocationFeed, Scope, SignedList, VerifyRequest, VerifyResponse } from "./types.js";
2
+ export type ErrorCode = "schema" | "form_not_supported" | "list_not_on_registry" | "brand_domain_mismatch" | "unknown_channel_type" | "marketplace_field_removed" | "marketplace_domain_mismatch" | "invalid_country" | "territory_mismatch" | "territories_required" | "territory_required" | "invalid_gtin" | "invalid_asin" | "product_without_identifier" | "duplicate_product_id" | "duplicate_identifier" | "unknown_product_line" | "unknown_product" | "invalid_timestamp" | "duplicate_authorization_id" | "valid_until_not_after_issued" | "valid_until_exceeds_max" | "stale_until_before_valid_until" | "stale_until_exceeds_max";
3
+ export type WarningCode = "territory_differs_from_domain";
3
4
  export interface ValidationError {
4
5
  code: ErrorCode;
5
- /** JSON Pointer into the instance, e.g. "/authorizations/0/expires". */
6
+ /** JSON Pointer into the instance, e.g. "/authorizations/0/channels/1". */
7
+ path: string;
8
+ message: string;
9
+ }
10
+ export interface ValidationWarning {
11
+ code: WarningCode;
6
12
  path: string;
7
13
  message: string;
8
14
  }
@@ -10,19 +16,27 @@ export type ValidationResult<T> = {
10
16
  valid: true;
11
17
  value: T;
12
18
  errors: [];
19
+ warnings: ValidationWarning[];
13
20
  } | {
14
21
  valid: false;
15
22
  errors: ValidationError[];
23
+ warnings: ValidationWarning[];
16
24
  };
17
- /** Validates an authorized-retailers.json file of any form. */
18
- export declare function validateFile(input: unknown): ValidationResult<AuthorizedRetailersFile>;
19
- export declare function validateFullFile(input: unknown): ValidationResult<FullFile>;
20
- export declare function validatePointerFile(input: unknown): ValidationResult<PointerFile>;
21
- export declare function validatePrivateFile(input: unknown): ValidationResult<PrivateFile>;
25
+ /**
26
+ * Validates a pointer file (section 5.1). Pass the domain it was fetched from (the domain first
27
+ * asked for, before any redirects) to check that the pointer vouches for it.
28
+ */
29
+ export declare function validateFile(input: unknown, fetchedFrom?: string): ValidationResult<PointerFile>;
30
+ /** Validates a signed list or not-public response (section 5.2). Does not check the signature: see checkPublishedList. */
31
+ export declare function validateList(input: unknown): ValidationResult<SignedList>;
22
32
  /** Validates a canonical verify request. Call normalizeVerifyRequest on raw agent input first. */
23
33
  export declare function validateVerifyRequest(input: unknown): ValidationResult<VerifyRequest>;
24
34
  export declare function validateVerifyResponse(input: unknown): ValidationResult<VerifyResponse>;
25
- /** Validates one authorization scope (§3), e.g. before a registry stores it. */
35
+ /** Validates a revocation feed (section 10.3). Does not check the signature: see checkRevocationFeed. */
36
+ export declare function validateRevocationFeed(input: unknown): ValidationResult<RevocationFeed>;
37
+ /** Validates one authorization scope (section 3), e.g. before the registry stores it. */
26
38
  export declare function validateScope(input: unknown): ValidationResult<Scope>;
27
- /** Validates one channel identifier (§6), e.g. before a registry stores it. */
39
+ /** Validates one channel identifier (section 6), e.g. before the registry stores it. */
28
40
  export declare function validateChannel(input: unknown): ValidationResult<Channel>;
41
+ /** Validates one catalog product (section 3.1), e.g. a row from a brand's CSV import. */
42
+ export declare function validateProduct(input: unknown): ValidationResult<import("./types.js").Product>;