@xylex-group/athena 2.10.0 → 2.11.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.
Files changed (42) hide show
  1. package/README.md +112 -28
  2. package/dist/browser.cjs +38 -1
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.cts +3 -3
  5. package/dist/browser.d.ts +3 -3
  6. package/dist/browser.js +38 -1
  7. package/dist/browser.js.map +1 -1
  8. package/dist/cli/index.cjs +38 -1
  9. package/dist/cli/index.cjs.map +1 -1
  10. package/dist/cli/index.js +38 -1
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/{client-BYii6dU9.d.ts → client-DD_UeF3Q.d.ts} +2 -0
  13. package/dist/{client-B7EQ_hPV.d.cts → client-WqBuu60O.d.cts} +2 -0
  14. package/dist/index.cjs +38 -1
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +2 -2
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.js +38 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/{module-DC96HJa3.d.cts → module-BFMyVmwX.d.cts} +1 -1
  21. package/dist/{module-DbHlxpeR.d.ts → module-DRkIHtY-.d.ts} +1 -1
  22. package/dist/next/client.cjs +38 -1
  23. package/dist/next/client.cjs.map +1 -1
  24. package/dist/next/client.d.cts +2 -2
  25. package/dist/next/client.d.ts +2 -2
  26. package/dist/next/client.js +38 -1
  27. package/dist/next/client.js.map +1 -1
  28. package/dist/next/server.cjs +38 -1
  29. package/dist/next/server.cjs.map +1 -1
  30. package/dist/next/server.d.cts +2 -2
  31. package/dist/next/server.d.ts +2 -2
  32. package/dist/next/server.js +38 -1
  33. package/dist/next/server.js.map +1 -1
  34. package/dist/react.cjs +1 -1
  35. package/dist/react.cjs.map +1 -1
  36. package/dist/react.d.cts +1 -1
  37. package/dist/react.d.ts +1 -1
  38. package/dist/react.js +1 -1
  39. package/dist/react.js.map +1 -1
  40. package/dist/{shared-BMVGMnti.d.cts → shared-B1ueL-Ox.d.cts} +1 -1
  41. package/dist/{shared-DRptGBWP.d.ts → shared-GPAprhBb.d.ts} +1 -1
  42. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # athena-js
2
2
 
3
- current version: `2.10.0`
3
+ current version: `2.11.0`
4
4
  `@xylex-group/athena` is a database driver and API gateway SDK that lets you interact with SQL backends over HTTP through a fluent builder API. It ships a typed query builder for Node.js / server environments plus Athena-native React hooks for client-side use.
5
5
 
6
6
  ## Install
@@ -51,30 +51,38 @@ if (error) {
51
51
  }
52
52
  ```
53
53
 
54
- `createClient(url, key)` is the canonical SDK shape. The SDK treats `url` as the public unified Athena base URL and derives:
55
-
56
- - DB: `${url}/db`
57
- - Auth: `${url}/auth`
58
- - Storage: `${url}/storage`
54
+ `createClient(url, key)` is the canonical SDK shape. The SDK treats `url` as the public unified Athena base URL and derives:
55
+
56
+ - DB: `${url}/db`
57
+ - Auth: `${url}/auth`
58
+ - Chat: `${url}/chat`
59
+ - Chat realtime: `${url}` converted to `ws:` / `wss:` plus `/chat/ws`
60
+ - Storage: `${url}/storage`
59
61
 
60
62
  You can still override individual services when needed:
61
63
 
62
64
  ```ts
63
- const athena = createClient({
64
- key: ATHENA_API_KEY,
65
- db: { url: process.env.ATHENA_DB_URL },
66
- auth: { url: process.env.ATHENA_AUTH_URL },
67
- storage: { url: process.env.ATHENA_STORAGE_URL },
68
- });
69
- ```
65
+ const athena = createClient({
66
+ key: ATHENA_API_KEY,
67
+ db: { url: process.env.ATHENA_DB_URL },
68
+ auth: { url: process.env.ATHENA_AUTH_URL },
69
+ chat: {
70
+ url: process.env.ATHENA_CHAT_URL,
71
+ wsUrl: process.env.ATHENA_CHAT_WS_URL,
72
+ },
73
+ storage: { url: process.env.ATHENA_STORAGE_URL },
74
+ });
75
+ ```
70
76
 
71
77
  Legacy top-level aliases are also supported:
72
78
 
