@buildinternet/releases-api-types 0.58.3 → 0.60.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 (125) hide show
  1. package/README.md +14 -6
  2. package/dist/api-types.d.ts +1168 -0
  3. package/dist/api-types.d.ts.map +1 -0
  4. package/dist/api-types.js +134 -0
  5. package/dist/schemas/account-profile.d.ts +29 -0
  6. package/dist/schemas/account-profile.d.ts.map +1 -0
  7. package/dist/schemas/account-profile.js +24 -0
  8. package/dist/schemas/ai-models.d.ts +67 -0
  9. package/dist/schemas/ai-models.d.ts.map +1 -0
  10. package/{src/schemas/ai-models.ts → dist/schemas/ai-models.js} +25 -31
  11. package/dist/schemas/api-keys.d.ts +71 -0
  12. package/dist/schemas/api-keys.d.ts.map +1 -0
  13. package/dist/schemas/api-keys.js +32 -0
  14. package/dist/schemas/classifications.d.ts +134 -0
  15. package/dist/schemas/classifications.d.ts.map +1 -0
  16. package/dist/schemas/classifications.js +96 -0
  17. package/dist/schemas/collections.d.ts +605 -0
  18. package/dist/schemas/collections.d.ts.map +1 -0
  19. package/dist/schemas/collections.js +320 -0
  20. package/dist/schemas/datasets.d.ts +34 -0
  21. package/dist/schemas/datasets.d.ts.map +1 -0
  22. package/dist/schemas/datasets.js +11 -0
  23. package/dist/schemas/errors.d.ts +43 -0
  24. package/dist/schemas/errors.d.ts.map +1 -0
  25. package/dist/schemas/errors.js +61 -0
  26. package/dist/schemas/feedback.d.ts +134 -0
  27. package/dist/schemas/feedback.d.ts.map +1 -0
  28. package/dist/schemas/feedback.js +76 -0
  29. package/dist/schemas/follows.d.ts +154 -0
  30. package/dist/schemas/follows.d.ts.map +1 -0
  31. package/dist/schemas/follows.js +42 -0
  32. package/dist/schemas/listing.d.ts +374 -0
  33. package/dist/schemas/listing.d.ts.map +1 -0
  34. package/dist/schemas/listing.js +175 -0
  35. package/dist/schemas/lookups.d.ts +285 -0
  36. package/dist/schemas/lookups.d.ts.map +1 -0
  37. package/{src/schemas/lookups.ts → dist/schemas/lookups.js} +67 -80
  38. package/dist/schemas/marketing-classifier.d.ts +32 -0
  39. package/dist/schemas/marketing-classifier.d.ts.map +1 -0
  40. package/{src/schemas/marketing-classifier.ts → dist/schemas/marketing-classifier.js} +14 -18
  41. package/dist/schemas/orgs.d.ts +950 -0
  42. package/dist/schemas/orgs.d.ts.map +1 -0
  43. package/dist/schemas/orgs.js +473 -0
  44. package/dist/schemas/overviews.d.ts +205 -0
  45. package/dist/schemas/overviews.d.ts.map +1 -0
  46. package/{src/schemas/overviews.ts → dist/schemas/overviews.js} +41 -54
  47. package/dist/schemas/products.d.ts +595 -0
  48. package/dist/schemas/products.d.ts.map +1 -0
  49. package/{src/schemas/products.ts → dist/schemas/products.js} +113 -136
  50. package/dist/schemas/publish-tokens.d.ts +55 -0
  51. package/dist/schemas/publish-tokens.d.ts.map +1 -0
  52. package/{src/schemas/publish-tokens.ts → dist/schemas/publish-tokens.js} +18 -29
  53. package/dist/schemas/recommendations.d.ts +52 -0
  54. package/dist/schemas/recommendations.d.ts.map +1 -0
  55. package/dist/schemas/recommendations.js +58 -0
  56. package/dist/schemas/related.d.ts +331 -0
  57. package/dist/schemas/related.d.ts.map +1 -0
  58. package/dist/schemas/related.js +115 -0
  59. package/dist/schemas/releases.d.ts +623 -0
  60. package/dist/schemas/releases.d.ts.map +1 -0
  61. package/dist/schemas/releases.js +414 -0
  62. package/dist/schemas/resolve.d.ts +259 -0
  63. package/dist/schemas/resolve.d.ts.map +1 -0
  64. package/{src/schemas/resolve.ts → dist/schemas/resolve.js} +2 -5
  65. package/dist/schemas/search.d.ts +475 -0
  66. package/dist/schemas/search.d.ts.map +1 -0
  67. package/dist/schemas/search.js +258 -0
  68. package/dist/schemas/semantic-alert-summary.d.ts +54 -0
  69. package/dist/schemas/semantic-alert-summary.d.ts.map +1 -0
  70. package/dist/schemas/semantic-alert-summary.js +57 -0
  71. package/dist/schemas/semantic-alerts.d.ts +41 -0
  72. package/dist/schemas/semantic-alerts.d.ts.map +1 -0
  73. package/dist/schemas/semantic-alerts.js +42 -0
  74. package/dist/schemas/shared.d.ts +247 -0
  75. package/dist/schemas/shared.d.ts.map +1 -0
  76. package/dist/schemas/shared.js +248 -0
  77. package/dist/schemas/site-notice.d.ts +35 -0
  78. package/dist/schemas/site-notice.d.ts.map +1 -0
  79. package/{src/schemas/site-notice.ts → dist/schemas/site-notice.js} +14 -18
  80. package/dist/schemas/sitemap.d.ts +97 -0
  81. package/dist/schemas/sitemap.d.ts.map +1 -0
  82. package/dist/schemas/sitemap.js +107 -0
  83. package/dist/schemas/sources.d.ts +1145 -0
  84. package/dist/schemas/sources.d.ts.map +1 -0
  85. package/dist/schemas/sources.js +645 -0
  86. package/dist/schemas/stats.d.ts +82 -0
  87. package/dist/schemas/stats.d.ts.map +1 -0
  88. package/dist/schemas/stats.js +59 -0
  89. package/dist/schemas/taxonomy.d.ts +344 -0
  90. package/dist/schemas/taxonomy.d.ts.map +1 -0
  91. package/{src/schemas/taxonomy.ts → dist/schemas/taxonomy.js} +47 -58
  92. package/dist/schemas/webhooks.d.ts +618 -0
  93. package/dist/schemas/webhooks.d.ts.map +1 -0
  94. package/dist/schemas/webhooks.js +191 -0
  95. package/dist/schemas/well-known.d.ts +302 -0
  96. package/dist/schemas/well-known.d.ts.map +1 -0
  97. package/dist/schemas/well-known.js +192 -0
  98. package/dist/schemas/workspace-integrations.d.ts +27 -0
  99. package/dist/schemas/workspace-integrations.d.ts.map +1 -0
  100. package/dist/schemas/workspace-integrations.js +22 -0
  101. package/package.json +16 -4
  102. package/src/api-types.ts +0 -2223
  103. package/src/schemas/account-profile.ts +0 -28
  104. package/src/schemas/ai-models.test.ts +0 -29
  105. package/src/schemas/classifications.ts +0 -109
  106. package/src/schemas/collections.ts +0 -346
  107. package/src/schemas/errors.test.ts +0 -55
  108. package/src/schemas/errors.ts +0 -81
  109. package/src/schemas/feedback.ts +0 -56
  110. package/src/schemas/listing.ts +0 -226
  111. package/src/schemas/orgs.ts +0 -533
  112. package/src/schemas/recommendations.ts +0 -39
  113. package/src/schemas/related.ts +0 -126
  114. package/src/schemas/releases.ts +0 -436
  115. package/src/schemas/search.ts +0 -274
  116. package/src/schemas/semantic-alert-summary.ts +0 -65
  117. package/src/schemas/shared.notice.test.ts +0 -36
  118. package/src/schemas/shared.ts +0 -267
  119. package/src/schemas/site-notice.test.ts +0 -67
  120. package/src/schemas/sitemap.ts +0 -114
  121. package/src/schemas/sources.ts +0 -674
  122. package/src/schemas/stats.ts +0 -62
  123. package/src/schemas/well-known.test.ts +0 -264
  124. package/src/schemas/well-known.ts +0 -252
  125. package/src/schemas/workspace-integrations.ts +0 -26
