@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.
- 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 -4
- package/src/api-types.ts +0 -2223
- 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/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 -436
- 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 -114
- 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
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
3
|
+
import { AppStoreSourceInfoSchema, ImportanceScoreSchema, MediaItemSchema, OrgStatusSchema, ReleaseThumbnailSchema, ReleaseTypeSchema, VideoSourceInfoSchema, } from "./shared.js";
|
|
4
|
+
import { SourceTypeSchema } from "./sources.js";
|
|
5
|
+
import { LookupStatusSchema } from "./lookups.js";
|
|
6
|
+
import { CollectionMemberSchema } from "./collections.js";
|
|
7
|
+
/**
|
|
8
|
+
* Org hit on the unified `/v1/search` response. The list is built either
|
|
9
|
+
* from `searchOrgs` LIKE matches or, when `?domain=` resolves, from a
|
|
10
|
+
* single-row "scoped org" projection — both produce the same wire shape.
|
|
11
|
+
*
|
|
12
|
+
* `category` is loose (`z.string().nullable()`) rather than the canonical
|
|
13
|
+
* `CategorySchema` enum because the scoped-org projection passes the raw
|
|
14
|
+
* DB column through without going through `resolveCategoryInput`; legacy
|
|
15
|
+
* rows may carry deprecated slugs that haven't been migrated yet. Tighten
|
|
16
|
+
* once #689 (category overlay backfill) lands across the prod data set.
|
|
17
|
+
*/
|
|
18
|
+
export const SearchOrgHitSchema = z.object({
|
|
19
|
+
slug: z.string(),
|
|
20
|
+
name: z.string(),
|
|
21
|
+
domain: z.string().nullable(),
|
|
22
|
+
avatarUrl: z.string().nullable(),
|
|
23
|
+
category: z.string().nullable(),
|
|
24
|
+
/**
|
|
25
|
+
* Org tier (#1947/#2034). Optional for mid-deploy tolerance; absent ⇒
|
|
26
|
+
* `"tracked"`. Lets search render the icon-only stub marker (#2031 parity).
|
|
27
|
+
*/
|
|
28
|
+
status: OrgStatusSchema.optional(),
|
|
29
|
+
/**
|
|
30
|
+
* Org-level alternate domains (product-scoped aliases excluded, sorted),
|
|
31
|
+
* for the `+N` hover on the origin domain — the anti-impersonation anchor
|
|
32
|
+
* mirrored from the catalog row (#2031/#2034). Optional; absent ⇒ none.
|
|
33
|
+
*/
|
|
34
|
+
aliasDomains: z.array(z.string()).optional(),
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Unified catalog entry — either a product row or a standalone source
|
|
38
|
+
* presented as product-shaped. `entryType` discriminates between the two
|
|
39
|
+
* row shapes (`"product"` vs `"source"`). `kind` carries the entity
|
|
40
|
+
* taxonomy (platform/sdk/mobile/…). `entryType` (not `type`) because
|
|
41
|
+
* source rows already carry `type: github|scrape|feed|agent` on the wire.
|
|
42
|
+
*/
|
|
43
|
+
export const SearchCatalogHitSchema = z.object({
|
|
44
|
+
slug: z.string(),
|
|
45
|
+
name: z.string(),
|
|
46
|
+
orgSlug: z.string().nullable(),
|
|
47
|
+
orgName: z.string().nullable(),
|
|
48
|
+
/** Owning org's avatar URL, for a small inline byline avatar. Products have
|
|
49
|
+
* no avatar of their own, so the web row anchors on the org's instead. */
|
|
50
|
+
orgAvatarUrl: z.string().nullable().optional(),
|
|
51
|
+
// Loose `z.string().nullable()` rather than the canonical `CategorySchema`
|
|
52
|
+
// enum because `foldSourcesIntoCatalog` and the catalog-search handlers
|
|
53
|
+
// pass `s.productCategory` / `o.category` through without validating
|
|
54
|
+
// against `resolveCategoryInput`. Legacy rows may carry deprecated slugs
|
|
55
|
+
// that haven't been migrated yet. Tighten once #689 (category overlay
|
|
56
|
+
// backfill) lands across the prod data set.
|
|
57
|
+
category: z.string().nullable(),
|
|
58
|
+
entryType: z.enum(["product", "source"]),
|
|
59
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
60
|
+
sourceSlug: z.string().optional(),
|
|
61
|
+
sourceType: SourceTypeSchema.optional(),
|
|
62
|
+
});
|
|
63
|
+
export const SearchSourceHitSchema = z.object({
|
|
64
|
+
slug: z.string(),
|
|
65
|
+
name: z.string(),
|
|
66
|
+
type: SourceTypeSchema,
|
|
67
|
+
orgSlug: z.string().nullable(),
|
|
68
|
+
orgName: z.string().nullable(),
|
|
69
|
+
productSlug: z.string().nullable(),
|
|
70
|
+
stars: z.number().int().min(0).nullable().optional(),
|
|
71
|
+
});
|
|
72
|
+
export const SearchReleaseHitSchema = z.object({
|
|
73
|
+
id: z.string(),
|
|
74
|
+
sourceSlug: z.string(),
|
|
75
|
+
sourceName: z.string(),
|
|
76
|
+
// Loose `z.string()` rather than `SourceTypeSchema` because the
|
|
77
|
+
// release-hit hydration path reads `sources.type` straight from the DB
|
|
78
|
+
// without re-validating; legacy rows occasionally drift from the
|
|
79
|
+
// canonical four-value set. Used by the web byline icon.
|
|
80
|
+
sourceType: z.string().optional(),
|
|
81
|
+
/**
|
|
82
|
+
* App Store platform + icon for `type: "appstore"` sources, null/absent
|
|
83
|
+
* otherwise. Powers the compact app-update treatment on the search card. #1206
|
|
84
|
+
*/
|
|
85
|
+
appStore: AppStoreSourceInfoSchema.nullable().optional(),
|
|
86
|
+
/**
|
|
87
|
+
* Video provider tag for `type: "video"` sources, absent otherwise. Powers
|
|
88
|
+
* the thumbnail-forward video row on search cards. #video
|
|
89
|
+
*/
|
|
90
|
+
video: VideoSourceInfoSchema.nullable().optional(),
|
|
91
|
+
orgSlug: z.string().nullable(),
|
|
92
|
+
orgName: z.string().nullable().optional(),
|
|
93
|
+
/** Owning product slug — present when the source belongs to a product. Lets
|
|
94
|
+
* the web byline link to the product page instead of the source. */
|
|
95
|
+
productSlug: z.string().nullable().optional(),
|
|
96
|
+
version: z.string().nullable(),
|
|
97
|
+
title: z.string(),
|
|
98
|
+
summary: z.string(),
|
|
99
|
+
titleGenerated: z.string().nullable().optional(),
|
|
100
|
+
titleShort: z.string().nullable().optional(),
|
|
101
|
+
/**
|
|
102
|
+
* The release's upstream source URL, when it has one. Lets the web link
|
|
103
|
+
* search/lookup hits straight to the original page instead of the
|
|
104
|
+
* noindexed `/release/<id>` stub — see `releaseLinkProps()` in
|
|
105
|
+
* `apps/web/src/lib/release-link.ts`. Optional for older servers / mid-deploy
|
|
106
|
+
* pin tolerance.
|
|
107
|
+
*/
|
|
108
|
+
url: z.string().nullable().optional(),
|
|
109
|
+
/**
|
|
110
|
+
* AI-scored importance 1–5 (5=landmark, 1=housekeeping). Null when
|
|
111
|
+
* unscored; optional for older servers / mid-deploy pin tolerance.
|
|
112
|
+
*/
|
|
113
|
+
importance: ImportanceScoreSchema,
|
|
114
|
+
/**
|
|
115
|
+
* Full markdown body. Omitted on list hits by default (summary + media
|
|
116
|
+
* cover the card/snippet surfaces). Opt in with `?include_content=true`
|
|
117
|
+
* on `/v1/search`. Fetch full body via `GET /v1/releases/:id` otherwise.
|
|
118
|
+
*/
|
|
119
|
+
content: z.string().optional(),
|
|
120
|
+
media: z.array(MediaItemSchema).optional(),
|
|
121
|
+
publishedAt: z.string().nullable(),
|
|
122
|
+
// Hybrid fusion score; absent on pure-lexical results.
|
|
123
|
+
score: z.number().optional(),
|
|
124
|
+
type: ReleaseTypeSchema.optional(),
|
|
125
|
+
coverageCount: z.number().int().min(0).optional(),
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Collection hit on the unified `/v1/search` response. Two origins are folded
|
|
129
|
+
* into the same wire shape via the `via` discriminator:
|
|
130
|
+
*
|
|
131
|
+
* - `direct` — the collection itself matched (name/description via LIKE in
|
|
132
|
+
* every mode, plus vector match in hybrid/semantic mode).
|
|
133
|
+
* - `member` — the collection was surfaced because one of the orgs that
|
|
134
|
+
* *did* match the query is a member of it; `matchedOrgSlugs`
|
|
135
|
+
* carries the subset of result-set org slugs that triggered
|
|
136
|
+
* the rollup so the UI can render an "includes X, Y" hint.
|
|
137
|
+
*
|
|
138
|
+
* `direct` rows always sort ahead of `member` rows; ties break on
|
|
139
|
+
* `score` then `memberCount`. Slugs are unique across the array — a
|
|
140
|
+
* direct hit that's also a member rollup keeps only the `direct` row
|
|
141
|
+
* with `matchedOrgSlugs` carried over.
|
|
142
|
+
*/
|
|
143
|
+
export const SearchCollectionHitSchema = z.object({
|
|
144
|
+
slug: z.string(),
|
|
145
|
+
name: z.string(),
|
|
146
|
+
description: z.string().nullable(),
|
|
147
|
+
memberCount: z.number().int().min(0),
|
|
148
|
+
via: z.enum(["direct", "member"]),
|
|
149
|
+
/** Hybrid/semantic fusion score; absent on pure-lexical hits. */
|
|
150
|
+
score: z.number().optional(),
|
|
151
|
+
/** Result-set org slugs that triggered this rollup. Always present on `via=member`. */
|
|
152
|
+
matchedOrgSlugs: z.array(z.string()).optional(),
|
|
153
|
+
/**
|
|
154
|
+
* A small org preview (capped at 3) for an inline avatar facepile on the
|
|
155
|
+
* search card, mirroring the collections list page. Org-kind only — search's
|
|
156
|
+
* `memberCount` counts orgs, so the facepile and its "+N more" stay
|
|
157
|
+
* consistent. Attached after hit merge; optional on the wire so older workers
|
|
158
|
+
* mid-rollout don't trip the schema.
|
|
159
|
+
*/
|
|
160
|
+
previewMembers: z.array(CollectionMemberSchema).optional(),
|
|
161
|
+
});
|
|
162
|
+
/**
|
|
163
|
+
* Heading-aware CHANGELOG.md slice returned by hybrid / semantic search.
|
|
164
|
+
* Clients can deep-link to
|
|
165
|
+
* `/<orgSlug>/<sourceSlug>/changelog?offset=<offset>#chunk` to read the
|
|
166
|
+
* surrounding file content (the web `chunkDeepLink` builder; falls back to
|
|
167
|
+
* the `/source/<sourceSlug>` redirect shim when `orgSlug` is null).
|
|
168
|
+
*/
|
|
169
|
+
export const SearchChunkHitSchema = z.object({
|
|
170
|
+
sourceSlug: z.string(),
|
|
171
|
+
sourceName: z.string(),
|
|
172
|
+
orgSlug: z.string().nullable(),
|
|
173
|
+
orgName: z.string().nullable().optional(),
|
|
174
|
+
filePath: z.string(),
|
|
175
|
+
offset: z.number().int().min(0),
|
|
176
|
+
length: z.number().int().min(0),
|
|
177
|
+
heading: z.string().nullable(),
|
|
178
|
+
snippet: z.string(),
|
|
179
|
+
score: z.number(),
|
|
180
|
+
});
|
|
181
|
+
/**
|
|
182
|
+
* Slim wire payload embedded in a search response when the query is a
|
|
183
|
+
* GitHub `org/repo` coordinate and no existing entity matched. Reuses
|
|
184
|
+
* `LookupStatusSchema` from `./lookups.js` rather than redefining — the
|
|
185
|
+
* thick `POST /v1/lookups` response and the slim search-embedded payload
|
|
186
|
+
* share the same status set.
|
|
187
|
+
*/
|
|
188
|
+
export const LookupResultPayloadSchema = z.object({
|
|
189
|
+
status: LookupStatusSchema,
|
|
190
|
+
source: z
|
|
191
|
+
.object({
|
|
192
|
+
id: z.string(),
|
|
193
|
+
slug: z.string(),
|
|
194
|
+
name: z.string(),
|
|
195
|
+
url: z.string(),
|
|
196
|
+
discovery: z.enum(["curated", "agent", "on_demand"]),
|
|
197
|
+
stars: z.number().int().min(0).nullable().optional(),
|
|
198
|
+
})
|
|
199
|
+
.optional(),
|
|
200
|
+
releases: z
|
|
201
|
+
.array(z.object({
|
|
202
|
+
id: z.string(),
|
|
203
|
+
version: z.string().nullable(),
|
|
204
|
+
title: z.string(),
|
|
205
|
+
publishedAt: z.string().nullable(),
|
|
206
|
+
/** First image/gif thumbnail; null when the release has none. */
|
|
207
|
+
thumbnail: ReleaseThumbnailSchema.nullable().optional(),
|
|
208
|
+
/** The release's upstream source URL, when it has one. See
|
|
209
|
+
* `SearchReleaseHitSchema.url`. */
|
|
210
|
+
url: z.string().nullable().optional(),
|
|
211
|
+
}))
|
|
212
|
+
.optional(),
|
|
213
|
+
// Unambiguous "did you mean" rail; null when the org segment matches
|
|
214
|
+
// multiple curated orgs or none.
|
|
215
|
+
relatedOrg: z
|
|
216
|
+
.object({
|
|
217
|
+
org: z.object({ id: z.string(), slug: z.string(), name: z.string() }),
|
|
218
|
+
sources: z.array(z.object({ id: z.string(), slug: z.string(), name: z.string(), url: z.string() })),
|
|
219
|
+
})
|
|
220
|
+
.nullable(),
|
|
221
|
+
});
|
|
222
|
+
export const UnifiedSearchResponseSchema = z.object({
|
|
223
|
+
query: z.string(),
|
|
224
|
+
// Normalized `?domain=` echo + resolution outcome. Both absent when no
|
|
225
|
+
// domain filter was applied.
|
|
226
|
+
domain: z.string().optional(),
|
|
227
|
+
domainStatus: z.enum(["matched", "not_found"]).optional(),
|
|
228
|
+
// `?org=` echo (the resolved slug on a match, the raw value on a miss) +
|
|
229
|
+
// resolution outcome. Both absent when no org filter was applied.
|
|
230
|
+
org: z.string().optional(),
|
|
231
|
+
orgStatus: z.enum(["matched", "not_found"]).optional(),
|
|
232
|
+
// Normalized `?category=` echo. Present only when a category filter was
|
|
233
|
+
// applied; the resolved canonical slug (aliases are folded to canonical).
|
|
234
|
+
// `categoryStatus` is always `matched` because an unknown category is a 400,
|
|
235
|
+
// not an empty envelope — categories are a fixed enum, unlike collections.
|
|
236
|
+
category: z.string().optional(),
|
|
237
|
+
categoryStatus: z.enum(["matched"]).optional(),
|
|
238
|
+
// Normalized `?collection=` echo + resolution outcome. `not_found` when the
|
|
239
|
+
// slug matched no collection (empty envelope, mirroring `domainStatus`).
|
|
240
|
+
collection: z.string().optional(),
|
|
241
|
+
collectionStatus: z.enum(["matched", "not_found"]).optional(),
|
|
242
|
+
orgs: z.array(SearchOrgHitSchema),
|
|
243
|
+
catalog: z.array(SearchCatalogHitSchema),
|
|
244
|
+
sources: z.array(SearchSourceHitSchema),
|
|
245
|
+
releases: z.array(SearchReleaseHitSchema),
|
|
246
|
+
/**
|
|
247
|
+
* Curated collections matching the query, either directly (name/description
|
|
248
|
+
* match or vector hit) or via member rollup (one of the result orgs is in
|
|
249
|
+
* the collection). Optional on the wire so older workers mid-rollout don't
|
|
250
|
+
* trip the schema check; clients should treat missing and `[]` identically.
|
|
251
|
+
*/
|
|
252
|
+
collections: z.array(SearchCollectionHitSchema).optional(),
|
|
253
|
+
chunks: z.array(SearchChunkHitSchema).optional(),
|
|
254
|
+
mode: z.enum(["lexical", "semantic", "hybrid"]).optional(),
|
|
255
|
+
degraded: z.boolean().optional(),
|
|
256
|
+
degradedReason: z.string().optional(),
|
|
257
|
+
lookup: LookupResultPayloadSchema.nullable().optional(),
|
|
258
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* `GET /v1/admin/semantic-alerts/summary`.
|
|
4
|
+
*
|
|
5
|
+
* `scored` is matched + below threshold (a probability came back).
|
|
6
|
+
* `matchRate` is matched / scored, or null when nothing was scored.
|
|
7
|
+
* `failed` is fail-closed and stays out of the rate.
|
|
8
|
+
* Cost is not on these points; `meta.costLane` names the `ai_usage` lane.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SemanticAlertSummarySchema: z.ZodObject<{
|
|
11
|
+
after: z.ZodString;
|
|
12
|
+
before: z.ZodString;
|
|
13
|
+
bucket: z.ZodEnum<{
|
|
14
|
+
day: "day";
|
|
15
|
+
hour: "hour";
|
|
16
|
+
}>;
|
|
17
|
+
totals: z.ZodObject<{
|
|
18
|
+
matched: z.ZodNumber;
|
|
19
|
+
belowThreshold: z.ZodNumber;
|
|
20
|
+
failed: z.ZodNumber;
|
|
21
|
+
scored: z.ZodNumber;
|
|
22
|
+
matchRate: z.ZodNullable<z.ZodNumber>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
series: z.ZodArray<z.ZodObject<{
|
|
25
|
+
matched: z.ZodNumber;
|
|
26
|
+
belowThreshold: z.ZodNumber;
|
|
27
|
+
failed: z.ZodNumber;
|
|
28
|
+
t: z.ZodString;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
failures: z.ZodArray<z.ZodObject<{
|
|
31
|
+
category: z.ZodEnum<{
|
|
32
|
+
invalid_probability: "invalid_probability";
|
|
33
|
+
provider_error: "provider_error";
|
|
34
|
+
unknown: "unknown";
|
|
35
|
+
}>;
|
|
36
|
+
count: z.ZodNumber;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
probability: z.ZodObject<{
|
|
39
|
+
defaultThreshold: z.ZodLiteral<0.8>;
|
|
40
|
+
bins: z.ZodArray<z.ZodObject<{
|
|
41
|
+
start: z.ZodNumber;
|
|
42
|
+
end: z.ZodNumber;
|
|
43
|
+
count: z.ZodNumber;
|
|
44
|
+
}, z.core.$strip>>;
|
|
45
|
+
missing: z.ZodNumber;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
meta: z.ZodObject<{
|
|
48
|
+
dataset: z.ZodString;
|
|
49
|
+
retentionDays: z.ZodLiteral<90>;
|
|
50
|
+
sampled: z.ZodLiteral<true>;
|
|
51
|
+
costLane: z.ZodLiteral<"semantic-alert-match">;
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
//# sourceMappingURL=semantic-alert-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-alert-summary.d.ts","sourceRoot":"","sources":["../../src/schemas/semantic-alert-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiCrC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Admin interest-alert quality (`GET /v1/admin/semantic-alerts/summary`).
|
|
4
|
+
* Decisions live in the classifications Analytics Engine dataset with
|
|
5
|
+
* `blob4 = semantic-alert`. This is the hydrated read model. Alert query
|
|
6
|
+
* text is not a field — it is not stored on the points.
|
|
7
|
+
*/
|
|
8
|
+
const ProbabilityBinSchema = z.object({
|
|
9
|
+
/** Inclusive. Width is 0.1. `0.8` is the start of the default-threshold bin. */
|
|
10
|
+
start: z.number(),
|
|
11
|
+
/** Exclusive, except the last bin (`0.9`–`1`) which includes `1`. */
|
|
12
|
+
end: z.number(),
|
|
13
|
+
count: z.number(),
|
|
14
|
+
});
|
|
15
|
+
const SemanticAlertDispositionCountsSchema = z.object({
|
|
16
|
+
matched: z.number(),
|
|
17
|
+
belowThreshold: z.number(),
|
|
18
|
+
failed: z.number(),
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* `GET /v1/admin/semantic-alerts/summary`.
|
|
22
|
+
*
|
|
23
|
+
* `scored` is matched + below threshold (a probability came back).
|
|
24
|
+
* `matchRate` is matched / scored, or null when nothing was scored.
|
|
25
|
+
* `failed` is fail-closed and stays out of the rate.
|
|
26
|
+
* Cost is not on these points; `meta.costLane` names the `ai_usage` lane.
|
|
27
|
+
*/
|
|
28
|
+
export const SemanticAlertSummarySchema = z.object({
|
|
29
|
+
after: z.string(),
|
|
30
|
+
before: z.string(),
|
|
31
|
+
bucket: z.enum(["hour", "day"]),
|
|
32
|
+
totals: SemanticAlertDispositionCountsSchema.extend({
|
|
33
|
+
scored: z.number(),
|
|
34
|
+
matchRate: z.number().nullable(),
|
|
35
|
+
}),
|
|
36
|
+
series: z.array(SemanticAlertDispositionCountsSchema.extend({
|
|
37
|
+
t: z.string(),
|
|
38
|
+
})),
|
|
39
|
+
failures: z.array(z.object({
|
|
40
|
+
category: z.enum(["provider_error", "invalid_probability", "unknown"]),
|
|
41
|
+
count: z.number(),
|
|
42
|
+
})),
|
|
43
|
+
probability: z.object({
|
|
44
|
+
/** Default alert threshold. Each point stores its own threshold separately. */
|
|
45
|
+
defaultThreshold: z.literal(0.8),
|
|
46
|
+
bins: z.array(ProbabilityBinSchema),
|
|
47
|
+
/** Sampled rows whose probability double is `< 0` (the absent sentinel). */
|
|
48
|
+
missing: z.number(),
|
|
49
|
+
}),
|
|
50
|
+
meta: z.object({
|
|
51
|
+
dataset: z.string(),
|
|
52
|
+
retentionDays: z.literal(90),
|
|
53
|
+
sampled: z.literal(true),
|
|
54
|
+
/** `ai_usage` lane that carries JEV cost. Not summed from these points. */
|
|
55
|
+
costLane: z.literal("semantic-alert-match"),
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Semantic alerts (#2304): saved interests matched against followed releases. */
|
|
3
|
+
/** Hard cap on saved semantic alerts per account. Enforced on create. */
|
|
4
|
+
export declare const SEMANTIC_ALERT_MAX_PER_USER = 5;
|
|
5
|
+
/** Freeform interest text, after trim. User-private — never an analytics label. */
|
|
6
|
+
export declare const SEMANTIC_ALERT_QUERY_MAX_CHARS = 500;
|
|
7
|
+
/** Default selected-choice probability, used unless an alert overrides it. */
|
|
8
|
+
export declare const SEMANTIC_ALERT_THRESHOLD_DEFAULT = 0.8;
|
|
9
|
+
export declare const SEMANTIC_ALERT_THRESHOLD_MIN = 0.5;
|
|
10
|
+
export declare const SEMANTIC_ALERT_THRESHOLD_MAX = 1;
|
|
11
|
+
/**
|
|
12
|
+
* v1 candidate pool. Matching scores only releases that already hit
|
|
13
|
+
* the caller's follow graph. Not a per-alert setting.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SEMANTIC_ALERT_CANDIDATE_POOL: "follows";
|
|
16
|
+
/**
|
|
17
|
+
* POST /v1/me/semantic-alerts body. Documentation shape: the handler parses
|
|
18
|
+
* each field itself. Omitted `enabled` defaults to true, `threshold` to
|
|
19
|
+
* {@link SEMANTIC_ALERT_THRESHOLD_DEFAULT}, `deliverEmail` to true and
|
|
20
|
+
* `deliverWebhook` to false.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SemanticAlertCreateBodySchema: z.ZodObject<{
|
|
23
|
+
query: z.ZodString;
|
|
24
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
threshold: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
deliverEmail: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
+
deliverWebhook: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
webhookSubscriptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
export type SemanticAlertCreateBody = z.infer<typeof SemanticAlertCreateBodySchema>;
|
|
31
|
+
/** PATCH /v1/me/semantic-alerts/:id body — any subset of the create fields. */
|
|
32
|
+
export declare const SemanticAlertUpdateBodySchema: z.ZodObject<{
|
|
33
|
+
query: z.ZodOptional<z.ZodString>;
|
|
34
|
+
enabled: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
35
|
+
threshold: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
36
|
+
deliverEmail: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
37
|
+
deliverWebhook: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
38
|
+
webhookSubscriptionId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export type SemanticAlertUpdateBody = z.infer<typeof SemanticAlertUpdateBodySchema>;
|
|
41
|
+
//# sourceMappingURL=semantic-alerts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-alerts.d.ts","sourceRoot":"","sources":["../../src/schemas/semantic-alerts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,kFAAkF;AAElF,yEAAyE;AACzE,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,8EAA8E;AAC9E,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAG,SAAkB,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;;;;;iBAkBxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,+EAA+E;AAC/E,eAAO,MAAM,6BAA6B;;;;;;;iBAA0C,CAAC;AACrF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Semantic alerts (#2304): saved interests matched against followed releases. */
|
|
3
|
+
/** Hard cap on saved semantic alerts per account. Enforced on create. */
|
|
4
|
+
export const SEMANTIC_ALERT_MAX_PER_USER = 5;
|
|
5
|
+
/** Freeform interest text, after trim. User-private — never an analytics label. */
|
|
6
|
+
export const SEMANTIC_ALERT_QUERY_MAX_CHARS = 500;
|
|
7
|
+
/** Default selected-choice probability, used unless an alert overrides it. */
|
|
8
|
+
export const SEMANTIC_ALERT_THRESHOLD_DEFAULT = 0.8;
|
|
9
|
+
export const SEMANTIC_ALERT_THRESHOLD_MIN = 0.5;
|
|
10
|
+
export const SEMANTIC_ALERT_THRESHOLD_MAX = 1;
|
|
11
|
+
/**
|
|
12
|
+
* v1 candidate pool. Matching scores only releases that already hit
|
|
13
|
+
* the caller's follow graph. Not a per-alert setting.
|
|
14
|
+
*/
|
|
15
|
+
export const SEMANTIC_ALERT_CANDIDATE_POOL = "follows";
|
|
16
|
+
/**
|
|
17
|
+
* POST /v1/me/semantic-alerts body. Documentation shape: the handler parses
|
|
18
|
+
* each field itself. Omitted `enabled` defaults to true, `threshold` to
|
|
19
|
+
* {@link SEMANTIC_ALERT_THRESHOLD_DEFAULT}, `deliverEmail` to true and
|
|
20
|
+
* `deliverWebhook` to false.
|
|
21
|
+
*/
|
|
22
|
+
export const SemanticAlertCreateBodySchema = z.object({
|
|
23
|
+
query: z
|
|
24
|
+
.string()
|
|
25
|
+
.max(SEMANTIC_ALERT_QUERY_MAX_CHARS)
|
|
26
|
+
.describe("Freeform interest. Trimmed. User-private."),
|
|
27
|
+
enabled: z.boolean().optional(),
|
|
28
|
+
threshold: z
|
|
29
|
+
.number()
|
|
30
|
+
.min(SEMANTIC_ALERT_THRESHOLD_MIN)
|
|
31
|
+
.max(SEMANTIC_ALERT_THRESHOLD_MAX)
|
|
32
|
+
.optional(),
|
|
33
|
+
deliverEmail: z.boolean().optional(),
|
|
34
|
+
deliverWebhook: z.boolean().optional(),
|
|
35
|
+
webhookSubscriptionId: z
|
|
36
|
+
.string()
|
|
37
|
+
.nullable()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("One of the caller's webhook subscriptions. `null` clears the link on update."),
|
|
40
|
+
});
|
|
41
|
+
/** PATCH /v1/me/semantic-alerts/:id body — any subset of the create fields. */
|
|
42
|
+
export const SemanticAlertUpdateBodySchema = SemanticAlertCreateBodySchema.partial();
|