73
79
  ```ts
74
80
  const athena = createClient({
75
- key: ATHENA_API_KEY,
76
- gatewayUrl: process.env.ATHENA_DB_URL,
77
- authUrl: process.env.ATHENA_AUTH_URL,
81
+ key: ATHENA_API_KEY,
82
+ gatewayUrl: process.env.ATHENA_DB_URL,
83
+ authUrl: process.env.ATHENA_AUTH_URL,
84
+ chatUrl: process.env.ATHENA_CHAT_URL,
85
+ chatWsUrl: process.env.ATHENA_CHAT_WS_URL,
78
86
  storageUrl: process.env.ATHENA_STORAGE_URL,
79
87
  });
80
88
  ```
@@ -115,6 +123,42 @@ Use `withOptions(...)` only when you intentionally need to re-target the client
115
123
 
116
124
  If you already pass `client: "web-dashboard"`, the SDK sends `X-Athena-Client` for you. You do not need to duplicate that header manually.
117
125
 
126
+ ### Low-level request hatch
127
+
128
+ If you need to hit a route the fluent SDK has not wrapped yet, use `client.request(...)`:
129
+
130
+ ```ts
131
+ const athena = createClient(ATHENA_URL, ATHENA_API_KEY, {
132
+ auth: {
133
+ baseUrl: AUTH_BASE_URL,
134
+ credentials: "include",
135
+ },
136
+ });
137
+
138
+ const response = await athena.request<{
139
+ ok: boolean;
140
+ }>({
141
+ service: "chat",
142
+ method: "POST",
143
+ path: "/rooms",
144
+ body: {
145
+ slug: "support",
146
+ name: "Support",
147
+ },
148
+ });
149
+
150
+ if (!response.ok) {
151
+ throw new Error(`chat route failed: ${response.status}`);
152
+ }
153
+ ```
154
+
155
+ Rules:
156
+
157
+ - use `service: "db" | "auth" | "chat" | "storage"` plus `path` for configured SDK services
158
+ - use `url` for absolute one-off targets
159
+ - `query`, `headers`, `body`, `signal`, `credentials`, and `responseType` are supported
160
+ - auth/session, API key, org/user context, and client headers are mirrored onto configured service calls automatically
161
+
118
162
  ### Next.js and React shortcuts
119
163
 
120
164
  If you are in a Next.js app, use the higher-level adapters instead of rebuilding request context by hand:
@@ -248,12 +292,12 @@ function WelcomeEmail(props: { name: string }) {
248
292
  );
249
293
  }
250
294
 
