@buildinternet/releases-api-types 0.59.0 → 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 (126) 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 -5
  102. package/src/api-types.ts +0 -2229
  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/datasets.ts +0 -31
  108. package/src/schemas/errors.test.ts +0 -55
  109. package/src/schemas/errors.ts +0 -81
  110. package/src/schemas/feedback.ts +0 -56
  111. package/src/schemas/listing.ts +0 -226
  112. package/src/schemas/orgs.ts +0 -533
  113. package/src/schemas/recommendations.ts +0 -39
  114. package/src/schemas/related.ts +0 -126
  115. package/src/schemas/releases.ts +0 -449
  116. package/src/schemas/search.ts +0 -274
  117. package/src/schemas/semantic-alert-summary.ts +0 -65
  118. package/src/schemas/shared.notice.test.ts +0 -36
  119. package/src/schemas/shared.ts +0 -267
  120. package/src/schemas/site-notice.test.ts +0 -67
  121. package/src/schemas/sitemap.ts +0 -117
  122. package/src/schemas/sources.ts +0 -674
  123. package/src/schemas/stats.ts +0 -62
  124. package/src/schemas/well-known.test.ts +0 -264
  125. package/src/schemas/well-known.ts +0 -252
  126. package/src/schemas/workspace-integrations.ts +0 -26
