@elizaos/plugin-imessage 2.0.0-beta.1 → 2.0.3-beta.2

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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -18
  3. package/auto-enable.ts +1 -1
  4. package/package.json +21 -4
  5. package/dist/accounts.d.ts +0 -135
  6. package/dist/accounts.d.ts.map +0 -1
  7. package/dist/accounts.js +0 -209
  8. package/dist/accounts.js.map +0 -1
  9. package/dist/api/bluebubbles-routes.d.ts +0 -10
  10. package/dist/api/bluebubbles-routes.d.ts.map +0 -1
  11. package/dist/api/bluebubbles-routes.js +0 -132
  12. package/dist/api/bluebubbles-routes.js.map +0 -1
  13. package/dist/api/imessage-routes.d.ts +0 -80
  14. package/dist/api/imessage-routes.d.ts.map +0 -1
  15. package/dist/api/imessage-routes.js +0 -230
  16. package/dist/api/imessage-routes.js.map +0 -1
  17. package/dist/chatdb-reader.d.ts +0 -240
  18. package/dist/chatdb-reader.d.ts.map +0 -1
  19. package/dist/chatdb-reader.js +0 -647
  20. package/dist/chatdb-reader.js.map +0 -1
  21. package/dist/config.d.ts +0 -60
  22. package/dist/config.d.ts.map +0 -1
  23. package/dist/config.js +0 -8
  24. package/dist/config.js.map +0 -1
  25. package/dist/connector-account-provider.d.ts +0 -18
  26. package/dist/connector-account-provider.d.ts.map +0 -1
  27. package/dist/connector-account-provider.js +0 -83
  28. package/dist/connector-account-provider.js.map +0 -1
  29. package/dist/contacts-reader.d.ts +0 -147
  30. package/dist/contacts-reader.d.ts.map +0 -1
  31. package/dist/contacts-reader.js +0 -481
  32. package/dist/contacts-reader.js.map +0 -1
  33. package/dist/index.d.ts +0 -23
  34. package/dist/index.d.ts.map +0 -1
  35. package/dist/index.js +0 -78
  36. package/dist/index.js.map +0 -1
  37. package/dist/providers/index.d.ts +0 -4
  38. package/dist/providers/index.d.ts.map +0 -1
  39. package/dist/providers/index.js +0 -5
  40. package/dist/providers/index.js.map +0 -1
  41. package/dist/rpc.d.ts +0 -206
  42. package/dist/rpc.d.ts.map +0 -1
  43. package/dist/rpc.js +0 -393
  44. package/dist/rpc.js.map +0 -1
  45. package/dist/service.d.ts +0 -266
  46. package/dist/service.d.ts.map +0 -1
  47. package/dist/service.js +0 -1694
  48. package/dist/service.js.map +0 -1
  49. package/dist/setup-routes.d.ts +0 -38
  50. package/dist/setup-routes.d.ts.map +0 -1
  51. package/dist/setup-routes.js +0 -322
  52. package/dist/setup-routes.js.map +0 -1
  53. package/dist/types.d.ts +0 -192
  54. package/dist/types.d.ts.map +0 -1
  55. package/dist/types.js +0 -138
  56. package/dist/types.js.map +0 -1
