@storyshelf/core 0.1.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 +127 -0
- package/dist/adapter/auth.d.mts +50 -0
- package/dist/adapter/auth.mjs +10 -0
- package/dist/adapter/auth.mjs.map +1 -0
- package/dist/adapter/capture-runner.d.mts +70 -0
- package/dist/adapter/capture-runner.mjs +4 -0
- package/dist/adapter/database.d.mts +43 -0
- package/dist/adapter/database.mjs +4 -0
- package/dist/adapter/git-host/helpers.d.mts +12 -0
- package/dist/adapter/git-host/helpers.mjs +29 -0
- package/dist/adapter/git-host/helpers.mjs.map +1 -0
- package/dist/adapter/git-host.d.mts +46 -0
- package/dist/adapter/git-host.mjs +4 -0
- package/dist/adapter/storage.d.mts +22 -0
- package/dist/adapter/storage.mjs +4 -0
- package/dist/adapters/capture-queue.d.mts +49 -0
- package/dist/adapters/metadata.d.mts +24 -0
- package/dist/adapters/webhook-events.mjs +39 -0
- package/dist/adapters/webhook-events.mjs.map +1 -0
- package/dist/capture/adapter.d.mts +29 -0
- package/dist/capture/adapter.mjs +13 -0
- package/dist/capture/adapter.mjs.map +1 -0
- package/dist/capture/orchestrator.d.mts +23 -0
- package/dist/capture/orchestrator.mjs +103 -0
- package/dist/capture/orchestrator.mjs.map +1 -0
- package/dist/capture/pipeline.d.mts +41 -0
- package/dist/capture/pipeline.mjs +119 -0
- package/dist/capture/pipeline.mjs.map +1 -0
- package/dist/capture/queue.d.mts +35 -0
- package/dist/capture/queue.mjs +96 -0
- package/dist/capture/queue.mjs.map +1 -0
- package/dist/capture/status-fanout.mjs +66 -0
- package/dist/capture/status-fanout.mjs.map +1 -0
- package/dist/capture/storybook.d.mts +14 -0
- package/dist/capture/storybook.mjs +40 -0
- package/dist/capture/storybook.mjs.map +1 -0
- package/dist/config.d.mts +68 -0
- package/dist/config.mjs +69 -0
- package/dist/config.mjs.map +1 -0
- package/dist/ddl.d.mts +7 -0
- package/dist/ddl.mjs +155 -0
- package/dist/ddl.mjs.map +1 -0
- package/dist/diff/engine.d.mts +8 -0
- package/dist/diff/engine.mjs +79 -0
- package/dist/diff/engine.mjs.map +1 -0
- package/dist/diff/options.d.mts +40 -0
- package/dist/diff/options.mjs +15 -0
- package/dist/diff/options.mjs.map +1 -0
- package/dist/index.d.mts +48 -0
- package/dist/index.mjs +327 -0
- package/dist/index.mjs.map +1 -0
- package/dist/logger.d.mts +39 -0
- package/dist/logger.mjs +35 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/middleware/csrf.mjs +39 -0
- package/dist/middleware/csrf.mjs.map +1 -0
- package/dist/middleware/rate-limit.mjs +38 -0
- package/dist/middleware/rate-limit.mjs.map +1 -0
- package/dist/models/baseline.d.mts +20 -0
- package/dist/models/baseline.mjs +89 -0
- package/dist/models/baseline.mjs.map +1 -0
- package/dist/models/build.d.mts +35 -0
- package/dist/models/build.mjs +77 -0
- package/dist/models/build.mjs.map +1 -0
- package/dist/models/comment.d.mts +20 -0
- package/dist/models/comment.mjs +42 -0
- package/dist/models/comment.mjs.map +1 -0
- package/dist/models/label.d.mts +43 -0
- package/dist/models/label.mjs +107 -0
- package/dist/models/label.mjs.map +1 -0
- package/dist/models/member.d.mts +27 -0
- package/dist/models/member.mjs +54 -0
- package/dist/models/member.mjs.map +1 -0
- package/dist/models/project.d.mts +42 -0
- package/dist/models/project.mjs +78 -0
- package/dist/models/project.mjs.map +1 -0
- package/dist/models/snapshot.d.mts +46 -0
- package/dist/models/snapshot.mjs +75 -0
- package/dist/models/snapshot.mjs.map +1 -0
- package/dist/models/status-config.mjs +61 -0
- package/dist/models/status-config.mjs.map +1 -0
- package/dist/models/token.d.mts +33 -0
- package/dist/models/token.mjs +60 -0
- package/dist/models/token.mjs.map +1 -0
- package/dist/models/webhook.d.mts +37 -0
- package/dist/models/webhook.mjs +67 -0
- package/dist/models/webhook.mjs.map +1 -0
- package/dist/pages/build-detail.mjs +333 -0
- package/dist/pages/build-detail.mjs.map +1 -0
- package/dist/pages/build-diff.mjs +437 -0
- package/dist/pages/build-diff.mjs.map +1 -0
- package/dist/pages/compute-jobs.mjs +196 -0
- package/dist/pages/compute-jobs.mjs.map +1 -0
- package/dist/pages/login.mjs +77 -0
- package/dist/pages/login.mjs.map +1 -0
- package/dist/pages/project-builds.mjs +228 -0
- package/dist/pages/project-builds.mjs.map +1 -0
- package/dist/pages/project-create.mjs +168 -0
- package/dist/pages/project-create.mjs.map +1 -0
- package/dist/pages/project-settings.mjs +111 -0
- package/dist/pages/project-settings.mjs.map +1 -0
- package/dist/pages/projects.mjs +178 -0
- package/dist/pages/projects.mjs.map +1 -0
- package/dist/pages/root.mjs +90 -0
- package/dist/pages/root.mjs.map +1 -0
- package/dist/pages/settings-general.mjs +191 -0
- package/dist/pages/settings-general.mjs.map +1 -0
- package/dist/pages/settings-labels.mjs +149 -0
- package/dist/pages/settings-labels.mjs.map +1 -0
- package/dist/pages/settings-members.mjs +124 -0
- package/dist/pages/settings-members.mjs.map +1 -0
- package/dist/pages/settings-status.mjs +150 -0
- package/dist/pages/settings-status.mjs.map +1 -0
- package/dist/pages/settings-tokens.mjs +95 -0
- package/dist/pages/settings-tokens.mjs.map +1 -0
- package/dist/pages/settings-webhooks.mjs +149 -0
- package/dist/pages/settings-webhooks.mjs.map +1 -0
- package/dist/retention/purge.d.mts +28 -0
- package/dist/retention/purge.mjs +66 -0
- package/dist/retention/purge.mjs.map +1 -0
- package/dist/routers/admin.mjs +41 -0
- package/dist/routers/admin.mjs.map +1 -0
- package/dist/routers/assets.mjs +24 -0
- package/dist/routers/assets.mjs.map +1 -0
- package/dist/routers/auth.mjs +77 -0
- package/dist/routers/auth.mjs.map +1 -0
- package/dist/routers/builds.handlers.mjs +87 -0
- package/dist/routers/builds.handlers.mjs.map +1 -0
- package/dist/routers/builds.mjs +162 -0
- package/dist/routers/builds.mjs.map +1 -0
- package/dist/routers/comments.mjs +89 -0
- package/dist/routers/comments.mjs.map +1 -0
- package/dist/routers/helpers.mjs +76 -0
- package/dist/routers/helpers.mjs.map +1 -0
- package/dist/routers/htmx.mjs +18 -0
- package/dist/routers/htmx.mjs.map +1 -0
- package/dist/routers/labels.mjs +77 -0
- package/dist/routers/labels.mjs.map +1 -0
- package/dist/routers/media.mjs +54 -0
- package/dist/routers/media.mjs.map +1 -0
- package/dist/routers/members.mjs +101 -0
- package/dist/routers/members.mjs.map +1 -0
- package/dist/routers/projects.mjs +121 -0
- package/dist/routers/projects.mjs.map +1 -0
- package/dist/routers/schemas.mjs +188 -0
- package/dist/routers/schemas.mjs.map +1 -0
- package/dist/routers/settings.mjs +235 -0
- package/dist/routers/settings.mjs.map +1 -0
- package/dist/routers/snapshots.mjs +143 -0
- package/dist/routers/snapshots.mjs.map +1 -0
- package/dist/routers/status-configs.mjs +100 -0
- package/dist/routers/status-configs.mjs.map +1 -0
- package/dist/routers/tokens.mjs +80 -0
- package/dist/routers/tokens.mjs.map +1 -0
- package/dist/routers/ui.mjs +142 -0
- package/dist/routers/ui.mjs.map +1 -0
- package/dist/routers/webhooks.mjs +89 -0
- package/dist/routers/webhooks.mjs.map +1 -0
- package/dist/schema.d.mts +4372 -0
- package/dist/schema.mjs +158 -0
- package/dist/schema.mjs.map +1 -0
- package/dist/store.mjs +18 -0
- package/dist/store.mjs.map +1 -0
- package/dist/types.d.mts +18 -0
- package/dist/types.mjs +49 -0
- package/dist/types.mjs.map +1 -0
- package/dist/ui/components.mjs +127 -0
- package/dist/ui/components.mjs.map +1 -0
- package/dist/ui/document.d.mts +8 -0
- package/dist/ui/document.mjs +338 -0
- package/dist/ui/document.mjs.map +1 -0
- package/dist/ui/styles.mjs +173 -0
- package/dist/ui/styles.mjs.map +1 -0
- package/dist/ui/theme.mjs +42 -0
- package/dist/ui/theme.mjs.map +1 -0
- package/dist/urls.d.mts +19 -0
- package/dist/urls.mjs +23 -0
- package/dist/urls.mjs.map +1 -0
- package/dist/utils/encrypt.mjs +49 -0
- package/dist/utils/encrypt.mjs.map +1 -0
- package/dist/utils/hash.mjs +22 -0
- package/dist/utils/hash.mjs.map +1 -0
- package/dist/utils/paths.d.mts +11 -0
- package/dist/utils/paths.mjs +23 -0
- package/dist/utils/paths.mjs.map +1 -0
- package/dist/utils/ulid.d.mts +8 -0
- package/dist/utils/ulid.mjs +41 -0
- package/dist/utils/ulid.mjs.map +1 -0
- package/package.json +162 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.mjs","names":[],"sources":["../../src/routers/media.ts"],"sourcesContent":["import type { ShelfApp } from \"../index.tsx\";\n\nimport { BaselineModel } from \"../models/baseline.ts\";\nimport { BuildModel } from \"../models/build.ts\";\nimport { SnapshotModel } from \"../models/snapshot.ts\";\nimport { getStore } from \"../store.ts\";\nimport type { Snapshot } from \"../schema.ts\";\nimport type { ProjectRole } from \"../types.ts\";\nimport { notFound, resolveAuthorizedProject } from \"./helpers.ts\";\n\nconst VIEW_ROLES: readonly ProjectRole[] = [\"viewer\", \"developer\", \"approver\", \"admin\"];\n\nconst PNG = \"image/png\";\n\nfunction imageResponse(buffer: Buffer): Response {\n return new Response(new Uint8Array(buffer), { headers: { \"content-type\": PNG, \"cache-control\": \"private, max-age=3600\" } });\n}\n\nexport function registerMedia(app: ShelfApp): void {\n app.get(\"/api/v1/projects/:slug/builds/:buildId/snapshots/:snapshotId/image\", async (c) => {\n const project = await resolveAuthorizedProject(c, c.req.param(\"slug\"), ...VIEW_ROLES);\n const snapshot = await findSnapshot(c.req.param(\"buildId\"), c.req.param(\"snapshotId\"), project.id);\n return imageResponse(await getStore().storage.read(snapshot.screenshotPath));\n });\n\n app.get(\"/api/v1/projects/:slug/builds/:buildId/snapshots/:snapshotId/diff\", async (c) => {\n const project = await resolveAuthorizedProject(c, c.req.param(\"slug\"), ...VIEW_ROLES);\n const snapshot = await findSnapshot(c.req.param(\"buildId\"), c.req.param(\"snapshotId\"), project.id);\n if (!snapshot.diffPath) {\n notFound(\"No diff for this snapshot\");\n }\n return imageResponse(await getStore().storage.read(snapshot.diffPath));\n });\n\n app.get(\"/api/v1/projects/:slug/builds/:buildId/snapshots/:snapshotId/baseline\", async (c) => {\n const project = await resolveAuthorizedProject(c, c.req.param(\"slug\"), ...VIEW_ROLES);\n const snapshot = await findSnapshot(c.req.param(\"buildId\"), c.req.param(\"snapshotId\"), project.id);\n const build = await new BuildModel(getStore().db).get(snapshot.buildId);\n if (!build) {\n notFound(\"Build not found\");\n }\n const baselines = new BaselineModel(getStore().db, getStore().storage);\n const baseline = await baselines.resolve(project.id, snapshot.storyId, snapshot.viewportName, build.gitBranch, project.gitDefaultBranch);\n if (!baseline) {\n notFound(\"No baseline for this snapshot\");\n }\n return imageResponse(await baselines.read(baseline));\n });\n}\n\nasync function findSnapshot(buildId: string, snapshotId: string, projectId: string): Promise<Snapshot> {\n const snapshot = await new SnapshotModel(getStore().db).get(snapshotId);\n if (!snapshot || snapshot.buildId !== buildId || snapshot.projectId !== projectId) {\n notFound(\"Snapshot not found\");\n }\n return snapshot;\n}"],"mappings":";;;;;;;;;AAUA,MAAM,aAAqC;CAAC;CAAU;CAAa;CAAY;AAAO;AAEtF,MAAM,MAAM;AAEZ,SAAS,cAAc,QAA0B;CAC/C,OAAO,IAAI,SAAS,IAAI,WAAW,MAAM,GAAG,EAAE,SAAS;EAAE,gBAAgB;EAAK,iBAAiB;CAAwB,EAAE,CAAC;AAC5H;AAEA,SAAgB,cAAc,KAAqB;CACjD,IAAI,IAAI,sEAAsE,OAAO,MAAM;EACzF,MAAM,UAAU,MAAM,yBAAyB,GAAG,EAAE,IAAI,MAAM,MAAM,GAAG,GAAG,UAAU;EACpF,MAAM,WAAW,MAAM,aAAa,EAAE,IAAI,MAAM,SAAS,GAAG,EAAE,IAAI,MAAM,YAAY,GAAG,QAAQ,EAAE;EACjG,OAAO,cAAc,MAAM,SAAS,CAAC,CAAC,QAAQ,KAAK,SAAS,cAAc,CAAC;CAC7E,CAAC;CAED,IAAI,IAAI,qEAAqE,OAAO,MAAM;EACxF,MAAM,UAAU,MAAM,yBAAyB,GAAG,EAAE,IAAI,MAAM,MAAM,GAAG,GAAG,UAAU;EACpF,MAAM,WAAW,MAAM,aAAa,EAAE,IAAI,MAAM,SAAS,GAAG,EAAE,IAAI,MAAM,YAAY,GAAG,QAAQ,EAAE;EACjG,IAAI,CAAC,SAAS,UACZ,SAAS,2BAA2B;EAEtC,OAAO,cAAc,MAAM,SAAS,CAAC,CAAC,QAAQ,KAAK,SAAS,QAAQ,CAAC;CACvE,CAAC;CAED,IAAI,IAAI,yEAAyE,OAAO,MAAM;EAC5F,MAAM,UAAU,MAAM,yBAAyB,GAAG,EAAE,IAAI,MAAM,MAAM,GAAG,GAAG,UAAU;EACpF,MAAM,WAAW,MAAM,aAAa,EAAE,IAAI,MAAM,SAAS,GAAG,EAAE,IAAI,MAAM,YAAY,GAAG,QAAQ,EAAE;EACjG,MAAM,QAAQ,MAAM,IAAI,WAAW,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,OAAO;EACtE,IAAI,CAAC,OACH,SAAS,iBAAiB;EAE5B,MAAM,YAAY,IAAI,cAAc,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,OAAO;EACrE,MAAM,WAAW,MAAM,UAAU,QAAQ,QAAQ,IAAI,SAAS,SAAS,SAAS,cAAc,MAAM,WAAW,QAAQ,gBAAgB;EACvI,IAAI,CAAC,UACH,SAAS,+BAA+B;EAE1C,OAAO,cAAc,MAAM,UAAU,KAAK,QAAQ,CAAC;CACrD,CAAC;AACH;AAEA,eAAe,aAAa,SAAiB,YAAoB,WAAsC;CACrG,MAAM,WAAW,MAAM,IAAI,cAAc,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,UAAU;CACtE,IAAI,CAAC,YAAY,SAAS,YAAY,WAAW,SAAS,cAAc,WACtE,SAAS,oBAAoB;CAE/B,OAAO;AACT"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { getStore } from "../store.mjs";
|
|
5
|
+
import { MemberModel } from "../models/member.mjs";
|
|
6
|
+
import { resolveAuthorizedProject } from "./helpers.mjs";
|
|
7
|
+
import { memberRoleSchema, memberSchema, memberSetSchema, notFound, unauthorized } from "./schemas.mjs";
|
|
8
|
+
import { createRoute, z } from "@hono/zod-openapi";
|
|
9
|
+
//#region src/routers/members.ts
|
|
10
|
+
const VIEW_ROLES = [
|
|
11
|
+
"viewer",
|
|
12
|
+
"developer",
|
|
13
|
+
"approver",
|
|
14
|
+
"admin"
|
|
15
|
+
];
|
|
16
|
+
const ADMIN_ROLES = ["admin"];
|
|
17
|
+
const listMembersRoute = createRoute({
|
|
18
|
+
method: "get",
|
|
19
|
+
path: "/api/v1/projects/{slug}/members",
|
|
20
|
+
request: { params: z.object({ slug: z.string() }) },
|
|
21
|
+
responses: {
|
|
22
|
+
200: {
|
|
23
|
+
content: { "application/json": { schema: memberSchema.array() } },
|
|
24
|
+
description: "List project members"
|
|
25
|
+
},
|
|
26
|
+
...notFound,
|
|
27
|
+
...unauthorized
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const setMemberRoute = createRoute({
|
|
31
|
+
method: "post",
|
|
32
|
+
path: "/api/v1/projects/{slug}/members",
|
|
33
|
+
request: {
|
|
34
|
+
params: z.object({ slug: z.string() }),
|
|
35
|
+
body: { content: { "application/json": { schema: memberSetSchema } } }
|
|
36
|
+
},
|
|
37
|
+
responses: {
|
|
38
|
+
201: {
|
|
39
|
+
content: { "application/json": { schema: memberSchema } },
|
|
40
|
+
description: "Added or updated member"
|
|
41
|
+
},
|
|
42
|
+
...notFound
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const updateMemberRoute = createRoute({
|
|
46
|
+
method: "patch",
|
|
47
|
+
path: "/api/v1/projects/{slug}/members/{userId}",
|
|
48
|
+
request: {
|
|
49
|
+
params: z.object({
|
|
50
|
+
slug: z.string(),
|
|
51
|
+
userId: z.string()
|
|
52
|
+
}),
|
|
53
|
+
body: { content: { "application/json": { schema: memberRoleSchema } } }
|
|
54
|
+
},
|
|
55
|
+
responses: {
|
|
56
|
+
200: {
|
|
57
|
+
content: { "application/json": { schema: memberSchema } },
|
|
58
|
+
description: "Updated member role"
|
|
59
|
+
},
|
|
60
|
+
...notFound
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const deleteMemberRoute = createRoute({
|
|
64
|
+
method: "delete",
|
|
65
|
+
path: "/api/v1/projects/{slug}/members/{userId}",
|
|
66
|
+
request: { params: z.object({
|
|
67
|
+
slug: z.string(),
|
|
68
|
+
userId: z.string()
|
|
69
|
+
}) },
|
|
70
|
+
responses: {
|
|
71
|
+
204: { description: "Removed member" },
|
|
72
|
+
...notFound
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
function registerMembers(app) {
|
|
76
|
+
app.openapi(listMembersRoute, async (c) => {
|
|
77
|
+
const project = await resolveAuthorizedProject(c, c.req.valid("param").slug, ...VIEW_ROLES);
|
|
78
|
+
return c.json(await new MemberModel(getStore().db).list(project.id));
|
|
79
|
+
});
|
|
80
|
+
app.openapi(setMemberRoute, async (c) => {
|
|
81
|
+
const project = await resolveAuthorizedProject(c, c.req.valid("param").slug, ...ADMIN_ROLES);
|
|
82
|
+
const body = c.req.valid("json");
|
|
83
|
+
return c.json(await new MemberModel(getStore().db).set(project.id, body.userId, body.role), 201);
|
|
84
|
+
});
|
|
85
|
+
app.openapi(updateMemberRoute, async (c) => {
|
|
86
|
+
const { slug, userId } = c.req.valid("param");
|
|
87
|
+
const project = await resolveAuthorizedProject(c, slug, ...ADMIN_ROLES);
|
|
88
|
+
const body = c.req.valid("json");
|
|
89
|
+
return c.json(await new MemberModel(getStore().db).set(project.id, userId, body.role));
|
|
90
|
+
});
|
|
91
|
+
app.openapi(deleteMemberRoute, async (c) => {
|
|
92
|
+
const { slug, userId } = c.req.valid("param");
|
|
93
|
+
const project = await resolveAuthorizedProject(c, slug, ...ADMIN_ROLES);
|
|
94
|
+
await new MemberModel(getStore().db).remove(project.id, userId);
|
|
95
|
+
return c.body(null, 204);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { registerMembers };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=members.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"members.mjs","names":[],"sources":["../../src/routers/members.ts"],"sourcesContent":["import { createRoute, z } from \"@hono/zod-openapi\";\nimport type { ShelfApp } from \"../index.tsx\";\n\nimport { MemberModel } from \"../models/member.ts\";\nimport { getStore } from \"../store.ts\";\nimport type { ProjectRole } from \"../types.ts\";\nimport { resolveAuthorizedProject } from \"./helpers.ts\";\nimport { memberRoleSchema, memberSchema, memberSetSchema, notFound, unauthorized } from \"./schemas.ts\";\n\nconst VIEW_ROLES: readonly ProjectRole[] = [\"viewer\", \"developer\", \"approver\", \"admin\"];\nconst ADMIN_ROLES: readonly ProjectRole[] = [\"admin\"];\n\nconst listMembersRoute = createRoute({\n method: \"get\",\n path: \"/api/v1/projects/{slug}/members\",\n request: { params: z.object({ slug: z.string() }) },\n responses: {\n 200: { content: { \"application/json\": { schema: memberSchema.array() } }, description: \"List project members\" },\n ...notFound,\n ...unauthorized,\n },\n});\n\nconst setMemberRoute = createRoute({\n method: \"post\",\n path: \"/api/v1/projects/{slug}/members\",\n request: {\n params: z.object({ slug: z.string() }),\n body: { content: { \"application/json\": { schema: memberSetSchema } } },\n },\n responses: {\n 201: { content: { \"application/json\": { schema: memberSchema } }, description: \"Added or updated member\" },\n ...notFound,\n },\n});\n\nconst updateMemberRoute = createRoute({\n method: \"patch\",\n path: \"/api/v1/projects/{slug}/members/{userId}\",\n request: {\n params: z.object({ slug: z.string(), userId: z.string() }),\n body: { content: { \"application/json\": { schema: memberRoleSchema } } },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: memberSchema } }, description: \"Updated member role\" },\n ...notFound,\n },\n});\n\nconst deleteMemberRoute = createRoute({\n method: \"delete\",\n path: \"/api/v1/projects/{slug}/members/{userId}\",\n request: { params: z.object({ slug: z.string(), userId: z.string() }) },\n responses: {\n 204: { description: \"Removed member\" },\n ...notFound,\n },\n});\n\nexport function registerMembers(app: ShelfApp): void {\n app.openapi(listMembersRoute, async (c) => {\n const project = await resolveAuthorizedProject(c, c.req.valid(\"param\").slug, ...VIEW_ROLES);\n return c.json(await new MemberModel(getStore().db).list(project.id));\n });\n\n app.openapi(setMemberRoute, async (c) => {\n const project = await resolveAuthorizedProject(c, c.req.valid(\"param\").slug, ...ADMIN_ROLES);\n const body = c.req.valid(\"json\");\n return c.json(await new MemberModel(getStore().db).set(project.id, body.userId, body.role), 201);\n });\n\n app.openapi(updateMemberRoute, async (c) => {\n const { slug, userId } = c.req.valid(\"param\");\n const project = await resolveAuthorizedProject(c, slug, ...ADMIN_ROLES);\n const body = c.req.valid(\"json\");\n return c.json(await new MemberModel(getStore().db).set(project.id, userId, body.role));\n });\n\n app.openapi(deleteMemberRoute, async (c) => {\n const { slug, userId } = c.req.valid(\"param\");\n const project = await resolveAuthorizedProject(c, slug, ...ADMIN_ROLES);\n await new MemberModel(getStore().db).remove(project.id, userId);\n return c.body(null, 204);\n });\n}"],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { ProjectModel } from "../models/project.mjs";
|
|
5
|
+
import { LabelModel } from "../models/label.mjs";
|
|
6
|
+
import { getStore } from "../store.mjs";
|
|
7
|
+
import { forbidden, requireSiteAdmin, resolveAuthorizedProject } from "./helpers.mjs";
|
|
8
|
+
import { badRequest, forbidden as forbidden$1, notFound, projectCreateSchema, projectSchema, projectUpdateSchema, unauthorized } from "./schemas.mjs";
|
|
9
|
+
import { createRoute, z } from "@hono/zod-openapi";
|
|
10
|
+
//#region src/routers/projects.ts
|
|
11
|
+
const VIEW_ROLES = [
|
|
12
|
+
"viewer",
|
|
13
|
+
"developer",
|
|
14
|
+
"approver",
|
|
15
|
+
"admin"
|
|
16
|
+
];
|
|
17
|
+
const ADMIN_ROLES = ["admin"];
|
|
18
|
+
function requireSessionUser() {
|
|
19
|
+
if (!getStore().authEnabled) return;
|
|
20
|
+
if (!getStore().user) forbidden();
|
|
21
|
+
}
|
|
22
|
+
const listProjectsRoute = createRoute({
|
|
23
|
+
method: "get",
|
|
24
|
+
path: "/api/v1/projects",
|
|
25
|
+
responses: {
|
|
26
|
+
200: {
|
|
27
|
+
content: { "application/json": { schema: projectSchema.array() } },
|
|
28
|
+
description: "List projects"
|
|
29
|
+
},
|
|
30
|
+
...unauthorized
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const createProjectRoute = createRoute({
|
|
34
|
+
method: "post",
|
|
35
|
+
path: "/api/v1/projects",
|
|
36
|
+
request: { body: { content: { "application/json": { schema: projectCreateSchema } } } },
|
|
37
|
+
responses: {
|
|
38
|
+
201: {
|
|
39
|
+
content: { "application/json": { schema: projectSchema } },
|
|
40
|
+
description: "Created project"
|
|
41
|
+
},
|
|
42
|
+
...badRequest,
|
|
43
|
+
...forbidden$1,
|
|
44
|
+
...unauthorized
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const getProjectRoute = createRoute({
|
|
48
|
+
method: "get",
|
|
49
|
+
path: "/api/v1/projects/{slug}",
|
|
50
|
+
request: { params: z.object({ slug: z.string() }) },
|
|
51
|
+
responses: {
|
|
52
|
+
200: {
|
|
53
|
+
content: { "application/json": { schema: projectSchema } },
|
|
54
|
+
description: "Fetch a project"
|
|
55
|
+
},
|
|
56
|
+
...notFound,
|
|
57
|
+
...unauthorized
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const updateProjectRoute = createRoute({
|
|
61
|
+
method: "patch",
|
|
62
|
+
path: "/api/v1/projects/{slug}",
|
|
63
|
+
request: {
|
|
64
|
+
params: z.object({ slug: z.string() }),
|
|
65
|
+
body: { content: { "application/json": { schema: projectUpdateSchema } } }
|
|
66
|
+
},
|
|
67
|
+
responses: {
|
|
68
|
+
200: {
|
|
69
|
+
content: { "application/json": { schema: projectSchema } },
|
|
70
|
+
description: "Updated project"
|
|
71
|
+
},
|
|
72
|
+
...forbidden$1,
|
|
73
|
+
...notFound
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
const deleteProjectRoute = createRoute({
|
|
77
|
+
method: "delete",
|
|
78
|
+
path: "/api/v1/projects/{slug}",
|
|
79
|
+
request: { params: z.object({ slug: z.string() }) },
|
|
80
|
+
responses: {
|
|
81
|
+
204: { description: "Deleted project" },
|
|
82
|
+
...forbidden$1,
|
|
83
|
+
...notFound
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
function registerProjects(app) {
|
|
87
|
+
app.openapi(listProjectsRoute, async (c) => {
|
|
88
|
+
requireSessionUser();
|
|
89
|
+
const projects = new ProjectModel(getStore().db);
|
|
90
|
+
return c.json(await projects.list());
|
|
91
|
+
});
|
|
92
|
+
app.openapi(createProjectRoute, async (c) => {
|
|
93
|
+
requireSiteAdmin();
|
|
94
|
+
const body = c.req.valid("json");
|
|
95
|
+
const project = await new ProjectModel(getStore().db).create(body);
|
|
96
|
+
await new LabelModel(getStore().db).seedFor(project.id);
|
|
97
|
+
return c.json(project, 201);
|
|
98
|
+
});
|
|
99
|
+
app.openapi(getProjectRoute, async (c) => {
|
|
100
|
+
const { slug } = c.req.valid("param");
|
|
101
|
+
const project = await resolveAuthorizedProject(c, slug, ...VIEW_ROLES);
|
|
102
|
+
return c.json(project);
|
|
103
|
+
});
|
|
104
|
+
app.openapi(updateProjectRoute, async (c) => {
|
|
105
|
+
const { slug } = c.req.valid("param");
|
|
106
|
+
const project = await resolveAuthorizedProject(c, slug, ...ADMIN_ROLES);
|
|
107
|
+
const updated = await new ProjectModel(getStore().db).update(project.id, c.req.valid("json"));
|
|
108
|
+
return c.json(updated);
|
|
109
|
+
});
|
|
110
|
+
app.openapi(deleteProjectRoute, async (c) => {
|
|
111
|
+
requireSiteAdmin();
|
|
112
|
+
const { slug } = c.req.valid("param");
|
|
113
|
+
const project = await resolveAuthorizedProject(c, slug, ...VIEW_ROLES);
|
|
114
|
+
await new ProjectModel(getStore().db).remove(project.id);
|
|
115
|
+
return c.body(null, 204);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { registerProjects };
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=projects.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.mjs","names":["forbiddenResponse"],"sources":["../../src/routers/projects.ts"],"sourcesContent":["import { createRoute, z } from \"@hono/zod-openapi\";\nimport type { ShelfApp } from \"../index.tsx\";\n\nimport { LabelModel } from \"../models/label.ts\";\nimport { ProjectModel } from \"../models/project.ts\";\nimport { getStore } from \"../store.ts\";\nimport type { ProjectRole } from \"../types.ts\";\nimport { forbidden, requireSiteAdmin, resolveAuthorizedProject } from \"./helpers.ts\";\nimport {\n badRequest,\n forbidden as forbiddenResponse,\n notFound,\n projectCreateSchema,\n projectSchema,\n projectUpdateSchema,\n unauthorized,\n} from \"./schemas.ts\";\n\nconst VIEW_ROLES: readonly ProjectRole[] = [\"viewer\", \"developer\", \"approver\", \"admin\"];\nconst ADMIN_ROLES: readonly ProjectRole[] = [\"admin\"];\n\nfunction requireSessionUser(): void {\n if (!getStore().authEnabled) {\n return;\n }\n if (!getStore().user) {\n forbidden();\n }\n}\n\nconst listProjectsRoute = createRoute({\n method: \"get\",\n path: \"/api/v1/projects\",\n responses: {\n 200: { content: { \"application/json\": { schema: projectSchema.array() } }, description: \"List projects\" },\n ...unauthorized,\n },\n});\n\nconst createProjectRoute = createRoute({\n method: \"post\",\n path: \"/api/v1/projects\",\n request: { body: { content: { \"application/json\": { schema: projectCreateSchema } } } },\n responses: {\n 201: { content: { \"application/json\": { schema: projectSchema } }, description: \"Created project\" },\n ...badRequest,\n ...forbiddenResponse,\n ...unauthorized,\n },\n});\n\nconst getProjectRoute = createRoute({\n method: \"get\",\n path: \"/api/v1/projects/{slug}\",\n request: { params: z.object({ slug: z.string() }) },\n responses: {\n 200: { content: { \"application/json\": { schema: projectSchema } }, description: \"Fetch a project\" },\n ...notFound,\n ...unauthorized,\n },\n});\n\nconst updateProjectRoute = createRoute({\n method: \"patch\",\n path: \"/api/v1/projects/{slug}\",\n request: {\n params: z.object({ slug: z.string() }),\n body: { content: { \"application/json\": { schema: projectUpdateSchema } } },\n },\n responses: {\n 200: { content: { \"application/json\": { schema: projectSchema } }, description: \"Updated project\" },\n ...forbiddenResponse,\n ...notFound,\n },\n});\n\nconst deleteProjectRoute = createRoute({\n method: \"delete\",\n path: \"/api/v1/projects/{slug}\",\n request: { params: z.object({ slug: z.string() }) },\n responses: {\n 204: { description: \"Deleted project\" },\n ...forbiddenResponse,\n ...notFound,\n },\n});\n\nexport function registerProjects(app: ShelfApp): void {\n app.openapi(listProjectsRoute, async (c) => {\n requireSessionUser();\n const projects = new ProjectModel(getStore().db);\n return c.json(await projects.list());\n });\n\n app.openapi(createProjectRoute, async (c) => {\n requireSiteAdmin();\n const body = c.req.valid(\"json\");\n const projects = new ProjectModel(getStore().db);\n const project = await projects.create(body);\n await new LabelModel(getStore().db).seedFor(project.id);\n return c.json(project, 201);\n });\n\n app.openapi(getProjectRoute, async (c) => {\n const { slug } = c.req.valid(\"param\");\n const project = await resolveAuthorizedProject(c, slug, ...VIEW_ROLES);\n return c.json(project);\n });\n\n app.openapi(updateProjectRoute, async (c) => {\n const { slug } = c.req.valid(\"param\");\n const project = await resolveAuthorizedProject(c, slug, ...ADMIN_ROLES);\n const updated = await new ProjectModel(getStore().db).update(project.id, c.req.valid(\"json\"));\n return c.json(updated);\n });\n\n app.openapi(deleteProjectRoute, async (c) => {\n requireSiteAdmin();\n const { slug } = c.req.valid(\"param\");\n const project = await resolveAuthorizedProject(c, slug, ...VIEW_ROLES);\n await new ProjectModel(getStore().db).remove(project.id);\n return c.body(null, 204);\n });\n}"],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { BUILD_STATUSES, PROJECT_ROLES, SNAPSHOT_STATUSES } from "../types.mjs";
|
|
5
|
+
import { z } from "@hono/zod-openapi";
|
|
6
|
+
//#region src/routers/schemas.ts
|
|
7
|
+
const storybookMetaSchema = z.record(z.string(), z.unknown()).nullable().optional();
|
|
8
|
+
const projectSchema = z.object({
|
|
9
|
+
id: z.string(),
|
|
10
|
+
name: z.string(),
|
|
11
|
+
slug: z.string(),
|
|
12
|
+
gitRepository: z.string().nullable(),
|
|
13
|
+
gitDefaultBranch: z.string(),
|
|
14
|
+
pixelThreshold: z.number(),
|
|
15
|
+
maxDiffRatio: z.number(),
|
|
16
|
+
publicBranchRegex: z.string().nullable(),
|
|
17
|
+
storybookMeta: z.string().nullable().optional(),
|
|
18
|
+
createdAt: z.string(),
|
|
19
|
+
updatedAt: z.string()
|
|
20
|
+
}).openapi("Project");
|
|
21
|
+
const projectCreateSchema = z.object({
|
|
22
|
+
name: z.string().min(1),
|
|
23
|
+
gitRepository: z.string().optional(),
|
|
24
|
+
gitDefaultBranch: z.string().optional(),
|
|
25
|
+
storybookMeta: storybookMetaSchema
|
|
26
|
+
}).openapi("ProjectCreateInput");
|
|
27
|
+
const projectUpdateSchema = z.object({
|
|
28
|
+
name: z.string().optional(),
|
|
29
|
+
gitRepository: z.string().optional(),
|
|
30
|
+
gitDefaultBranch: z.string().optional(),
|
|
31
|
+
pixelThreshold: z.number().optional(),
|
|
32
|
+
maxDiffRatio: z.number().optional(),
|
|
33
|
+
publicBranchRegex: z.string().nullable().optional(),
|
|
34
|
+
storybookMeta: storybookMetaSchema
|
|
35
|
+
}).openapi("ProjectUpdateInput");
|
|
36
|
+
const buildSchema = z.object({
|
|
37
|
+
id: z.string(),
|
|
38
|
+
projectId: z.string(),
|
|
39
|
+
gitSha: z.string(),
|
|
40
|
+
gitBranch: z.string(),
|
|
41
|
+
isDefault: z.boolean(),
|
|
42
|
+
authorEmail: z.string().nullable(),
|
|
43
|
+
authorName: z.string().nullable(),
|
|
44
|
+
message: z.string().nullable(),
|
|
45
|
+
public: z.boolean(),
|
|
46
|
+
status: z.enum(BUILD_STATUSES),
|
|
47
|
+
snapshotCount: z.number(),
|
|
48
|
+
changedCount: z.number(),
|
|
49
|
+
approvedCount: z.number(),
|
|
50
|
+
rejectedCount: z.number(),
|
|
51
|
+
createdAt: z.string(),
|
|
52
|
+
updatedAt: z.string()
|
|
53
|
+
}).openapi("Build");
|
|
54
|
+
const snapshotSchema = z.object({
|
|
55
|
+
id: z.string(),
|
|
56
|
+
projectId: z.string(),
|
|
57
|
+
buildId: z.string(),
|
|
58
|
+
storyId: z.string(),
|
|
59
|
+
storyName: z.string(),
|
|
60
|
+
storyTitle: z.string(),
|
|
61
|
+
storyImportPath: z.string().nullable(),
|
|
62
|
+
viewportName: z.string(),
|
|
63
|
+
viewportWidth: z.number(),
|
|
64
|
+
viewportHeight: z.number(),
|
|
65
|
+
screenshotPath: z.string(),
|
|
66
|
+
diffPath: z.string().nullable(),
|
|
67
|
+
diffPixels: z.number().nullable(),
|
|
68
|
+
diffRatio: z.number().nullable(),
|
|
69
|
+
diffPassed: z.boolean().nullable(),
|
|
70
|
+
status: z.enum(SNAPSHOT_STATUSES),
|
|
71
|
+
reviewedBy: z.string().nullable(),
|
|
72
|
+
reviewedAt: z.string().nullable(),
|
|
73
|
+
createdAt: z.string(),
|
|
74
|
+
updatedAt: z.string()
|
|
75
|
+
}).openapi("Snapshot");
|
|
76
|
+
const commentSchema = z.object({
|
|
77
|
+
id: z.string(),
|
|
78
|
+
projectId: z.string(),
|
|
79
|
+
buildId: z.string(),
|
|
80
|
+
snapshotId: z.string().nullable(),
|
|
81
|
+
userId: z.string(),
|
|
82
|
+
body: z.string(),
|
|
83
|
+
parentId: z.string().nullable(),
|
|
84
|
+
resolved: z.boolean(),
|
|
85
|
+
createdAt: z.string(),
|
|
86
|
+
updatedAt: z.string()
|
|
87
|
+
}).openapi("Comment");
|
|
88
|
+
const commentCreateSchema = z.object({
|
|
89
|
+
body: z.string().min(1),
|
|
90
|
+
snapshotId: z.string().optional(),
|
|
91
|
+
parentId: z.string().optional()
|
|
92
|
+
}).openapi("CommentCreateInput");
|
|
93
|
+
const labelTypeSchema = z.object({
|
|
94
|
+
id: z.string(),
|
|
95
|
+
projectId: z.string(),
|
|
96
|
+
key: z.string(),
|
|
97
|
+
name: z.string(),
|
|
98
|
+
linkTemplate: z.string().nullable(),
|
|
99
|
+
color: z.string().nullable(),
|
|
100
|
+
createdAt: z.string()
|
|
101
|
+
}).openapi("LabelType");
|
|
102
|
+
const labelTypeCreateSchema = z.object({
|
|
103
|
+
key: z.string().min(1),
|
|
104
|
+
name: z.string().min(1),
|
|
105
|
+
linkTemplate: z.string().optional(),
|
|
106
|
+
color: z.string().optional()
|
|
107
|
+
}).openapi("LabelTypeCreateInput");
|
|
108
|
+
const tokenPublicSchema = z.object({
|
|
109
|
+
id: z.string(),
|
|
110
|
+
projectId: z.string(),
|
|
111
|
+
name: z.string(),
|
|
112
|
+
lastUsedAt: z.string().nullable(),
|
|
113
|
+
createdAt: z.string()
|
|
114
|
+
}).openapi("Token");
|
|
115
|
+
const tokenCreateSchema = z.object({ name: z.string().min(1) }).openapi("TokenCreateInput");
|
|
116
|
+
const tokenCreatedSchema = z.object({
|
|
117
|
+
name: z.string(),
|
|
118
|
+
token: z.string()
|
|
119
|
+
}).openapi("TokenCreated");
|
|
120
|
+
const memberSchema = z.object({
|
|
121
|
+
id: z.string(),
|
|
122
|
+
projectId: z.string(),
|
|
123
|
+
userId: z.string(),
|
|
124
|
+
role: z.enum(PROJECT_ROLES),
|
|
125
|
+
createdAt: z.string()
|
|
126
|
+
}).openapi("ProjectMember");
|
|
127
|
+
const memberRoleSchema = z.object({ role: z.enum(PROJECT_ROLES) }).openapi("MemberRoleInput");
|
|
128
|
+
const memberSetSchema = z.object({
|
|
129
|
+
userId: z.string().min(1),
|
|
130
|
+
role: z.enum(PROJECT_ROLES)
|
|
131
|
+
}).openapi("MemberSetInput");
|
|
132
|
+
const webhookPublicSchema = z.object({
|
|
133
|
+
id: z.string(),
|
|
134
|
+
url: z.string(),
|
|
135
|
+
events: z.array(z.string())
|
|
136
|
+
}).openapi("Webhook");
|
|
137
|
+
const webhookCreateSchema = z.object({
|
|
138
|
+
url: z.url(),
|
|
139
|
+
events: z.array(z.string().min(1)).optional()
|
|
140
|
+
}).openapi("WebhookCreateInput");
|
|
141
|
+
const webhookCreatedSchema = z.object({
|
|
142
|
+
id: z.string(),
|
|
143
|
+
url: z.string(),
|
|
144
|
+
events: z.array(z.string()),
|
|
145
|
+
secret: z.string()
|
|
146
|
+
}).openapi("WebhookCreated");
|
|
147
|
+
const statusConfigSchema = z.object({
|
|
148
|
+
id: z.string(),
|
|
149
|
+
projectId: z.string(),
|
|
150
|
+
provider: z.string(),
|
|
151
|
+
config: z.record(z.string(), z.unknown()),
|
|
152
|
+
hasToken: z.boolean(),
|
|
153
|
+
createdAt: z.string(),
|
|
154
|
+
updatedAt: z.string()
|
|
155
|
+
}).openapi("StatusConfig");
|
|
156
|
+
const statusConfigCreateSchema = z.object({
|
|
157
|
+
provider: z.string().min(1),
|
|
158
|
+
config: z.record(z.string(), z.unknown()),
|
|
159
|
+
token: z.string().min(1)
|
|
160
|
+
}).openapi("StatusConfigCreateInput");
|
|
161
|
+
const okSchema = z.object({ ok: z.boolean() }).openapi("Ok");
|
|
162
|
+
const errorSchema = z.object({ message: z.string() }).openapi("Error");
|
|
163
|
+
const purgeSchema = z.object({ removedBuilds: z.number() }).openapi("PurgeResult");
|
|
164
|
+
const purgeInputSchema = z.object({ ttlDays: z.number().optional() }).openapi("PurgeInput");
|
|
165
|
+
/** Shared response spec for a 400 Bad Request. */
|
|
166
|
+
const badRequest = { 400: {
|
|
167
|
+
content: { "application/json": { schema: errorSchema } },
|
|
168
|
+
description: "Bad request"
|
|
169
|
+
} };
|
|
170
|
+
/** Shared response spec for a 401 Unauthorized. */
|
|
171
|
+
const unauthorized = { 401: {
|
|
172
|
+
content: { "application/json": { schema: errorSchema } },
|
|
173
|
+
description: "Unauthorized"
|
|
174
|
+
} };
|
|
175
|
+
/** Shared response spec for a 403 Forbidden. */
|
|
176
|
+
const forbidden = { 403: {
|
|
177
|
+
content: { "application/json": { schema: errorSchema } },
|
|
178
|
+
description: "Forbidden"
|
|
179
|
+
} };
|
|
180
|
+
/** Shared response spec for a 404 Not Found. */
|
|
181
|
+
const notFound = { 404: {
|
|
182
|
+
content: { "application/json": { schema: errorSchema } },
|
|
183
|
+
description: "Not found"
|
|
184
|
+
} };
|
|
185
|
+
//#endregion
|
|
186
|
+
export { badRequest, buildSchema, commentCreateSchema, commentSchema, errorSchema, forbidden, labelTypeCreateSchema, labelTypeSchema, memberRoleSchema, memberSchema, memberSetSchema, notFound, okSchema, projectCreateSchema, projectSchema, projectUpdateSchema, purgeInputSchema, purgeSchema, snapshotSchema, statusConfigCreateSchema, statusConfigSchema, tokenCreateSchema, tokenCreatedSchema, tokenPublicSchema, unauthorized, webhookCreateSchema, webhookCreatedSchema, webhookPublicSchema };
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=schemas.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.mjs","names":[],"sources":["../../src/routers/schemas.ts"],"sourcesContent":["import { z } from \"@hono/zod-openapi\";\n\nimport { BUILD_STATUSES, PROJECT_ROLES, SNAPSHOT_STATUSES } from \"../types.ts\";\n\nconst storybookMetaSchema = z.record(z.string(), z.unknown()).nullable().optional();\n\nexport const projectSchema = z.object({\n id: z.string(),\n name: z.string(),\n slug: z.string(),\n gitRepository: z.string().nullable(),\n gitDefaultBranch: z.string(),\n pixelThreshold: z.number(),\n maxDiffRatio: z.number(),\n publicBranchRegex: z.string().nullable(),\n storybookMeta: z.string().nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n}).openapi(\"Project\");\n\nexport const projectCreateSchema = z.object({\n name: z.string().min(1),\n gitRepository: z.string().optional(),\n gitDefaultBranch: z.string().optional(),\n storybookMeta: storybookMetaSchema,\n}).openapi(\"ProjectCreateInput\");\n\nexport const projectUpdateSchema = z.object({\n name: z.string().optional(),\n gitRepository: z.string().optional(),\n gitDefaultBranch: z.string().optional(),\n pixelThreshold: z.number().optional(),\n maxDiffRatio: z.number().optional(),\n publicBranchRegex: z.string().nullable().optional(),\n storybookMeta: storybookMetaSchema,\n}).openapi(\"ProjectUpdateInput\");\n\nexport const buildSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n gitSha: z.string(),\n gitBranch: z.string(),\n isDefault: z.boolean(),\n authorEmail: z.string().nullable(),\n authorName: z.string().nullable(),\n message: z.string().nullable(),\n public: z.boolean(),\n status: z.enum(BUILD_STATUSES),\n snapshotCount: z.number(),\n changedCount: z.number(),\n approvedCount: z.number(),\n rejectedCount: z.number(),\n createdAt: z.string(),\n updatedAt: z.string(),\n}).openapi(\"Build\");\n\nexport const snapshotSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n buildId: z.string(),\n storyId: z.string(),\n storyName: z.string(),\n storyTitle: z.string(),\n storyImportPath: z.string().nullable(),\n viewportName: z.string(),\n viewportWidth: z.number(),\n viewportHeight: z.number(),\n screenshotPath: z.string(),\n diffPath: z.string().nullable(),\n diffPixels: z.number().nullable(),\n diffRatio: z.number().nullable(),\n diffPassed: z.boolean().nullable(),\n status: z.enum(SNAPSHOT_STATUSES),\n reviewedBy: z.string().nullable(),\n reviewedAt: z.string().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n}).openapi(\"Snapshot\");\n\nexport const commentSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n buildId: z.string(),\n snapshotId: z.string().nullable(),\n userId: z.string(),\n body: z.string(),\n parentId: z.string().nullable(),\n resolved: z.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n}).openapi(\"Comment\");\n\nexport const commentCreateSchema = z.object({\n body: z.string().min(1),\n snapshotId: z.string().optional(),\n parentId: z.string().optional(),\n}).openapi(\"CommentCreateInput\");\n\nexport const labelTypeSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n key: z.string(),\n name: z.string(),\n linkTemplate: z.string().nullable(),\n color: z.string().nullable(),\n createdAt: z.string(),\n}).openapi(\"LabelType\");\n\nexport const labelTypeCreateSchema = z.object({\n key: z.string().min(1),\n name: z.string().min(1),\n linkTemplate: z.string().optional(),\n color: z.string().optional(),\n}).openapi(\"LabelTypeCreateInput\");\n\nexport const tokenPublicSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n name: z.string(),\n lastUsedAt: z.string().nullable(),\n createdAt: z.string(),\n}).openapi(\"Token\");\n\nexport const tokenCreateSchema = z.object({ name: z.string().min(1) }).openapi(\"TokenCreateInput\");\n\nexport const tokenCreatedSchema = z.object({\n name: z.string(),\n token: z.string(),\n}).openapi(\"TokenCreated\");\n\nexport const memberSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n userId: z.string(),\n role: z.enum(PROJECT_ROLES),\n createdAt: z.string(),\n}).openapi(\"ProjectMember\");\n\nexport const memberRoleSchema = z.object({ role: z.enum(PROJECT_ROLES) }).openapi(\"MemberRoleInput\");\n\nexport const memberSetSchema = z.object({\n userId: z.string().min(1),\n role: z.enum(PROJECT_ROLES),\n}).openapi(\"MemberSetInput\");\n\nexport const webhookPublicSchema = z.object({\n id: z.string(),\n url: z.string(),\n events: z.array(z.string()),\n}).openapi(\"Webhook\");\n\nexport const webhookCreateSchema = z.object({\n url: z.url(),\n events: z.array(z.string().min(1)).optional(),\n}).openapi(\"WebhookCreateInput\");\n\nexport const webhookCreatedSchema = z.object({\n id: z.string(),\n url: z.string(),\n events: z.array(z.string()),\n secret: z.string(),\n}).openapi(\"WebhookCreated\");\n\nexport const statusConfigSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n provider: z.string(),\n config: z.record(z.string(), z.unknown()),\n hasToken: z.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n}).openapi(\"StatusConfig\");\n\nexport const statusConfigCreateSchema = z.object({\n provider: z.string().min(1),\n config: z.record(z.string(), z.unknown()),\n token: z.string().min(1),\n}).openapi(\"StatusConfigCreateInput\");\n\nexport const okSchema = z.object({ ok: z.boolean() }).openapi(\"Ok\");\n\nexport const errorSchema = z.object({ message: z.string() }).openapi(\"Error\");\n\nexport const purgeSchema = z.object({ removedBuilds: z.number() }).openapi(\"PurgeResult\");\n\nexport const purgeInputSchema = z.object({ ttlDays: z.number().optional() }).openapi(\"PurgeInput\");\n\n/** Shared response spec for a 400 Bad Request. */\nexport const badRequest = {\n 400: { content: { \"application/json\": { schema: errorSchema } }, description: \"Bad request\" },\n} as const;\n\n/** Shared response spec for a 401 Unauthorized. */\nexport const unauthorized = {\n 401: { content: { \"application/json\": { schema: errorSchema } }, description: \"Unauthorized\" },\n} as const;\n\n/** Shared response spec for a 403 Forbidden. */\nexport const forbidden = {\n 403: { content: { \"application/json\": { schema: errorSchema } }, description: \"Forbidden\" },\n} as const;\n\n/** Shared response spec for a 404 Not Found. */\nexport const notFound = {\n 404: { content: { \"application/json\": { schema: errorSchema } }, description: \"Not found\" },\n} as const;"],"mappings":"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"}
|