@@ -1,533 +0,0 @@
1
- import { z } from "zod";
2
- import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
3
- import { BREAKING_LEVELS } from "@buildinternet/releases-core/breaking";
4
- import {
5
- AppStoreSourceInfoSchema,
6
- CategorySchema,
7
- ImportanceScoreSchema,
8
- ListResponseSchema,
9
- NoticeSchema,
10
- OrgStatusSchema,
11
- OverviewPageItemSchema,
12
- PaginationSchema,
13
- ReleaseItemSchema,
14
- ReleaseLocationItemSchema,
15
- VideoSourceInfoSchema,
16
- } from "./shared.js";
17
- import { SourceListItemSchema } from "./sources.js";
18
- import { ProductListItemSchema } from "./products.js";
19
- import { CollectionListItemSchema } from "./collections.js";
20
-
21
- export const OrgListItemSchema = z.object({
22
- id: z.string(),
23
- slug: z.string(),
24
- name: z.string(),
25
- domain: z.string().nullable(),
26
- description: z.string().nullable(),
27
- category: CategorySchema.nullable(),
28
- avatarUrl: z.string().nullable(),
29
- featured: z.boolean(),
30
- /**
31
- * Org tier (#1947). Optional for mid-deploy tolerance; absent ⇒ `"tracked"`.
32
- * A `"stub"` org has no processed sources yet — the UI renders a badge and a
33
- * stub is excluded from release-ranked surfaces.
34
- */
35
- status: OrgStatusSchema.optional(),
36
- sourceCount: z.number().int().min(0),
37
- releaseCount: z.number().int().min(0),
38
- recentReleaseCount: z.number().int().min(0),
39
- lastActivity: z.string().nullable(),
40
- topProducts: z.array(z.string()),
41
- /**
42
- * Org-level alternate domains (`domain_aliases`, product-scoped aliases
43
- * excluded), sorted. Surfaced next to the primary `domain` in catalog rows so
44
- * a self-declared name reads against every domain the org actually controls.
45
- * Optional for mid-deploy tolerance; absent ⇒ treat as none.
46
- */
47
- aliasDomains: z.array(z.string()).optional(),
48
- sparkline: z.array(z.number().int().min(0)).length(30),
49
- /**
50
- * Additive, admin-only field (#1947 phase 2). Only populated on the
51
- * `GET /v1/orgs?trackingRequested=1` demand-queue projection — absent on
52
- * the public catalog listing.
53
- */
54
- trackingRequestedAt: z.string().nullable().optional(),
55
- });
56
-
57
- /**
58
- * Per-request side-channel for the orgs list (#746). `emptyOrgCount` is the
59
- * number of orgs that match the same `q` filter but have zero indexed
60
- * releases — used to label a "Show empty orgs" toggle without a second
61
- * round-trip. The value is scoped by the search term but independent of
62
- * `?includeEmpty=` so the toggle CTA can render a count whether the current
63
- * response included empty orgs or not.
64
- */
65
- export const OrgListMetaSchema = z.object({
66
- emptyOrgCount: z.number().int().min(0),
67
- });
68
-
69
- /**
70
- * `meta` is optional on the wire so older workers / pinned clients mid-deploy
71
- * don't trip the schema check. New clients can treat missing as
72
- * `emptyOrgCount: 0` (the toggle just won't render a count).
73
- */
74
- export const OrgListResponseSchema = z.object({
75
- items: z.array(OrgListItemSchema),
76
- pagination: PaginationSchema,
77
- meta: OrgListMetaSchema.optional(),
78
- });
79
-
80
- export const OrgAccountItemSchema = z.object({
81
- platform: z.string(),
82
- handle: z.string(),
83
- });
84
-
85
- export const OrgAccountsListResponseSchema = ListResponseSchema(OrgAccountItemSchema);
86
-
87
- /**
88
- * Response shape for `GET /v1/orgs/:slug/accounts`. Returns the paginated list
89
- * by default; with `?platform=<name>` returns a single matching account or
90
- * `null` when no row matches. The dual shape is preserved for compatibility
91
- * with the OSS CLI which calls `?platform=` and expects a single row.
92
- */
93
- export const OrgAccountsResponseSchema = z.union([
94
- OrgAccountsListResponseSchema,
95
- OrgAccountItemSchema,
96
- z.null(),
97
- ]);
98
- export const OrgTagsResponseSchema = ListResponseSchema(z.string());
99
-
100
- /**
101
- * Body accepted by `POST /v1/orgs`. `category` is a non-empty string at the
102
- * wire boundary so callers can pass either a canonical slug or one of its
103
- * configured aliases (resolved server-side via `resolveCategoryInput`).
104
- * Responses always carry the canonical slug. Empty strings are rejected so
105
- * the truthy-guard around `resolveCategoryInput` in the handler can't be
106
- * bypassed into persisting an invalid `""` value.
107
- */
108
- export const CreateOrgBodySchema = z.object({
109
- name: z.string().min(1),
110
- slug: z.string().optional(),
111
- domain: z.string().optional(),
112
- description: z.string().optional(),
113
- category: z.string().min(1).optional(),
114
- tags: z.array(z.string()).optional(),
115
- /**
116
- * Admin-only: opt the new org into automatic AI content (overviews +
117
- * per-release summaries). Omitted → defaults to `true` server-side, since
118
- * `POST /v1/orgs` only ever mints `curated` orgs and onboarding into the
119
- * registry should mean it gets overviews. Pass `false` for a deliberate
120
- * opt-out (#1795).
121
- */
122
- autoGenerateContent: z.boolean().optional(),
123
- });
124
-
125
- /**
126
- * Body accepted by `PATCH /v1/orgs/:slug`. Same alias-allowed string rule
127
- * as create, plus `null` to explicitly clear the overlay. Empty strings
128
- * stay rejected so callers must pick between a slug/alias or `null`.
129
- */
130
- export const UpdateOrgBodySchema = z.object({
131
- name: z.string().optional(),
132
- slug: z.string().optional(),
133
- domain: z.string().nullable().optional(),
134
- description: z.string().nullable().optional(),
135
- category: z.string().min(1).nullable().optional(),
136
- avatarUrl: z.string().nullable().optional(),
137
- tags: z.array(z.string()).optional(),
138
- aliases: z.array(z.string()).optional(),
139
- /** Admin-only: pause/unpause all ingest for this org without touching sources (#1057). */
140
- fetchPaused: z.boolean().optional(),
141
- /** Admin-only: hide the org from the homepage ticker + /v1/orgs directory. Stays reachable via detail, search, sitemap. */
142
- isHidden: z.boolean().optional(),
143
- /** Admin-only: opt the org into automatic AI content — org overviews AND per-release summaries (single backend flag `auto_generate_content`). */
144
- autoGenerateContent: z.boolean().optional(),
145
- /**
146
- * Admin-only: manual override for the automated overview-regen cadence in
147
- * days (#1895). `null` clears back to automatic (velocity-tiered: 7d
148
- * default, 2d at high release velocity). A set value pins the cadence in
149
- * either direction — faster for a hot org, slower for a bursty one.
150
- */
151
- overviewCadenceDays: z.number().int().min(1).max(90).nullable().optional(),
152
- /** Admin-only: promote this org on the home-page featured rail. */
153
- featured: z.boolean().optional(),
154
- /** Admin-only: promote or demote the org's discovery status (curated/agent/on_demand). */
155
- discovery: z.enum(["curated", "agent", "on_demand"]).optional(),
156
- notice: NoticeSchema.nullable().optional(),
157
- });
158
-
159
- /** Body for `POST /v1/orgs/:slug/avatar` — the remote image to mirror to R2 (#1406). */
160
- export const SetOrgAvatarBodySchema = z.object({
161
- sourceUrl: z.url(),
162
- });
163
-
164
- /** Response for `POST /v1/orgs/:slug/avatar` — the mirrored avatar's public URL + dims. */
165
- export const SetOrgAvatarResponseSchema = z.object({
166
- avatarUrl: z.string(),
167
- key: z.string(),
168
- width: z.number(),
169
- height: z.number(),
170
- });
171
-
172
- // Org detail's products query selects a strict subset of `ProductListItem` —
173
- // no category/orgId because the parent already names the org; createdAt is
174
- // included for age-based filtering by consumers.
175
- const OrgDetailProductSchema = ProductListItemSchema.pick({
176
- id: true,
177
- slug: true,
178
- name: true,
179
- url: true,
180
- description: true,
181
- sourceCount: true,
182
- kind: true,
183
- createdAt: true,
184
- }).extend({
185
- releaseCount: z.number().int().min(0),
186
- });
187
-
188
- const OrgDetailPlaybookSchema = z.object({
189
- scope: z.literal("playbook"),
190
- content: z.string(),
191
- updatedAt: z.string(),
192
- });
193
-
194
- // ── Org catalog (/orgs/:slug/catalog) ──
195
-
196
- const OrgCatalogProductItemSchema = z.object({
197
- entryType: z.literal("product"),
198
- kind: z.enum(KIND_VALUES).nullable().optional(),
199
- id: z.string(),
200
- slug: z.string(),
201
- name: z.string(),
202
- url: z.string().nullable(),
203
- description: z.string().nullable(),
204
- category: CategorySchema.nullable(),
205
- });
206
-
207
- const OrgCatalogSourceItemSchema = z.object({
208
- entryType: z.literal("source"),
209
- kind: z.enum(KIND_VALUES).nullable().optional(),
210
- id: z.string(),
211
- slug: z.string(),
212
- name: z.string(),
213
- type: z.string(),
214
- url: z.string(),
215
- productId: z.string().nullable(),
216
- });
217
-
218
- /**
219
- * Combined product + source catalog for `GET /v1/orgs/:slug/catalog`.
220
- * `entryType` discriminates between the two row shapes (`"product"` vs
221
- * `"source"`). `kind` carries the entity taxonomy (platform/sdk/mobile/…).
222
- * Products carry `category` and `description`; sources carry `type` and
223
- * `productId`.
224
- */
225
- export const OrgCatalogItemSchema = z.discriminatedUnion("entryType", [
226
- OrgCatalogProductItemSchema,
227
- OrgCatalogSourceItemSchema,
228
- ]);
229
-
230
- export const OrgCatalogResponseSchema = z.object({
231
- org: z.object({ id: z.string(), slug: z.string(), name: z.string() }),
232
- items: z.array(OrgCatalogItemSchema),
233
- });
234
-
235
- // ── Org collections membership (/orgs/:slug/collections) ──
236
-
237
- /**
238
- * List of collections the org belongs to, returned by
239
- * `GET /v1/orgs/:slug/collections`. Each item follows the same shape as
240
- * `CollectionListItem` on `GET /v1/collections` — `previewMembers` is
241
- * omitted here because the context (one org's collections) makes inline
242
- * member previews redundant.
243
- */
244
- export const OrgCollectionsResponseSchema = z.array(CollectionListItemSchema);
245
-
246
- // ── Org accounts (/orgs/:slug/accounts) ──
247
-
248
- /**
249
- * Body accepted by `POST /v1/orgs/:slug/accounts`.
250
- * Both `platform` and `handle` are required.
251
- */
252
- export const AddOrgAccountBodySchema = z.object({
253
- platform: z.string().min(1),
254
- handle: z.string().min(1),
255
- });
256
-
257
- // ── Org ignored URLs (/orgs/:slug/ignored-urls) ──
258
-
259
- export const IgnoredUrlItemSchema = z.object({
260
- id: z.string(),
261
- url: z.string(),
262
- orgId: z.string(),
263
- reason: z.string().nullable(),
264
- ignoredAt: z.string(),
265
- });
266
-
267
- export const OrgIgnoredUrlsListResponseSchema = ListResponseSchema(IgnoredUrlItemSchema);
268
-
269
- /**
270
- * Response shape for `GET /v1/orgs/:slug/ignored-urls`. Returns the paginated
271
- * list by default; with `?url=<encoded>&single=1` returns the matching single
272
- * row or `null` when not present.
273
- */
274
- export const OrgIgnoredUrlsResponseSchema = z.union([
275
- OrgIgnoredUrlsListResponseSchema,
276
- IgnoredUrlItemSchema,
277
- z.null(),
278
- ]);
279
-
280
- /**
281
- * Body accepted by `POST /v1/orgs/:slug/ignored-urls`.
282
- * `reason` is optional.
283
- */
284
- export const AddIgnoredUrlBodySchema = z.object({
285
- url: z.string().min(1),
286
- reason: z.string().optional(),
287
- });
288
-
289
- /** Response shape for `POST /v1/orgs/:slug/ignored-urls`. */
290
- export const AddIgnoredUrlResponseSchema = z.object({
291
- ignored: z.literal(true),
292
- });
293
-
294
- /** Response shape for `DELETE /v1/orgs/:slug/ignored-urls/:url`. */
295
- export const DeleteIgnoredUrlResponseSchema = z.object({
296
- deleted: z.literal(true),
297
- });
298
-
299
- // ── Org tags (/orgs/:slug/tags and PUT /DELETE) ──
300
-
301
- /** Body accepted by `PUT` and `DELETE` `/v1/orgs/:slug/tags`. */
302
- export const OrgTagsBodySchema = z.object({
303
- tags: z.array(z.string()),
304
- });
305
-
306
- /** Response shape returned by `PUT` and `DELETE` `/v1/orgs/:slug/tags`. */
307
- export const OrgTagsMutationResponseSchema = z.object({
308
- ok: z.literal(true),
309
- });
310
-
311
- // ── POST /tags (global tag creation) ──
312
-
313
- /** Body accepted by `POST /v1/tags`. */
314
- export const CreateTagBodySchema = z.object({
315
- name: z.string().min(1),
316
- });
317
-
318
- /** Row returned by `POST /v1/tags` (201 on create, 200 if already exists). */
319
- export const TagRowSchema = z.object({
320
- id: z.string(),
321
- name: z.string(),
322
- slug: z.string(),
323
- createdAt: z.string(),
324
- });
325
-
326
- // ── Org activity (/orgs/:slug/activity) ──
327
-
328
- const OrgActivityWeeklyBucketSchema = z.object({
329
- weekStart: z.string(),
330
- count: z.number().int().min(0),
331
- earliestVersion: z.string().nullable(),
332
- latestVersion: z.string().nullable(),
333
- });
334
-
335
- const OrgActivitySourceSchema = z.object({
336
- slug: z.string(),
337
- name: z.string(),
338
- releaseCount: z.number().int().min(0),
339
- avgReleasesPerWeek: z.number(),
340
- earliestVersion: z.string().nullable(),
341
- latestVersion: z.string().nullable(),
342
- latestDate: z.string().nullable(),
343
- weeklyBuckets: z.array(OrgActivityWeeklyBucketSchema),
344
- });
345
-
346
- /**
347
- * Response shape for `GET /v1/orgs/:slug/activity`. Returns per-source
348
- * weekly release buckets plus an aggregate rollup — used for timeline
349
- * visualization in the web org detail page.
350
- */
351
- export const OrgActivityResponseSchema = z.object({
352
- org: z.object({ slug: z.string(), name: z.string() }),
353
- range: z.object({ from: z.string(), to: z.string() }),
354
- sources: z.array(OrgActivitySourceSchema),
355
- aggregateWeekly: z.array(z.object({ weekStart: z.string(), count: z.number().int().min(0) })),
356
- });
357
-
358
- // ── Org heatmap (/orgs/:slug/heatmap) ──
359
-
360
- /**
361
- * Response shape for `GET /v1/orgs/:slug/heatmap`. Returns daily release
362
- * counts for the trailing 365 days — used for contribution-graph
363
- * visualization in the web org detail page.
364
- */
365
- export const OrgHeatmapResponseSchema = z.object({
366
- org: z.object({ slug: z.string(), name: z.string() }),
367
- range: z.object({ from: z.string(), to: z.string() }),
368
- dailyCounts: z.array(z.object({ date: z.string(), count: z.number().int().min(0) })),
369
- total: z.number().int().min(0),
370
- });
371
-
372
- // ── Org sparklines (/orgs/:slug/sparklines) ──
373
-
374
- const SparklineSourceSchema = z.object({
375
- slug: z.string(),
376
- name: z.string(),
377
- sparkline: z.array(z.number().int().min(0)).length(30),
378
- });
379
-
380
- /**
381
- * Response shape for `GET /v1/orgs/:slug/sparklines`. Returns 30-day daily
382
- * release counts per source and per product, plus an aggregate rollup.
383
- */
384
- export const OrgSparklinesResponseSchema = z.object({
385
- org: z.object({ slug: z.string(), name: z.string() }),
386
- range: z.object({ from: z.string(), to: z.string() }),
387
- aggregate: z.array(z.number().int().min(0)).length(30),
388
- sources: z.array(SparklineSourceSchema),
389
- products: z.array(SparklineSourceSchema),
390
- });
391
-
392
- // ── Org releases feed (/orgs/:slug/releases) ──
393
-
394
- /**
395
- * Release feed item on `GET /v1/orgs/:slug/releases`. Extends `ReleaseItem`
396
- * with a `source` block identifying the originating source within the org.
397
- */
398
- export const OrgReleaseItemSchema = ReleaseItemSchema.extend({
399
- source: z.object({
400
- slug: z.string(),
401
- name: z.string(),
402
- type: z.string(),
403
- appStore: AppStoreSourceInfoSchema.optional(),
404
- video: VideoSourceInfoSchema.optional(),
405
- }),
406
- /**
407
- * Owning product, when the release's source is grouped under a product.
408
- * `null` when the source has no `product_id`. Additive — older API responses
409
- * omit this field; treat `undefined` as `null`. #1217.
410
- */
411
- product: z.object({ slug: z.string(), name: z.string() }).nullable().optional(),
412
- /**
413
- * Server-resolved grouping identity — `COALESCE(product.slug, source.slug)` /
414
- * `COALESCE(product.name, source.name)`. The web releases feed keys and labels
415
- * SDK/package-cluster rollups on these instead of reconstructing
416
- * `product ?? source` client-side. Optional on the wire: older workers omit
417
- * them, so clients must fall back to deriving from `product ?? source`. Never
418
- * null when present (`source` is always set). #1234
419
- */
420
- groupSlug: z.string().optional(),
421
- groupName: z.string().optional(),
422
- });
423
-
424
- /** Cursor pagination shape for the org releases feed. */
425
- export const OrgFeedPaginationSchema = z.object({
426
- nextCursor: z.string().nullable(),
427
- limit: z.number().int().min(1),
428
- });
429
-
430
- /**
431
- * Response shape for `GET /v1/orgs/:slug/releases`.
432
- * Cursor-paginated; `nextCursor` is `null` when this is the last page.
433
- */
434
- export const OrgReleasesFeedResponseSchema = z.object({
435
- releases: z.array(OrgReleaseItemSchema),
436
- pagination: OrgFeedPaginationSchema,
437
- });
438
-
439
- // ── Org recent releases (/orgs/:slug/recent-releases) ──
440
-
441
- /**
442
- * Row returned by `GET /v1/orgs/:slug/recent-releases`. This is the full
443
- * `releasesVisible` row with `sourceName` and `sourceSlug` joined from
444
- * `sourcesVisible` — intended for summarization / grouping by agents.
445
- * Many fields are nullable because they may not be populated at ingest time.
446
- */
447
- export const OrgRecentReleaseItemSchema = z.object({
448
- id: z.string(),
449
- sourceId: z.string(),
450
- version: z.string().nullable(),
451
- type: z.string().optional(),
452
- title: z.string(),
453
- content: z.string(),
454
- summary: z.string().nullable(),
455
- titleGenerated: z.string().nullable().optional(),
456
- titleShort: z.string().nullable().optional(),
457
- /**
458
- * Machine-readable breaking-change level (#1696, surfaced on read paths in
459
- * #1710). `.optional()` for mid-deploy tolerance; absent or `"unknown"`
460
- * means not classified. List paths carry `breaking` only.
461
- */
462
- breaking: z.enum(BREAKING_LEVELS).optional(),
463
- importance: ImportanceScoreSchema,
464
- url: z.string().nullable(),
465
- contentHash: z.string().nullable(),
466
- metadata: z.string().nullable(),
467
- media: z.string().nullable(),
468
- publishedAt: z.string().nullable(),
469
- suppressed: z.number().optional(),
470
- suppressedReason: z.string().nullable().optional(),
471
- fetchedAt: z.string().optional(),
472
- embeddedAt: z.string().nullable().optional(),
473
- sourceName: z.string(),
474
- sourceSlug: z.string(),
475
- });
476
-
477
- export const OrgRecentReleasesResponseSchema = z.array(OrgRecentReleaseItemSchema);
478
-
479
- // ── Org accounts mutation responses ──
480
-
481
- /** Response returned by `DELETE /v1/orgs/:slug/accounts/:platform/:handle`. */
482
- export const DeleteOrgAccountResponseSchema = z.object({
483
- deleted: z.literal(true),
484
- });
485
-
486
- export const OrgDetailSchema = z.object({
487
- id: z.string().optional(),
488
- slug: z.string(),
489
- name: z.string(),
490
- domain: z.string().nullable(),
491
- description: z.string().nullable().optional(),
492
- category: CategorySchema.nullable().optional(),
493
- avatarUrl: z.string().nullable(),
494
- /** Admin display flag: true when the org is hidden from listings (homepage + /v1/orgs). Optional on the wire for older workers mid-deploy. */
495
- isHidden: z.boolean().optional(),
496
- /** Admin display flag: org is opted into automatic overviews + per-release summaries. Optional on the wire for older workers mid-deploy. */
497
- autoGenerateContent: z.boolean().optional(),
498
- /** Manual overview-regen cadence override in days (#1895); null = automatic velocity tier. Optional on the wire for older workers mid-deploy. */
499
- overviewCadenceDays: z.number().int().nullable().optional(),
500
- /** Admin display flag: org is promoted on the home-page featured rail. Optional on the wire for older workers mid-deploy. */
501
- featured: z.boolean().optional(),
502
- /** Admin display flag: all ingest paused for this org. */
503
- fetchPaused: z.boolean().optional(),
504
- /** How the org row was created. `on_demand` orgs are excluded from overview generation regardless of `autoGenerateContent`. */
505
- discovery: z.enum(["curated", "agent", "on_demand"]).optional(),
506
- /**
507
- * Org tier (#1947). Optional for mid-deploy tolerance; absent ⇒ `"tracked"`.
508
- * A `"stub"` org's `sources` array is empty — `locations` carries the declared
509
- * release locations instead.
510
- */
511
- status: OrgStatusSchema.optional(),
512
- /**
513
- * Declared release locations (#1947), present (and non-empty) for stub orgs.
514
- * Same shape as a releases.json `releases[]` entry plus `basis`/`sourceId`.
515
- * Omitted or empty for a tracked org with no locators.
516
- */
517
- locations: z.array(ReleaseLocationItemSchema).optional(),
518
- tags: z.array(z.string()).optional(),
519
- sourceCount: z.number().int().min(0),
520
- releaseCount: z.number().int().min(0),
521
- releasesLast30Days: z.number().int().min(0),
522
- avgReleasesPerWeek: z.number(),
523
- lastFetchedAt: z.string().nullable(),
524
- lastPolledAt: z.string().nullable(),
525
- trackingSince: z.string(),
526
- aliases: z.array(z.string()).optional(),
527
- accounts: z.array(OrgAccountItemSchema),
528
- products: z.array(OrgDetailProductSchema),
529
- sources: z.array(SourceListItemSchema),
530
- overview: OverviewPageItemSchema.nullable().optional(),
531
- playbook: OrgDetailPlaybookSchema.nullable().optional(),
532
- notice: NoticeSchema.nullable().optional(),
533
- });
@@ -1,39 +0,0 @@
1
- import { z } from "zod";
2
-
3
- /**
4
- * `POST /v1/admin/recommendations/:id/notify-added` body.
5
- *
6
- * Resolves a live registry listing (org required, source optional) and
7
- * emails the submitter's `contactEmail` that their suggestion was added.
8
- * Opt-in only — triage / close / archive never send this.
9
- */
10
- export const RecommendationNotifyAddedBodySchema = z.object({
11
- orgSlug: z
12
- .string()
13
- .min(1)
14
- .describe(
15
- "Org slug or `org_…` id of the onboarded listing. Required so the email can link a live registry URL.",
16
- ),
17
- sourceSlug: z
18
- .string()
19
- .min(1)
20
- .optional()
21
- .describe(
22
- "Optional source slug or `src_…` id under that org. When set, the email links the source page.",
23
- ),
24
- });
25
-
26
- /**
27
- * `POST /v1/admin/recommendations/:id/notify-added` success body.
28
- *
29
- * `sent: false` + `reason: "already_notified"` is the idempotent replay —
30
- * a second call does not email again.
31
- */
32
- export const RecommendationNotifyAddedResultSchema = z.object({
33
- ok: z.literal(true),
34
- sent: z.boolean(),
35
- reason: z.enum(["already_notified"]).optional(),
36
- notifiedAt: z.number().nullable(),
37
- registryUrl: z.string().optional(),
38
- contactEmail: z.string().optional(),
39
- });
@@ -1,126 +0,0 @@
1
- import { z } from "zod";
2
- import { AppStoreSourceInfoSchema, ImportanceScoreSchema } from "./shared.js";
3
-
4
- /**
5
- * Anchor scope for related-* lookups. `org` filters the Vectorize query by
6
- * the anchor's org id; `global` (default) runs unscoped.
7
- */
8
- export const RelatedScopeSchema = z.enum(["org", "global"]);
9
-
10
- /** Thumbnail picked from the release's first image-like media entry. */
11
- export const RelatedReleaseThumbnailSchema = z.object({
12
- url: z.string(),
13
- alt: z.string().optional(),
14
- });
15
-
16
- /** Owning source rollup attached to each related-release row. */
17
- export const RelatedReleaseSourceSchema = z.object({
18
- id: z.string(),
19
- slug: z.string(),
20
- name: z.string(),
21
- /** Parent product name, when the source belongs to one — preferred over the
22
- * bare source/feed name for display. Null for sources with no product. */
23
- productName: z.string().nullable(),
24
- orgSlug: z.string().nullable(),
25
- orgName: z.string().nullable(),
26
- orgAvatarUrl: z.string().nullable(),
27
- /**
28
- * App Store platform + icon, present only for `appstore` sources (resolved
29
- * server-side, same block the org/product/ticker read paths already carry).
30
- * Its presence is the signal the related rail uses to render the lean
31
- * mobile-app card (app icon + "iOS/macOS" cue) instead of the standard
32
- * headline/thumbnail. Additive/optional for mid-deploy pin tolerance.
33
- * #mobile-app-release-cards
34
- */
35
- appStore: AppStoreSourceInfoSchema.optional(),
36
- });
37
-
38
- /**
39
- * One neighbor returned by `GET /v1/related/releases`. `score` is the
40
- * Vectorize cosine similarity from the underlying query.
41
- */
42
- export const RelatedReleaseItemSchema = z.object({
43
- id: z.string(),
44
- title: z.string(),
45
- version: z.string().nullable(),
46
- url: z.string().nullable(),
47
- publishedAt: z.string().nullable(),
48
- summary: z.string(),
49
- titleGenerated: z.string().nullable(),
50
- titleShort: z.string().nullable(),
51
- /**
52
- * AI-scored importance 1–5 (5=landmark, 1=housekeeping). Null when
53
- * unscored; optional for older servers / mid-deploy pin tolerance.
54
- */
55
- importance: ImportanceScoreSchema,
56
- thumbnail: RelatedReleaseThumbnailSchema.nullable(),
57
- score: z.number(),
58
- source: RelatedReleaseSourceSchema,
59
- });
60
-
61
- /**
62
- * One neighbor returned by `GET /v1/related/sources`. Carries enough
63
- * source + org + recent-release stats for the rail card to render without
64
- * a follow-up request.
65
- */
66
- export const RelatedSourceItemSchema = z.object({
67
- id: z.string(),
68
- slug: z.string(),
69
- name: z.string(),
70
- type: z.string(),
71
- url: z.string().nullable(),
72
- score: z.number(),
73
- orgSlug: z.string().nullable(),
74
- orgName: z.string().nullable(),
75
- orgAvatarUrl: z.string().nullable(),
76
- releaseCount: z.number().int().min(0),
77
- latestDate: z.string().nullable(),
78
- latestTitle: z.string().nullable(),
79
- latestVersion: z.string().nullable(),
80
- /** Total releases published in the last 30 days (includes the latest). */
81
- recentCount: z.number().int().min(0),
82
- });
83
-
84
- /**
85
- * Successful response from `GET /v1/related/releases`. The handler returns
86
- * `{scope, items}` when Vectorize is reachable and the anchor has a vector.
87
- */
88
- export const RelatedReleasesOkResponseSchema = z.object({
89
- scope: RelatedScopeSchema,
90
- items: z.array(RelatedReleaseItemSchema),
91
- });
92
-
93
- /**
94
- * Degraded response from `GET /v1/related/releases`. Returned (HTTP 200) when
95
- * Vectorize bindings are missing, the anchor hasn't been embedded yet, or a
96
- * downstream call errored. Callers render nothing in this case rather than
97
- * surfacing a hard failure. `degradedReason` is human-readable, not stable.
98
- */
99
- export const RelatedReleasesDegradedResponseSchema = z.object({
100
- degraded: z.literal(true),
101
- degradedReason: z.string(),
102
- items: z.array(RelatedReleaseItemSchema),
103
- });
104
-
105
- export const RelatedReleasesResponseSchema = z.union([
106
- RelatedReleasesOkResponseSchema,
107
- RelatedReleasesDegradedResponseSchema,
108
- ]);
109
-
110
- /** Successful response from `GET /v1/related/sources`. */
111
- export const RelatedSourcesOkResponseSchema = z.object({
112
- scope: RelatedScopeSchema,
113
- items: z.array(RelatedSourceItemSchema),
114
- });
115
-
116
- /** Degraded response from `GET /v1/related/sources`. Same semantics as the releases variant. */
117
- export const RelatedSourcesDegradedResponseSchema = z.object({
118
- degraded: z.literal(true),
119
- degradedReason: z.string(),
120
- items: z.array(RelatedSourceItemSchema),
121
- });
122
-
123
- export const RelatedSourcesResponseSchema = z.union([
124
- RelatedSourcesOkResponseSchema,
125
- RelatedSourcesDegradedResponseSchema,
126
- ]);