@xylex-group/athena 3.1.0 → 3.3.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 (82) hide show
  1. package/README.md +1 -1
  2. package/dist/admin.cjs +55 -1
  3. package/dist/admin.cjs.map +1 -1
  4. package/dist/admin.d.cts +32 -8
  5. package/dist/admin.d.ts +32 -8
  6. package/dist/admin.js +54 -2
  7. package/dist/admin.js.map +1 -1
  8. package/dist/athena-auth-url-C1FbVmN6.d.cts +200 -0
  9. package/dist/athena-auth-url-C1FbVmN6.d.ts +200 -0
  10. package/dist/{athena-request-headers-C7Jy-c_D.d.ts → athena-request-headers-DzimbvOA.d.ts} +48 -200
  11. package/dist/{athena-request-headers-DujFFyMU.d.cts → athena-request-headers-Lr_m8xCV.d.cts} +48 -200
  12. package/dist/billing.cjs +1 -1
  13. package/dist/billing.cjs.map +1 -1
  14. package/dist/billing.js +1 -1
  15. package/dist/billing.js.map +1 -1
  16. package/dist/browser.cjs +602 -16
  17. package/dist/browser.cjs.map +1 -1
  18. package/dist/browser.d.cts +8 -7
  19. package/dist/browser.d.ts +8 -7
  20. package/dist/browser.js +593 -17
  21. package/dist/browser.js.map +1 -1
  22. package/dist/cli/index.cjs +141 -6
  23. package/dist/cli/index.cjs.map +1 -1
  24. package/dist/cli/index.d.cts +2 -2
  25. package/dist/cli/index.d.ts +2 -2
  26. package/dist/cli/index.js +141 -6
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/env.cjs +130 -0
  29. package/dist/env.cjs.map +1 -0
  30. package/dist/env.d.cts +70 -0
  31. package/dist/env.d.ts +70 -0
  32. package/dist/env.js +122 -0
  33. package/dist/env.js.map +1 -0
  34. package/dist/index.cjs +624 -19
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +8 -7
  37. package/dist/index.d.ts +8 -7
  38. package/dist/index.js +615 -20
  39. package/dist/index.js.map +1 -1
  40. package/dist/{model-form-BhWWsA-7.d.cts → model-form-3Gr8rkdT.d.cts} +24 -2
  41. package/dist/{model-form-BbdzJ9Uh.d.ts → model-form-CotpEL7z.d.ts} +24 -2
  42. package/dist/{module-xFd7_Igv.d.cts → module-CQmOaDzP.d.cts} +4 -4
  43. package/dist/{module-DKkJKOuJ.d.ts → module-CWkUTcUc.d.ts} +4 -4
  44. package/dist/next/client.cjs +123 -7
  45. package/dist/next/client.cjs.map +1 -1
  46. package/dist/next/client.d.cts +4 -3
  47. package/dist/next/client.d.ts +4 -3
  48. package/dist/next/client.js +123 -7
  49. package/dist/next/client.js.map +1 -1
  50. package/dist/next/server.cjs +1130 -364
  51. package/dist/next/server.cjs.map +1 -1
  52. package/dist/next/server.d.cts +121 -8
  53. package/dist/next/server.d.ts +121 -8
  54. package/dist/next/server.js +1120 -365
  55. package/dist/next/server.js.map +1 -1
  56. package/dist/{pipeline-DuKzYGia.d.cts → pipeline-BnRKO_Pd.d.cts} +1 -1
  57. package/dist/{pipeline-wer2G9xW.d.ts → pipeline-sWCmlFqu.d.ts} +1 -1
  58. package/dist/{proxy-request-headers-m4D2Tduy.d.ts → proxy-request-headers-CttlcuRb.d.ts} +1 -1
  59. package/dist/{proxy-request-headers-DGxdoyA0.d.cts → proxy-request-headers-pIBSn1Fw.d.cts} +1 -1
  60. package/dist/react.cjs +290 -31
  61. package/dist/react.cjs.map +1 -1
  62. package/dist/react.d.cts +59 -9
  63. package/dist/react.d.ts +59 -9
  64. package/dist/react.js +290 -32
  65. package/dist/react.js.map +1 -1
  66. package/dist/schema-handlers-BtT_IQFi.d.cts +138 -0
  67. package/dist/schema-handlers-VjFDhIMw.d.ts +138 -0
  68. package/dist/social-providers.d.cts +1 -1
  69. package/dist/social-providers.d.ts +1 -1
  70. package/dist/{types-CccOiXPo.d.ts → types-BDX8zS7w.d.ts} +12 -0
  71. package/dist/{types-AOY-GLu8.d.cts → types-BVKpQmfY.d.cts} +11 -0
  72. package/dist/{types-AOY-GLu8.d.ts → types-BVKpQmfY.d.ts} +11 -0
  73. package/dist/{types-1ztXDgPa.d.cts → types-D-Am7YSd.d.cts} +12 -0
  74. package/dist/utils.cjs +30 -0
  75. package/dist/utils.cjs.map +1 -1
  76. package/dist/utils.d.cts +3 -2
  77. package/dist/utils.d.ts +3 -2
  78. package/dist/utils.js +30 -1
  79. package/dist/utils.js.map +1 -1
  80. package/dist/{v3-client-CWfZHcKL.d.cts → v3-client-G1SLeHRa.d.cts} +23 -1
  81. package/dist/{v3-client-DZp2NEhK.d.ts → v3-client-ao8BWQ8v.d.ts} +23 -1
  82. package/package.json +16 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @xylex-group/athena
2
2
 
3
- current version: `3.1.0`
3
+ current version: `3.3.0`
4
4
  Athena JS 3 is the runtime-neutral TypeScript SDK for Athena database, authentication, chat, and storage services.
5
5
 
6
6
  ## Install
package/dist/admin.cjs CHANGED
@@ -1,6 +1,36 @@
1
1
  'use strict';
2
2
 
3
3
  // src/admin/index.ts
