@buildinternet/releases-api-types 0.28.0 → 0.30.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 +7 -0
- package/src/schemas/orgs.ts +16 -0
- package/src/schemas/products.ts +3 -1
- package/src/schemas/shared.notice.test.ts +36 -0
- package/src/schemas/shared.ts +21 -0
- package/src/schemas/sources.ts +8 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buildinternet/releases-api-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.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.23.0",
|
|
21
21
|
"zod": "^4.4.3"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
package/src/api-types.ts
CHANGED
|
@@ -32,6 +32,8 @@ import type {
|
|
|
32
32
|
OrgTagsResponseSchema,
|
|
33
33
|
CreateOrgBodySchema,
|
|
34
34
|
UpdateOrgBodySchema,
|
|
35
|
+
SetOrgAvatarBodySchema,
|
|
36
|
+
SetOrgAvatarResponseSchema,
|
|
35
37
|
OrgDetailSchema,
|
|
36
38
|
OrgCatalogItemSchema,
|
|
37
39
|
OrgCatalogResponseSchema,
|
|
@@ -250,6 +252,7 @@ export {
|
|
|
250
252
|
OverviewPageItemSchema,
|
|
251
253
|
OverviewCitationSchema,
|
|
252
254
|
CategorySchema,
|
|
255
|
+
NoticeSchema,
|
|
253
256
|
} from "./schemas/shared.js";
|
|
254
257
|
export {
|
|
255
258
|
OrgListItemSchema,
|
|
@@ -259,6 +262,8 @@ export {
|
|
|
259
262
|
OrgTagsResponseSchema,
|
|
260
263
|
CreateOrgBodySchema,
|
|
261
264
|
UpdateOrgBodySchema,
|
|
265
|
+
SetOrgAvatarBodySchema,
|
|
266
|
+
SetOrgAvatarResponseSchema,
|
|
262
267
|
OrgDetailSchema,
|
|
263
268
|
OrgCatalogItemSchema,
|
|
264
269
|
OrgCatalogResponseSchema,
|
|
@@ -514,6 +519,8 @@ export type OrgAccountsResponse = z.infer<typeof OrgAccountsResponseSchema>;
|
|
|
514
519
|
export type OrgTagsResponse = z.infer<typeof OrgTagsResponseSchema>;
|
|
515
520
|
export type CreateOrgBody = z.infer<typeof CreateOrgBodySchema>;
|
|
516
521
|
export type UpdateOrgBody = z.infer<typeof UpdateOrgBodySchema>;
|
|
522
|
+
export type SetOrgAvatarBody = z.infer<typeof SetOrgAvatarBodySchema>;
|
|
523
|
+
export type SetOrgAvatarResponse = z.infer<typeof SetOrgAvatarResponseSchema>;
|
|
517
524
|
export type OrgDetail = z.infer<typeof OrgDetailSchema>;
|
|
518
525
|
|
|
519
526
|
export type OrgCatalogItem = z.infer<typeof OrgCatalogItemSchema>;
|
package/src/schemas/orgs.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
AppStoreSourceInfoSchema,
|
|
5
5
|
CategorySchema,
|
|
6
6
|
ListResponseSchema,
|
|
7
|
+
NoticeSchema,
|
|
7
8
|
OverviewPageItemSchema,
|
|
8
9
|
PaginationSchema,
|
|
9
10
|
ReleaseItemSchema,
|
|
@@ -114,6 +115,20 @@ export const UpdateOrgBodySchema = z.object({
|
|
|
114
115
|
featured: z.boolean().optional(),
|
|
115
116
|
/** Admin-only: promote or demote the org's discovery status (curated/agent/on_demand). */
|
|
116
117
|
discovery: z.enum(["curated", "agent", "on_demand"]).optional(),
|
|
118
|
+
notice: NoticeSchema.nullable().optional(),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
/** Body for `POST /v1/orgs/:slug/avatar` — the remote image to mirror to R2 (#1406). */
|
|
122
|
+
export const SetOrgAvatarBodySchema = z.object({
|
|
123
|
+
sourceUrl: z.url(),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/** Response for `POST /v1/orgs/:slug/avatar` — the mirrored avatar's public URL + dims. */
|
|
127
|
+
export const SetOrgAvatarResponseSchema = z.object({
|
|
128
|
+
avatarUrl: z.string(),
|
|
129
|
+
key: z.string(),
|
|
130
|
+
width: z.number(),
|
|
131
|
+
height: z.number(),
|
|
117
132
|
});
|
|
118
133
|
|
|
119
134
|
// Org detail's products query selects a strict subset of `ProductListItem` —
|
|
@@ -455,4 +470,5 @@ export const OrgDetailSchema = z.object({
|
|
|
455
470
|
sources: z.array(SourceListItemSchema),
|
|
456
471
|
overview: OverviewPageItemSchema.nullable().optional(),
|
|
457
472
|
playbook: OrgDetailPlaybookSchema.nullable().optional(),
|
|
473
|
+
notice: NoticeSchema.nullable().optional(),
|
|
458
474
|
});
|
package/src/schemas/products.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
3
|
-
import { CategorySchema, ListResponseSchema, ReleaseItemSchema } from "./shared.js";
|
|
3
|
+
import { CategorySchema, ListResponseSchema, NoticeSchema, ReleaseItemSchema } from "./shared.js";
|
|
4
4
|
import { SourceTypeSchema, SourceFeedPaginationSchema } from "./sources.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -89,6 +89,7 @@ export const ProductDetailSchema = ProductRowSchema.extend({
|
|
|
89
89
|
releases: z.array(ReleaseItemSchema).optional(),
|
|
90
90
|
/** Cursor pagination for the embedded release feed — set by the web format adapter (PR #1207), absent on bare product detail. */
|
|
91
91
|
pagination: SourceFeedPaginationSchema.optional(),
|
|
92
|
+
notice: NoticeSchema.nullable().optional(),
|
|
92
93
|
});
|
|
93
94
|
|
|
94
95
|
/**
|
|
@@ -125,6 +126,7 @@ export const UpdateProductBodySchema = z.object({
|
|
|
125
126
|
aliases: z.array(z.string()).optional(),
|
|
126
127
|
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
127
128
|
avatarUrl: z.string().nullable().optional(),
|
|
129
|
+
notice: NoticeSchema.nullable().optional(),
|
|
128
130
|
});
|
|
129
131
|
|
|
130
132
|
/**
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { NoticeSchema } from "./shared";
|
|
3
|
+
|
|
4
|
+
describe("NoticeSchema", () => {
|
|
5
|
+
it("accepts a message-only notice", () => {
|
|
6
|
+
expect(NoticeSchema.safeParse({ message: "Heads up" }).success).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
it("accepts a message + internal coordinate", () => {
|
|
9
|
+
expect(
|
|
10
|
+
NoticeSchema.safeParse({
|
|
11
|
+
message: "Moved",
|
|
12
|
+
coordinate: "cognition/devin",
|
|
13
|
+
linkText: "View Devin",
|
|
14
|
+
}).success,
|
|
15
|
+
).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
it("accepts a message + external href", () => {
|
|
18
|
+
expect(NoticeSchema.safeParse({ message: "Moved", href: "https://devin.ai" }).success).toBe(
|
|
19
|
+
true,
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
it("rejects both coordinate and href", () => {
|
|
23
|
+
expect(
|
|
24
|
+
NoticeSchema.safeParse({ message: "x", coordinate: "a/b", href: "https://x.com" }).success,
|
|
25
|
+
).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
it("rejects an empty message and an over-long message", () => {
|
|
28
|
+
expect(NoticeSchema.safeParse({ message: "" }).success).toBe(false);
|
|
29
|
+
expect(NoticeSchema.safeParse({ message: "x".repeat(281) }).success).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
it("rejects a malformed coordinate", () => {
|
|
32
|
+
expect(NoticeSchema.safeParse({ message: "x", coordinate: "/leading" }).success).toBe(false);
|
|
33
|
+
expect(NoticeSchema.safeParse({ message: "x", coordinate: "a/b/c" }).success).toBe(false);
|
|
34
|
+
expect(NoticeSchema.safeParse({ message: "x", coordinate: "" }).success).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|
package/src/schemas/shared.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { RELEASE_TYPES } from "@buildinternet/releases-core/schema";
|
|
3
3
|
import { CATEGORIES } from "@buildinternet/releases-core/categories";
|
|
4
|
+
import { isValidNoticeCoordinate } from "@buildinternet/releases-core/notice";
|
|
4
5
|
|
|
5
6
|
export const CategorySchema = z.enum(CATEGORIES);
|
|
6
7
|
|
|
@@ -150,6 +151,26 @@ export const OverviewCitationSchema = z.object({
|
|
|
150
151
|
releaseId: z.string().nullable().optional(),
|
|
151
152
|
});
|
|
152
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Entity notice — a small curator-set note on an org / product / source. Stored
|
|
156
|
+
* under the `notice` key of the entity's metadata JSON; mirrors the `Notice`
|
|
157
|
+
* type in @buildinternet/releases-core/notice. `coordinate` is an internal
|
|
158
|
+
* registry path ("org" / "org/slug"); `href` is an external URL; at most one.
|
|
159
|
+
*/
|
|
160
|
+
export const NoticeSchema = z
|
|
161
|
+
.object({
|
|
162
|
+
message: z.string().min(1).max(280),
|
|
163
|
+
linkText: z.string().min(1).max(60).optional(),
|
|
164
|
+
coordinate: z.string().min(1).max(200).optional(),
|
|
165
|
+
href: z.url().max(500).optional(),
|
|
166
|
+
})
|
|
167
|
+
.refine((n) => !(n.coordinate && n.href), {
|
|
168
|
+
message: "notice may set coordinate or href, not both",
|
|
169
|
+
})
|
|
170
|
+
.refine((n) => !n.coordinate || isValidNoticeCoordinate(n.coordinate), {
|
|
171
|
+
message: "notice.coordinate must be 'org' or 'org/slug'",
|
|
172
|
+
});
|
|
173
|
+
|
|
153
174
|
export const OverviewPageItemSchema = z.object({
|
|
154
175
|
scope: z.enum(["org", "product"]),
|
|
155
176
|
orgSlug: z.string().nullable().optional(),
|
package/src/schemas/sources.ts
CHANGED
|
@@ -5,7 +5,12 @@ import {
|
|
|
5
5
|
SOURCE_FETCH_PRIORITIES,
|
|
6
6
|
} from "@buildinternet/releases-core/source-enums";
|
|
7
7
|
import { KIND_VALUES } from "@buildinternet/releases-core/kinds";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ListResponseSchema,
|
|
10
|
+
NoticeSchema,
|
|
11
|
+
ReleaseItemSchema,
|
|
12
|
+
ReleaseSummaryItemSchema,
|
|
13
|
+
} from "./shared.js";
|
|
9
14
|
|
|
10
15
|
export const SourceTypeSchema = z.enum(SOURCE_TYPES);
|
|
11
16
|
export const SourceDiscoverySchema = z.enum(SOURCE_DISCOVERY);
|
|
@@ -176,6 +181,7 @@ export const SourceDetailSchema = z.object({
|
|
|
176
181
|
// carry `null`. Consumers treat null/undefined as "unknown".
|
|
177
182
|
stars: z.number().int().min(0).nullable().optional(),
|
|
178
183
|
starsFetchedAt: z.string().nullable().optional(),
|
|
184
|
+
notice: NoticeSchema.nullable().optional(),
|
|
179
185
|
});
|
|
180
186
|
|
|
181
187
|
/**
|
|
@@ -263,6 +269,7 @@ export const SourcePatchInputSchema = z.object({
|
|
|
263
269
|
kind: z.enum(KIND_VALUES).nullable().optional(),
|
|
264
270
|
/** Admin-only: promote or demote the source's discovery status (curated/agent/on_demand). */
|
|
265
271
|
discovery: SourceDiscoverySchema.optional(),
|
|
272
|
+
notice: NoticeSchema.nullable().optional(),
|
|
266
273
|
});
|
|
267
274
|
|
|
268
275
|
/** Body accepted by `POST /v1/sources`. */
|