@@ -0,0 +1,247 @@
1
+ import { z } from "zod";
2
+ export declare const CategorySchema: z.ZodEnum<{
3
+ ai: "ai";
4
+ cloud: "cloud";
5
+ commerce: "commerce";
6
+ crm: "crm";
7
+ database: "database";
8
+ design: "design";
9
+ "developer-tools": "developer-tools";
10
+ devops: "devops";
11
+ finance: "finance";
12
+ framework: "framework";
13
+ infrastructure: "infrastructure";
14
+ observability: "observability";
15
+ productivity: "productivity";
16
+ security: "security";
17
+ }>;
18
+ /**
19
+ * AI-scored release importance, 1 (housekeeping) to 5 (landmark). Scored at
20
+ * ingest; `.nullable().optional()` — null when unscored, absent on older
21
+ * servers/pinned workers.
22
+ */
23
+ export declare const ImportanceScoreSchema: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
24
+ export declare const MediaItemSchema: z.ZodObject<{
25
+ type: z.ZodEnum<{
26
+ gif: "gif";
27
+ image: "image";
28
+ video: "video";
29
+ }>;
30
+ url: z.ZodString;
31
+ alt: z.ZodOptional<z.ZodString>;
32
+ r2Key: z.ZodOptional<z.ZodString>;
33
+ r2Url: z.ZodOptional<z.ZodString>;
34
+ linkUrl: z.ZodOptional<z.ZodString>;
35
+ }, z.core.$strip>;
36
+ /**
37
+ * App Store platform + icon for a `type: "appstore"` source. Threaded onto
38
+ * read surfaces so the UI can render the compact app-update row (app icon +
39
+ * "Available for iOS/macOS") instead of the standard version/notes/thumbnail
40
+ * layout. Sourced from `source.metadata.appStore` server-side. #mobile-appstore-feed-row
41
+ */
42
+ export declare const AppStoreSourceInfoSchema: z.ZodObject<{
43
+ platform: z.ZodEnum<{
44
+ ios: "ios";
45
+ macos: "macos";
46
+ }>;
47
+ iconUrl: z.ZodNullable<z.ZodString>;
48
+ }, z.core.$strip>;
49
+ /** Video provider tag, present only when `sourceType === "video"`. Thumbnail
50
+ * and watch URL reuse the release's existing `media[]` / `url`. */
51
+ export declare const VideoSourceInfoSchema: z.ZodObject<{
52
+ provider: z.ZodEnum<{
53
+ vimeo: "vimeo";
54
+ wistia: "wistia";
55
+ youtube: "youtube";
56
+ }>;
57
+ }, z.core.$strip>;
58
+ /**
59
+ * Org tier surfaced on read paths (#1947). `stub` = known only by declared
60
+ * release locations (no processed sources yet); `tracked` = a normal org whose
61
+ * sources fetch. The column is `organizations.tier`; the wire name is `status`.
62
+ * Optional on the wire so a pinned client mid-deploy tolerates its absence —
63
+ * treat a missing value as `"tracked"`.
64
+ */
65
+ export declare const OrgStatusSchema: z.ZodEnum<{
66
+ stub: "stub";
67
+ tracked: "tracked";
68
+ }>;
69
+ /**
70
+ * A declared release location (#1947) — one `release_locations` row on the
71
+ * wire, the same shape a releases.json `releases[]` entry carries plus its
72
+ * provenance `basis` and, once promoted, the `sourceId` it materialized into.
73
+ * Surfaced on stub orgs so an agent gets "release info is published at these
74
+ * locations" instead of an empty sources list.
75
+ */
76
+ export declare const ReleaseLocationItemSchema: z.ZodObject<{
77
+ url: z.ZodOptional<z.ZodString>;
78
+ feed: z.ZodOptional<z.ZodString>;
79
+ github: z.ZodOptional<z.ZodString>;
80
+ appstore: z.ZodOptional<z.ZodString>;
81
+ file: z.ZodOptional<z.ZodString>;
82
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
83
+ canonical: z.ZodBoolean;
84
+ basis: z.ZodEnum<{
85
+ curator: "curator";
86
+ declared: "declared";
87
+ detected: "detected";
88
+ generated: "generated";
89
+ }>;
90
+ productId: z.ZodNullable<z.ZodString>;
91
+ sourceId: z.ZodNullable<z.ZodString>;
92
+ publish: z.ZodOptional<z.ZodLiteral<"push">>;
93
+ path: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$strip>;
95
+ export declare const PaginationSchema: z.ZodObject<{
96
+ page: z.ZodNumber;
97
+ pageSize: z.ZodNumber;
98
+ returned: z.ZodNumber;
99
+ totalItems: z.ZodOptional<z.ZodNumber>;
100
+ totalPages: z.ZodOptional<z.ZodNumber>;
101
+ hasMore: z.ZodBoolean;
102
+ }, z.core.$strip>;
103
+ export declare const ListResponseSchema: <T extends z.ZodTypeAny>(item: T) => z.ZodObject<{
104
+ items: z.ZodArray<T>;
105
+ pagination: z.ZodObject<{
106
+ page: z.ZodNumber;
107
+ pageSize: z.ZodNumber;
108
+ returned: z.ZodNumber;
109
+ totalItems: z.ZodOptional<z.ZodNumber>;
110
+ totalPages: z.ZodOptional<z.ZodNumber>;
111
+ hasMore: z.ZodBoolean;
112
+ }, z.core.$strip>;
113
+ }, z.core.$strip>;
114
+ export declare const StatsSchema: z.ZodObject<{
115
+ orgs: z.ZodNumber;
116
+ sources: z.ZodNumber;
117
+ releases: z.ZodNumber;
118
+ products: z.ZodNumber;
119
+ }, z.core.$strip>;
120
+ export declare const ReleaseTypeSchema: z.ZodEnum<{
121
+ feature: "feature";
122
+ rollup: "rollup";
123
+ }>;
124
+ /**
125
+ * Per-category item counts produced by the AI release-content pass and
126
+ * persisted on `releases.metadata.composition`. Surfaces as a chip on the
127
+ * release detail UI ("12 fixes · 3 features"); `null` when the row hasn't
128
+ * been through the AI pass yet, the body was empty/boilerplate, or all
129
+ * three counts came back zero (we filter that case out on the parse side).
130
+ */
131
+ export declare const ReleaseCompositionSchema: z.ZodObject<{
132
+ bugs: z.ZodNumber;
133
+ features: z.ZodNumber;
134
+ enhancements: z.ZodNumber;
135
+ }, z.core.$strip>;
136
+ export declare const ReleaseItemSchema: z.ZodObject<{
137
+ id: z.ZodOptional<z.ZodString>;
138
+ version: z.ZodNullable<z.ZodString>;
139
+ title: z.ZodString;
140
+ summary: z.ZodString;
141
+ content: z.ZodOptional<z.ZodString>;
142
+ publishedAt: z.ZodNullable<z.ZodString>;
143
+ fetchedAt: z.ZodOptional<z.ZodString>;
144
+ url: z.ZodNullable<z.ZodString>;
145
+ media: z.ZodOptional<z.ZodArray<z.ZodObject<{
146
+ type: z.ZodEnum<{
147
+ gif: "gif";
148
+ image: "image";
149
+ video: "video";
150
+ }>;
151
+ url: z.ZodString;
152
+ alt: z.ZodOptional<z.ZodString>;
153
+ r2Key: z.ZodOptional<z.ZodString>;
154
+ r2Url: z.ZodOptional<z.ZodString>;
155
+ linkUrl: z.ZodOptional<z.ZodString>;
156
+ }, z.core.$strip>>>;
157
+ type: z.ZodOptional<z.ZodEnum<{
158
+ feature: "feature";
159
+ rollup: "rollup";
160
+ }>>;
161
+ prerelease: z.ZodOptional<z.ZodBoolean>;
162
+ titleGenerated: z.ZodOptional<z.ZodNullable<z.ZodString>>;
163
+ titleShort: z.ZodOptional<z.ZodNullable<z.ZodString>>;
164
+ breaking: z.ZodOptional<z.ZodEnum<{
165
+ major: "major";
166
+ minor: "minor";
167
+ none: "none";
168
+ unknown: "unknown";
169
+ }>>;
170
+ importance: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
171
+ coverageCount: z.ZodOptional<z.ZodNumber>;
172
+ contentChars: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
173
+ contentTokens: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
174
+ composition: z.ZodOptional<z.ZodNullable<z.ZodObject<{
175
+ bugs: z.ZodNumber;
176
+ features: z.ZodNumber;
177
+ enhancements: z.ZodNumber;
178
+ }, z.core.$strip>>>;
179
+ }, z.core.$strip>;
180
+ export declare const ReleaseSummaryItemSchema: z.ZodObject<{
181
+ year: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
182
+ month: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
183
+ windowDays: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
184
+ summary: z.ZodString;
185
+ releaseCount: z.ZodNumber;
186
+ generatedAt: z.ZodString;
187
+ }, z.core.$strip>;
188
+ /**
189
+ * A source attached to an overview page (#846, reshaped #1934). Each row names
190
+ * a source the overview drew on — `sourceUrl` plus, when it resolved to an
191
+ * on-registry release, `releaseId` + a canonical `releaseWebUrl`. This is a
192
+ * source *list*, not span-anchored provenance: the old body char offsets +
193
+ * verbatim quote are removed. Optional everywhere it appears — consumers should
194
+ * degrade gracefully.
195
+ */
196
+ export declare const OverviewCitationSchema: z.ZodObject<{
197
+ sourceUrl: z.ZodString;
198
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
199
+ releaseId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
200
+ releaseWebUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
201
+ startIndex: z.ZodOptional<z.ZodNumber>;
202
+ endIndex: z.ZodOptional<z.ZodNumber>;
203
+ citedText: z.ZodOptional<z.ZodString>;
204
+ }, z.core.$strip>;
205
+ /**
206
+ * Entity notice — a small curator-set note on an org / product / source. Stored
207
+ * under the `notice` key of the entity's metadata JSON; mirrors the `Notice`
208
+ * type in @buildinternet/releases-core/notice. `coordinate` is an internal
209
+ * registry path ("org" / "org/slug"); `href` is an external URL; at most one.
210
+ */
211
+ export declare const NoticeSchema: z.ZodObject<{
212
+ message: z.ZodString;
213
+ linkText: z.ZodOptional<z.ZodString>;
214
+ coordinate: z.ZodOptional<z.ZodString>;
215
+ href: z.ZodOptional<z.ZodURL>;
216
+ }, z.core.$strip>;
217
+ /**
218
+ * Display thumbnail derived server-side from a release's first image/gif media
219
+ * entry. Shared by the coverage, lookup, and related-release payloads.
220
+ */
221
+ export declare const ReleaseThumbnailSchema: z.ZodObject<{
222
+ url: z.ZodString;
223
+ alt: z.ZodOptional<z.ZodString>;
224
+ }, z.core.$strip>;
225
+ export declare const OverviewPageItemSchema: z.ZodObject<{
226
+ scope: z.ZodEnum<{
227
+ org: "org";
228
+ product: "product";
229
+ }>;
230
+ orgSlug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
231
+ productSlug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
232
+ content: z.ZodString;
233
+ releaseCount: z.ZodNumber;
234
+ lastContributingReleaseAt: z.ZodNullable<z.ZodString>;
235
+ generatedAt: z.ZodString;
236
+ updatedAt: z.ZodString;
237
+ citations: z.ZodOptional<z.ZodArray<z.ZodObject<{
238
+ sourceUrl: z.ZodString;
239
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
240
+ releaseId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
241
+ releaseWebUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
242
+ startIndex: z.ZodOptional<z.ZodNumber>;
243
+ endIndex: z.ZodOptional<z.ZodNumber>;
244
+ citedText: z.ZodOptional<z.ZodString>;
245
+ }, z.core.$strip>>>;
246
+ }, z.core.$strip>;
247
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/schemas/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAAqB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,2CAMrB,CAAC;AAEd,eAAO,MAAM,eAAe;;;;;;;;;;;iBAmB1B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;iBAGnC,CAAC;AAEH;mEACmE;AACnE,eAAO,MAAM,qBAAqB;;;;;;iBAEhC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;EAA8B,CAAC;AAE3D;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;iBAiBpC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;iBAO3B,CAAC;AAEH,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,UAAU,QAAQ,CAAC;;;;;;;;;;iBAI9D,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;iBAKtB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;EAAwB,CAAC;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;;;;iBAInC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsD5B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;iBAOnC,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;iBAoBjC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY;;;;;iBAYrB,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;iBAUjC,CAAC"}
@@ -0,0 +1,248 @@
1
+ import { z } from "zod";
2
+ import { RELEASE_TYPES } from "@buildinternet/releases-core/schema";
3
+ import { BREAKING_LEVELS } from "@buildinternet/releases-core/breaking";
4
+ import { CATEGORIES } from "@buildinternet/releases-core/categories";
5
+ import { isValidNoticeCoordinate } from "@buildinternet/releases-core/notice";
6
+ import { IMPORTANCE_MAX, IMPORTANCE_MIN } from "@buildinternet/releases-core/importance";
7
+ export const CategorySchema = z.enum(CATEGORIES);
8
+ /**
9
+ * AI-scored release importance, 1 (housekeeping) to 5 (landmark). Scored at
10
+ * ingest; `.nullable().optional()` — null when unscored, absent on older
11
+ * servers/pinned workers.
12
+ */
13
+ export const ImportanceScoreSchema = z
14
+ .number()
15
+ .int()
16
+ .min(IMPORTANCE_MIN)
17
+ .max(IMPORTANCE_MAX)
18
+ .nullable()
19
+ .optional();
20
+ export const MediaItemSchema = z.object({
21
+ type: z.enum(["image", "video", "gif"]),
22
+ url: z.string(),
23
+ alt: z.string().optional(),
24
+ // R2 object key (`releases/<hash>.<ext>`) for media mirrored into the
25
+ // `released-media` bucket; read paths resolve it to a same-origin `r2Url`
26
+ // (`resolveR2Url`). Stamped by `processMediaForR2` at ingest / manual edit and
27
+ // part of the stored `media[]` JSON — surfaced on the wire so a curator round-
28
+ // tripping `media` through `PATCH /v1/releases/:id` can preserve an already-
29
+ // mirrored item without forcing a re-fetch.
30
+ r2Key: z.string().optional(),
31
+ r2Url: z.string().optional(),
32
+ // For `type: "video"` items promoted from a hosted-video link found inline in
33
+ // a release body (Wistia/Loom/Vimeo/YouTube), `url` holds the poster/thumbnail
34
+ // (mirrored to R2 like any image) and `linkUrl` holds the human watch URL the
35
+ // play-card links out to. Absent for ordinary image/gif media. See
36
+ // `detectInlineVideos` in `@releases/rendering/video-embed` and web's
37
+ // release-content video card.
38
+ linkUrl: z.string().optional(),
39
+ });
40
+ /**
41
+ * App Store platform + icon for a `type: "appstore"` source. Threaded onto
42
+ * read surfaces so the UI can render the compact app-update row (app icon +
43
+ * "Available for iOS/macOS") instead of the standard version/notes/thumbnail
44
+ * layout. Sourced from `source.metadata.appStore` server-side. #mobile-appstore-feed-row
45
+ */
46
+ export const AppStoreSourceInfoSchema = z.object({
47
+ platform: z.enum(["ios", "macos"]),
48
+ iconUrl: z.string().nullable(),
49
+ });
50
+ /** Video provider tag, present only when `sourceType === "video"`. Thumbnail
51
+ * and watch URL reuse the release's existing `media[]` / `url`. */
52
+ export const VideoSourceInfoSchema = z.object({
53
+ provider: z.enum(["youtube", "vimeo", "wistia"]),
54
+ });
55
+ /**
56
+ * Org tier surfaced on read paths (#1947). `stub` = known only by declared
57
+ * release locations (no processed sources yet); `tracked` = a normal org whose
58
+ * sources fetch. The column is `organizations.tier`; the wire name is `status`.
59
+ * Optional on the wire so a pinned client mid-deploy tolerates its absence —
60
+ * treat a missing value as `"tracked"`.
61
+ */
62
+ export const OrgStatusSchema = z.enum(["stub", "tracked"]);
63
+ /**
64
+ * A declared release location (#1947) — one `release_locations` row on the
65
+ * wire, the same shape a releases.json `releases[]` entry carries plus its
66
+ * provenance `basis` and, once promoted, the `sourceId` it materialized into.
67
+ * Surfaced on stub orgs so an agent gets "release info is published at these
68
+ * locations" instead of an empty sources list.
69
+ */
70
+ export const ReleaseLocationItemSchema = z.object({
71
+ url: z.string().optional(),
72
+ feed: z.string().optional(),
73
+ github: z.string().optional(),
74
+ appstore: z.string().optional(),
75
+ file: z.string().optional(),
76
+ title: z.string().nullable().optional(),
77
+ canonical: z.boolean(),
78
+ basis: z.enum(["curator", "declared", "detected", "generated"]),
79
+ /** Owning product id when the locator is product-scoped, else null. */
80
+ productId: z.string().nullable(),
81
+ /** Set once the locator has been promoted into a source, else null. */
82
+ sourceId: z.string().nullable(),
83
+ /** `"push"` when the owner publishes this changelog instead of us polling it. */
84
+ publish: z.literal("push").optional(),
85
+ /** Changelog file or glob. Present with `publish: "push"`. */
86
+ path: z.string().optional(),
87
+ });
88
+ export const PaginationSchema = z.object({
89
+ page: z.number().int().min(1),
90
+ pageSize: z.number().int().min(1),
91
+ returned: z.number().int().min(0),
92
+ totalItems: z.number().int().min(0).optional(),
93
+ totalPages: z.number().int().min(0).optional(),
94
+ hasMore: z.boolean(),
95
+ });
96
+ export const ListResponseSchema = (item) => z.object({
97
+ items: z.array(item),
98
+ pagination: PaginationSchema,
99
+ });
100
+ export const StatsSchema = z.object({
101
+ orgs: z.number().int().min(0),
102
+ sources: z.number().int().min(0),
103
+ releases: z.number().int().min(0),
104
+ products: z.number().int().min(0),
105
+ });
106
+ export const ReleaseTypeSchema = z.enum(RELEASE_TYPES);
107
+ /**
108
+ * Per-category item counts produced by the AI release-content pass and
109
+ * persisted on `releases.metadata.composition`. Surfaces as a chip on the
110
+ * release detail UI ("12 fixes · 3 features"); `null` when the row hasn't
111
+ * been through the AI pass yet, the body was empty/boilerplate, or all
112
+ * three counts came back zero (we filter that case out on the parse side).
113
+ */
114
+ export const ReleaseCompositionSchema = z.object({
115
+ bugs: z.number().int().min(0),
116
+ features: z.number().int().min(0),
117
+ enhancements: z.number().int().min(0),
118
+ });
119
+ export const ReleaseItemSchema = z.object({
120
+ id: z.string().optional(),
121
+ version: z.string().nullable(),
122
+ title: z.string(),
123
+ summary: z.string(),
124
+ content: z.string().optional(),
125
+ publishedAt: z.string().nullable(),
126
+ // ISO timestamp of when the row was fetched/inserted — used by the feed
127
+ // cursor's tie-break (publishedAt|fetchedAt|id) so that same-`publishedAt`
128
+ // rows stay stably ordered across paginated requests. `.optional()` because
129
+ // not every endpoint that returns a ReleaseItem populates it (notably
130
+ // single-release reads).
131
+ fetchedAt: z.string().optional(),
132
+ url: z.string().nullable(),
133
+ media: z.array(MediaItemSchema).optional(),
134
+ // `.optional()` — older API responses (mid-deploy or pinned old workers)
135
+ // may omit `type`; consumers should treat `undefined` as `"feature"`.
136
+ type: ReleaseTypeSchema.optional(),
137
+ // Pre-release flag (alpha/beta/rc/preview/nightly). Computed at ingest —
138
+ // GitHub uses the API's authoritative `prerelease` field; other adapters
139
+ // fall back to a SemVer-prerelease regex. `.optional()` for the same
140
+ // older-response degrade-gracefully reason as `type`.
141
+ prerelease: z.boolean().optional(),
142
+ // AI-generated headline forms paired with `summary` (#852, renamed in #860).
143
+ // Both nullable — most rows in the DB have neither populated, and we don't
144
+ // plan to backfill, so consumers must fall back to `title` for display.
145
+ // `.optional()` for the same mid-deploy / pinned-worker reason as `type`.
146
+ titleGenerated: z.string().nullable().optional(),
147
+ titleShort: z.string().nullable().optional(),
148
+ // Machine-readable breaking-change level (#1696, surfaced on read paths in
149
+ // #1710). `.optional()` for mid-deploy / pinned-worker tolerance and because
150
+ // rows predating the column omit it; absent or `"unknown"` means not
151
+ // classified (the fail-open default). List paths carry `breaking` only —
152
+ // `migrationNotes` stays detail-route-only to keep list payloads slim.
153
+ breaking: z.enum(BREAKING_LEVELS).optional(),
154
+ importance: ImportanceScoreSchema,
155
+ // Count of demoted siblings rolling up into this row via `release_coverage`
156
+ // (0 when standalone). Lets list views show a cluster indicator without a
157
+ // detail-page round trip. `.optional()` — older API responses and pinned
158
+ // workers omit the field; treat undefined as 0.
159
+ coverageCount: z.number().int().min(0).optional(),
160
+ // Cached `LENGTH(content)` and `countTokensSafe(content)` for the release
161
+ // body — lets feed surfaces ("releases get <org>", `/v1/releases/latest`,
162
+ // MCP `get_latest_releases`) advertise "this release is ~1.5K tokens" so
163
+ // agents can decide whether to pull the full body. `.optional()` and
164
+ // nullable because pre-existing rows landed without the columns; the
165
+ // backfill script populates them and renderers degrade to "size unknown"
166
+ // when null. See #958.
167
+ contentChars: z.number().int().min(0).nullable().optional(),
168
+ contentTokens: z.number().int().min(0).nullable().optional(),
169
+ // Per-category item counts produced by the AI release-content pass and
170
+ // stored on `releases.metadata.composition`. `null`/`undefined` when the
171
+ // row hasn't been through the AI pass yet or the body was boilerplate.
172
+ composition: ReleaseCompositionSchema.nullable().optional(),
173
+ });
174
+ export const ReleaseSummaryItemSchema = z.object({
175
+ year: z.number().int().nullable().optional(),
176
+ month: z.number().int().nullable().optional(),
177
+ windowDays: z.number().int().nullable().optional(),
178
+ summary: z.string(),
179
+ releaseCount: z.number().int().min(0),
180
+ generatedAt: z.string(),
181
+ });
182
+ /**
183
+ * A source attached to an overview page (#846, reshaped #1934). Each row names
184
+ * a source the overview drew on — `sourceUrl` plus, when it resolved to an
185
+ * on-registry release, `releaseId` + a canonical `releaseWebUrl`. This is a
186
+ * source *list*, not span-anchored provenance: the old body char offsets +
187
+ * verbatim quote are removed. Optional everywhere it appears — consumers should
188
+ * degrade gracefully.
189
+ */
190
+ export const OverviewCitationSchema = z.object({
191
+ sourceUrl: z.string(),
192
+ title: z.string().nullable().optional(),
193
+ /** Best-effort link to the on-registry release this source maps to (resolved server-side). */
194
+ releaseId: z.string().nullable().optional(),
195
+ /**
196
+ * Canonical web URL of the on-registry release page for this source, when
197
+ * `releaseId` resolved (#1934). Kept for machine consumers; the web Sources
198
+ * footer links `sourceUrl` (the #2218 link policy — `/release/*` pages are
199
+ * noindexed).
200
+ */
201
+ releaseWebUrl: z.string().nullable().optional(),
202
+ /**
203
+ * @deprecated Body char offsets / verbatim quote — removed with span-anchored
204
+ * citations (#1934). Kept optional for wire back-compat; no producer emits
205
+ * them and no consumer should read them.
206
+ */
207
+ startIndex: z.number().int().min(0).optional(),
208
+ endIndex: z.number().int().min(0).optional(),
209
+ citedText: z.string().optional(),
210
+ });
211
+ /**
212
+ * Entity notice — a small curator-set note on an org / product / source. Stored
213
+ * under the `notice` key of the entity's metadata JSON; mirrors the `Notice`
214
+ * type in @buildinternet/releases-core/notice. `coordinate` is an internal
215
+ * registry path ("org" / "org/slug"); `href` is an external URL; at most one.
216
+ */
217
+ export const NoticeSchema = z
218
+ .object({
219
+ message: z.string().min(1).max(280),
220
+ linkText: z.string().min(1).max(60).optional(),
221
+ coordinate: z.string().min(1).max(200).optional(),
222
+ href: z.url().max(500).optional(),
223
+ })
224
+ .refine((n) => !(n.coordinate && n.href), {
225
+ message: "notice may set coordinate or href, not both",
226
+ })
227
+ .refine((n) => !n.coordinate || isValidNoticeCoordinate(n.coordinate), {
228
+ message: "notice.coordinate must be 'org' or 'org/slug'",
229
+ });
230
+ /**
231
+ * Display thumbnail derived server-side from a release's first image/gif media
232
+ * entry. Shared by the coverage, lookup, and related-release payloads.
233
+ */
234
+ export const ReleaseThumbnailSchema = z.object({
235
+ url: z.string(),
236
+ alt: z.string().optional(),
237
+ });
238
+ export const OverviewPageItemSchema = z.object({
239
+ scope: z.enum(["org", "product"]),
240
+ orgSlug: z.string().nullable().optional(),
241
+ productSlug: z.string().nullable().optional(),
242
+ content: z.string(),
243
+ releaseCount: z.number().int().min(0),
244
+ lastContributingReleaseAt: z.string().nullable(),
245
+ generatedAt: z.string(),
246
+ updatedAt: z.string(),
247
+ citations: z.array(OverviewCitationSchema).optional(),
248
+ });
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Editable site-notice payload. A bare `linkText` with no `href` renders nothing
4
+ * (the view only draws a link when there's a target), so require `href` whenever
5
+ * `linkText` is set.
6
+ */
7
+ export declare const SiteNoticeSchema: z.ZodObject<{
8
+ active: z.ZodBoolean;
9
+ message: z.ZodString;
10
+ linkText: z.ZodOptional<z.ZodString>;
11
+ href: z.ZodOptional<z.ZodString>;
12
+ placement: z.ZodEnum<{
13
+ banner: "banner";
14
+ home: "home";
15
+ }>;
16
+ color: z.ZodString;
17
+ dismissible: z.ZodBoolean;
18
+ }, z.core.$strip>;
19
+ /** GET /v1/site-notice response: the stored notice (+updatedAt) or null. */
20
+ export declare const SiteNoticeResponseSchema: z.ZodObject<{
21
+ notice: z.ZodNullable<z.ZodObject<{
22
+ active: z.ZodBoolean;
23
+ message: z.ZodString;
24
+ linkText: z.ZodOptional<z.ZodString>;
25
+ href: z.ZodOptional<z.ZodString>;
26
+ placement: z.ZodEnum<{
27
+ banner: "banner";
28
+ home: "home";
29
+ }>;
30
+ color: z.ZodString;
31
+ dismissible: z.ZodBoolean;
32
+ updatedAt: z.ZodISODateTime;
33
+ }, z.core.$strip>>;
34
+ }, z.core.$strip>;
35
+ //# sourceMappingURL=site-notice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-notice.d.ts","sourceRoot":"","sources":["../../src/schemas/site-notice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+BxB;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;iBAG3B,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;iBAEnC,CAAC"}
@@ -1,18 +1,16 @@
1
1
  import { z } from "zod";
2
2
  import { SITE_NOTICE_PLACEMENTS } from "@buildinternet/releases-core/site-notice";
3
-
4
3
  /**
5
4
  * Absolute http(s) URL or a site-relative path beginning with a single "/".
6
5
  * Rejects other schemes (javascript:, data:, …) and protocol-relative "//host"
7
6
  * so a stored href can never become an unexpected-scheme or off-site link.
8
7
  */
9
8
  const HrefSchema = z
10
- .string()
11
- .max(500)
12
- .refine((h) => /^https?:\/\//.test(h) || (h.startsWith("/") && !h.startsWith("//")), {
9
+ .string()
10
+ .max(500)
11
+ .refine((h) => /^https?:\/\//.test(h) || (h.startsWith("/") && !h.startsWith("//")), {
13
12
  message: "href must be an absolute http(s) URL or a site-relative path",
14
- });
15
-
13
+ });
16
14
  /**
17
15
  * Editable site-notice fields. Kept structurally in sync with the
18
16
  * `SiteNotice` interface in `@buildinternet/releases-core/site-notice`. Split
@@ -20,26 +18,24 @@ const HrefSchema = z
20
18
  * it (a `.refine()` returns a non-extendable effect).
21
19
  */
