Skip to content
File

Blob: src/worker/routes/api/addressbooks.ts

typescript94 lines
1import {
2 AddressbookCreateRequestSchema,
3 AddressbookPatchRequestSchema,
4 AddressbookResponseSchema,
5} from "@/worker/openapi/schemas";
6import type { AddressbookRecord } from "@/worker/objects/card-dav-object";
7import { createCollectionCrudRoutes, isoDate } from "@/worker/routes/api/collection-crud";
8 
9const addressbookErrorStatuses = [400, 401, 403, 404, 409, 500] as const;
10const addressbookDeleteErrorStatuses = [400, 401, 403, 404, 500] as const;
11 
12function addressbookResponse(row: AddressbookRecord) {
13 return {
14 id: row.id,
15 name: row.name,
16 display_name: row.displayName,
17 description: row.description,
18 href: row.href,
19 created_at: isoDate(row.createdAtMs),
20 modified_at: isoDate(row.modifiedAtMs),
21 sync_token: row.syncToken,
22 };
23}
24 
25export function createAddressbookApiRoutes() {
26 return createCollectionCrudRoutes({
27 tag: "addressbooks",
28 idParam: "addressbook_id",
29 summaries: {
30 list: "List address books",
31 create: "Create address book",
32 get: "Get address book",
33 update: "Update address book",
34 delete: "Delete address book",
35 },
36 deleteSuccessDescription: "Address book deleted",
37 responseSchema: AddressbookResponseSchema,
38 listResponseSchema: AddressbookResponseSchema.array(),
39 createSchema: AddressbookCreateRequestSchema,
40 patchSchema: AddressbookPatchRequestSchema,
41 errorStatuses: addressbookErrorStatuses,
42 deleteErrorStatuses: addressbookDeleteErrorStatuses,
43 emptyPatch: {
44 fields: ["display_name", "description"],
45 code: "invalid_addressbook_update",
46 message: "Address book update must change at least one field.",
47 },
48 toResponse: addressbookResponse,
49 list: async (c, subject) =>
50 (
51 await c.env.CARD_DAV.getByName(subject.storageId).listAddressbooks({
52 subjectId: subject.id,
53 nowMs: Date.now(),
54 })
55 ).addressbooks,
56 create: async (c, subject, body) => {
57 const result = await c.env.CARD_DAV.getByName(subject.storageId).createAddressbook({
58 subjectId: subject.id,
59 name: body.name,
60 displayName: body.display_name,
61 description: body.description,
62 nowMs: Date.now(),
63 });
64 return result.ok ? { ok: true, value: result.addressbook } : result;
65 },
66 get: async (c, subject, id) => {
67 const result = await c.env.CARD_DAV.getByName(subject.storageId).getAddressbook({
68 subjectId: subject.id,
69 id,
70 nowMs: Date.now(),
71 });
72 return result.ok ? { ok: true, value: result.addressbook } : result;
73 },
74 patch: async (c, subject, id, body) => {
75 const result = await c.env.CARD_DAV.getByName(subject.storageId).updateAddressbook({
76 subjectId: subject.id,
77 id,
78 displayName: body.display_name,
79 description: body.description,
80 nowMs: Date.now(),
81 });
82 return result.ok ? { ok: true, value: result.addressbook } : result;
83 },
84 delete: async (c, subject, id) => {
85 const result = await c.env.CARD_DAV.getByName(subject.storageId).deleteAddressbook({
86 subjectId: subject.id,
87 id,
88 nowMs: Date.now(),
89 });
90 return result.ok ? { ok: true, value: null } : result;
91 },
92 });
93}