@buildinternet/releases-api-types 0.21.0 → 0.22.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/package.json +2 -2
- package/src/api-types.ts +11 -4
- package/src/schemas/lookups.ts +2 -0
- package/src/schemas/orgs.ts +10 -5
- package/src/schemas/products.ts +5 -0
- package/src/schemas/search.ts +7 -5
- package/src/schemas/sources.ts +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buildinternet/releases-api-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Wire protocol — request/response types for the Releases registry API. Shared by web, workers, and clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@buildinternet/releases-core": "^0.
|
|
20
|
+
"@buildinternet/releases-core": "^0.22.0",
|
|
21
21
|
"zod": "^4.4.3"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
package/src/api-types.ts
CHANGED
|
@@ -644,17 +644,22 @@ export type SearchSourceHit = z.infer<typeof SearchSourceHitSchema>;
|
|
|
644
644
|
export interface RawSourceHit extends SearchSourceHit {
|
|
645
645
|
productName?: string;
|
|
646
646
|
productCategory?: string;
|
|
647
|
+
/** Entity taxonomy kind from the `sources.kind` column. */
|
|
648
|
+
entityKind?: string | null;
|
|
647
649
|
}
|
|
648
650
|
|
|
649
651
|
/**
|
|
650
652
|
* Fold source hits into the catalog list. Sources under a matched product
|
|
651
|
-
* are dropped (product wins); orphan sources become `
|
|
653
|
+
* are dropped (product wins); orphan sources become `entryType: "source"`.
|
|
652
654
|
*/
|
|
653
655
|
export function foldSourcesIntoCatalog(
|
|
654
656
|
existingProducts: SearchCatalogHit[],
|
|
655
657
|
rawSources: RawSourceHit[],
|
|
656
658
|
): SearchCatalogHit[] {
|
|
657
|
-
const result: SearchCatalogHit[] = existingProducts.map((p) => ({
|
|
659
|
+
const result: SearchCatalogHit[] = existingProducts.map((p) => ({
|
|
660
|
+
...p,
|
|
661
|
+
entryType: "product" as const,
|
|
662
|
+
}));
|
|
658
663
|
const seen = new Set(result.map((p) => p.slug));
|
|
659
664
|
for (const s of rawSources) {
|
|
660
665
|
if (s.productSlug) {
|
|
@@ -665,7 +670,8 @@ export function foldSourcesIntoCatalog(
|
|
|
665
670
|
orgSlug: s.orgSlug,
|
|
666
671
|
orgName: s.orgName,
|
|
667
672
|
category: s.productCategory ?? null,
|
|
668
|
-
|
|
673
|
+
entryType: "product",
|
|
674
|
+
kind: undefined,
|
|
669
675
|
});
|
|
670
676
|
seen.add(s.productSlug);
|
|
671
677
|
} else {
|
|
@@ -675,7 +681,8 @@ export function foldSourcesIntoCatalog(
|
|
|
675
681
|
orgSlug: s.orgSlug,
|
|
676
682
|
orgName: s.orgName,
|
|
677
683
|
category: null,
|
|
678
|
-
|
|
684
|
+
entryType: "source",
|
|
685
|
+
kind: (s.entityKind as SearchCatalogHit["kind"]) ?? undefined,
|
|
679
686
|
sourceSlug: s.slug,
|
|
680
687
|
sourceType: s.type,
|
|
681
688
|
});
|
package/src/schemas/lookups.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
2
3
|
import { CategorySchema } from "./shared.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -114,6 +115,7 @@ export const DomainLookupProductSchema = z.object({
|
|
|
114
115
|
// path resolves through `resolveCategoryInput` before persisting — unlike
|
|
115
116
|
// the search catalog category, which passes the column through raw.
|
|
116
117
|
category: CategorySchema.nullable(),
|
|
118
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
117
119
|
});
|
|
118
120
|
|
|
119
121
|
export const DomainLookupResponseSchema = z.object({
|
package/src/schemas/orgs.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
2
3
|
import {
|
|
3
4
|
CategorySchema,
|
|
4
5
|
ListResponseSchema,
|
|
@@ -125,7 +126,8 @@ const OrgDetailPlaybookSchema = z.object({
|
|
|
125
126
|
// ── Org catalog (/orgs/:slug/catalog) ──
|
|
126
127
|
|
|
127
128
|
const OrgCatalogProductItemSchema = z.object({
|
|
128
|
-
|
|
129
|
+
entryType: z.literal("product"),
|
|
130
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
129
131
|
id: z.string(),
|
|
130
132
|
slug: z.string(),
|
|
131
133
|
name: z.string(),
|
|
@@ -135,7 +137,8 @@ const OrgCatalogProductItemSchema = z.object({
|
|
|
135
137
|
});
|
|
136
138
|
|
|
137
139
|
const OrgCatalogSourceItemSchema = z.object({
|
|
138
|
-
|
|
140
|
+
entryType: z.literal("source"),
|
|
141
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
139
142
|
id: z.string(),
|
|
140
143
|
slug: z.string(),
|
|
141
144
|
name: z.string(),
|
|
@@ -146,10 +149,12 @@ const OrgCatalogSourceItemSchema = z.object({
|
|
|
146
149
|
|
|
147
150
|
/**
|
|
148
151
|
* Combined product + source catalog for `GET /v1/orgs/:slug/catalog`.
|
|
149
|
-
* `
|
|
150
|
-
* `
|
|
152
|
+
* `entryType` discriminates between the two row shapes (`"product"` vs
|
|
153
|
+
* `"source"`). `kind` carries the entity taxonomy (platform/sdk/mobile/…).
|
|
154
|
+
* Products carry `category` and `description`; sources carry `type` and
|
|
155
|
+
* `productId`.
|
|
151
156
|
*/
|
|
152
|
-
export const OrgCatalogItemSchema = z.discriminatedUnion("
|
|
157
|
+
export const OrgCatalogItemSchema = z.discriminatedUnion("entryType", [
|
|
153
158
|
OrgCatalogProductItemSchema,
|
|
154
159
|
OrgCatalogSourceItemSchema,
|
|
155
160
|
]);
|
package/src/schemas/products.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
2
3
|
import { CategorySchema, ListResponseSchema } from "./shared.js";
|
|
3
4
|
import { SourceTypeSchema } from "./sources.js";
|
|
4
5
|
|
|
@@ -19,6 +20,7 @@ export const ProductRowSchema = z.object({
|
|
|
19
20
|
url: z.string().nullable(),
|
|
20
21
|
description: z.string().nullable(),
|
|
21
22
|
category: CategorySchema.nullable(),
|
|
23
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
22
24
|
createdAt: z.string(),
|
|
23
25
|
embeddedAt: z.string().nullable(),
|
|
24
26
|
deletedAt: z.string().nullable(),
|
|
@@ -37,6 +39,7 @@ export const ProductListItemSchema = z.object({
|
|
|
37
39
|
url: z.string().nullable(),
|
|
38
40
|
description: z.string().nullable(),
|
|
39
41
|
category: CategorySchema.nullable(),
|
|
42
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
40
43
|
createdAt: z.string(),
|
|
41
44
|
sourceCount: z.number().int().min(0),
|
|
42
45
|
});
|
|
@@ -83,6 +86,7 @@ export const CreateProductBodySchema = z.object({
|
|
|
83
86
|
description: z.string().optional(),
|
|
84
87
|
category: z.string().min(1).optional(),
|
|
85
88
|
tags: z.array(z.string()).optional(),
|
|
89
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
86
90
|
});
|
|
87
91
|
|
|
88
92
|
/**
|
|
@@ -97,6 +101,7 @@ export const UpdateProductBodySchema = z.object({
|
|
|
97
101
|
category: z.string().min(1).nullable().optional(),
|
|
98
102
|
tags: z.array(z.string()).optional(),
|
|
99
103
|
aliases: z.array(z.string()).optional(),
|
|
104
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
100
105
|
});
|
|
101
106
|
|
|
102
107
|
/**
|
package/src/schemas/search.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
2
3
|
import { MediaItemSchema, ReleaseTypeSchema } from "./shared.js";
|
|
3
4
|
import { SourceTypeSchema } from "./sources.js";
|
|
4
5
|
import { LookupStatusSchema } from "./lookups.js";
|
|
@@ -24,10 +25,10 @@ export const SearchOrgHitSchema = z.object({
|
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Unified catalog entry — either a product row or a standalone source
|
|
27
|
-
* presented as product-shaped. `
|
|
28
|
-
*
|
|
29
|
-
* `type`) because
|
|
30
|
-
* `type: github|scrape|feed|agent` on the wire.
|
|
28
|
+
* presented as product-shaped. `entryType` discriminates between the two
|
|
29
|
+
* row shapes (`"product"` vs `"source"`). `kind` carries the entity
|
|
30
|
+
* taxonomy (platform/sdk/mobile/…). `entryType` (not `type`) because
|
|
31
|
+
* source rows already carry `type: github|scrape|feed|agent` on the wire.
|
|
31
32
|
*/
|
|
32
33
|
export const SearchCatalogHitSchema = z.object({
|
|
33
34
|
slug: z.string(),
|
|
@@ -41,7 +42,8 @@ export const SearchCatalogHitSchema = z.object({
|
|
|
41
42
|
// that haven't been migrated yet. Tighten once #689 (category overlay
|
|
42
43
|
// backfill) lands across the prod data set.
|
|
43
44
|
category: z.string().nullable(),
|
|
44
|
-
|
|
45
|
+
entryType: z.enum(["product", "source"]),
|
|
46
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
45
47
|
sourceSlug: z.string().optional(),
|
|
46
48
|
sourceType: SourceTypeSchema.optional(),
|
|
47
49
|
});
|
package/src/schemas/sources.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
SOURCE_DISCOVERY,
|
|
5
5
|
SOURCE_FETCH_PRIORITIES,
|
|
6
6
|
} from "@buildinternet/releases-core/source-enums";
|
|
7
|
+
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
7
8
|
import { ListResponseSchema, ReleaseItemSchema, ReleaseSummaryItemSchema } from "./shared.js";
|
|
8
9
|
|
|
9
10
|
export const SourceTypeSchema = z.enum(SOURCE_TYPES);
|
|
@@ -48,6 +49,7 @@ export const SourceListItemSchema = z.object({
|
|
|
48
49
|
metadata: z.string().nullable().optional(),
|
|
49
50
|
productName: z.string().nullable().optional(),
|
|
50
51
|
productSlug: z.string().nullable().optional(),
|
|
52
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
51
53
|
});
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -81,6 +83,7 @@ export const SourceWithOrgSchema = z.object({
|
|
|
81
83
|
nextFetchAfter: z.string().nullable(),
|
|
82
84
|
medianGapDays: z.number().nullable(),
|
|
83
85
|
lastRetieredAt: z.string().nullable(),
|
|
86
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
84
87
|
});
|
|
85
88
|
|
|
86
89
|
export const SourceListResponseSchema = ListResponseSchema(SourceWithOrgSchema);
|
|
@@ -157,6 +160,7 @@ export const SourceDetailSchema = z.object({
|
|
|
157
160
|
releases: z.array(ReleaseItemSchema),
|
|
158
161
|
pagination: SourceFeedPaginationSchema,
|
|
159
162
|
summaries: SourceDetailSummariesSchema,
|
|
163
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
160
164
|
});
|
|
161
165
|
|
|
162
166
|
/**
|
|
@@ -187,6 +191,7 @@ export const SourceMutationResponseSchema = z.looseObject({
|
|
|
187
191
|
isHidden: z.boolean().nullable().optional(),
|
|
188
192
|
discovery: SourceDiscoverySchema.optional(),
|
|
189
193
|
createdAt: z.string().optional(),
|
|
194
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
190
195
|
});
|
|
191
196
|
|
|
192
197
|
/** Body accepted by `PATCH /v1/sources/:slug`. */
|
|
@@ -208,6 +213,7 @@ export const SourcePatchInputSchema = z.object({
|
|
|
208
213
|
isHidden: z.boolean().optional(),
|
|
209
214
|
changeDetectedAt: z.string().nullable().optional(),
|
|
210
215
|
lastPolledAt: z.string().nullable().optional(),
|
|
216
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
211
217
|
});
|
|
212
218
|
|
|
213
219
|
/** Body accepted by `POST /v1/sources`. */
|
|
@@ -228,6 +234,7 @@ export const CreateSourceBodySchema = z.object({
|
|
|
228
234
|
productSlug: z.string().optional(),
|
|
229
235
|
metadata: z.string().optional(),
|
|
230
236
|
isPrimary: z.boolean().optional(),
|
|
237
|
+
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
231
238
|
});
|
|
232
239
|
|
|
233
240
|
export const ChangelogFileSummarySchema = z.object({
|