4
+ function resolveAdminPermissionClient(client) {
5
+ if (!client || typeof client !== "object") {
6
+ return null;
7
+ }
8
+ const record = client;
9
+ const nestedAuth = record.auth;
10
+ if (nestedAuth && typeof nestedAuth === "object" && nestedAuth !== null && "admin" in nestedAuth) {
11
+ return client;
12
+ }
13
+ if ("admin" in record) {
14
+ return { auth: client };
15
+ }
16
+ return null;
17
+ }
18
+ function buildAdminAuthFetchOptions(credentials = {}) {
19
+ const cookie = credentials.cookie?.trim() || void 0;
20
+ const bearerToken = credentials.bearerToken?.trim() || void 0;
21
+ const headers = {};
22
+ if (cookie) {
23
+ headers.cookie = cookie;
24
+ }
25
+ if (bearerToken) {
26
+ headers.authorization = `Bearer ${bearerToken}`;
27
+ }
28
+ return {
29
+ credentials: "include",
30
+ ...bearerToken ? { bearerToken } : {},
31
+ ...Object.keys(headers).length > 0 ? { headers } : {}
32
+ };
33
+ }
4
34
  function hasAdminRole(session) {
5
35
  const role = session?.user?.role;
6
36
  if (!role) {
@@ -8,6 +38,27 @@ function hasAdminRole(session) {
8
38
  }
9
39
  return role.split(",").map((item) => item.trim().toLowerCase()).includes("admin");
10
40
  }
41
+ function mergeAdminFetchOptions(input) {
42
+ const fromCredentials = input.credentials ? buildAdminAuthFetchOptions(input.credentials) : void 0;
43
+ const explicit = input.fetchOptions;
44
+ if (!fromCredentials && !explicit) {
45
+ return void 0;
46
+ }
47
+ if (!fromCredentials) {
48
+ return explicit;
49
+ }
50
+ if (!explicit) {
51
+ return fromCredentials;
52
+ }
53
+ return {
54
+ ...fromCredentials,
55
+ ...explicit,
56
+ headers: {
57
+ ...fromCredentials.headers ?? {},
58
+ ...explicit.headers ?? {}
59
+ }
60
+ };
61
+ }
11
62
  async function hasAdminPermission(client, input) {
12
63
  if (!input.session?.user?.id) {
13
64
  return false;
@@ -15,11 +66,12 @@ async function hasAdminPermission(client, input) {
15
66
  if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {
16
67
  return true;
17
68
  }
69
+ const fetchOptions = mergeAdminFetchOptions(input);
18
70
  const result = await client.auth.admin.hasPermission(
19
71
  {
20
72
  permission: input.permission,
21
73
  permissions: input.permissions,
22
- ...input.fetchOptions ? { fetchOptions: input.fetchOptions } : {}
74
+ ...fetchOptions ? { fetchOptions } : {}
23
75
  },
24
76
  input.requestOptions
25
77
  );
@@ -38,8 +90,10 @@ async function resolveAdminPermission(client, input) {
38
90
  };
39
91
  }
40
92
 
93
+ exports.buildAdminAuthFetchOptions = buildAdminAuthFetchOptions;
41
94
  exports.hasAdminPermission = hasAdminPermission;
42
95
  exports.hasAdminRole = hasAdminRole;
43
96
  exports.resolveAdminPermission = resolveAdminPermission;
97
+ exports.resolveAdminPermissionClient = resolveAdminPermissionClient;
44
98
  //# sourceMappingURL=admin.cjs.map
45
99
  //# sourceMappingURL=admin.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/admin/index.ts"],"names":[],"mappings":";;;AA4DO,SAAS,aACd,OAAA,EACS;AACT,EAAA,MAAM,IAAA,GAAO,SAAS,IAAA,EAAM,IAAA;AAC5B,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CACJ,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAA,IAAA,KAAQ,IAAA,CAAK,IAAA,EAAK,CAAE,WAAA,EAAa,CAAA,CACrC,SAAS,OAAO,CAAA;AACrB;AAQA,eAAsB,kBAAA,CACpB,QACA,KAAA,EACkB;AAClB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,EAAS,IAAA,EAAM,EAAA,EAAI;AAC5B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAM,eAAA,KAAoB,KAAA,IAAS,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA,EAAG;AAClE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,aAAA;AAAA,IACrC;AAAA,MACE,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,GAAI,MAAM,YAAA,GAAe,EAAE,cAAc,KAAA,CAAM,YAAA,KAAiB;AAAC,KACnE;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AAEA,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,EAAA,IAAM,MAAA,CAAO,MAAM,OAAO,CAAA;AAClD;AAQA,eAAsB,sBAAA,CAGpB,QACA,KAAA,EAGgD;AAChD,EAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,OAAO,cAAA,EAAe;AAAA,EACzD;AAEA,EAAA,IAAI,CAAE,MAAM,kBAAA,CAAmB,MAAA,EAAQ,KAAK,CAAA,EAAI;AAC9C,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,OAAO,WAAA,EAAY;AAAA,EACtD;AAEA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,SAAS,KAAA,CAAM;AAAA,GACjB;AACF","file":"admin.cjs","sourcesContent":["import type {\n AthenaAdminHasPermissionRequest,\n AthenaAuthBindings,\n AthenaAuthCallOptions,\n AthenaAuthFetchCompatibleInput,\n} from '../auth/types.ts'\n\n/**\n * Minimal session shape used by the admin convenience helpers.\n *\n * This stays framework-agnostic so callers can pass Athena auth sessions,\n * app-local session wrappers, or request-derived session snapshots.\n */\nexport interface AthenaAdminSessionLike {\n user?: {\n id?: string | null | undefined\n role?: string | null | undefined\n } | null | undefined\n session?: {\n token?: string | null | undefined\n activeOrganizationId?: string | null | undefined\n } | null | undefined\n}\n\nexport interface AthenaAdminPermissionClient {\n auth: Pick<AthenaAuthBindings, 'admin'>\n}\n\nexport interface AthenaAdminPermissionCheckInput {\n session: AthenaAdminSessionLike | null | undefined\n permissions: AthenaAdminHasPermissionRequest['permissions']\n permission?: AthenaAdminHasPermissionRequest['permission']\n fetchOptions?: AthenaAuthFetchCompatibleInput['fetchOptions']\n requestOptions?: AthenaAuthCallOptions\n allowRoleBypass?: boolean\n}\n\nexport interface AthenaAdminPermissionSuccess<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> {\n ok: true\n session: NonNullable<TSession>\n}\n\nexport interface AthenaAdminPermissionFailure {\n ok: false\n status: 401 | 403\n error: 'Unauthorized' | 'Forbidden'\n}\n\nexport type AthenaAdminPermissionResult<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> = AthenaAdminPermissionSuccess<TSession> | AthenaAdminPermissionFailure\n\n/**\n * Returns true when the session user already carries the `admin` role locally.\n *\n * Role strings are treated as a comma-separated list and normalized\n * case-insensitively so `\"admin\"`, `\"ADMIN\"`, and `\"member, admin\"` all pass.\n */\nexport function hasAdminRole(\n session: AthenaAdminSessionLike | null | undefined,\n): boolean {\n const role = session?.user?.role\n if (!role) {\n return false\n }\n\n return role\n .split(',')\n .map(item => item.trim().toLowerCase())\n .includes('admin')\n}\n\n/**\n * Checks admin permission against the configured Athena auth client.\n *\n * This helper short-circuits when no session user is present and, by default,\n * trusts a local `admin` role before calling `client.auth.admin.hasPermission(...)`.\n */\nexport async function hasAdminPermission(\n client: AthenaAdminPermissionClient,\n input: AthenaAdminPermissionCheckInput,\n): Promise<boolean> {\n if (!input.session?.user?.id) {\n return false\n }\n\n if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {\n return true\n }\n\n const result = await client.auth.admin.hasPermission(\n {\n permission: input.permission,\n permissions: input.permissions,\n ...(input.fetchOptions ? { fetchOptions: input.fetchOptions } : {}),\n },\n input.requestOptions,\n )\n\n return Boolean(result.ok && result.data?.success)\n}\n\n/**\n * Resolves an admin permission check into a small framework-agnostic guard result.\n *\n * Consumers can map the returned `{ ok, status, error }` shape into Next.js,\n * Hono, Express, or any other response layer without importing framework types here.\n */\nexport async function resolveAdminPermission<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n>(\n client: AthenaAdminPermissionClient,\n input: Omit<AthenaAdminPermissionCheckInput, 'session'> & {\n session: TSession | null | undefined\n },\n): Promise<AthenaAdminPermissionResult<TSession>> {\n if (!input.session) {\n return { ok: false, status: 401, error: 'Unauthorized' }\n }\n\n if (!(await hasAdminPermission(client, input))) {\n return { ok: false, status: 403, error: 'Forbidden' }\n }\n\n return {\n ok: true,\n session: input.session as NonNullable<TSession>,\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/admin/index.ts"],"names":[],"mappings":"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","file":"admin.cjs","sourcesContent":["import type {\n AthenaAdminHasPermissionRequest,\n AthenaAuthBindings,\n AthenaAuthCallOptions,\n AthenaAuthFetchCompatibleInput,\n} from '../auth/types.ts'\n\n/**\n * Minimal session shape used by the admin convenience helpers.\n *\n * This stays framework-agnostic so callers can pass Athena auth sessions,\n * app-local session wrappers, or request-derived session snapshots.\n */\nexport interface AthenaAdminSessionLike {\n user?: {\n id?: string | null | undefined\n role?: string | null | undefined\n } | null | undefined\n session?: {\n token?: string | null | undefined\n activeOrganizationId?: string | null | undefined\n } | null | undefined\n}\n\nexport interface AthenaAdminPermissionClient {\n auth: Pick<AthenaAuthBindings, 'admin'>\n}\n\n/**\n * Normalizes common Athena client shapes into the admin-permission client contract.\n *\n * Accepts:\n * - `createClient(...)` → `{ auth: { admin } }`\n * - auth bindings only → `{ admin, … }` wrapped as `{ auth: bindings }`\n */\nexport function resolveAdminPermissionClient(\n client: unknown,\n): AthenaAdminPermissionClient | null {\n if (!client || typeof client !== 'object') {\n return null\n }\n\n const record = client as Record<string, unknown>\n const nestedAuth = record.auth\n\n if (\n nestedAuth &&\n typeof nestedAuth === 'object' &&\n nestedAuth !== null &&\n 'admin' in nestedAuth\n ) {\n return client as AthenaAdminPermissionClient\n }\n\n if ('admin' in record) {\n return { auth: client as Pick<AthenaAuthBindings, 'admin'> }\n }\n\n return null\n}\n\n/**\n * Request credentials for admin permission checks without manual cookie\n * string matching. Prefer these over assembling `fetchOptions` by hand.\n */\nexport interface AthenaAdminRequestCredentials {\n /** Raw `Cookie` header value from the current request. */\n cookie?: string | null\n /** Bearer token (without the `Bearer ` prefix). */\n bearerToken?: string | null\n}\n\n/**\n * Build auth `fetchOptions` for admin routes from cookie and/or bearer.\n *\n * Replaces app helpers that inspect cookie strings for `athena-auth` /\n * `better-auth` prefixes before calling `hasPermission`.\n */\nexport function buildAdminAuthFetchOptions(\n credentials: AthenaAdminRequestCredentials = {},\n): NonNullable<AthenaAuthFetchCompatibleInput['fetchOptions']> {\n const cookie = credentials.cookie?.trim() || undefined\n const bearerToken = credentials.bearerToken?.trim() || undefined\n const headers: Record<string, string> = {}\n if (cookie) {\n headers.cookie = cookie\n }\n if (bearerToken) {\n headers.authorization = `Bearer ${bearerToken}`\n }\n return {\n credentials: 'include',\n ...(bearerToken ? { bearerToken } : {}),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n }\n}\n\nexport interface AthenaAdminPermissionCheckInput {\n session: AthenaAdminSessionLike | null | undefined\n permissions: AthenaAdminHasPermissionRequest['permissions']\n permission?: AthenaAdminHasPermissionRequest['permission']\n fetchOptions?: AthenaAuthFetchCompatibleInput['fetchOptions']\n /**\n * Cookie/bearer from the request. Merged under any explicit `fetchOptions`\n * (explicit keys win on shallow header merge).\n */\n credentials?: AthenaAdminRequestCredentials\n requestOptions?: AthenaAuthCallOptions\n allowRoleBypass?: boolean\n}\n\nexport interface AthenaAdminPermissionSuccess<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> {\n ok: true\n session: NonNullable<TSession>\n}\n\nexport interface AthenaAdminPermissionFailure {\n ok: false\n status: 401 | 403\n error: 'Unauthorized' | 'Forbidden'\n}\n\nexport type AthenaAdminPermissionResult<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> = AthenaAdminPermissionSuccess<TSession> | AthenaAdminPermissionFailure\n\n/**\n * Returns true when the session user already carries the `admin` role locally.\n *\n * Role strings are treated as a comma-separated list and normalized\n * case-insensitively so `\"admin\"`, `\"ADMIN\"`, and `\"member, admin\"` all pass.\n */\nexport function hasAdminRole(\n session: AthenaAdminSessionLike | null | undefined,\n): boolean {\n const role = session?.user?.role\n if (!role) {\n return false\n }\n\n return role\n .split(',')\n .map(item => item.trim().toLowerCase())\n .includes('admin')\n}\n\n/**\n * Checks admin permission against the configured Athena auth client.\n *\n * This helper short-circuits when no session user is present and, by default,\n * trusts a local `admin` role before calling `client.auth.admin.hasPermission(...)`.\n */\nfunction mergeAdminFetchOptions(\n input: AthenaAdminPermissionCheckInput,\n): AthenaAuthFetchCompatibleInput['fetchOptions'] | undefined {\n const fromCredentials = input.credentials\n ? buildAdminAuthFetchOptions(input.credentials)\n : undefined\n const explicit = input.fetchOptions\n if (!fromCredentials && !explicit) {\n return undefined\n }\n if (!fromCredentials) {\n return explicit\n }\n if (!explicit) {\n return fromCredentials\n }\n return {\n ...fromCredentials,\n ...explicit,\n headers: {\n ...(fromCredentials.headers ?? {}),\n ...(explicit.headers ?? {}),\n },\n }\n}\n\nexport async function hasAdminPermission(\n client: AthenaAdminPermissionClient,\n input: AthenaAdminPermissionCheckInput,\n): Promise<boolean> {\n if (!input.session?.user?.id) {\n return false\n }\n\n if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {\n return true\n }\n\n const fetchOptions = mergeAdminFetchOptions(input)\n\n const result = await client.auth.admin.hasPermission(\n {\n permission: input.permission,\n permissions: input.permissions,\n ...(fetchOptions ? { fetchOptions } : {}),\n },\n input.requestOptions,\n )\n\n return Boolean(result.ok && result.data?.success)\n}\n\n/**\n * Resolves an admin permission check into a small framework-agnostic guard result.\n *\n * Consumers can map the returned `{ ok, status, error }` shape into Next.js,\n * Hono, Express, or any other response layer without importing framework types here.\n */\nexport async function resolveAdminPermission<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n>(\n client: AthenaAdminPermissionClient,\n input: Omit<AthenaAdminPermissionCheckInput, 'session'> & {\n session: TSession | null | undefined\n },\n): Promise<AthenaAdminPermissionResult<TSession>> {\n if (!input.session) {\n return { ok: false, status: 401, error: 'Unauthorized' }\n }\n\n if (!(await hasAdminPermission(client, input))) {\n return { ok: false, status: 403, error: 'Forbidden' }\n }\n\n return {\n ok: true,\n session: input.session as NonNullable<TSession>,\n }\n}\n"]}
package/dist/admin.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { aD as AthenaAdminHasPermissionRequest, aE as AthenaAuthFetchCompatibleInput, E as AthenaAuthCallOptions, D as AthenaAuthBindings } from './types-AOY-GLu8.cjs';
1
+ import { aD as AthenaAdminHasPermissionRequest, aE as AthenaAuthFetchCompatibleInput, E as AthenaAuthCallOptions, D as AthenaAuthBindings } from './types-BVKpQmfY.cjs';
2
2
 
3
3
  /**
4
4
  * Minimal session shape used by the admin convenience helpers.
@@ -19,11 +19,41 @@ interface AthenaAdminSessionLike {
19
19
  interface AthenaAdminPermissionClient {
20
20
  auth: Pick<AthenaAuthBindings, 'admin'>;
21
21
  }
22
+ /**
23
+ * Normalizes common Athena client shapes into the admin-permission client contract.
24
+ *
25
+ * Accepts:
26
+ * - `createClient(...)` → `{ auth: { admin } }`
27
+ * - auth bindings only → `{ admin, … }` wrapped as `{ auth: bindings }`
28
+ */
29
+ declare function resolveAdminPermissionClient(client: unknown): AthenaAdminPermissionClient | null;
30
+ /**
31
+ * Request credentials for admin permission checks without manual cookie
32
+ * string matching. Prefer these over assembling `fetchOptions` by hand.
33
+ */
34
+ interface AthenaAdminRequestCredentials {
35
+ /** Raw `Cookie` header value from the current request. */
36
+ cookie?: string | null;
37
+ /** Bearer token (without the `Bearer ` prefix). */
38
+ bearerToken?: string | null;
39
+ }
40
+ /**
41
+ * Build auth `fetchOptions` for admin routes from cookie and/or bearer.
42
+ *
43
+ * Replaces app helpers that inspect cookie strings for `athena-auth` /
44
+ * `better-auth` prefixes before calling `hasPermission`.
45
+ */
46
+ declare function buildAdminAuthFetchOptions(credentials?: AthenaAdminRequestCredentials): NonNullable<AthenaAuthFetchCompatibleInput['fetchOptions']>;
22
47
  interface AthenaAdminPermissionCheckInput {
23
48
  session: AthenaAdminSessionLike | null | undefined;
24
49
  permissions: AthenaAdminHasPermissionRequest['permissions'];
25
50
  permission?: AthenaAdminHasPermissionRequest['permission'];
26
51
  fetchOptions?: AthenaAuthFetchCompatibleInput['fetchOptions'];
52
+ /**
53
+ * Cookie/bearer from the request. Merged under any explicit `fetchOptions`
54
+ * (explicit keys win on shallow header merge).
55
+ */
56
+ credentials?: AthenaAdminRequestCredentials;
27
57
  requestOptions?: AthenaAuthCallOptions;
28
58
  allowRoleBypass?: boolean;
29
59
  }
@@ -44,12 +74,6 @@ type AthenaAdminPermissionResult<TSession extends AthenaAdminSessionLike = Athen
44
74
  * case-insensitively so `"admin"`, `"ADMIN"`, and `"member, admin"` all pass.
45
75
  */
46
76
  declare function hasAdminRole(session: AthenaAdminSessionLike | null | undefined): boolean;
47
- /**
48
- * Checks admin permission against the configured Athena auth client.
49
- *
50
- * This helper short-circuits when no session user is present and, by default,
51
- * trusts a local `admin` role before calling `client.auth.admin.hasPermission(...)`.
52
- */
53
77
  declare function hasAdminPermission(client: AthenaAdminPermissionClient, input: AthenaAdminPermissionCheckInput): Promise<boolean>;
54
78
  /**
55
79
  * Resolves an admin permission check into a small framework-agnostic guard result.
@@ -61,4 +85,4 @@ declare function resolveAdminPermission<TSession extends AthenaAdminSessionLike
61
85
  session: TSession | null | undefined;
62
86
  }): Promise<AthenaAdminPermissionResult<TSession>>;
63
87
 
64
- export { type AthenaAdminPermissionCheckInput, type AthenaAdminPermissionClient, type AthenaAdminPermissionFailure, type AthenaAdminPermissionResult, type AthenaAdminPermissionSuccess, type AthenaAdminSessionLike, hasAdminPermission, hasAdminRole, resolveAdminPermission };
88
+ export { type AthenaAdminPermissionCheckInput, type AthenaAdminPermissionClient, type AthenaAdminPermissionFailure, type AthenaAdminPermissionResult, type AthenaAdminPermissionSuccess, type AthenaAdminRequestCredentials, type AthenaAdminSessionLike, buildAdminAuthFetchOptions, hasAdminPermission, hasAdminRole, resolveAdminPermission, resolveAdminPermissionClient };
package/dist/admin.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { aD as AthenaAdminHasPermissionRequest, aE as AthenaAuthFetchCompatibleInput, E as AthenaAuthCallOptions, D as AthenaAuthBindings } from './types-AOY-GLu8.js';
1
+ import { aD as AthenaAdminHasPermissionRequest, aE as AthenaAuthFetchCompatibleInput, E as AthenaAuthCallOptions, D as AthenaAuthBindings } from './types-BVKpQmfY.js';
2
2
 
3
3
  /**
4
4
  * Minimal session shape used by the admin convenience helpers.
@@ -19,11 +19,41 @@ interface AthenaAdminSessionLike {
19
19
  interface AthenaAdminPermissionClient {
20
20
  auth: Pick<AthenaAuthBindings, 'admin'>;
21
21
  }
22
+ /**
23
+ * Normalizes common Athena client shapes into the admin-permission client contract.
24
+ *
25
+ * Accepts:
26
+ * - `createClient(...)` → `{ auth: { admin } }`
27
+ * - auth bindings only → `{ admin, … }` wrapped as `{ auth: bindings }`
28
+ */
29
+ declare function resolveAdminPermissionClient(client: unknown): AthenaAdminPermissionClient | null;
30
+ /**
31
+ * Request credentials for admin permission checks without manual cookie
32
+ * string matching. Prefer these over assembling `fetchOptions` by hand.
33
+ */
34
+ interface AthenaAdminRequestCredentials {
35
+ /** Raw `Cookie` header value from the current request. */
36
+ cookie?: string | null;
37
+ /** Bearer token (without the `Bearer ` prefix). */
38
+ bearerToken?: string | null;
39
+ }
40
+ /**
41
+ * Build auth `fetchOptions` for admin routes from cookie and/or bearer.
42
+ *
43
+ * Replaces app helpers that inspect cookie strings for `athena-auth` /
44
+ * `better-auth` prefixes before calling `hasPermission`.
45
+ */
46
+ declare function buildAdminAuthFetchOptions(credentials?: AthenaAdminRequestCredentials): NonNullable<AthenaAuthFetchCompatibleInput['fetchOptions']>;
22
47
  interface AthenaAdminPermissionCheckInput {
23
48
  session: AthenaAdminSessionLike | null | undefined;
24
49
  permissions: AthenaAdminHasPermissionRequest['permissions'];
25
50
  permission?: AthenaAdminHasPermissionRequest['permission'];
26
51
  fetchOptions?: AthenaAuthFetchCompatibleInput['fetchOptions'];
52
+ /**
53
+ * Cookie/bearer from the request. Merged under any explicit `fetchOptions`
54
+ * (explicit keys win on shallow header merge).
55
+ */
56
+ credentials?: AthenaAdminRequestCredentials;
27
57
  requestOptions?: AthenaAuthCallOptions;
28
58
  allowRoleBypass?: boolean;
29
59
  }
@@ -44,12 +74,6 @@ type AthenaAdminPermissionResult<TSession extends AthenaAdminSessionLike = Athen
44
74
  * case-insensitively so `"admin"`, `"ADMIN"`, and `"member, admin"` all pass.
45
75
  */
46
76
  declare function hasAdminRole(session: AthenaAdminSessionLike | null | undefined): boolean;
47
- /**
48
- * Checks admin permission against the configured Athena auth client.
49
- *
50
- * This helper short-circuits when no session user is present and, by default,
51
- * trusts a local `admin` role before calling `client.auth.admin.hasPermission(...)`.
52
- */
53
77
  declare function hasAdminPermission(client: AthenaAdminPermissionClient, input: AthenaAdminPermissionCheckInput): Promise<boolean>;
54
78
  /**
55
79
  * Resolves an admin permission check into a small framework-agnostic guard result.
@@ -61,4 +85,4 @@ declare function resolveAdminPermission<TSession extends AthenaAdminSessionLike
61
85
  session: TSession | null | undefined;
62
86
  }): Promise<AthenaAdminPermissionResult<TSession>>;
63
87
 
64
- export { type AthenaAdminPermissionCheckInput, type AthenaAdminPermissionClient, type AthenaAdminPermissionFailure, type AthenaAdminPermissionResult, type AthenaAdminPermissionSuccess, type AthenaAdminSessionLike, hasAdminPermission, hasAdminRole, resolveAdminPermission };
88
+ export { type AthenaAdminPermissionCheckInput, type AthenaAdminPermissionClient, type AthenaAdminPermissionFailure, type AthenaAdminPermissionResult, type AthenaAdminPermissionSuccess, type AthenaAdminRequestCredentials, type AthenaAdminSessionLike, buildAdminAuthFetchOptions, hasAdminPermission, hasAdminRole, resolveAdminPermission, resolveAdminPermissionClient };
package/dist/admin.js CHANGED
@@ -1,4 +1,34 @@
1
1
  // src/admin/index.ts
2
+ function resolveAdminPermissionClient(client) {
3
+ if (!client || typeof client !== "object") {
4
+ return null;
5
+ }
6
+ const record = client;
7
+ const nestedAuth = record.auth;
8
+ if (nestedAuth && typeof nestedAuth === "object" && nestedAuth !== null && "admin" in nestedAuth) {
9
+ return client;
10
+ }
11
+ if ("admin" in record) {
12
+ return { auth: client };
13
+ }
14
+ return null;
15
+ }
16
+ function buildAdminAuthFetchOptions(credentials = {}) {
17
+ const cookie = credentials.cookie?.trim() || void 0;
18
+ const bearerToken = credentials.bearerToken?.trim() || void 0;
19
+ const headers = {};
20
+ if (cookie) {
21
+ headers.cookie = cookie;
22
+ }
23
+ if (bearerToken) {
24
+ headers.authorization = `Bearer ${bearerToken}`;
25
+ }
26
+ return {
27
+ credentials: "include",
28
+ ...bearerToken ? { bearerToken } : {},
29
+ ...Object.keys(headers).length > 0 ? { headers } : {}
30
+ };
31
+ }
2
32
  function hasAdminRole(session) {
3
33
  const role = session?.user?.role;
4
34
  if (!role) {
@@ -6,6 +36,27 @@ function hasAdminRole(session) {
6
36
  }
7
37
  return role.split(",").map((item) => item.trim().toLowerCase()).includes("admin");
8
38
  }
39
+ function mergeAdminFetchOptions(input) {
40
+ const fromCredentials = input.credentials ? buildAdminAuthFetchOptions(input.credentials) : void 0;
41
+ const explicit = input.fetchOptions;
42
+ if (!fromCredentials && !explicit) {
43
+ return void 0;
44
+ }
45
+ if (!fromCredentials) {
46
+ return explicit;
47
+ }
48
+ if (!explicit) {
49
+ return fromCredentials;
50
+ }
51
+ return {
52
+ ...fromCredentials,
53
+ ...explicit,
54
+ headers: {
55
+ ...fromCredentials.headers ?? {},
56
+ ...explicit.headers ?? {}
57
+ }
58
+ };
59
+ }
9
60
  async function hasAdminPermission(client, input) {
10
61
  if (!input.session?.user?.id) {
11
62
  return false;
@@ -13,11 +64,12 @@ async function hasAdminPermission(client, input) {
13
64
  if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {
14
65
  return true;
15
66
  }
67
+ const fetchOptions = mergeAdminFetchOptions(input);
16
68
  const result = await client.auth.admin.hasPermission(
17
69
  {
18
70
  permission: input.permission,
19
71
  permissions: input.permissions,
20
- ...input.fetchOptions ? { fetchOptions: input.fetchOptions } : {}
72
+ ...fetchOptions ? { fetchOptions } : {}
21
73
  },
22
74
  input.requestOptions
23
75
  );
@@ -36,6 +88,6 @@ async function resolveAdminPermission(client, input) {
36
88
  };
37
89
  }
38
90
 
39
- export { hasAdminPermission, hasAdminRole, resolveAdminPermission };
91
+ export { buildAdminAuthFetchOptions, hasAdminPermission, hasAdminRole, resolveAdminPermission, resolveAdminPermissionClient };
40
92
  //# sourceMappingURL=admin.js.map
41
93
  //# sourceMappingURL=admin.js.map
package/dist/admin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/admin/index.ts"],"names":[],"mappings":";AA4DO,SAAS,aACd,OAAA,EACS;AACT,EAAA,MAAM,IAAA,GAAO,SAAS,IAAA,EAAM,IAAA;AAC5B,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CACJ,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAA,IAAA,KAAQ,IAAA,CAAK,IAAA,EAAK,CAAE,WAAA,EAAa,CAAA,CACrC,SAAS,OAAO,CAAA;AACrB;AAQA,eAAsB,kBAAA,CACpB,QACA,KAAA,EACkB;AAClB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,EAAS,IAAA,EAAM,EAAA,EAAI;AAC5B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAM,eAAA,KAAoB,KAAA,IAAS,YAAA,CAAa,KAAA,CAAM,OAAO,CAAA,EAAG;AAClE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,aAAA;AAAA,IACrC;AAAA,MACE,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,GAAI,MAAM,YAAA,GAAe,EAAE,cAAc,KAAA,CAAM,YAAA,KAAiB;AAAC,KACnE;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AAEA,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,EAAA,IAAM,MAAA,CAAO,MAAM,OAAO,CAAA;AAClD;AAQA,eAAsB,sBAAA,CAGpB,QACA,KAAA,EAGgD;AAChD,EAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,OAAO,cAAA,EAAe;AAAA,EACzD;AAEA,EAAA,IAAI,CAAE,MAAM,kBAAA,CAAmB,MAAA,EAAQ,KAAK,CAAA,EAAI;AAC9C,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,OAAO,WAAA,EAAY;AAAA,EACtD;AAEA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,SAAS,KAAA,CAAM;AAAA,GACjB;AACF","file":"admin.js","sourcesContent":["import type {\n AthenaAdminHasPermissionRequest,\n AthenaAuthBindings,\n AthenaAuthCallOptions,\n AthenaAuthFetchCompatibleInput,\n} from '../auth/types.ts'\n\n/**\n * Minimal session shape used by the admin convenience helpers.\n *\n * This stays framework-agnostic so callers can pass Athena auth sessions,\n * app-local session wrappers, or request-derived session snapshots.\n */\nexport interface AthenaAdminSessionLike {\n user?: {\n id?: string | null | undefined\n role?: string | null | undefined\n } | null | undefined\n session?: {\n token?: string | null | undefined\n activeOrganizationId?: string | null | undefined\n } | null | undefined\n}\n\nexport interface AthenaAdminPermissionClient {\n auth: Pick<AthenaAuthBindings, 'admin'>\n}\n\nexport interface AthenaAdminPermissionCheckInput {\n session: AthenaAdminSessionLike | null | undefined\n permissions: AthenaAdminHasPermissionRequest['permissions']\n permission?: AthenaAdminHasPermissionRequest['permission']\n fetchOptions?: AthenaAuthFetchCompatibleInput['fetchOptions']\n requestOptions?: AthenaAuthCallOptions\n allowRoleBypass?: boolean\n}\n\nexport interface AthenaAdminPermissionSuccess<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> {\n ok: true\n session: NonNullable<TSession>\n}\n\nexport interface AthenaAdminPermissionFailure {\n ok: false\n status: 401 | 403\n error: 'Unauthorized' | 'Forbidden'\n}\n\nexport type AthenaAdminPermissionResult<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> = AthenaAdminPermissionSuccess<TSession> | AthenaAdminPermissionFailure\n\n/**\n * Returns true when the session user already carries the `admin` role locally.\n *\n * Role strings are treated as a comma-separated list and normalized\n * case-insensitively so `\"admin\"`, `\"ADMIN\"`, and `\"member, admin\"` all pass.\n */\nexport function hasAdminRole(\n session: AthenaAdminSessionLike | null | undefined,\n): boolean {\n const role = session?.user?.role\n if (!role) {\n return false\n }\n\n return role\n .split(',')\n .map(item => item.trim().toLowerCase())\n .includes('admin')\n}\n\n/**\n * Checks admin permission against the configured Athena auth client.\n *\n * This helper short-circuits when no session user is present and, by default,\n * trusts a local `admin` role before calling `client.auth.admin.hasPermission(...)`.\n */\nexport async function hasAdminPermission(\n client: AthenaAdminPermissionClient,\n input: AthenaAdminPermissionCheckInput,\n): Promise<boolean> {\n if (!input.session?.user?.id) {\n return false\n }\n\n if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {\n return true\n }\n\n const result = await client.auth.admin.hasPermission(\n {\n permission: input.permission,\n permissions: input.permissions,\n ...(input.fetchOptions ? { fetchOptions: input.fetchOptions } : {}),\n },\n input.requestOptions,\n )\n\n return Boolean(result.ok && result.data?.success)\n}\n\n/**\n * Resolves an admin permission check into a small framework-agnostic guard result.\n *\n * Consumers can map the returned `{ ok, status, error }` shape into Next.js,\n * Hono, Express, or any other response layer without importing framework types here.\n */\nexport async function resolveAdminPermission<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n>(\n client: AthenaAdminPermissionClient,\n input: Omit<AthenaAdminPermissionCheckInput, 'session'> & {\n session: TSession | null | undefined\n },\n): Promise<AthenaAdminPermissionResult<TSession>> {\n if (!input.session) {\n return { ok: false, status: 401, error: 'Unauthorized' }\n }\n\n if (!(await hasAdminPermission(client, input))) {\n return { ok: false, status: 403, error: 'Forbidden' }\n }\n\n return {\n ok: true,\n session: input.session as NonNullable<TSession>,\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/admin/index.ts"],"names":[],"mappings":"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","file":"admin.js","sourcesContent":["import type {\n AthenaAdminHasPermissionRequest,\n AthenaAuthBindings,\n AthenaAuthCallOptions,\n AthenaAuthFetchCompatibleInput,\n} from '../auth/types.ts'\n\n/**\n * Minimal session shape used by the admin convenience helpers.\n *\n * This stays framework-agnostic so callers can pass Athena auth sessions,\n * app-local session wrappers, or request-derived session snapshots.\n */\nexport interface AthenaAdminSessionLike {\n user?: {\n id?: string | null | undefined\n role?: string | null | undefined\n } | null | undefined\n session?: {\n token?: string | null | undefined\n activeOrganizationId?: string | null | undefined\n } | null | undefined\n}\n\nexport interface AthenaAdminPermissionClient {\n auth: Pick<AthenaAuthBindings, 'admin'>\n}\n\n/**\n * Normalizes common Athena client shapes into the admin-permission client contract.\n *\n * Accepts:\n * - `createClient(...)` → `{ auth: { admin } }`\n * - auth bindings only → `{ admin, … }` wrapped as `{ auth: bindings }`\n */\nexport function resolveAdminPermissionClient(\n client: unknown,\n): AthenaAdminPermissionClient | null {\n if (!client || typeof client !== 'object') {\n return null\n }\n\n const record = client as Record<string, unknown>\n const nestedAuth = record.auth\n\n if (\n nestedAuth &&\n typeof nestedAuth === 'object' &&\n nestedAuth !== null &&\n 'admin' in nestedAuth\n ) {\n return client as AthenaAdminPermissionClient\n }\n\n if ('admin' in record) {\n return { auth: client as Pick<AthenaAuthBindings, 'admin'> }\n }\n\n return null\n}\n\n/**\n * Request credentials for admin permission checks without manual cookie\n * string matching. Prefer these over assembling `fetchOptions` by hand.\n */\nexport interface AthenaAdminRequestCredentials {\n /** Raw `Cookie` header value from the current request. */\n cookie?: string | null\n /** Bearer token (without the `Bearer ` prefix). */\n bearerToken?: string | null\n}\n\n/**\n * Build auth `fetchOptions` for admin routes from cookie and/or bearer.\n *\n * Replaces app helpers that inspect cookie strings for `athena-auth` /\n * `better-auth` prefixes before calling `hasPermission`.\n */\nexport function buildAdminAuthFetchOptions(\n credentials: AthenaAdminRequestCredentials = {},\n): NonNullable<AthenaAuthFetchCompatibleInput['fetchOptions']> {\n const cookie = credentials.cookie?.trim() || undefined\n const bearerToken = credentials.bearerToken?.trim() || undefined\n const headers: Record<string, string> = {}\n if (cookie) {\n headers.cookie = cookie\n }\n if (bearerToken) {\n headers.authorization = `Bearer ${bearerToken}`\n }\n return {\n credentials: 'include',\n ...(bearerToken ? { bearerToken } : {}),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n }\n}\n\nexport interface AthenaAdminPermissionCheckInput {\n session: AthenaAdminSessionLike | null | undefined\n permissions: AthenaAdminHasPermissionRequest['permissions']\n permission?: AthenaAdminHasPermissionRequest['permission']\n fetchOptions?: AthenaAuthFetchCompatibleInput['fetchOptions']\n /**\n * Cookie/bearer from the request. Merged under any explicit `fetchOptions`\n * (explicit keys win on shallow header merge).\n */\n credentials?: AthenaAdminRequestCredentials\n requestOptions?: AthenaAuthCallOptions\n allowRoleBypass?: boolean\n}\n\nexport interface AthenaAdminPermissionSuccess<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> {\n ok: true\n session: NonNullable<TSession>\n}\n\nexport interface AthenaAdminPermissionFailure {\n ok: false\n status: 401 | 403\n error: 'Unauthorized' | 'Forbidden'\n}\n\nexport type AthenaAdminPermissionResult<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n> = AthenaAdminPermissionSuccess<TSession> | AthenaAdminPermissionFailure\n\n/**\n * Returns true when the session user already carries the `admin` role locally.\n *\n * Role strings are treated as a comma-separated list and normalized\n * case-insensitively so `\"admin\"`, `\"ADMIN\"`, and `\"member, admin\"` all pass.\n */\nexport function hasAdminRole(\n session: AthenaAdminSessionLike | null | undefined,\n): boolean {\n const role = session?.user?.role\n if (!role) {\n return false\n }\n\n return role\n .split(',')\n .map(item => item.trim().toLowerCase())\n .includes('admin')\n}\n\n/**\n * Checks admin permission against the configured Athena auth client.\n *\n * This helper short-circuits when no session user is present and, by default,\n * trusts a local `admin` role before calling `client.auth.admin.hasPermission(...)`.\n */\nfunction mergeAdminFetchOptions(\n input: AthenaAdminPermissionCheckInput,\n): AthenaAuthFetchCompatibleInput['fetchOptions'] | undefined {\n const fromCredentials = input.credentials\n ? buildAdminAuthFetchOptions(input.credentials)\n : undefined\n const explicit = input.fetchOptions\n if (!fromCredentials && !explicit) {\n return undefined\n }\n if (!fromCredentials) {\n return explicit\n }\n if (!explicit) {\n return fromCredentials\n }\n return {\n ...fromCredentials,\n ...explicit,\n headers: {\n ...(fromCredentials.headers ?? {}),\n ...(explicit.headers ?? {}),\n },\n }\n}\n\nexport async function hasAdminPermission(\n client: AthenaAdminPermissionClient,\n input: AthenaAdminPermissionCheckInput,\n): Promise<boolean> {\n if (!input.session?.user?.id) {\n return false\n }\n\n if (input.allowRoleBypass !== false && hasAdminRole(input.session)) {\n return true\n }\n\n const fetchOptions = mergeAdminFetchOptions(input)\n\n const result = await client.auth.admin.hasPermission(\n {\n permission: input.permission,\n permissions: input.permissions,\n ...(fetchOptions ? { fetchOptions } : {}),\n },\n input.requestOptions,\n )\n\n return Boolean(result.ok && result.data?.success)\n}\n\n/**\n * Resolves an admin permission check into a small framework-agnostic guard result.\n *\n * Consumers can map the returned `{ ok, status, error }` shape into Next.js,\n * Hono, Express, or any other response layer without importing framework types here.\n */\nexport async function resolveAdminPermission<\n TSession extends AthenaAdminSessionLike = AthenaAdminSessionLike,\n>(\n client: AthenaAdminPermissionClient,\n input: Omit<AthenaAdminPermissionCheckInput, 'session'> & {\n session: TSession | null | undefined\n },\n): Promise<AthenaAdminPermissionResult<TSession>> {\n if (!input.session) {\n return { ok: false, status: 401, error: 'Unauthorized' }\n }\n\n if (!(await hasAdminPermission(client, input))) {\n return { ok: false, status: 403, error: 'Forbidden' }\n }\n\n return {\n ok: true,\n session: input.session as NonNullable<TSession>,\n }\n}\n"]}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Resolve Athena Auth base / upstream URLs from env or explicit config.
3
+ *
4
+ * Mirrors the Athena Auth UI base-url contract so apps and the SDK share one
5
+ * precedence order for `ATHENA_AUTH_*` environment variables.
6
+ */
7
+ /** Default browser/proxy path for same-origin auth routing. */
8
+ declare const ATHENA_AUTH_PATH = "/api/auth";
9
+ /** Fallback origin when no absolute upstream is configured (server-side). */
10
+ declare const LOCAL_DEV_ORIGIN = "http://localhost:3000";
11
+ /**
12
+ * Hosted Athena Auth origin used when no upstream override is supplied.
13
+ * Origin only — no `/api/auth` suffix.
14
+ */
15
+ declare const DEFAULT_ATHENA_AUTH_ORIGIN = "https://auth.athena-auth.com";
16
+ /**
17
+ * @deprecated Prefer {@link DEFAULT_ATHENA_AUTH_ORIGIN}.
18
+ * Kept for callers that used the older name.
19
+ */
20
+ declare const DEFAULT_ATHENA_AUTH_UPSTREAM_URL = "https://auth.athena-auth.com";
21
+ /**
22
+ * Environment keys checked (in order) for the Athena Auth upstream URL.
23
+ *
24
+ * Prefer server-only keys first so private upstream hosts are not forced to
25
+ * rely on `NEXT_PUBLIC_*` values.
26
+ */
27
+ declare const ATHENA_AUTH_UPSTREAM_ENV_KEYS: readonly ["ATHENA_AUTH_UPSTREAM_URL", "ATHENA_AUTH_URL", "NEXT_PUBLIC_ATHENA_AUTH_UPSTREAM_URL", "NEXT_PUBLIC_ATHENA_AUTH_URL"];
28
+ /**
29
+ * Auth UI naming parity (`base-url.ts`).
30
+ * Same ordered list as {@link ATHENA_AUTH_UPSTREAM_ENV_KEYS}.
31
+ */
32
+ declare const ATHENA_AUTH_UPSTREAM_URL_ENV_NAMES: readonly ["ATHENA_AUTH_UPSTREAM_URL", "ATHENA_AUTH_URL", "NEXT_PUBLIC_ATHENA_AUTH_UPSTREAM_URL", "NEXT_PUBLIC_ATHENA_AUTH_URL"];
33
+ type AthenaAuthUpstreamEnvKey = (typeof ATHENA_AUTH_UPSTREAM_ENV_KEYS)[number];
34
+ /** Loose env map (Node `process.env` or a test fixture). */
35
+ type EnvLike = Record<string, string | undefined>;
36
+ type AthenaAuthUpstreamEnv = Partial<Record<AthenaAuthUpstreamEnvKey, string | undefined>> & EnvLike;
37
+ interface AthenaAuthClientBaseUrlOptions {
38
+ /**
39
+ * When `true` (default), ensure the client base ends with `/api/auth`.
40
+ * Set `false` when the auth server is mounted at a custom path or root.
41
+ */
42
+ appendAuthPath?: boolean;
43
+ }
44
+ /**
45
+ * Returns `true` when the value is an absolute `http://` or `https://` URL.
46
+ */
47
+ declare function isAbsoluteUrl(value: string): boolean;
48
+ /**
49
+ * Read the first non-empty Athena Auth upstream URL from an env-like map.
50
+ *
51
+ * @returns Trimmed URL string, or `undefined` when none of the keys are set
52
+ */
53
+ declare function readAthenaAuthUpstreamUrlFromEnv(env: EnvLike): string | undefined;
54
+ /**
55
+ * Normalize a consumer-supplied auth base URL so it targets `/api/auth`
56
+ * (unless the path already ends with that segment).
57
+ *
58
+ * Absolute URLs keep origin and rewrite pathname; relative paths are ensured
59
+ * to end with `/api/auth`.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * normalizeAthenaAuthBaseUrl('https://auth.example.com')
64
+ * // => 'https://auth.example.com/api/auth'
65
+ *
66
+ * normalizeAthenaAuthBaseUrl('/api/auth')
67
+ * // => '/api/auth'
68
+ * ```
69
+ */
70
+ declare function normalizeAthenaAuthBaseUrl(urlOrPath: string): string;
71
+ /**
72
+ * Resolve the **server-side** Athena Auth upstream origin (no `/api/auth` suffix).
73
+ *
74
+ * Used when proxying or calling the auth host directly from Node / edge.
75
+ *
76
+ * @param rawUpstreamUrl - Explicit URL, env map, or omit to read `process.env`
77
+ * @returns Origin like `https://auth.example.com` (no trailing slash)
78
+ */
79
+ declare function resolveAthenaAuthUpstreamUrl(rawUpstreamUrl?: string | AthenaAuthUpstreamEnv): string;
80
+ /**
81
+ * Resolve the **browser-facing** auth client base URL.
82
+ *
83
+ * Default behavior appends `/api/auth` for same-origin proxying. Pass
84
+ * `{ appendAuthPath: false }` to keep a custom path or root mount.
85
+ *
86
+ * Overloads match common call styles from Athena Auth UI and app code:
87
+ * - `resolveAthenaAuthClientBaseUrl("https://auth.example.com")`
88
+ * - `resolveAthenaAuthClientBaseUrl(process.env)`
89
+ * - `resolveAthenaAuthClientBaseUrl(undefined)` → env + defaults
90
+ * - `resolveAthenaAuthClientBaseUrl(path, upstream, { appendAuthPath: false })`
91
+ */
92
+ declare function resolveAthenaAuthClientBaseUrl(configuredAuthBaseUrl?: string | EnvLike, rawUpstreamUrl?: string | AthenaAuthUpstreamEnv, options?: AthenaAuthClientBaseUrlOptions): string;
93
+ declare function resolveAthenaAuthClientBaseUrl(configuredAuthBaseUrl: string, rawUpstreamUrl?: string | AthenaAuthUpstreamEnv, options?: AthenaAuthClientBaseUrlOptions): string;
94
+ /**
95
+ * Build an absolute Athena Auth request URL for a path under the client base.
96
+ *
97
+ * Resolves at **call time** (reads env when `rawBaseUrl` is omitted) so module
98
+ * load order does not freeze a stale URL.
99
+ *
100
+ * @param path - Path relative to the auth base (leading slashes stripped)
101
+ * @param rawBaseUrl - Optional base string or env map
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * resolveAthenaAuthRequestUrl('get-session', 'https://auth.example.com')
106
+ * // => 'https://auth.example.com/api/auth/get-session'
107
+ * ```
108
+ */
109
+ declare function resolveAthenaAuthRequestUrl(path: string, rawBaseUrl?: string | EnvLike): string;
110
+ /** Relative auth path for email verification (`GET /verify-email`). */
111
+ declare const ATHENA_AUTH_VERIFY_EMAIL_PATH = "verify-email";
112
+ /**
113
+ * Relative segment for session lookup (`GET /get-session`).
114
+ * Prefer with {@link resolveAthenaAuthRequestUrl} when `base` already ends in `/api/auth`.
115
+ */
116
+ declare const ATHENA_AUTH_GET_SESSION_PATH = "get-session";
117
+ /**
118
+ * Absolute app/proxy path for session lookup.
119
+ * Use with `new URL(ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH, appOrigin)` when
120
+ * `baseUrl` is the **app origin** (e.g. `https://app.example.com`), not the auth client base.
121
+ */
122
+ declare const ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH = "/api/auth/get-session";
123
+ /**
124
+ * @deprecated Alias of {@link ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH} for drop-in
125
+ * replacement of app-local `AUTH_SESSION_PATH` constants. Prefer the `ATHENA_` name.
126
+ */
127
+ declare const AUTH_SESSION_PATH = "/api/auth/get-session";
128
+ /**
129
+ * Query param that forces Athena Auth / Better Auth style session handlers to
130
+ * skip cookie cache and re-read the live session cookie.
131
+ */
132
+ declare const ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM = "disableCookieCache";
133
+ /**
134
+ * @deprecated Alias of {@link ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM}.
135
+ */
136
+ declare const DISABLE_COOKIE_CACHE_QUERY_PARAM = "disableCookieCache";
137
+ /** Value paired with {@link ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM}. */
138
+ declare const ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE = "true";
139
+ /**
140
+ * @deprecated Alias of {@link ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE}.
141
+ */
142
+ declare const DISABLE_COOKIE_CACHE_QUERY_VALUE = "true";
143
+ /**
144
+ * Optional request/response header some apps use to pass serialized session
145
+ * payload between edge middleware and the app (not set by the SDK itself).
146
+ */
147
+ declare const ATHENA_SESSION_DATA_HEADER = "x-session-data";
148
+ /**
149
+ * @deprecated Alias of {@link ATHENA_SESSION_DATA_HEADER}.
150
+ */
151
+ declare const SESSION_DATA_HEADER = "x-session-data";
152
+ /**
153
+ * Absolute callback URL for email verification.
154
+ *
155
+ * Equivalent to `resolveAthenaAuthRequestUrl("verify-email")` — use this in
156
+ * sign-up / send-verification payloads as `callbackURL` instead of a local
157
+ * wrapper around Auth UI `base-url` helpers.
158
+ *
159
+ * @param rawBaseUrl - Optional base string or env map (defaults to process env)
160
+ * @returns e.g. `https://auth.example.com/api/auth/verify-email`
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { resolveEmailVerificationCallbackUrl } from "@xylex-group/athena/utils"
165
+ *
166
+ * await client.auth.signUp.email({
167
+ * email,
168
+ * password,
169
+ * name,
170
+ * callbackURL: resolveEmailVerificationCallbackUrl(),
171
+ * })
172
+ * ```
173
+ */
174
+ declare function resolveEmailVerificationCallbackUrl(rawBaseUrl?: string | EnvLike): string;
175
+ /**
176
+ * Build a same-origin (or absolute) **fresh** get-session URL.
177
+ *
178
+ * Appends `disableCookieCache=true` so middleware / RSC session probes do not
179
+ * reuse a stale cookie-cache entry.
180
+ *
181
+ * @param baseUrl - App origin (`https://app.example.com`) or any base accepted by
182
+ * the `URL` constructor. Resolves {@link ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH}
183
+ * (`/api/auth/get-session`) against that base.
184
+ * @returns URL such as `https://app.example.com/api/auth/get-session?disableCookieCache=true`
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * import { createFreshSessionLookupUrl } from "@xylex-group/athena/utils"
189
+ *
190
+ * const url = createFreshSessionLookupUrl("https://app.example.com")
191
+ * await fetch(url, { headers: { cookie: requestHeaders.get("cookie") ?? "" } })
192
+ * ```
193
+ *
194
+ * For auth-client base URLs that already include `/api/auth`, prefer:
195
+ * `resolveAthenaAuthRequestUrl("get-session", authBase) + "?disableCookieCache=true"`
196
+ * or pass the **app** origin into this helper when you proxy `/api/auth/*` locally.
197
+ */
198
+ declare function createFreshSessionLookupUrl(baseUrl: string | URL): URL;
199
+
200
+ export { ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_PARAM as A, DEFAULT_ATHENA_AUTH_ORIGIN as D, type EnvLike as E, LOCAL_DEV_ORIGIN as L, SESSION_DATA_HEADER as S, ATHENA_AUTH_DISABLE_COOKIE_CACHE_QUERY_VALUE as a, ATHENA_AUTH_GET_SESSION_ABSOLUTE_PATH as b, ATHENA_AUTH_GET_SESSION_PATH as c, ATHENA_AUTH_PATH as d, ATHENA_AUTH_UPSTREAM_ENV_KEYS as e, ATHENA_AUTH_UPSTREAM_URL_ENV_NAMES as f, ATHENA_AUTH_VERIFY_EMAIL_PATH as g, ATHENA_SESSION_DATA_HEADER as h, AUTH_SESSION_PATH as i, type AthenaAuthClientBaseUrlOptions as j, type AthenaAuthUpstreamEnv as k, type AthenaAuthUpstreamEnvKey as l, DEFAULT_ATHENA_AUTH_UPSTREAM_URL as m, DISABLE_COOKIE_CACHE_QUERY_PARAM as n, DISABLE_COOKIE_CACHE_QUERY_VALUE as o, createFreshSessionLookupUrl as p, isAbsoluteUrl as q, normalizeAthenaAuthBaseUrl as r, readAthenaAuthUpstreamUrlFromEnv as s, resolveAthenaAuthClientBaseUrl as t, resolveAthenaAuthRequestUrl as u, resolveAthenaAuthUpstreamUrl as v, resolveEmailVerificationCallbackUrl as w };