@@ -1,132 +0,0 @@
1
- const BLUEBUBBLES_SERVICE_NAME = "bluebubbles";
2
- const DEFAULT_WEBHOOK_PATH = "/webhooks/bluebubbles";
3
- const MAX_BODY_BYTES = 1_048_576;
4
- function resolveService(state) {
5
- if (!state.runtime) {
6
- return null;
7
- }
8
- const raw = state.runtime.getService(BLUEBUBBLES_SERVICE_NAME);
9
- return raw ?? null;
10
- }
11
- export function resolveBlueBubblesWebhookPath(state) {
12
- const service = resolveService(state);
13
- const configuredPath = service?.getWebhookPath();
14
- if (typeof configuredPath === "string" && configuredPath.trim().length > 0) {
15
- return configuredPath.trim();
16
- }
17
- return DEFAULT_WEBHOOK_PATH;
18
- }
19
- export async function handleBlueBubblesRoute(req, res, pathname, method, state, helpers) {
20
- const webhookPath = resolveBlueBubblesWebhookPath(state);
21
- const isWebhookPath = pathname === webhookPath;
22
- const isApiPath = pathname.startsWith("/api/bluebubbles");
23
- if (!isWebhookPath && !isApiPath) {
24
- return false;
25
- }
26
- if (method === "GET" && pathname === "/api/bluebubbles/status") {
27
- const service = resolveService(state);
28
- if (!service) {
29
- helpers.json(res, {
30
- available: false,
31
- connected: false,
32
- webhookPath,
33
- reason: "bluebubbles service not registered",
34
- });
35
- return true;
36
- }
37
- helpers.json(res, {
38
- available: true,
39
- connected: service.isConnected(),
40
- webhookPath,
41
- });
42
- return true;
43
- }
44
- if (method === "GET" && pathname === "/api/bluebubbles/chats") {
45
- const service = resolveService(state);
46
- if (!service) {
47
- helpers.error(res, "bluebubbles service not registered", 503);
48
- return true;
49
- }
50
- const client = service.getClient();
51
- if (!client) {
52
- helpers.error(res, "bluebubbles client not available", 503);
53
- return true;
54
- }
55
- const url = new URL(req.url ?? pathname, "http://localhost");
56
- const limit = Math.min(Math.max(1, Number.parseInt(url.searchParams.get("limit") ?? "100", 10) || 100), 500);
57
- const offset = Math.max(0, Number.parseInt(url.searchParams.get("offset") ?? "0", 10) || 0);
58
- try {
59
- const chats = await client.listChats(limit, offset);
60
- helpers.json(res, { chats, count: chats.length, limit, offset });
61
- }
62
- catch (error) {
63
- helpers.error(res, `failed to read bluebubbles chats: ${error instanceof Error ? error.message : String(error)}`, 500);
64
- }
65
- return true;
66
- }
67
- if (method === "GET" && pathname === "/api/bluebubbles/messages") {
68
- const service = resolveService(state);
69
- if (!service) {
70
- helpers.error(res, "bluebubbles service not registered", 503);
71
- return true;
72
- }
73
- const client = service.getClient();
74
- if (!client) {
75
- helpers.error(res, "bluebubbles client not available", 503);
76
- return true;
77
- }
78
- const url = new URL(req.url ?? pathname, "http://localhost");
79
- const chatGuid = (url.searchParams.get("chatGuid") ?? "").trim();
80
- if (!chatGuid) {
81
- helpers.error(res, "chatGuid query parameter is required", 400);
82
- return true;
83
- }
84
- const limit = Math.min(Math.max(1, Number.parseInt(url.searchParams.get("limit") ?? "50", 10) || 50), 500);
85
- const offset = Math.max(0, Number.parseInt(url.searchParams.get("offset") ?? "0", 10) || 0);
86
- try {
87
- const messages = await client.getMessages(chatGuid, limit, offset);
88
- helpers.json(res, {
89
- chatGuid,
90
- messages,
91
- count: messages.length,
92
- limit,
93
- offset,
94
- });
95
- }
96
- catch (error) {
97
- helpers.error(res, `failed to read bluebubbles messages: ${error instanceof Error ? error.message : String(error)}`, 500);
98
- }
99
- return true;
100
- }
101
- if (method === "POST" && isWebhookPath) {
102
- const service = resolveService(state);
103
- if (!service) {
104
- helpers.error(res, "bluebubbles service not registered", 503);
105
- return true;
106
- }
107
- const payload = await helpers.readJsonBody(req, res, {
108
- maxBytes: MAX_BODY_BYTES,
109
- });
110
- if (!payload) {
111
- return true;
112
- }
113
- if (typeof payload.type !== "string" ||
114
- !payload.type.trim() ||
115
- typeof payload.data !== "object" ||
116
- payload.data === null ||
117
- Array.isArray(payload.data)) {
118
- helpers.error(res, "invalid BlueBubbles webhook payload", 400);
119
- return true;
120
- }
121
- try {
122
- await service.handleWebhook(payload);
123
- helpers.json(res, { ok: true });
124
- }
125
- catch (error) {
126
- helpers.error(res, `failed to handle bluebubbles webhook: ${error instanceof Error ? error.message : String(error)}`, 500);
127
- }
128
- return true;
129
- }
130
- return false;
131
- }
132
- //# sourceMappingURL=bluebubbles-routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bluebubbles-routes.js","sourceRoot":"","sources":["../../src/api/bluebubbles-routes.ts"],"names":[],"mappings":"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"}
@@ -1,80 +0,0 @@
1
- /**
2
- * iMessage connector HTTP routes.
3
- *
4
- * Exposes the @elizaos/plugin-imessage service state through Eliza's
5
- * HTTP API so downstream UI layers (the dashboard, a future CLI, third-
6
- * party integrations) can read and write against the macOS Messages.app
7
- * world without each client having to go straight to chat.db or to
8
- * AppleScript.
9
- *
10
- * Routes served (all under `/api/imessage`):
11
- *
12
- * GET /api/imessage/status service health + cursor + counts
13
- * GET /api/imessage/messages recent messages from chat.db
14
- * GET /api/imessage/chats list of chats (DMs + groups)
15
- * GET /api/imessage/contacts every contact with full detail
16
- * POST /api/imessage/contacts create a new contact
17
- * PATCH /api/imessage/contacts/:id update an existing contact
18
- * DELETE /api/imessage/contacts/:id delete a contact
19
- *
20
- * Each handler pulls the IMessageService instance off the runtime via
21
- * `runtime.getService("imessage")` and calls the public methods added
22
- * in the plugin's patched branch. If the service isn't registered (the
23
- * plugin isn't enabled, Eliza booted before it was loaded, etc.) we
24
- * return 503 with a structured reason so the UI can render an
25
- * informative empty state.
26
- *
27
- * Write endpoints (POST/PATCH/DELETE on contacts) touch the real macOS
28
- * Contacts.app and will trigger a one-time TCC permission prompt the
29
- * first time they fire. That prompt targets whichever process ran the
30
- * osascript child; in Eliza's case that's `bun`/`node`. Once granted
31
- * the permission is persistent across restarts.
32
- */
33
- import type http from "node:http";
34
- /**
35
- * Minimal structural copy of the agent's RouteHelpers / RouteRequestMeta
36
- * surface, inlined here so this file can live inside @elizaos/plugin-imessage
37
- * without taking a build-time dependency on @elizaos/agent.
38
- */
39
- export interface ReadJsonBodyOptions {
40
- maxBytes?: number;
41
- requireObject?: boolean;
42
- readErrorStatus?: number;
43
- nonObjectStatus?: number;
44
- parseErrorStatus?: number;
45
- readErrorMessage?: string;
46
- nonObjectMessage?: string;
47
- parseErrorMessage?: string;
48
- }
49
- export interface RouteRequestMeta {
50
- req: http.IncomingMessage;
51
- res: http.ServerResponse;
52
- method: string;
53
- pathname: string;
54
- }
55
- export interface RouteHelpers {
56
- json: (res: http.ServerResponse, data: unknown, status?: number) => void;
57
- error: (res: http.ServerResponse, message: string, status?: number) => void;
58
- readJsonBody: <T extends object>(req: http.IncomingMessage, res: http.ServerResponse, options?: ReadJsonBodyOptions) => Promise<T | null>;
59
- }
60
- export interface IMessageRouteState {
61
- /**
62
- * The running AgentRuntime (or a test stub). Typed loosely as
63
- * `unknown` so this route file doesn't re-declare core's stricter
64
- * generic getService signature — we narrow the result inside
65
- * resolveService via an unknown cast. Optional so route files
66
- * tolerate the boot window where the runtime hasn't finished
67
- * registering services yet.
68
- */
69
- runtime?: {
70
- getService(type: string): unknown;
71
- };
72
- }
73
- /**
74
- * Route handler entry point. Returns `true` when a route matched and
75
- * the response has been written; returns `false` so the caller can
76
- * continue to other route handlers (mirrors the handleWhatsAppRoute /
77
- * handleWalletRoute pattern used elsewhere in this codebase).
78
- */
79
- export declare function handleIMessageRoute(req: http.IncomingMessage, res: http.ServerResponse, pathname: string, method: string, state: IMessageRouteState, helpers: RouteHelpers): Promise<boolean>;
80
- //# sourceMappingURL=imessage-routes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"imessage-routes.d.ts","sourceRoot":"","sources":["../../src/api/imessage-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC;IAC1B,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5E,YAAY,EAAE,CAAC,CAAC,SAAS,MAAM,EAC7B,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,OAAO,CAAC,EAAE,mBAAmB,KAC1B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACxB;AA2ED,MAAM,WAAW,kBAAkB;IACjC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;KACnC,CAAC;CACH;AAyBD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,OAAO,CAAC,CA0NlB"}
@@ -1,230 +0,0 @@
1
- /**
2
- * iMessage connector HTTP routes.
3
- *
4
- * Exposes the @elizaos/plugin-imessage service state through Eliza's
5
- * HTTP API so downstream UI layers (the dashboard, a future CLI, third-
6
- * party integrations) can read and write against the macOS Messages.app
7
- * world without each client having to go straight to chat.db or to
8
- * AppleScript.
9
- *
10
- * Routes served (all under `/api/imessage`):
11
- *
12
- * GET /api/imessage/status service health + cursor + counts
13
- * GET /api/imessage/messages recent messages from chat.db
14
- * GET /api/imessage/chats list of chats (DMs + groups)
15
- * GET /api/imessage/contacts every contact with full detail
16
- * POST /api/imessage/contacts create a new contact
17
- * PATCH /api/imessage/contacts/:id update an existing contact
18
- * DELETE /api/imessage/contacts/:id delete a contact
19
- *
20
- * Each handler pulls the IMessageService instance off the runtime via
21
- * `runtime.getService("imessage")` and calls the public methods added
22
- * in the plugin's patched branch. If the service isn't registered (the
23
- * plugin isn't enabled, Eliza booted before it was loaded, etc.) we
24
- * return 503 with a structured reason so the UI can render an
25
- * informative empty state.
26
- *
27
- * Write endpoints (POST/PATCH/DELETE on contacts) touch the real macOS
28
- * Contacts.app and will trigger a one-time TCC permission prompt the
29
- * first time they fire. That prompt targets whichever process ran the
30
- * osascript child; in Eliza's case that's `bun`/`node`. Once granted
31
- * the permission is persistent across restarts.
32
- */
33
- const IMESSAGE_SERVICE_NAME = "imessage";
34
- const MAX_BODY_BYTES = 256 * 1024; // Contacts payloads are tiny; cap aggressively.
35
- function resolveService(state) {
36
- if (!state.runtime)
37
- return null;
38
- const raw = state.runtime.getService(IMESSAGE_SERVICE_NAME);
39
- return raw ?? null;
40
- }
41
- /**
42
- * Extract the `:id` segment from a contact path like
43
- * `/api/imessage/contacts/ABCD-EFGH-...`. Returns null if the path
44
- * doesn't match. The id is URL-decoded since Contacts.app ids are
45
- * GUID-style and safe, but callers could URL-encode for paranoia.
46
- */
47
- function parseContactId(pathname) {
48
- const prefix = "/api/imessage/contacts/";
49
- if (!pathname.startsWith(prefix))
50
- return null;
51
- const rest = pathname.slice(prefix.length);
52
- if (!rest)
53
- return null;
54
- return decodeURIComponent(rest);
55
- }
56
- /**
57
- * Route handler entry point. Returns `true` when a route matched and
58
- * the response has been written; returns `false` so the caller can
59
- * continue to other route handlers (mirrors the handleWhatsAppRoute /
60
- * handleWalletRoute pattern used elsewhere in this codebase).
61
- */
62
- export async function handleIMessageRoute(req, res, pathname, method, state, helpers) {
63
- if (!pathname.startsWith("/api/imessage"))
64
- return false;
65
- const meta = { req, res, method, pathname };
66
- // ── GET /api/imessage/status ──────────────────────────────────────
67
- if (method === "GET" && pathname === "/api/imessage/status") {
68
- const service = resolveService(state);
69
- if (!service) {
70
- helpers.json(res, {
71
- available: false,
72
- reason: "imessage service not registered",
73
- });
74
- return true;
75
- }
76
- helpers.json(res, {
77
- available: true,
78
- connected: service.isConnected(),
79
- ...(service.getStatus?.() ?? {}),
80
- });
81
- return true;
82
- }
83
- // ── GET /api/imessage/messages?limit=N ────────────────────────────
84
- if (method === "GET" && pathname === "/api/imessage/messages") {
85
- const service = resolveService(state);
86
- if (!service) {
87
- helpers.error(res, "imessage service not registered", 503);
88
- return true;
89
- }
90
- const url = new URL(req.url ?? pathname, "http://localhost");
91
- const limitParam = url.searchParams.get("limit");
92
- const limit = Math.min(Math.max(1, Number.parseInt(limitParam ?? "50", 10) || 50), 500);
93
- try {
94
- const messages = await service.getRecentMessages(limit);
95
- helpers.json(res, { messages, count: messages.length });
96
- }
97
- catch (error) {
98
- helpers.error(res, `failed to read messages: ${error instanceof Error ? error.message : String(error)}`, 500);
99
- }
100
- return true;
101
- }
102
- // ── GET /api/imessage/chats ───────────────────────────────────────
103
- if (method === "GET" && pathname === "/api/imessage/chats") {
104
- const service = resolveService(state);
105
- if (!service) {
106
- helpers.error(res, "imessage service not registered", 503);
107
- return true;
108
- }
109
- try {
110
- const chats = await service.getChats();
111
- helpers.json(res, { chats, count: chats.length });
112
- }
113
- catch (error) {
114
- helpers.error(res, `failed to read chats: ${error instanceof Error ? error.message : String(error)}`, 500);
115
- }
116
- return true;
117
- }
118
- // ── GET /api/imessage/contacts ────────────────────────────────────
119
- if (method === "GET" && pathname === "/api/imessage/contacts") {
120
- const service = resolveService(state);
121
- if (!service) {
122
- helpers.error(res, "imessage service not registered", 503);
123
- return true;
124
- }
125
- try {
126
- const contacts = await service.listAllContacts();
127
- helpers.json(res, { contacts, count: contacts.length });
128
- }
129
- catch (error) {
130
- helpers.error(res, `failed to read contacts: ${error instanceof Error ? error.message : String(error)}`, 500);
131
- }
132
- return true;
133
- }
134
- // ── POST /api/imessage/contacts ───────────────────────────────────
135
- if (method === "POST" && pathname === "/api/imessage/contacts") {
136
- const service = resolveService(state);
137
- if (!service) {
138
- helpers.error(res, "imessage service not registered", 503);
139
- return true;
140
- }
141
- const body = await helpers.readJsonBody(req, res, { maxBytes: MAX_BODY_BYTES });
142
- if (!body)
143
- return true; // helpers.readJsonBody has already sent the error.
144
- if (!body.firstName && !body.lastName && !body.phones?.length && !body.emails?.length) {
145
- helpers.error(res, "at least one of firstName, lastName, phones, or emails is required", 400);
146
- return true;
147
- }
148
- try {
149
- const id = await service.addContact({
150
- firstName: body.firstName,
151
- lastName: body.lastName,
152
- phones: body.phones,
153
- emails: body.emails,
154
- });
155
- if (!id) {
156
- helpers.error(res, "contact creation failed — see server logs. Common cause: Contacts write permission not granted yet.", 500);
157
- return true;
158
- }
159
- helpers.json(res, { id, created: true }, 201);
160
- }
161
- catch (error) {
162
- helpers.error(res, `addContact threw: ${error instanceof Error ? error.message : String(error)}`, 500);
163
- }
164
- return true;
165
- }
166
- // ── PATCH /api/imessage/contacts/:id ──────────────────────────────
167
- if (method === "PATCH" && pathname.startsWith("/api/imessage/contacts/")) {
168
- const id = parseContactId(pathname);
169
- if (!id) {
170
- helpers.error(res, "contact id is required in the path", 400);
171
- return true;
172
- }
173
- const service = resolveService(state);
174
- if (!service) {
175
- helpers.error(res, "imessage service not registered", 503);
176
- return true;
177
- }
178
- const body = await helpers.readJsonBody(req, res, { maxBytes: MAX_BODY_BYTES });
179
- if (!body)
180
- return true;
181
- try {
182
- const ok = await service.updateContact(id, {
183
- firstName: body.firstName,
184
- lastName: body.lastName,
185
- addPhones: body.addPhones,
186
- removePhones: body.removePhones,
187
- addEmails: body.addEmails,
188
- removeEmails: body.removeEmails,
189
- });
190
- if (!ok) {
191
- helpers.error(res, "contact update failed — see server logs. Contact may not exist, or write permission may be denied.", 500);
192
- return true;
193
- }
194
- helpers.json(res, { id, updated: true });
195
- }
196
- catch (error) {
197
- helpers.error(res, `updateContact threw: ${error instanceof Error ? error.message : String(error)}`, 500);
198
- }
199
- return true;
200
- }
201
- // ── DELETE /api/imessage/contacts/:id ─────────────────────────────
202
- if (method === "DELETE" && pathname.startsWith("/api/imessage/contacts/")) {
203
- const id = parseContactId(pathname);
204
- if (!id) {
205
- helpers.error(res, "contact id is required in the path", 400);
206
- return true;
207
- }
208
- const service = resolveService(state);
209
- if (!service) {
210
- helpers.error(res, "imessage service not registered", 503);
211
- return true;
212
- }
213
- try {
214
- const ok = await service.deleteContact(id);
215
- if (!ok) {
216
- helpers.error(res, "contact delete failed — see server logs. Contact may not exist, or write permission may be denied.", 500);
217
- return true;
218
- }
219
- helpers.json(res, { id, deleted: true });
220
- }
221
- catch (error) {
222
- helpers.error(res, `deleteContact threw: ${error instanceof Error ? error.message : String(error)}`, 500);
223
- }
224
- return true;
225
- }
226
- // Path starts with /api/imessage but none of the above matched.
227
- void meta; // reserved for future telemetry spans
228
- return false;
229
- }
230
- //# sourceMappingURL=imessage-routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"imessage-routes.js","sourceRoot":"","sources":["../../src/api/imessage-routes.ts"],"names":[],"mappings":"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"}