chore: add formatting
This commit is contained in:
+25
-8
@@ -52,7 +52,9 @@ describe("api", () => {
|
||||
const { api, cleanup } = withApi();
|
||||
|
||||
const response = api.getDrawing(
|
||||
Object.assign(new Request("http://local/api/drawings/missing"), { params: { id: "missing" } }),
|
||||
Object.assign(new Request("http://local/api/drawings/missing"), {
|
||||
params: { id: "missing" },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
@@ -199,9 +201,13 @@ describe("api", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const stored = await api.getDrawing(
|
||||
Object.assign(new Request(`http://local/api/drawings/${created.id}`), { params: { id: created.id } }),
|
||||
).json();
|
||||
const stored = await api
|
||||
.getDrawing(
|
||||
Object.assign(new Request(`http://local/api/drawings/${created.id}`), {
|
||||
params: { id: created.id },
|
||||
}),
|
||||
)
|
||||
.json();
|
||||
expect(stored.elements).toEqual([{ id: "server" }]);
|
||||
cleanup();
|
||||
});
|
||||
@@ -211,7 +217,10 @@ describe("api", () => {
|
||||
const created = await api.createDrawing().json();
|
||||
|
||||
const disabled = await api.getDrawingPublication(
|
||||
Object.assign(new Request(`http://local/api/drawings/${created.id}/publication`), { params: { id: created.id } }),
|
||||
Object.assign(
|
||||
new Request(`http://local/api/drawings/${created.id}/publication`),
|
||||
{ params: { id: created.id } },
|
||||
),
|
||||
);
|
||||
expect(disabled.status).toBe(200);
|
||||
expect(await disabled.json()).toEqual({ enabled: false });
|
||||
@@ -236,7 +245,10 @@ describe("api", () => {
|
||||
});
|
||||
|
||||
const enabled = await api.getDrawingPublication(
|
||||
Object.assign(new Request(`http://local/api/drawings/${created.id}/publication`), { params: { id: created.id } }),
|
||||
Object.assign(
|
||||
new Request(`http://local/api/drawings/${created.id}/publication`),
|
||||
{ params: { id: created.id } },
|
||||
),
|
||||
);
|
||||
expect(await enabled.json()).toEqual({
|
||||
enabled: true,
|
||||
@@ -394,7 +406,10 @@ describe("api", () => {
|
||||
);
|
||||
|
||||
const enabled = await api.getPublicDrawing(
|
||||
Object.assign(new Request("http://local/api/public/drawings/public-flow"), { params: { slug: "public-flow" } }),
|
||||
Object.assign(
|
||||
new Request("http://local/api/public/drawings/public-flow"),
|
||||
{ params: { slug: "public-flow" } },
|
||||
),
|
||||
);
|
||||
|
||||
expect(enabled.status).toBe(200);
|
||||
@@ -406,7 +421,9 @@ describe("api", () => {
|
||||
});
|
||||
|
||||
const missing = await api.getPublicDrawing(
|
||||
Object.assign(new Request("http://local/api/public/drawings/missing"), { params: { slug: "missing" } }),
|
||||
Object.assign(new Request("http://local/api/public/drawings/missing"), {
|
||||
params: { slug: "missing" },
|
||||
}),
|
||||
);
|
||||
expect(missing.status).toBe(404);
|
||||
cleanup();
|
||||
|
||||
+48
-12
@@ -1,7 +1,12 @@
|
||||
import { type DrawingStore } from "./db";
|
||||
import { normalizePublicationSlug } from "../core/publication";
|
||||
import { type DrawingMeta, type DrawingPublication } from "../core/shared";
|
||||
import { HttpError, normalizeTitle, parseJsonBody, parseSceneText } from "../core/scene";
|
||||
import {
|
||||
HttpError,
|
||||
normalizeTitle,
|
||||
parseJsonBody,
|
||||
parseSceneText,
|
||||
} from "../core/scene";
|
||||
|
||||
type RouteRequest = Request & {
|
||||
params?: Record<string, string>;
|
||||
@@ -34,7 +39,9 @@ function toMeta(drawing: DrawingMeta): DrawingMeta {
|
||||
};
|
||||
}
|
||||
|
||||
function parseExpectedRevision(raw: Record<string, unknown>): number | undefined {
|
||||
function parseExpectedRevision(
|
||||
raw: Record<string, unknown>,
|
||||
): number | undefined {
|
||||
if (!Object.hasOwn(raw, "expectedRevision")) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -78,7 +85,10 @@ export function createApi(store: DrawingStore) {
|
||||
const drawing = id ? store.getDrawing(id) : null;
|
||||
|
||||
if (!drawing) {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
return json({
|
||||
@@ -99,7 +109,10 @@ export function createApi(store: DrawingStore) {
|
||||
|
||||
const drawing = store.getPublicDrawing(slug);
|
||||
if (!drawing) {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
return json(drawing);
|
||||
@@ -136,7 +149,10 @@ export function createApi(store: DrawingStore) {
|
||||
});
|
||||
|
||||
if (!result.ok && result.reason === "not_found") {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
if (!result.ok && result.reason === "conflict") {
|
||||
@@ -163,7 +179,10 @@ export function createApi(store: DrawingStore) {
|
||||
deleteDrawing(request: RouteRequest) {
|
||||
const id = request.params?.id;
|
||||
if (!id) {
|
||||
return json({ ok: false, error: "Missing drawing id" }, { status: 400 });
|
||||
return json(
|
||||
{ ok: false, error: "Missing drawing id" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const { deleted, next } = store.deleteDrawing(id);
|
||||
@@ -183,7 +202,10 @@ export function createApi(store: DrawingStore) {
|
||||
|
||||
const publication = store.getDrawingPublication(id);
|
||||
if (!publication) {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
return jsonPublication(publication);
|
||||
@@ -199,11 +221,16 @@ export function createApi(store: DrawingStore) {
|
||||
throw new HttpError(400, "Missing drawing id");
|
||||
}
|
||||
|
||||
const raw = parseJsonBody<Record<string, unknown>>(await request.text());
|
||||
const raw = parseJsonBody<Record<string, unknown>>(
|
||||
await request.text(),
|
||||
);
|
||||
if (raw.enabled === false) {
|
||||
const result = store.disableDrawingPublication(id);
|
||||
if (!result.ok) {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
return jsonPublication(result.publication);
|
||||
@@ -215,7 +242,10 @@ export function createApi(store: DrawingStore) {
|
||||
|
||||
const drawing = store.getDrawing(id);
|
||||
if (!drawing) {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
const result = store.publishDrawing(id, {
|
||||
@@ -223,11 +253,17 @@ export function createApi(store: DrawingStore) {
|
||||
});
|
||||
|
||||
if (!result.ok && result.reason === "not_found") {
|
||||
return json({ ok: false, error: "Drawing not found" }, { status: 404 });
|
||||
return json(
|
||||
{ ok: false, error: "Drawing not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
if (!result.ok && result.reason === "slug_conflict") {
|
||||
return json({ ok: false, error: "Published slug already exists" }, { status: 409 });
|
||||
return json(
|
||||
{ ok: false, error: "Published slug already exists" },
|
||||
{ status: 409 },
|
||||
);
|
||||
}
|
||||
|
||||
return jsonPublication(result.publication);
|
||||
|
||||
+23
-6
@@ -79,7 +79,9 @@ describe("drawing store", () => {
|
||||
expect(stale.ok).toBe(false);
|
||||
expect(stale.ok ? null : stale.reason).toBe("conflict");
|
||||
expect(store.getDrawing(created.id)?.revision).toBe(1);
|
||||
expect(store.getDrawing(created.id)?.scene.elements).toEqual([{ id: "first" }]);
|
||||
expect(store.getDrawing(created.id)?.scene.elements).toEqual([
|
||||
{ id: "first" },
|
||||
]);
|
||||
});
|
||||
|
||||
test("keeps the revision unchanged when the scene is already stored", () => {
|
||||
@@ -109,13 +111,21 @@ describe("drawing store", () => {
|
||||
files: {},
|
||||
};
|
||||
|
||||
const first = store.updateDrawing(created.id, { expectedRevision: 0, scene });
|
||||
const first = store.updateDrawing(created.id, {
|
||||
expectedRevision: 0,
|
||||
scene,
|
||||
});
|
||||
expect(first.ok ? first.drawing.revision : null).toBe(1);
|
||||
|
||||
const repeated = store.updateDrawing(created.id, { expectedRevision: 0, scene });
|
||||
const repeated = store.updateDrawing(created.id, {
|
||||
expectedRevision: 0,
|
||||
scene,
|
||||
});
|
||||
expect(repeated.ok).toBe(true);
|
||||
expect(repeated.ok ? repeated.drawing.revision : null).toBe(1);
|
||||
expect(store.getDrawing(created.id)?.scene.elements).toEqual([{ id: "same" }]);
|
||||
expect(store.getDrawing(created.id)?.scene.elements).toEqual([
|
||||
{ id: "same" },
|
||||
]);
|
||||
});
|
||||
|
||||
test("increments the revision when the title changes but the scene does not", () => {
|
||||
@@ -127,10 +137,17 @@ describe("drawing store", () => {
|
||||
files: {},
|
||||
};
|
||||
|
||||
const first = store.updateDrawing(created.id, { expectedRevision: 0, scene });
|
||||
const first = store.updateDrawing(created.id, {
|
||||
expectedRevision: 0,
|
||||
scene,
|
||||
});
|
||||
expect(first.ok ? first.drawing.revision : null).toBe(1);
|
||||
|
||||
const renamed = store.updateDrawing(created.id, { expectedRevision: 1, title: "Renamed", scene });
|
||||
const renamed = store.updateDrawing(created.id, {
|
||||
expectedRevision: 1,
|
||||
title: "Renamed",
|
||||
scene,
|
||||
});
|
||||
expect(renamed.ok).toBe(true);
|
||||
expect(renamed.ok ? renamed.drawing.title : null).toBe("Renamed");
|
||||
expect(renamed.ok ? renamed.drawing.revision : null).toBe(2);
|
||||
|
||||
+73
-20
@@ -2,7 +2,13 @@ import { Database } from "bun:sqlite";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { dirname } from "node:path";
|
||||
import { DEFAULT_TITLE, type DrawingMeta, type DrawingPublication, type DrawingRecord, type ScenePayload } from "../core/shared";
|
||||
import {
|
||||
DEFAULT_TITLE,
|
||||
type DrawingMeta,
|
||||
type DrawingPublication,
|
||||
type DrawingRecord,
|
||||
type ScenePayload,
|
||||
} from "../core/shared";
|
||||
import { emptyScene, normalizeScene, normalizeTitle } from "../core/scene";
|
||||
|
||||
type DrawingRow = {
|
||||
@@ -69,7 +75,9 @@ function readMeta(row: DrawingMetaRow | null | undefined): DrawingMeta | null {
|
||||
};
|
||||
}
|
||||
|
||||
function readPublication(row: DrawingPublicationRow | null | undefined): DrawingPublication | null {
|
||||
function readPublication(
|
||||
row: DrawingPublicationRow | null | undefined,
|
||||
): DrawingPublication | null {
|
||||
if (!row) {
|
||||
return null;
|
||||
}
|
||||
@@ -93,7 +101,8 @@ function readPublicDrawing(row: PublicDrawingRow | null | undefined) {
|
||||
try {
|
||||
scene = normalizeScene(JSON.parse(row.data));
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown scene parsing error";
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Unknown scene parsing error";
|
||||
throw new Error(`Invalid stored public scene: ${message}`);
|
||||
}
|
||||
|
||||
@@ -112,7 +121,8 @@ function readRow(row: DrawingRow | null | undefined): DrawingRecord | null {
|
||||
try {
|
||||
scene = normalizeScene(JSON.parse(row.data));
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown scene parsing error";
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Unknown scene parsing error";
|
||||
throw new Error(`Invalid stored scene for drawing ${row.id}: ${message}`);
|
||||
}
|
||||
|
||||
@@ -123,13 +133,15 @@ function readRow(row: DrawingRow | null | undefined): DrawingRecord | null {
|
||||
}
|
||||
|
||||
function ensurePublicationColumns(db: Database) {
|
||||
const columns = db
|
||||
.query("PRAGMA table_info(drawings)")
|
||||
.all() as Array<{ name: string }>;
|
||||
const columns = db.query("PRAGMA table_info(drawings)").all() as Array<{
|
||||
name: string;
|
||||
}>;
|
||||
const names = new Set(columns.map((column) => column.name));
|
||||
|
||||
if (!names.has("public_enabled")) {
|
||||
db.exec("ALTER TABLE drawings ADD COLUMN public_enabled INTEGER NOT NULL DEFAULT 0");
|
||||
db.exec(
|
||||
"ALTER TABLE drawings ADD COLUMN public_enabled INTEGER NOT NULL DEFAULT 0",
|
||||
);
|
||||
}
|
||||
|
||||
if (!names.has("public_slug")) {
|
||||
@@ -138,7 +150,10 @@ function ensurePublicationColumns(db: Database) {
|
||||
}
|
||||
|
||||
function isSlugConflictError(error: unknown): boolean {
|
||||
return error instanceof Error && error.message.includes("UNIQUE constraint failed: drawings.public_slug");
|
||||
return (
|
||||
error instanceof Error &&
|
||||
error.message.includes("UNIQUE constraint failed: drawings.public_slug")
|
||||
);
|
||||
}
|
||||
|
||||
export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
@@ -310,8 +325,12 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
return { ok: true, drawing: existing };
|
||||
}
|
||||
|
||||
const nextTitle = hasTitle ? normalizeTitle(update.title) : existingRow.title;
|
||||
const nextScene = hasScene ? JSON.stringify(update.scene) : existingRow.data;
|
||||
const nextTitle = hasTitle
|
||||
? normalizeTitle(update.title)
|
||||
: existingRow.title;
|
||||
const nextScene = hasScene
|
||||
? JSON.stringify(update.scene)
|
||||
: existingRow.data;
|
||||
const titleChanged = nextTitle !== existingRow.title;
|
||||
const sceneChanged = nextScene !== existingRow.data;
|
||||
|
||||
@@ -319,7 +338,10 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
return { ok: true, drawing: existing };
|
||||
}
|
||||
|
||||
if (update.expectedRevision !== undefined && update.expectedRevision !== existingRow.revision) {
|
||||
if (
|
||||
update.expectedRevision !== undefined &&
|
||||
update.expectedRevision !== existingRow.revision
|
||||
) {
|
||||
return { ok: false, reason: "conflict", drawing: existing };
|
||||
}
|
||||
|
||||
@@ -328,17 +350,36 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
changes =
|
||||
update.expectedRevision === undefined
|
||||
? Number(updateBothQuery.run(id, nextTitle, nextScene).changes)
|
||||
: Number(updateBothExpectedQuery.run(id, nextTitle, nextScene, update.expectedRevision).changes);
|
||||
: Number(
|
||||
updateBothExpectedQuery.run(
|
||||
id,
|
||||
nextTitle,
|
||||
nextScene,
|
||||
update.expectedRevision,
|
||||
).changes,
|
||||
);
|
||||
} else if (sceneChanged) {
|
||||
changes =
|
||||
update.expectedRevision === undefined
|
||||
? Number(updateSceneQuery.run(id, nextScene).changes)
|
||||
: Number(updateSceneExpectedQuery.run(id, nextScene, update.expectedRevision).changes);
|
||||
: Number(
|
||||
updateSceneExpectedQuery.run(
|
||||
id,
|
||||
nextScene,
|
||||
update.expectedRevision,
|
||||
).changes,
|
||||
);
|
||||
} else {
|
||||
changes =
|
||||
update.expectedRevision === undefined
|
||||
? Number(updateTitleQuery.run(id, nextTitle).changes)
|
||||
: Number(updateTitleExpectedQuery.run(id, nextTitle, update.expectedRevision).changes);
|
||||
: Number(
|
||||
updateTitleExpectedQuery.run(
|
||||
id,
|
||||
nextTitle,
|
||||
update.expectedRevision,
|
||||
).changes,
|
||||
);
|
||||
}
|
||||
|
||||
const drawing = getDrawing(id);
|
||||
@@ -353,7 +394,10 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
return { ok: false, reason: "conflict", drawing };
|
||||
}
|
||||
|
||||
function deleteDrawing(id: string): { deleted: boolean; next: DrawingMeta | null } {
|
||||
function deleteDrawing(id: string): {
|
||||
deleted: boolean;
|
||||
next: DrawingMeta | null;
|
||||
} {
|
||||
const changes = Number(deleteQuery.run(id).changes);
|
||||
if (changes === 0) {
|
||||
return { deleted: false, next: null };
|
||||
@@ -366,10 +410,15 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
}
|
||||
|
||||
function getDrawingPublication(id: string): DrawingPublication | null {
|
||||
return readPublication(getPublicationQuery.get(id) as DrawingPublicationRow | null | undefined);
|
||||
return readPublication(
|
||||
getPublicationQuery.get(id) as DrawingPublicationRow | null | undefined,
|
||||
);
|
||||
}
|
||||
|
||||
function publishDrawing(id: string, publication: { slug: string }): DrawingPublicationUpdateResult {
|
||||
function publishDrawing(
|
||||
id: string,
|
||||
publication: { slug: string },
|
||||
): DrawingPublicationUpdateResult {
|
||||
try {
|
||||
const changes = Number(publishQuery.run(id, publication.slug).changes);
|
||||
if (changes === 0) {
|
||||
@@ -389,7 +438,9 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
};
|
||||
}
|
||||
|
||||
function disableDrawingPublication(id: string): DrawingPublicationUpdateResult {
|
||||
function disableDrawingPublication(
|
||||
id: string,
|
||||
): DrawingPublicationUpdateResult {
|
||||
const changes = Number(disablePublicationQuery.run(id).changes);
|
||||
if (changes === 0) {
|
||||
return { ok: false, reason: "not_found" };
|
||||
@@ -402,7 +453,9 @@ export function createDrawingStore(databasePath = resolveDatabasePath()) {
|
||||
}
|
||||
|
||||
function getPublicDrawing(slug: string) {
|
||||
return readPublicDrawing(getPublicDrawingQuery.get(slug) as PublicDrawingRow | null | undefined);
|
||||
return readPublicDrawing(
|
||||
getPublicDrawingQuery.get(slug) as PublicDrawingRow | null | undefined,
|
||||
);
|
||||
}
|
||||
|
||||
function close() {
|
||||
|
||||
@@ -38,12 +38,16 @@ describe("createServer", () => {
|
||||
test("redirects / to the latest drawing", () => {
|
||||
const { server, store } = createServerFixture();
|
||||
|
||||
const response = server.routes["/"]?.(new Request("http://local/")) as Response;
|
||||
const response = server.routes["/"]?.(
|
||||
new Request("http://local/"),
|
||||
) as Response;
|
||||
const created = store.listDrawings();
|
||||
|
||||
expect(created).toHaveLength(1);
|
||||
expect(response.status).toBe(302);
|
||||
expect(response.headers.get("location")).toBe(`http://local/d/${created[0]?.id}`);
|
||||
expect(response.headers.get("location")).toBe(
|
||||
`http://local/d/${created[0]?.id}`,
|
||||
);
|
||||
});
|
||||
|
||||
test("keeps Bun responsible for API routes", async () => {
|
||||
@@ -67,9 +71,12 @@ describe("createServer", () => {
|
||||
store.publishDrawing(drawing.id, { slug: "published-note" });
|
||||
|
||||
const response = await server.routes["/api/public/drawings/:slug"]?.GET?.(
|
||||
Object.assign(new Request("http://local/api/public/drawings/published-note"), {
|
||||
params: { slug: "published-note" },
|
||||
}),
|
||||
Object.assign(
|
||||
new Request("http://local/api/public/drawings/published-note"),
|
||||
{
|
||||
params: { slug: "published-note" },
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(response?.status).toBe(200);
|
||||
@@ -85,7 +92,9 @@ describe("createServer", () => {
|
||||
const { server } = createServerFixture();
|
||||
|
||||
const response = await server.routes["/api/public/drawings/:slug"]?.GET?.(
|
||||
Object.assign(new Request("http://local/api/public/drawings/missing"), { params: { slug: "missing" } }),
|
||||
Object.assign(new Request("http://local/api/public/drawings/missing"), {
|
||||
params: { slug: "missing" },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response?.status).toBe(404);
|
||||
@@ -93,7 +102,9 @@ describe("createServer", () => {
|
||||
|
||||
test("returns JSON 404 for unmatched requests", async () => {
|
||||
const { server } = createServerFixture();
|
||||
const response = await server.fetch(new Request("http://local/index-abc123.js"));
|
||||
const response = await server.fetch(
|
||||
new Request("http://local/index-abc123.js"),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
expect(await response.json()).toEqual({ ok: false, error: "Not found" });
|
||||
|
||||
@@ -25,19 +25,26 @@ export function createServer(options: CreateServerOptions = {}) {
|
||||
POST: () => api.createDrawing(),
|
||||
},
|
||||
"/api/drawings/:id": {
|
||||
GET: (request: Request & { params: Record<string, string> }) => api.getDrawing(request),
|
||||
PUT: (request: Request & { params: Record<string, string> }) => api.updateDrawing(request),
|
||||
DELETE: (request: Request & { params: Record<string, string> }) => api.deleteDrawing(request),
|
||||
GET: (request: Request & { params: Record<string, string> }) =>
|
||||
api.getDrawing(request),
|
||||
PUT: (request: Request & { params: Record<string, string> }) =>
|
||||
api.updateDrawing(request),
|
||||
DELETE: (request: Request & { params: Record<string, string> }) =>
|
||||
api.deleteDrawing(request),
|
||||
},
|
||||
"/api/public/drawings/:slug": {
|
||||
GET: (request: Request & { params: Record<string, string> }) => api.getPublicDrawing(request),
|
||||
GET: (request: Request & { params: Record<string, string> }) =>
|
||||
api.getPublicDrawing(request),
|
||||
},
|
||||
"/api/drawings/:id/publication": {
|
||||
GET: (request: Request & { params: Record<string, string> }) => api.getDrawingPublication(request),
|
||||
PUT: (request: Request & { params: Record<string, string> }) => api.updateDrawingPublication(request),
|
||||
GET: (request: Request & { params: Record<string, string> }) =>
|
||||
api.getDrawingPublication(request),
|
||||
PUT: (request: Request & { params: Record<string, string> }) =>
|
||||
api.updateDrawingPublication(request),
|
||||
},
|
||||
},
|
||||
fetch: (_request: Request) => Response.json({ ok: false, error: "Not found" }, { status: 404 }),
|
||||
fetch: (_request: Request) =>
|
||||
Response.json({ ok: false, error: "Not found" }, { status: 404 }),
|
||||
} satisfies Parameters<typeof Bun.serve>[0];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user