251
- await athena.auth.admin.email.template.create({
252
- templateKey: "welcome",
253
- subjectTemplate: "Welcome",
254
- react: {
255
- component: WelcomeEmail,
256
- props: { name: "Ava" },
295
+ await athena.auth.admin.email.template.create({
296
+ template_key: "welcome",
297
+ subject_template: "Welcome",
298
+ react: {
299
+ component: WelcomeEmail,
300
+ props: { name: "Ava" },
257
301
  },
258
302
  });
259
303
  ```
@@ -263,11 +307,11 @@ For reusable templates, use `defineAuthEmailTemplate(...)`:
263
307
  ```ts
264
308
  import { defineAuthEmailTemplate } from "@xylex-group/athena";
265
309
 
266
- const welcomeTemplate = defineAuthEmailTemplate({
267
- component: WelcomeEmail,
268
- templateKey: "welcome",
269
- subjectTemplate: "Welcome",
270
- });
310
+ const welcomeTemplate = defineAuthEmailTemplate({
311
+ component: WelcomeEmail,
312
+ templateKey: "welcome",
313
+ subjectTemplate: "Welcome",
314
+ });
271
315
 
272
316
  await athena.auth.admin.email.template.create(
273
317
  welcomeTemplate.toTemplateCreate({
@@ -297,7 +341,47 @@ Install support packages in your app:
297
341
  pnpm add @react-email/components @react-email/render
298
342
  ```
299
343
 
300
- Auth responses follow the same envelope style: `{ ok, status, data, error, errorDetails, raw }`.
344
+ Auth responses follow the same envelope style: `{ ok, status, data, error, errorDetails, raw }`.
345
+
346
+ #### Chat module
347
+
348
+ The root client now exposes `client.chat` for room, message, search, and realtime flows:
349
+
350
+ ```ts
351
+ const athena = createClient(ATHENA_URL, ATHENA_API_KEY, {
352
+ chatWsUrl: process.env.ATHENA_CHAT_WS_URL,
353
+ });
354
+
355
+ const rooms = await athena.chat.room.list({ limit: 20 });
356
+ const created = await athena.chat.room.create({
357
+ slug: "engineering",
358
+ name: "Engineering",
359
+ });
360
+
361
+ await athena.chat.room.message.send(created.data?.id ?? "room_1", {
362
+ body: "Hello team",
363
+ });
364
+
365
+ const socket = athena.chat.realtime.connect({
366
+ token: "chat_token",
367
+ onMessage(event) {
368
+ console.log(event);
369
+ },
370
+ });
371
+
372
+ socket.ping();
373
+ socket.close();
374
+ ```
375
+
376
+ Available chat surfaces:
377
+
378
+ - `chat.room.list/create/get/update/archive`
379
+ - `chat.room.readCursor.upTo`
380
+ - `chat.room.member.list/add/remove`
381
+ - `chat.room.message.list/send/update/delete`
382
+ - `chat.message.reaction.add/remove`
383
+ - `chat.message.search`
384
+ - `chat.realtime.info/connect`
301
385
 
302
386
  #### Native auth bootstrap helpers
303
387
 
package/dist/browser.cjs CHANGED
@@ -802,7 +802,7 @@ var getCookieCache = async (request2, config) => {
802
802
 
803
803
  // package.json
804
804
  var package_default = {
805
- version: "2.10.0"
805
+ version: "2.11.0"
806
806
  };
807
807
 
808
808
  // src/sdk-version.ts
@@ -1863,6 +1863,21 @@ function copyDefinedField(target, source, targetKey, sourceKey) {
1863
1863
  target[targetKey] = value;
1864
1864
  }
1865
1865
  }
1866
+ function normalizeEmailTemplateAttachmentsValue(value) {
1867
+ if (typeof value === "string" || value == null) {
1868
+ return value;
1869
+ }
1870
+ if (Array.isArray(value)) {
1871
+ return value.map((item) => normalizeEmailTemplateAttachmentsValue(item));
1872
+ }
1873
+ if (typeof value !== "object") {
1874
+ return value;
1875
+ }
1876
+ const attachment = { ...value };
1877
+ copyDefinedField(attachment, attachment, "file_url", "fileUrl");
1878
+ delete attachment.fileUrl;
1879
+ return attachment;
1880
+ }
1866
1881
  function normalizeAdminEmailTemplatePayload(payload) {
1867
1882
  const normalized = { ...payload };
1868
1883
  copyDefinedField(normalized, payload, "template_key", "templateKey");
@@ -1873,6 +1888,17 @@ function normalizeAdminEmailTemplatePayload(payload) {
1873
1888
  copyDefinedField(normalized, payload, "variable_bindings", "variableBindings");
1874
1889
  copyDefinedField(normalized, payload, "attachment_failure_mode", "attachmentFailureMode");
1875
1890
  copyDefinedField(normalized, payload, "is_active", "isActive");
1891
+ if (Object.hasOwn(payload, "attachments")) {
1892
+ normalized.attachments = normalizeEmailTemplateAttachmentsValue(payload.attachments);
1893
+ }
1894
+ delete normalized.templateKey;
1895
+ delete normalized.eventType;
1896
+ delete normalized.subjectTemplate;
1897
+ delete normalized.textTemplate;
1898
+ delete normalized.htmlTemplate;
1899
+ delete normalized.variableBindings;
1900
+ delete normalized.attachmentFailureMode;
1901
+ delete normalized.isActive;
1876
1902
  return normalized;
1877
1903
  }
1878
1904
  function toReactEmailTemplateCompatibilityInput(input) {
@@ -1896,6 +1922,17 @@ function normalizeAdminEmailTemplateSendPayload(payload) {
1896
1922
  copyDefinedField(normalized, payload, "user_id", "userId");
1897
1923
  copyDefinedField(normalized, payload, "organization_id", "organizationId");
1898
1924
  copyDefinedField(normalized, payload, "session_token", "sessionToken");
1925
+ copyDefinedField(normalized, payload, "attachment_failure_mode", "attachmentFailureMode");
1926
+ if (Object.hasOwn(payload, "attachments")) {
1927
+ normalized.attachments = normalizeEmailTemplateAttachmentsValue(payload.attachments);
1928
+ }
1929
+ delete normalized.templateId;
1930
+ delete normalized.recipientEmail;
1931
+ delete normalized.renderVariables;
1932
+ delete normalized.userId;
1933
+ delete normalized.organizationId;
1934
+ delete normalized.sessionToken;
1935
+ delete normalized.attachmentFailureMode;
1899
1936
  return normalized;
1900
1937
  }
1901
1938
  function toSessionGuardFailure(sessionResult) {