22
20
  const SiteNoticeFieldsSchema = z.object({
23
- active: z.boolean(),
24
- message: z.string().min(1).max(280),
25
- linkText: z.string().min(1).max(60).optional(),
26
- href: HrefSchema.optional(),
27
- placement: z.enum(SITE_NOTICE_PLACEMENTS),
28
- color: z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be a 6-digit hex like #0081e7"),
29
- dismissible: z.boolean(),
21
+ active: z.boolean(),
22
+ message: z.string().min(1).max(280),
23
+ linkText: z.string().min(1).max(60).optional(),
24
+ href: HrefSchema.optional(),
25
+ placement: z.enum(SITE_NOTICE_PLACEMENTS),
26
+ color: z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be a 6-digit hex like #0081e7"),
27
+ dismissible: z.boolean(),
30
28
  });
31
-
32
29
  /**
33
30
  * Editable site-notice payload. A bare `linkText` with no `href` renders nothing
34
31
  * (the view only draws a link when there's a target), so require `href` whenever
35
32
  * `linkText` is set.
36
33
  */
37
34
  export const SiteNoticeSchema = SiteNoticeFieldsSchema.refine((n) => !(n.linkText && !n.href), {
38
- message: "href is required when linkText is set",
39
- path: ["href"],
35
+ message: "href is required when linkText is set",
36
+ path: ["href"],
40
37
  });
41
-
42
38
  /** GET /v1/site-notice response: the stored notice (+updatedAt) or null. */
43
39
  export const SiteNoticeResponseSchema = z.object({
44
- notice: SiteNoticeFieldsSchema.extend({ updatedAt: z.iso.datetime() }).nullable(),
40
+ notice: SiteNoticeFieldsSchema.extend({ updatedAt: z.iso.datetime() }).nullable(),
45
41
  });