@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.
- package/README.md +14 -6
- package/dist/api-types.d.ts +1168 -0
- package/dist/api-types.d.ts.map +1 -0
- package/dist/api-types.js +134 -0
- package/dist/schemas/account-profile.d.ts +29 -0
- package/dist/schemas/account-profile.d.ts.map +1 -0
- package/dist/schemas/account-profile.js +24 -0
- package/dist/schemas/ai-models.d.ts +67 -0
- package/dist/schemas/ai-models.d.ts.map +1 -0
- package/{src/schemas/ai-models.ts → dist/schemas/ai-models.js} +25 -31
- package/dist/schemas/api-keys.d.ts +71 -0
- package/dist/schemas/api-keys.d.ts.map +1 -0
- package/dist/schemas/api-keys.js +32 -0
- package/dist/schemas/classifications.d.ts +134 -0
- package/dist/schemas/classifications.d.ts.map +1 -0
- package/dist/schemas/classifications.js +96 -0
- package/dist/schemas/collections.d.ts +605 -0
- package/dist/schemas/collections.d.ts.map +1 -0
- package/dist/schemas/collections.js +320 -0
- package/dist/schemas/datasets.d.ts +34 -0
- package/dist/schemas/datasets.d.ts.map +1 -0
- package/dist/schemas/datasets.js +11 -0
- package/dist/schemas/errors.d.ts +43 -0
- package/dist/schemas/errors.d.ts.map +1 -0
- package/dist/schemas/errors.js +61 -0
- package/dist/schemas/feedback.d.ts +134 -0
- package/dist/schemas/feedback.d.ts.map +1 -0
- package/dist/schemas/feedback.js +76 -0
- package/dist/schemas/follows.d.ts +154 -0
- package/dist/schemas/follows.d.ts.map +1 -0
- package/dist/schemas/follows.js +42 -0
- package/dist/schemas/listing.d.ts +374 -0
- package/dist/schemas/listing.d.ts.map +1 -0
- package/dist/schemas/listing.js +175 -0
- package/dist/schemas/lookups.d.ts +285 -0
- package/dist/schemas/lookups.d.ts.map +1 -0
- package/{src/schemas/lookups.ts → dist/schemas/lookups.js} +67 -80
- package/dist/schemas/marketing-classifier.d.ts +32 -0
- package/dist/schemas/marketing-classifier.d.ts.map +1 -0
- package/{src/schemas/marketing-classifier.ts → dist/schemas/marketing-classifier.js} +14 -18
- package/dist/schemas/orgs.d.ts +950 -0
- package/dist/schemas/orgs.d.ts.map +1 -0
- package/dist/schemas/orgs.js +473 -0
- package/dist/schemas/overviews.d.ts +205 -0
- package/dist/schemas/overviews.d.ts.map +1 -0
- package/{src/schemas/overviews.ts → dist/schemas/overviews.js} +41 -54
- package/dist/schemas/products.d.ts +595 -0
- package/dist/schemas/products.d.ts.map +1 -0
- package/{src/schemas/products.ts → dist/schemas/products.js} +113 -136
- package/dist/schemas/publish-tokens.d.ts +55 -0
- package/dist/schemas/publish-tokens.d.ts.map +1 -0
- package/{src/schemas/publish-tokens.ts → dist/schemas/publish-tokens.js} +18 -29
- package/dist/schemas/recommendations.d.ts +52 -0
- package/dist/schemas/recommendations.d.ts.map +1 -0
- package/dist/schemas/recommendations.js +58 -0
- package/dist/schemas/related.d.ts +331 -0
- package/dist/schemas/related.d.ts.map +1 -0
- package/dist/schemas/related.js +115 -0
- package/dist/schemas/releases.d.ts +623 -0
- package/dist/schemas/releases.d.ts.map +1 -0
- package/dist/schemas/releases.js +414 -0
- package/dist/schemas/resolve.d.ts +259 -0
- package/dist/schemas/resolve.d.ts.map +1 -0
- package/{src/schemas/resolve.ts → dist/schemas/resolve.js} +2 -5
- package/dist/schemas/search.d.ts +475 -0
- package/dist/schemas/search.d.ts.map +1 -0
- package/dist/schemas/search.js +258 -0
- package/dist/schemas/semantic-alert-summary.d.ts +54 -0
- package/dist/schemas/semantic-alert-summary.d.ts.map +1 -0
- package/dist/schemas/semantic-alert-summary.js +57 -0
- package/dist/schemas/semantic-alerts.d.ts +41 -0
- package/dist/schemas/semantic-alerts.d.ts.map +1 -0
- package/dist/schemas/semantic-alerts.js +42 -0
- package/dist/schemas/shared.d.ts +247 -0
- package/dist/schemas/shared.d.ts.map +1 -0
- package/dist/schemas/shared.js +248 -0
- package/dist/schemas/site-notice.d.ts +35 -0
- package/dist/schemas/site-notice.d.ts.map +1 -0
- package/{src/schemas/site-notice.ts → dist/schemas/site-notice.js} +14 -18
- package/dist/schemas/sitemap.d.ts +97 -0
- package/dist/schemas/sitemap.d.ts.map +1 -0
- package/dist/schemas/sitemap.js +107 -0
- package/dist/schemas/sources.d.ts +1145 -0
- package/dist/schemas/sources.d.ts.map +1 -0
- package/dist/schemas/sources.js +645 -0
- package/dist/schemas/stats.d.ts +82 -0
- package/dist/schemas/stats.d.ts.map +1 -0
- package/dist/schemas/stats.js +59 -0
- package/dist/schemas/taxonomy.d.ts +344 -0
- package/dist/schemas/taxonomy.d.ts.map +1 -0
- package/{src/schemas/taxonomy.ts → dist/schemas/taxonomy.js} +47 -58
- package/dist/schemas/webhooks.d.ts +618 -0
- package/dist/schemas/webhooks.d.ts.map +1 -0
- package/dist/schemas/webhooks.js +191 -0
- package/dist/schemas/well-known.d.ts +302 -0
- package/dist/schemas/well-known.d.ts.map +1 -0
- package/dist/schemas/well-known.js +192 -0
- package/dist/schemas/workspace-integrations.d.ts +27 -0
- package/dist/schemas/workspace-integrations.d.ts.map +1 -0
- package/dist/schemas/workspace-integrations.js +22 -0
- package/package.json +16 -5
- package/src/api-types.ts +0 -2229
- package/src/schemas/account-profile.ts +0 -28
- package/src/schemas/ai-models.test.ts +0 -29
- package/src/schemas/classifications.ts +0 -109
- package/src/schemas/collections.ts +0 -346
- package/src/schemas/datasets.ts +0 -31
- package/src/schemas/errors.test.ts +0 -55
- package/src/schemas/errors.ts +0 -81
- package/src/schemas/feedback.ts +0 -56
- package/src/schemas/listing.ts +0 -226
- package/src/schemas/orgs.ts +0 -533
- package/src/schemas/recommendations.ts +0 -39
- package/src/schemas/related.ts +0 -126
- package/src/schemas/releases.ts +0 -449
- package/src/schemas/search.ts +0 -274
- package/src/schemas/semantic-alert-summary.ts +0 -65
- package/src/schemas/shared.notice.test.ts +0 -36
- package/src/schemas/shared.ts +0 -267
- package/src/schemas/site-notice.test.ts +0 -67
- package/src/schemas/sitemap.ts +0 -117
- package/src/schemas/sources.ts +0 -674
- package/src/schemas/stats.ts +0 -62
- package/src/schemas/well-known.test.ts +0 -264
- package/src/schemas/well-known.ts +0 -252
- package/src/schemas/workspace-integrations.ts +0 -26
package/src/schemas/sources.ts
DELETED
|
@@ -1,674 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
SOURCE_TYPES,
|
|
4
|
-
SOURCE_DISCOVERY,
|
|
5
|
-
SOURCE_FETCH_PRIORITIES,
|
|
6
|
-
} from "@buildinternet/releases-core/source-enums";
|
|
7
|
-
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
8
|
-
import {
|
|
9
|
-
ListResponseSchema,
|
|
10
|
-
NoticeSchema,
|
|
11
|
-
ReleaseItemSchema,
|
|
12
|
-
ReleaseSummaryItemSchema,
|
|
13
|
-
} from "./shared.js";
|
|
14
|
-
|
|
15
|
-
export const SourceTypeSchema = z.enum(SOURCE_TYPES);
|
|
16
|
-
export const SourceDiscoverySchema = z.enum(SOURCE_DISCOVERY);
|
|
17
|
-
export const SourceFetchPrioritySchema = z.enum(SOURCE_FETCH_PRIORITIES);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Per-source row used in list/embedded contexts (e.g. nested inside OrgDetail).
|
|
21
|
-
* Most fields are optional — embedded shapes (org detail) only carry the
|
|
22
|
-
* subset needed for that view.
|
|
23
|
-
*/
|
|
24
|
-
export const SourceListItemSchema = z.object({
|
|
25
|
-
id: z.string().optional(),
|
|
26
|
-
slug: z.string(),
|
|
27
|
-
name: z.string(),
|
|
28
|
-
type: SourceTypeSchema,
|
|
29
|
-
url: z.string().optional(),
|
|
30
|
-
// `orgSlug` is populated on the standalone `/v1/sources` list path; the
|
|
31
|
-
// `OrgDetail.sources` embedded path omits it (the parent already names the org).
|
|
32
|
-
orgSlug: z.string().nullable().optional(),
|
|
33
|
-
releaseCount: z.number().int().min(0),
|
|
34
|
-
latestVersion: z.string().nullable(),
|
|
35
|
-
latestDate: z.string().nullable(),
|
|
36
|
-
latestAddedAt: z.string().nullable().optional(),
|
|
37
|
-
isPrimary: z.boolean().optional(),
|
|
38
|
-
isHidden: z.boolean().optional(),
|
|
39
|
-
/**
|
|
40
|
-
* How the row was created. Optional on the wire so older API responses
|
|
41
|
-
* (mid-deploy or pinned old workers) degrade gracefully — consumers that
|
|
42
|
-
* see `undefined` should treat it as `"curated"`.
|
|
43
|
-
*/
|
|
44
|
-
discovery: SourceDiscoverySchema.optional(),
|
|
45
|
-
fetchPriority: SourceFetchPrioritySchema.nullable().optional(),
|
|
46
|
-
lastFetchedAt: z.string().nullable().optional(),
|
|
47
|
-
lastPolledAt: z.string().nullable().optional(),
|
|
48
|
-
changeDetectedAt: z.string().nullable().optional(),
|
|
49
|
-
consecutiveNoChange: z.number().int().nullable().optional(),
|
|
50
|
-
consecutiveErrors: z.number().int().nullable().optional(),
|
|
51
|
-
nextFetchAfter: z.string().nullable().optional(),
|
|
52
|
-
medianGapDays: z.number().nullable().optional(),
|
|
53
|
-
lastRetieredAt: z.string().nullable().optional(),
|
|
54
|
-
metadata: z.string().nullable().optional(),
|
|
55
|
-
productName: z.string().nullable().optional(),
|
|
56
|
-
productSlug: z.string().nullable().optional(),
|
|
57
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
58
|
-
// GitHub stargazer count. `nullable().optional()` (the house idiom for these
|
|
59
|
-
// shapes): non-github sources and older responses omit it; a fetched row may
|
|
60
|
-
// carry `null`. Consumers treat null/undefined as "unknown".
|
|
61
|
-
stars: z.number().int().min(0).nullable().optional(),
|
|
62
|
-
starsFetchedAt: z.string().nullable().optional(),
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Canonical row returned by `GET /v1/sources` (list). Superset of
|
|
67
|
-
* `SourceListItem` with required `id` / `orgName` / `orgSlug` fields used by
|
|
68
|
-
* the CLI `list` command.
|
|
69
|
-
*/
|
|
70
|
-
export const SourceWithOrgSchema = z.object({
|
|
71
|
-
id: z.string(),
|
|
72
|
-
name: z.string(),
|
|
73
|
-
slug: z.string(),
|
|
74
|
-
type: SourceTypeSchema,
|
|
75
|
-
url: z.string(),
|
|
76
|
-
orgName: z.string().nullable(),
|
|
77
|
-
orgSlug: z.string().nullable(),
|
|
78
|
-
productName: z.string().nullable(),
|
|
79
|
-
productSlug: z.string().nullable(),
|
|
80
|
-
isPrimary: z.boolean(),
|
|
81
|
-
isHidden: z.boolean().nullable(),
|
|
82
|
-
discovery: SourceDiscoverySchema.optional(),
|
|
83
|
-
metadata: z.string().nullable(),
|
|
84
|
-
releaseCount: z.number().int().min(0),
|
|
85
|
-
latestVersion: z.string().nullable(),
|
|
86
|
-
latestDate: z.string().nullable(),
|
|
87
|
-
lastFetchedAt: z.string().nullable(),
|
|
88
|
-
lastPolledAt: z.string().nullable(),
|
|
89
|
-
fetchPriority: SourceFetchPrioritySchema.nullable(),
|
|
90
|
-
changeDetectedAt: z.string().nullable(),
|
|
91
|
-
consecutiveNoChange: z.number().int().nullable(),
|
|
92
|
-
consecutiveErrors: z.number().int().nullable(),
|
|
93
|
-
nextFetchAfter: z.string().nullable(),
|
|
94
|
-
medianGapDays: z.number().nullable(),
|
|
95
|
-
lastRetieredAt: z.string().nullable(),
|
|
96
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
97
|
-
// GitHub stargazer count. `nullable().optional()` (the house idiom for these
|
|
98
|
-
// shapes): non-github sources and older responses omit it; a fetched row may
|
|
99
|
-
// carry `null`. Consumers treat null/undefined as "unknown".
|
|
100
|
-
stars: z.number().int().min(0).nullable().optional(),
|
|
101
|
-
starsFetchedAt: z.string().nullable().optional(),
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
export const SourceListResponseSchema = ListResponseSchema(SourceWithOrgSchema);
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* `GET /v1/sources` returns a bare array by default and an envelope when
|
|
108
|
-
* `?envelope=true` is passed. The OpenAPI spec advertises the union so
|
|
109
|
-
* either client expectation is documented.
|
|
110
|
-
*/
|
|
111
|
-
export const SourceListResultSchema = z.union([
|
|
112
|
-
z.array(SourceWithOrgSchema),
|
|
113
|
-
SourceListResponseSchema,
|
|
114
|
-
]);
|
|
115
|
-
|
|
116
|
-
const SourceDetailSummariesSchema = z.object({
|
|
117
|
-
rolling: ReleaseSummaryItemSchema.nullable(),
|
|
118
|
-
monthly: z.array(ReleaseSummaryItemSchema),
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Cursor pagination shape for the source detail's embedded release feed.
|
|
123
|
-
* Mirrors `OrgFeedPaginationSchema` and `CollectionFeedPaginationSchema` —
|
|
124
|
-
* release lists are feed-shaped (append-only, mutates between calls), so they
|
|
125
|
-
* use cursor pagination per the AGENTS.md convention.
|
|
126
|
-
*/
|
|
127
|
-
export const SourceFeedPaginationSchema = z.object({
|
|
128
|
-
nextCursor: z.string().nullable(),
|
|
129
|
-
limit: z.number().int().min(1),
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Resolved attribution block returned alongside a source row. `id` is
|
|
134
|
-
* additive vs the legacy `{ slug, name }` shape — older clients that ignored
|
|
135
|
-
* it still parse cleanly. `productId` / `productSlug` are sibling top-level
|
|
136
|
-
* fields on the source response (kept flat to mirror `orgId`), not nested
|
|
137
|
-
* inside this block.
|
|
138
|
-
*/
|
|
139
|
-
export const SourceOrgRefSchema = z.object({
|
|
140
|
-
id: z.string(),
|
|
141
|
-
slug: z.string(),
|
|
142
|
-
name: z.string(),
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
export const SourceDetailSchema = z.object({
|
|
146
|
-
id: z.string(),
|
|
147
|
-
slug: z.string(),
|
|
148
|
-
name: z.string(),
|
|
149
|
-
type: SourceTypeSchema,
|
|
150
|
-
url: z.string(),
|
|
151
|
-
orgId: z.string().nullable(),
|
|
152
|
-
productId: z.string().nullable(),
|
|
153
|
-
productSlug: z.string().nullable(),
|
|
154
|
-
// Hidden sources are reachable by direct URL but excluded from listings,
|
|
155
|
-
// sitemap, and AI features. On-demand lookups and admin-suppressed rows
|
|
156
|
-
// set this true; canonical curated/agent sources leave it false.
|
|
157
|
-
isHidden: z.boolean(),
|
|
158
|
-
// Pairs with `isHidden` to distinguish admin-suppressed rows (`curated` /
|
|
159
|
-
// `agent` + hidden) from rows materialized by `/v1/lookups` (`on_demand`).
|
|
160
|
-
// Optional for graceful degradation against older API responses.
|
|
161
|
-
discovery: SourceDiscoverySchema.optional(),
|
|
162
|
-
isPrimary: z.boolean(),
|
|
163
|
-
metadata: z.string(),
|
|
164
|
-
changelogUrl: z.string().nullable().optional(),
|
|
165
|
-
hasChangelogFile: z.boolean().optional(),
|
|
166
|
-
org: SourceOrgRefSchema.nullable(),
|
|
167
|
-
releaseCount: z.number().int().min(0),
|
|
168
|
-
releasesLast30Days: z.number().int().min(0),
|
|
169
|
-
avgReleasesPerWeek: z.number(),
|
|
170
|
-
latestVersion: z.string().nullable(),
|
|
171
|
-
latestDate: z.string().nullable(),
|
|
172
|
-
lastFetchedAt: z.string().nullable(),
|
|
173
|
-
lastPolledAt: z.string().nullable(),
|
|
174
|
-
// #1969: additive so pinned old workers/clients degrade gracefully.
|
|
175
|
-
changeDetectedAt: z.string().nullable().optional(),
|
|
176
|
-
trackingSince: z.string(),
|
|
177
|
-
releases: z.array(ReleaseItemSchema),
|
|
178
|
-
pagination: SourceFeedPaginationSchema,
|
|
179
|
-
summaries: SourceDetailSummariesSchema,
|
|
180
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
181
|
-
// GitHub stargazer count. `nullable().optional()` (the house idiom for these
|
|
182
|
-
// shapes): non-github sources and older responses omit it; a fetched row may
|
|
183
|
-
// carry `null`. Consumers treat null/undefined as "unknown".
|
|
184
|
-
stars: z.number().int().min(0).nullable().optional(),
|
|
185
|
-
starsFetchedAt: z.string().nullable().optional(),
|
|
186
|
-
notice: NoticeSchema.nullable().optional(),
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Response returned by `POST /v1/sources` and `PATCH /v1/sources/:slug`.
|
|
191
|
-
*
|
|
192
|
-
* Pre-#794 these endpoints returned the bare drizzle row, leaving callers to
|
|
193
|
-
* round-trip a separate `GET` to confirm the resolved org/product attribution.
|
|
194
|
-
* Now they return the same source row plus a resolved `org { id, slug, name }`
|
|
195
|
-
* block and `productSlug`, so an agent can answer "did the write take?" from
|
|
196
|
-
* the response alone.
|
|
197
|
-
*
|
|
198
|
-
* Wire fields are loosely-typed (`z.unknown()`) for the timestamps/counters
|
|
199
|
-
* that aren't load-bearing for callers — the row is large and we don't want
|
|
200
|
-
* to hand-mirror every column. Stable, agent-relevant fields are typed.
|
|
201
|
-
*/
|
|
202
|
-
export const SourceMutationResponseSchema = z.looseObject({
|
|
203
|
-
id: z.string(),
|
|
204
|
-
slug: z.string(),
|
|
205
|
-
name: z.string(),
|
|
206
|
-
type: SourceTypeSchema,
|
|
207
|
-
url: z.string(),
|
|
208
|
-
orgId: z.string().nullable(),
|
|
209
|
-
productId: z.string().nullable(),
|
|
210
|
-
productSlug: z.string().nullable(),
|
|
211
|
-
org: SourceOrgRefSchema.nullable(),
|
|
212
|
-
metadata: z.string().nullable(),
|
|
213
|
-
isPrimary: z.boolean().nullable().optional(),
|
|
214
|
-
isHidden: z.boolean().nullable().optional(),
|
|
215
|
-
discovery: SourceDiscoverySchema.optional(),
|
|
216
|
-
createdAt: z.string().optional(),
|
|
217
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Response from `POST /v1/sources/appstore` — materializes an App Store listing
|
|
222
|
-
* into a curated Org → Product → Source → first Release (modeled on the GitHub
|
|
223
|
-
* coordinate `LookupResponse`).
|
|
224
|
-
*
|
|
225
|
-
* Unlike `SourceMutationResponse`, the `source` here is the **bare inserted (or
|
|
226
|
-
* idempotently looked-up) drizzle row** the materialize handler returns verbatim:
|
|
227
|
-
* no resolved `org { id, slug, name }` block and no `productSlug`. `loose` so the
|
|
228
|
-
* untyped timestamp/counter columns on the row pass through.
|
|
229
|
-
*
|
|
230
|
-
* `status: "indexed"` is a brand-new source (HTTP 201); `"existing"` is the
|
|
231
|
-
* idempotent hit on a prior materialize of the same trackId (HTTP 200).
|
|
232
|
-
*/
|
|
233
|
-
export const AppStoreMaterializeResponseSchema = z.object({
|
|
234
|
-
status: z.enum(["indexed", "existing"]),
|
|
235
|
-
source: z.looseObject({
|
|
236
|
-
id: z.string(),
|
|
237
|
-
slug: z.string(),
|
|
238
|
-
name: z.string(),
|
|
239
|
-
type: SourceTypeSchema,
|
|
240
|
-
url: z.string(),
|
|
241
|
-
orgId: z.string().nullable(),
|
|
242
|
-
productId: z.string().nullable(),
|
|
243
|
-
metadata: z.string().nullable(),
|
|
244
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
245
|
-
discovery: SourceDiscoverySchema.optional(),
|
|
246
|
-
isHidden: z.boolean().nullable().optional(),
|
|
247
|
-
createdAt: z.string().optional(),
|
|
248
|
-
}),
|
|
249
|
-
releaseCount: z.number(),
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
/** Body accepted by `PATCH /v1/sources/:slug`. */
|
|
253
|
-
export const SourcePatchInputSchema = z.object({
|
|
254
|
-
name: z.string().optional(),
|
|
255
|
-
url: z.string().optional(),
|
|
256
|
-
type: SourceTypeSchema.optional(),
|
|
257
|
-
slug: z.string().optional(),
|
|
258
|
-
metadata: z.string().optional(),
|
|
259
|
-
orgId: z.string().nullable().optional(),
|
|
260
|
-
productId: z.string().nullable().optional(),
|
|
261
|
-
lastFetchedAt: z.string().nullable().optional(),
|
|
262
|
-
lastContentHash: z.string().nullable().optional(),
|
|
263
|
-
fetchPriority: SourceFetchPrioritySchema.optional(),
|
|
264
|
-
consecutiveNoChange: z.number().int().optional(),
|
|
265
|
-
consecutiveErrors: z.number().int().optional(),
|
|
266
|
-
nextFetchAfter: z.string().nullable().optional(),
|
|
267
|
-
isPrimary: z.boolean().optional(),
|
|
268
|
-
isHidden: z.boolean().optional(),
|
|
269
|
-
changeDetectedAt: z.string().nullable().optional(),
|
|
270
|
-
lastPolledAt: z.string().nullable().optional(),
|
|
271
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
272
|
-
/** Admin-only: promote or demote the source's discovery status (curated/agent/on_demand). */
|
|
273
|
-
discovery: SourceDiscoverySchema.optional(),
|
|
274
|
-
notice: NoticeSchema.nullable().optional(),
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
/** Body accepted by `POST /v1/sources`. */
|
|
278
|
-
export const CreateSourceBodySchema = z.object({
|
|
279
|
-
name: z.string().min(1),
|
|
280
|
-
url: z.string().min(1),
|
|
281
|
-
type: SourceTypeSchema.optional(),
|
|
282
|
-
slug: z.string().optional(),
|
|
283
|
-
orgId: z.string().optional(),
|
|
284
|
-
orgSlug: z.string().optional(),
|
|
285
|
-
/**
|
|
286
|
-
* Either accepted; `productId` wins when both are supplied. `productSlug`
|
|
287
|
-
* resolves within the requested org (slug uniqueness is per-org). The
|
|
288
|
-
* legacy `productId` ingestion path is preserved for callers that already
|
|
289
|
-
* resolve products client-side; new agent flows should pass `productSlug`.
|
|
290
|
-
*/
|
|
291
|
-
productId: z.string().optional(),
|
|
292
|
-
productSlug: z.string().optional(),
|
|
293
|
-
metadata: z.string().optional(),
|
|
294
|
-
isPrimary: z.boolean().optional(),
|
|
295
|
-
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
export const ChangelogFileSummarySchema = z.object({
|
|
299
|
-
path: z.string(),
|
|
300
|
-
filename: z.string(),
|
|
301
|
-
url: z.string(),
|
|
302
|
-
bytes: z.number().int().min(0),
|
|
303
|
-
fetchedAt: z.string(),
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
export const SourceChangelogResponseSchema = z.object({
|
|
307
|
-
path: z.string(),
|
|
308
|
-
filename: z.string(),
|
|
309
|
-
url: z.string(),
|
|
310
|
-
rawUrl: z.string(),
|
|
311
|
-
content: z.string(),
|
|
312
|
-
bytes: z.number().int().min(0),
|
|
313
|
-
fetchedAt: z.string(),
|
|
314
|
-
/** Character offset of the first character in `content` within the full file. */
|
|
315
|
-
offset: z.number().int().min(0),
|
|
316
|
-
/** The limit (in chars) that was applied to produce this slice. */
|
|
317
|
-
limit: z.number().int().min(0),
|
|
318
|
-
/** Next offset to request for the next slice, or null if `content` is the tail. */
|
|
319
|
-
nextOffset: z.number().int().nullable(),
|
|
320
|
-
/** Total length of the full file in characters. */
|
|
321
|
-
totalChars: z.number().int().min(0),
|
|
322
|
-
/** Requested token budget when in token mode (cl100k_base). */
|
|
323
|
-
tokens: z.number().int().optional(),
|
|
324
|
-
/** Encoded token count of the returned `content`. Set in token mode. */
|
|
325
|
-
sliceTokens: z.number().int().optional(),
|
|
326
|
-
/** Full-file token count (cl100k_base). Always populated. */
|
|
327
|
-
totalTokens: z.number().int().min(0),
|
|
328
|
-
/** True when the upstream file exceeded the 1MB cap and content was sliced. */
|
|
329
|
-
truncated: z.boolean(),
|
|
330
|
-
/** Byte offset where the file was truncated, or null when not truncated. */
|
|
331
|
-
truncatedAt: z.number().int().nullable(),
|
|
332
|
-
/**
|
|
333
|
-
* Index of every changelog file tracked for this source (root plus any
|
|
334
|
-
* discovered per-package files). Always present even for single-file
|
|
335
|
-
* sources so clients can lazily render a file picker.
|
|
336
|
-
*/
|
|
337
|
-
files: z.array(ChangelogFileSummarySchema),
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// ── Source activity (/sources/:slug/activity, /orgs/:orgSlug/sources/:sourceSlug/activity) ──
|
|
341
|
-
|
|
342
|
-
const SourceActivityWeeklyBucketSchema = z.object({
|
|
343
|
-
weekStart: z.string(),
|
|
344
|
-
count: z.number().int().min(0),
|
|
345
|
-
earliestVersion: z.string().nullable(),
|
|
346
|
-
latestVersion: z.string().nullable(),
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Response shape for `GET /v1/sources/:slug/activity` and the org-scoped twin.
|
|
351
|
-
* Returns week-bucketed release counts for the full tracking lifetime of the source.
|
|
352
|
-
* Optional `?from=YYYY-MM-DD` and `?to=YYYY-MM-DD` narrow the range.
|
|
353
|
-
*/
|
|
354
|
-
export const SourceActivityResponseSchema = z.object({
|
|
355
|
-
source: z.object({
|
|
356
|
-
slug: z.string(),
|
|
357
|
-
name: z.string(),
|
|
358
|
-
orgSlug: z.string().nullable(),
|
|
359
|
-
orgName: z.string().nullable(),
|
|
360
|
-
}),
|
|
361
|
-
range: z.object({ from: z.string(), to: z.string() }),
|
|
362
|
-
weeklyBuckets: z.array(SourceActivityWeeklyBucketSchema),
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
// ── Source heatmap (/sources/:slug/heatmap, /orgs/:orgSlug/sources/:sourceSlug/heatmap) ──
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Response shape for `GET /v1/sources/:slug/heatmap` and the org-scoped twin.
|
|
369
|
-
* Returns daily release counts for the trailing 365 days — contribution-graph
|
|
370
|
-
* visualization for the source detail page.
|
|
371
|
-
*/
|
|
372
|
-
export const SourceHeatmapResponseSchema = z.object({
|
|
373
|
-
source: z.object({ slug: z.string(), name: z.string() }),
|
|
374
|
-
range: z.object({ from: z.string(), to: z.string() }),
|
|
375
|
-
dailyCounts: z.array(z.object({ date: z.string(), count: z.number().int().min(0) })),
|
|
376
|
-
total: z.number().int().min(0),
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
// ── Source known releases (/sources/:slug/known-releases, /orgs/:orgSlug/…) ──
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Single row returned inside `GET /v1/sources/:slug/known-releases`. Minimal
|
|
383
|
-
* identifier set used by the incremental parsing agent to skip already-known
|
|
384
|
-
* versions without fetching full content.
|
|
385
|
-
*/
|
|
386
|
-
export const SourceKnownReleaseItemSchema = z.object({
|
|
387
|
-
version: z.string().nullable(),
|
|
388
|
-
title: z.string(),
|
|
389
|
-
publishedAt: z.string().nullable(),
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Response shape for `GET /v1/sources/:slug/known-releases`. Returns the
|
|
394
|
-
* N most-recent non-suppressed releases (default N=10, max 500), ordered
|
|
395
|
-
* by `publishedAt` descending. Accepts `?limit=N`.
|
|
396
|
-
*/
|
|
397
|
-
export const SourceKnownReleasesResponseSchema = z.array(SourceKnownReleaseItemSchema);
|
|
398
|
-
|
|
399
|
-
// ── Source recent releases (/sources/:slug/recent-releases, /orgs/:orgSlug/…) ──
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Response shape for `GET /v1/sources/:slug/recent-releases`. Returns the
|
|
403
|
-
* full release rows (non-suppressed, published at or after `?cutoff=`) ordered
|
|
404
|
-
* by `publishedAt` descending. Used by the summarization agent to retrieve the
|
|
405
|
-
* release window it needs to summarize. `?cutoff=` is required (ISO-8601 date
|
|
406
|
-
* string); missing `?cutoff=` returns 400.
|
|
407
|
-
*/
|
|
408
|
-
export const SourceRecentReleasesResponseSchema = z.array(
|
|
409
|
-
z.looseObject({
|
|
410
|
-
id: z.string(),
|
|
411
|
-
sourceId: z.string(),
|
|
412
|
-
version: z.string().nullable(),
|
|
413
|
-
title: z.string(),
|
|
414
|
-
content: z.string(),
|
|
415
|
-
url: z.string().nullable(),
|
|
416
|
-
publishedAt: z.string().nullable(),
|
|
417
|
-
fetchedAt: z.string().optional(),
|
|
418
|
-
}),
|
|
419
|
-
);
|
|
420
|
-
|
|
421
|
-
// ── Source sessions (/sources/:slug/sessions) ──
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Response shape for `GET /v1/sources/:slug/sessions`. Returns the active
|
|
425
|
-
* discovery session (if any) touching this source. The session object is the
|
|
426
|
-
* live DO state blob from the `StatusHub` Durable Object. Returns `{ sessions:
|
|
427
|
-
* [] }` when no active session references this source.
|
|
428
|
-
*/
|
|
429
|
-
export const SourceSessionsResponseSchema = z.object({
|
|
430
|
-
sessions: z.array(z.record(z.string(), z.unknown())),
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
// ── Source summaries (/sources/:slug/summaries) ──
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Full summary row as stored in `release_summaries`, returned by
|
|
437
|
-
* `GET /v1/sources/:slug/summaries`. Filter by `?type=rolling|monthly`,
|
|
438
|
-
* `?year=`, `?month=`.
|
|
439
|
-
*/
|
|
440
|
-
export const SourceSummaryRowSchema = z.object({
|
|
441
|
-
id: z.string().optional(),
|
|
442
|
-
sourceId: z.string(),
|
|
443
|
-
orgId: z.string().nullable(),
|
|
444
|
-
type: z.enum(["rolling", "monthly"]),
|
|
445
|
-
year: z.number().int().nullable(),
|
|
446
|
-
month: z.number().int().nullable(),
|
|
447
|
-
windowDays: z.number().int().nullable(),
|
|
448
|
-
summary: z.string(),
|
|
449
|
-
releaseCount: z.number().int().min(0),
|
|
450
|
-
generatedAt: z.string(),
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
export const SourceSummariesResponseSchema = z.array(SourceSummaryRowSchema);
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Body accepted by `POST /v1/sources/:slug/summaries`.
|
|
457
|
-
*
|
|
458
|
-
* `month` is calendar-bounded (1..12) and `windowDays` must be a positive
|
|
459
|
-
* integer when present — silently dropping wrong-typed values masks client
|
|
460
|
-
* bugs, so the validator rejects them explicitly. `year` is not bound-checked
|
|
461
|
-
* (any cutoff would be arbitrary).
|
|
462
|
-
*/
|
|
463
|
-
export const CreateSourceSummaryBodySchema = z.object({
|
|
464
|
-
type: z.enum(["rolling", "monthly"]),
|
|
465
|
-
year: z.number().int().nullable().optional(),
|
|
466
|
-
month: z.number().int().min(1).max(12).nullable().optional(),
|
|
467
|
-
windowDays: z.number().int().min(1).nullable().optional(),
|
|
468
|
-
summary: z.string().min(1),
|
|
469
|
-
releaseCount: z.number().int().min(0),
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
/** Response for `POST /v1/sources/:slug/summaries` (upsert). */
|
|
473
|
-
export const CreateSourceSummaryResponseSchema = z.object({
|
|
474
|
-
ok: z.literal(true),
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
// ── Source fetch trigger (POST /sources/:slug/fetch) ──
|
|
478
|
-
|
|
479
|
-
/**
|
|
480
|
-
* Response shape for `POST /v1/sources/:slug/fetch`. Three branches:
|
|
481
|
-
* - Feed/GitHub/scraped-with-feed sources: `{ fetched: true, releasesInserted, … }`
|
|
482
|
-
* - Scrape/agent sources (flagged for CLI pickup): `{ queued: true, type: "flagged" }`
|
|
483
|
-
* - Render dry-run probe (`?dryRun=true` on a client-rendered scrape source):
|
|
484
|
-
* `{ renderCheck: true, rendered, candidateCount, sampleUrls, … }`
|
|
485
|
-
*/
|
|
486
|
-
export const SourceFetchResponseSchema = z.union([
|
|
487
|
-
z.looseObject({ fetched: z.literal(true) }),
|
|
488
|
-
z.object({ queued: z.literal(true), type: z.string() }),
|
|
489
|
-
// Render dry-run probe (#1528): renders a client-rendered scrape source's
|
|
490
|
-
// index once and reports candidate links found, without the managed-agent
|
|
491
|
-
// extraction loop.
|
|
492
|
-
z.looseObject({
|
|
493
|
-
renderCheck: z.literal(true),
|
|
494
|
-
status: z.enum(["dry_run", "error"]),
|
|
495
|
-
rendered: z.boolean(),
|
|
496
|
-
candidateCount: z.number().int(),
|
|
497
|
-
sampleUrls: z.array(z.string()),
|
|
498
|
-
durationMs: z.number().int(),
|
|
499
|
-
error: z.string().optional(),
|
|
500
|
-
}),
|
|
501
|
-
]);
|
|
502
|
-
|
|
503
|
-
// ── Source content-hash check (POST /sources/:slug/content-hash) ──
|
|
504
|
-
|
|
505
|
-
/** Response for `POST /v1/sources/:slug/content-hash`. */
|
|
506
|
-
export const SourceContentHashResponseSchema = z.union([
|
|
507
|
-
z.object({ unchanged: z.literal(true) }),
|
|
508
|
-
z.object({ unchanged: z.literal(false) }),
|
|
509
|
-
]);
|
|
510
|
-
|
|
511
|
-
/** Body for `POST /v1/sources/:slug/content-hash`. */
|
|
512
|
-
export const SourceContentHashBodySchema = z.object({
|
|
513
|
-
contentHash: z.string().min(1),
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
// ── Changelog token backfill (PATCH /sources/:slug/changelog/tokens) ──
|
|
517
|
-
|
|
518
|
-
/** Response for `PATCH /v1/sources/:slug/changelog/tokens`. */
|
|
519
|
-
export const ChangelogTokensResponseSchema = z.object({
|
|
520
|
-
path: z.string(),
|
|
521
|
-
oldTokens: z.number().int().nullable(),
|
|
522
|
-
tokens: z.number().int().min(0),
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
// ── Source metadata merge (PATCH /sources/:slug/metadata) ──
|
|
526
|
-
|
|
527
|
-
/** Response for `PATCH /v1/sources/:slug/metadata`. Echoes the merged metadata object. */
|
|
528
|
-
export const SourceMetadataResponseSchema = z.object({
|
|
529
|
-
metadata: z.record(z.string(), z.unknown()),
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
// ── Changelog probe (POST /sources/:slug/changelog/probe) ──
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* A discovered CHANGELOG path returned by the probe. Mirrors
|
|
536
|
-
* `DiscoveredChangelogPath` from `@releases/adapters/github-discovery`:
|
|
537
|
-
* `origin` tags where the path came from (repo root, a workspace package, or
|
|
538
|
-
* an explicit `metadata.changelogPaths` override) and `exists` is true when a
|
|
539
|
-
* directory listing confirmed the file on HEAD.
|
|
540
|
-
*/
|
|
541
|
-
export const DiscoveredChangelogPathSchema = z.object({
|
|
542
|
-
path: z.string(),
|
|
543
|
-
origin: z.enum(["root", "workspace", "override"]),
|
|
544
|
-
exists: z.boolean(),
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
/** Response for `POST /v1/sources/:slug/changelog/probe`. */
|
|
548
|
-
export const ChangelogProbeResponseSchema = z.object({
|
|
549
|
-
sourceId: z.string(),
|
|
550
|
-
sourceSlug: z.string(),
|
|
551
|
-
url: z.string(),
|
|
552
|
-
paths: z.array(DiscoveredChangelogPathSchema),
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
// ── Delete source (DELETE /sources/:slug) ──
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Response for `DELETE /v1/sources/:slug`. Two shapes:
|
|
559
|
-
* - Soft delete: `{ deleted: true, deletedAt: "<iso>" }`
|
|
560
|
-
* - Hard delete (`?hard=true`): `{ deleted: true, hard: true }`
|
|
561
|
-
*/
|
|
562
|
-
export const DeleteSourceResponseSchema = z.union([
|
|
563
|
-
z.object({ deleted: z.literal(true), deletedAt: z.string() }),
|
|
564
|
-
z.object({ deleted: z.literal(true), hard: z.literal(true) }),
|
|
565
|
-
]);
|
|
566
|
-
|
|
567
|
-
// ── Delete source releases (DELETE /sources/:slug/releases) ──
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* Response for `DELETE /v1/sources/:slug/releases`. Two shapes:
|
|
571
|
-
* - Soft (`?hard` absent): `{ suppressed: N }` — releases hidden, not deleted
|
|
572
|
-
* - Hard (`?hard=true`): `{ deleted: N, hard: true }`
|
|
573
|
-
*/
|
|
574
|
-
export const DeleteSourceReleasesResponseSchema = z.union([
|
|
575
|
-
z.object({ suppressed: z.number().int().min(0) }),
|
|
576
|
-
z.object({ deleted: z.number().int().min(0), hard: z.literal(true) }),
|
|
577
|
-
]);
|
|
578
|
-
|
|
579
|
-
// ── Single release insert (POST /sources/:slug/releases) ──
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* Response for `POST /v1/sources/:slug/releases`. Returns the inserted release
|
|
583
|
-
* row (201) or `{ skipped: true }` (200) on URL conflict.
|
|
584
|
-
*/
|
|
585
|
-
export const InsertReleaseResponseSchema = z.union([
|
|
586
|
-
z.looseObject({
|
|
587
|
-
id: z.string(),
|
|
588
|
-
sourceId: z.string(),
|
|
589
|
-
title: z.string(),
|
|
590
|
-
}),
|
|
591
|
-
z.object({ skipped: z.literal(true) }),
|
|
592
|
-
]);
|
|
593
|
-
|
|
594
|
-
// ── Batch release insert (POST /sources/:slug/releases/batch) ──
|
|
595
|
-
|
|
596
|
-
/** Response for `POST /v1/sources/:slug/releases/batch`. */
|
|
597
|
-
export const BatchReleasesResponseSchema = z.object({
|
|
598
|
-
inserted: z.number().int().min(0),
|
|
599
|
-
total: z.number().int().min(0),
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
// ── Raw page snapshot (POST /sources/:slug/raw-snapshot) ──
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Response for `POST /v1/sources/:slug/raw-snapshot` (#1283). On a store or a
|
|
606
|
-
* content-hash dedup hit, all fields are present; `stored` is `false` for the
|
|
607
|
-
* dedup case. When the `RAW_SNAPSHOTS` bucket is unbound the capture soft-fails
|
|
608
|
-
* with `{ stored: false, reason: "no_binding" }` and the snapshot fields are
|
|
609
|
-
* omitted — capture is best-effort and never errors ingest.
|
|
610
|
-
*/
|
|
611
|
-
export const RawSnapshotResponseSchema = z.object({
|
|
612
|
-
stored: z.boolean(),
|
|
613
|
-
r2Key: z.string().optional(),
|
|
614
|
-
contentHash: z.string().optional(),
|
|
615
|
-
bytes: z.number().int().min(0).optional(),
|
|
616
|
-
// Only set on the soft-fail path; bounded so consumers can branch on it.
|
|
617
|
-
reason: z.enum(["no_binding"]).optional(),
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
// ── Oversized changelog files (GET /sources/changelog-files/oversized) ──
|
|
621
|
-
|
|
622
|
-
/**
|
|
623
|
-
* Row returned by `GET /v1/sources/changelog-files/oversized`. Each row is a
|
|
624
|
-
* changelog file whose content length exceeds `?minBytes=` (default 256 KB).
|
|
625
|
-
* Used by `scripts/backfill-changelog-tokens.ts` to find rows with estimated
|
|
626
|
-
* (not exact) token counts.
|
|
627
|
-
*/
|
|
628
|
-
export const OversizedChangelogFileRowSchema = z.object({
|
|
629
|
-
sourceId: z.string(),
|
|
630
|
-
sourceSlug: z.string(),
|
|
631
|
-
sourceName: z.string(),
|
|
632
|
-
orgSlug: z.string(),
|
|
633
|
-
path: z.string(),
|
|
634
|
-
filename: z.string(),
|
|
635
|
-
bytes: z.number().int().min(0),
|
|
636
|
-
tokens: z.number().int().nullable(),
|
|
637
|
-
fetchedAt: z.string(),
|
|
638
|
-
});
|
|
639
|
-
|
|
640
|
-
export const OversizedChangelogFilesResponseSchema = z.array(OversizedChangelogFileRowSchema);
|
|
641
|
-
|
|
642
|
-
// ── Fetchable sources (GET /sources/fetchable) ──
|
|
643
|
-
|
|
644
|
-
/**
|
|
645
|
-
* Response for `GET /v1/sources/fetchable`. Returns raw source rows matching
|
|
646
|
-
* the requested fetch mode (`?mode=unfetched|stale|retry_errors|all`).
|
|
647
|
-
* Accepts `?staleHours=N` when `mode=stale`.
|
|
648
|
-
*/
|
|
649
|
-
export const FetchableSourcesResponseSchema = z.array(
|
|
650
|
-
z.looseObject({
|
|
651
|
-
id: z.string(),
|
|
652
|
-
slug: z.string(),
|
|
653
|
-
name: z.string(),
|
|
654
|
-
type: SourceTypeSchema,
|
|
655
|
-
url: z.string(),
|
|
656
|
-
metadata: z.string().nullable(),
|
|
657
|
-
}),
|
|
658
|
-
);
|
|
659
|
-
|
|
660
|
-
// ── Feed sources (GET /sources/feeds) ──
|
|
661
|
-
|
|
662
|
-
/**
|
|
663
|
-
* Response for `GET /v1/sources/feeds`. Returns visible source rows where
|
|
664
|
-
* `metadata.feedUrl` is set and `fetchPriority != 'paused'`.
|
|
665
|
-
*/
|
|
666
|
-
export const FeedSourcesResponseSchema = FetchableSourcesResponseSchema;
|
|
667
|
-
|
|
668
|
-
// ── Changed sources (GET /sources/changes) ──
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* Response for `GET /v1/sources/changes`. Returns visible source rows that
|
|
672
|
-
* have a non-null `changeDetectedAt` — the set flagged for CLI pickup.
|
|
673
|
-
*/
|
|
674
|
-
export const ChangedSourcesResponseSchema = FetchableSourcesResponseSchema;
|