@xylex-group/athena 2.12.0 → 2.13.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.
- package/LICENSE +21 -21
- package/README.md +1190 -1184
- package/bin/athena-js.js +104 -76
- package/dist/admin.cjs +45 -0
- package/dist/admin.cjs.map +1 -0
- package/dist/admin.d.cts +64 -0
- package/dist/admin.d.ts +64 -0
- package/dist/admin.js +41 -0
- package/dist/admin.js.map +1 -0
- package/dist/athena-auth-url-oLux_57a.d.cts +377 -0
- package/dist/athena-auth-url-oLux_57a.d.ts +377 -0
- package/dist/browser.cjs +33 -46
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +12 -10
- package/dist/browser.d.ts +12 -10
- package/dist/browser.js +33 -46
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +150 -48
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +14 -5
- package/dist/cli/index.d.ts +14 -5
- package/dist/cli/index.js +150 -49
- package/dist/cli/index.js.map +1 -1
- package/dist/{client-QUbAs7E8.d.ts → client-BJjUwDSg.d.cts} +109 -1448
- package/dist/{client-C3x75Zgn.d.cts → client-DVOKSYDI.d.ts} +109 -1448
- package/dist/cookies.cjs +18 -0
- package/dist/cookies.cjs.map +1 -1
- package/dist/cookies.d.cts +2 -1
- package/dist/cookies.d.ts +2 -1
- package/dist/cookies.js +17 -1
- package/dist/cookies.js.map +1 -1
- package/dist/{index-CVcQCGyG.d.ts → index-CFL9xbFR.d.cts} +2 -0
- package/dist/{index-CVcQCGyG.d.cts → index-UKJpunc6.d.ts} +2 -0
- package/dist/index.cjs +101 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.js +101 -47
- package/dist/index.js.map +1 -1
- package/dist/{model-form-CD1uhWSh.d.cts → model-form-Dw4zEL5a.d.cts} +2 -2
- package/dist/{model-form-Dm69I-oO.d.ts → model-form-yRg71q3H.d.ts} +2 -2
- package/dist/{module-CW3tWJ10.d.ts → module-DBteUIob.d.ts} +12 -9
- package/dist/{module-Cxcurfes.d.cts → module-yoX49uQC.d.cts} +12 -9
- package/dist/next/client.cjs +452 -46
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.d.cts +7 -4
- package/dist/next/client.d.ts +7 -4
- package/dist/next/client.js +430 -47
- package/dist/next/client.js.map +1 -1
- package/dist/next/server.cjs +292 -46
- package/dist/next/server.cjs.map +1 -1
- package/dist/next/server.d.cts +81 -5
- package/dist/next/server.d.ts +81 -5
- package/dist/next/server.js +280 -47
- package/dist/next/server.js.map +1 -1
- package/dist/organization.cjs +72 -0
- package/dist/organization.cjs.map +1 -0
- package/dist/organization.d.cts +43 -0
- package/dist/organization.d.ts +43 -0
- package/dist/organization.js +70 -0
- package/dist/organization.js.map +1 -0
- package/dist/payload-BzVbUgY_.d.cts +219 -0
- package/dist/payload-DEOWN_oo.d.ts +219 -0
- package/dist/{pipeline-BAwb6Vzm.d.ts → pipeline-Bj6RWt1A.d.ts} +1 -1
- package/dist/{pipeline-B14jVK7J.d.cts → pipeline-Dwck-wZO.d.cts} +1 -1
- package/dist/react.cjs +2 -10
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +26 -7
- package/dist/react.d.ts +26 -7
- package/dist/react.js +2 -10
- package/dist/react.js.map +1 -1
- package/dist/session-cookie-detection-BqOp9mO6.d.cts +46 -0
- package/dist/session-cookie-detection-BqOp9mO6.d.ts +46 -0
- package/dist/social-providers.cjs +4189 -0
- package/dist/social-providers.cjs.map +1 -0
- package/dist/social-providers.d.cts +4948 -0
- package/dist/social-providers.d.ts +4948 -0
- package/dist/social-providers.js +4117 -0
- package/dist/social-providers.js.map +1 -0
- package/dist/{types-Cq4-NoB4.d.ts → types-BRP7sfSF.d.ts} +50 -2
- package/dist/{types-Dr849HD6.d.cts → types-BU8uJH_b.d.cts} +50 -2
- package/dist/{types-CwJCPpLD.d.ts → types-CH78O90i.d.cts} +2 -2
- package/dist/{types-CwJCPpLD.d.cts → types-CH78O90i.d.ts} +2 -2
- package/dist/{types-DMOoYnPS.d.cts → types-CjC9_5ZQ.d.cts} +3 -3
- package/dist/{types-BcVmPBP-.d.ts → types-DPgejxYC.d.ts} +3 -3
- package/dist/types-eAKAh71s.d.cts +1476 -0
- package/dist/types-eAKAh71s.d.ts +1476 -0
- package/dist/utils.cjs +438 -12
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +76 -11
- package/dist/utils.d.ts +76 -11
- package/dist/utils.js +390 -13
- package/dist/utils.js.map +1 -1
- package/package.json +49 -22
- package/dist/shared-0Kdc74lu.d.ts +0 -35
- package/dist/shared-C0wVICRv.d.cts +0 -35
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/organization/ensure-active-organization.ts
|
|
4
|
+
function normalizeOrganizationId(value) {
|
|
5
|
+
if (typeof value !== "string") {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const normalized = value.trim();
|
|
9
|
+
return normalized.length > 0 ? normalized : null;
|
|
10
|
+
}
|
|
11
|
+
function defaultSelectOrganizationId(organizations) {
|
|
12
|
+
for (const organization of organizations) {
|
|
13
|
+
const id = normalizeOrganizationId(organization.id);
|
|
14
|
+
if (id) {
|
|
15
|
+
return id;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
async function ensureActiveOrganization(options) {
|
|
21
|
+
const currentActiveOrganizationId = normalizeOrganizationId(
|
|
22
|
+
options.session?.session?.activeOrganizationId
|
|
23
|
+
);
|
|
24
|
+
if (currentActiveOrganizationId) {
|
|
25
|
+
return {
|
|
26
|
+
activeOrganizationId: currentActiveOrganizationId,
|
|
27
|
+
didSetActiveOrganization: false
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
let organizations;
|
|
31
|
+
try {
|
|
32
|
+
organizations = await options.listOrganizations();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
options.onError?.(error);
|
|
35
|
+
return {
|
|
36
|
+
activeOrganizationId: null,
|
|
37
|
+
didSetActiveOrganization: false
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (organizations.length === 0) {
|
|
41
|
+
return {
|
|
42
|
+
activeOrganizationId: null,
|
|
43
|
+
didSetActiveOrganization: false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const selectedOrganizationId = normalizeOrganizationId(
|
|
47
|
+
(options.selectOrganizationId ?? defaultSelectOrganizationId)(organizations)
|
|
48
|
+
);
|
|
49
|
+
if (!selectedOrganizationId) {
|
|
50
|
+
return {
|
|
51
|
+
activeOrganizationId: null,
|
|
52
|
+
didSetActiveOrganization: false
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
await options.setActiveOrganization(selectedOrganizationId);
|
|
57
|
+
return {
|
|
58
|
+
activeOrganizationId: selectedOrganizationId,
|
|
59
|
+
didSetActiveOrganization: true
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
options.onError?.(error);
|
|
63
|
+
return {
|
|
64
|
+
activeOrganizationId: null,
|
|
65
|
+
didSetActiveOrganization: false
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exports.ensureActiveOrganization = ensureActiveOrganization;
|
|
71
|
+
//# sourceMappingURL=organization.cjs.map
|
|
72
|
+
//# sourceMappingURL=organization.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/organization/ensure-active-organization.ts"],"names":[],"mappings":";;;AAqCA,SAAS,wBAAwB,KAAA,EAAiD;AAChF,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,UAAA,GAAa,MAAM,IAAA,EAAK;AAC9B,EAAA,OAAO,UAAA,CAAW,MAAA,GAAS,CAAA,GAAI,UAAA,GAAa,IAAA;AAC9C;AAEA,SAAS,4BACP,aAAA,EACe;AACf,EAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,IAAA,MAAM,EAAA,GAAK,uBAAA,CAAwB,YAAA,CAAa,EAAE,CAAA;AAClD,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAUA,eAAsB,yBACpB,OAAA,EACyC;AACzC,EAAA,MAAM,2BAAA,GAA8B,uBAAA;AAAA,IAClC,OAAA,CAAQ,SAAS,OAAA,EAAS;AAAA,GAC5B;AAEA,EAAA,IAAI,2BAAA,EAA6B;AAC/B,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,2BAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgB,MAAM,QAAQ,iBAAA,EAAkB;AAAA,EAClD,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,UAAU,KAAK,CAAA;AACvB,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,MAAM,sBAAA,GAAyB,uBAAA;AAAA,IAAA,CAC5B,OAAA,CAAQ,oBAAA,IAAwB,2BAAA,EAA6B,aAAa;AAAA,GAC7E;AAEA,EAAA,IAAI,CAAC,sBAAA,EAAwB;AAC3B,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,CAAQ,sBAAsB,sBAAsB,CAAA;AAC1D,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,sBAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,UAAU,KAAK,CAAA;AACvB,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AACF","file":"organization.cjs","sourcesContent":["/**\n * Framework-agnostic active-organization bootstrap.\n *\n * Promoted from consumer apps (e.g. speedrun-formations) so product code only\n * supplies list/set-active + optional org selection policy.\n *\n * Does not call Athena Auth routes itself — inject your client's\n * `auth.organization.list` / `setActive` (or any compatible functions).\n */\n\nexport interface ActiveOrganizationSessionLike {\n session?: {\n activeOrganizationId?: string | null\n } | null\n}\n\nexport interface OrganizationLike {\n id: string\n}\n\nexport interface EnsureActiveOrganizationOptions<TOrganization extends OrganizationLike> {\n listOrganizations: () => Promise<readonly TOrganization[]>\n onError?: (error: unknown) => void\n /**\n * Choose which org to activate when the session has none.\n * Default: first organization with a non-empty `id`.\n */\n selectOrganizationId?: (organizations: readonly TOrganization[]) => string | null\n session: ActiveOrganizationSessionLike | null | undefined\n setActiveOrganization: (organizationId: string) => Promise<unknown>\n}\n\nexport interface EnsureActiveOrganizationResult {\n activeOrganizationId: string | null\n didSetActiveOrganization: boolean\n}\n\nfunction normalizeOrganizationId(value: string | null | undefined): string | null {\n if (typeof value !== 'string') {\n return null\n }\n const normalized = value.trim()\n return normalized.length > 0 ? normalized : null\n}\n\nfunction defaultSelectOrganizationId<TOrganization extends OrganizationLike>(\n organizations: readonly TOrganization[],\n): string | null {\n for (const organization of organizations) {\n const id = normalizeOrganizationId(organization.id)\n if (id) {\n return id\n }\n }\n return null\n}\n\n/**\n * Ensure the session has an active organization when memberships exist.\n *\n * - If `session.session.activeOrganizationId` is already set → return it (no network).\n * - Else list organizations; if empty → `{ activeOrganizationId: null, didSetActiveOrganization: false }`.\n * - Else select an id (custom or first) and call `setActiveOrganization`.\n * - List/set failures invoke `onError` and return unset (never throw).\n */\nexport async function ensureActiveOrganization<TOrganization extends OrganizationLike>(\n options: EnsureActiveOrganizationOptions<TOrganization>,\n): Promise<EnsureActiveOrganizationResult> {\n const currentActiveOrganizationId = normalizeOrganizationId(\n options.session?.session?.activeOrganizationId,\n )\n\n if (currentActiveOrganizationId) {\n return {\n activeOrganizationId: currentActiveOrganizationId,\n didSetActiveOrganization: false,\n }\n }\n\n let organizations: readonly TOrganization[]\n try {\n organizations = await options.listOrganizations()\n } catch (error) {\n options.onError?.(error)\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n\n if (organizations.length === 0) {\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n\n const selectedOrganizationId = normalizeOrganizationId(\n (options.selectOrganizationId ?? defaultSelectOrganizationId)(organizations),\n )\n\n if (!selectedOrganizationId) {\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n\n try {\n await options.setActiveOrganization(selectedOrganizationId)\n return {\n activeOrganizationId: selectedOrganizationId,\n didSetActiveOrganization: true,\n }\n } catch (error) {\n options.onError?.(error)\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic active-organization bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* Promoted from consumer apps (e.g. speedrun-formations) so product code only
|
|
5
|
+
* supplies list/set-active + optional org selection policy.
|
|
6
|
+
*
|
|
7
|
+
* Does not call Athena Auth routes itself — inject your client's
|
|
8
|
+
* `auth.organization.list` / `setActive` (or any compatible functions).
|
|
9
|
+
*/
|
|
10
|
+
interface ActiveOrganizationSessionLike {
|
|
11
|
+
session?: {
|
|
12
|
+
activeOrganizationId?: string | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
interface OrganizationLike {
|
|
16
|
+
id: string;
|
|
17
|
+
}
|
|
18
|
+
interface EnsureActiveOrganizationOptions<TOrganization extends OrganizationLike> {
|
|
19
|
+
listOrganizations: () => Promise<readonly TOrganization[]>;
|
|
20
|
+
onError?: (error: unknown) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Choose which org to activate when the session has none.
|
|
23
|
+
* Default: first organization with a non-empty `id`.
|
|
24
|
+
*/
|
|
25
|
+
selectOrganizationId?: (organizations: readonly TOrganization[]) => string | null;
|
|
26
|
+
session: ActiveOrganizationSessionLike | null | undefined;
|
|
27
|
+
setActiveOrganization: (organizationId: string) => Promise<unknown>;
|
|
28
|
+
}
|
|
29
|
+
interface EnsureActiveOrganizationResult {
|
|
30
|
+
activeOrganizationId: string | null;
|
|
31
|
+
didSetActiveOrganization: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Ensure the session has an active organization when memberships exist.
|
|
35
|
+
*
|
|
36
|
+
* - If `session.session.activeOrganizationId` is already set → return it (no network).
|
|
37
|
+
* - Else list organizations; if empty → `{ activeOrganizationId: null, didSetActiveOrganization: false }`.
|
|
38
|
+
* - Else select an id (custom or first) and call `setActiveOrganization`.
|
|
39
|
+
* - List/set failures invoke `onError` and return unset (never throw).
|
|
40
|
+
*/
|
|
41
|
+
declare function ensureActiveOrganization<TOrganization extends OrganizationLike>(options: EnsureActiveOrganizationOptions<TOrganization>): Promise<EnsureActiveOrganizationResult>;
|
|
42
|
+
|
|
43
|
+
export { type ActiveOrganizationSessionLike, type EnsureActiveOrganizationOptions, type EnsureActiveOrganizationResult, type OrganizationLike, ensureActiveOrganization };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic active-organization bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* Promoted from consumer apps (e.g. speedrun-formations) so product code only
|
|
5
|
+
* supplies list/set-active + optional org selection policy.
|
|
6
|
+
*
|
|
7
|
+
* Does not call Athena Auth routes itself — inject your client's
|
|
8
|
+
* `auth.organization.list` / `setActive` (or any compatible functions).
|
|
9
|
+
*/
|
|
10
|
+
interface ActiveOrganizationSessionLike {
|
|
11
|
+
session?: {
|
|
12
|
+
activeOrganizationId?: string | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
interface OrganizationLike {
|
|
16
|
+
id: string;
|
|
17
|
+
}
|
|
18
|
+
interface EnsureActiveOrganizationOptions<TOrganization extends OrganizationLike> {
|
|
19
|
+
listOrganizations: () => Promise<readonly TOrganization[]>;
|
|
20
|
+
onError?: (error: unknown) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Choose which org to activate when the session has none.
|
|
23
|
+
* Default: first organization with a non-empty `id`.
|
|
24
|
+
*/
|
|
25
|
+
selectOrganizationId?: (organizations: readonly TOrganization[]) => string | null;
|
|
26
|
+
session: ActiveOrganizationSessionLike | null | undefined;
|
|
27
|
+
setActiveOrganization: (organizationId: string) => Promise<unknown>;
|
|
28
|
+
}
|
|
29
|
+
interface EnsureActiveOrganizationResult {
|
|
30
|
+
activeOrganizationId: string | null;
|
|
31
|
+
didSetActiveOrganization: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Ensure the session has an active organization when memberships exist.
|
|
35
|
+
*
|
|
36
|
+
* - If `session.session.activeOrganizationId` is already set → return it (no network).
|
|
37
|
+
* - Else list organizations; if empty → `{ activeOrganizationId: null, didSetActiveOrganization: false }`.
|
|
38
|
+
* - Else select an id (custom or first) and call `setActiveOrganization`.
|
|
39
|
+
* - List/set failures invoke `onError` and return unset (never throw).
|
|
40
|
+
*/
|
|
41
|
+
declare function ensureActiveOrganization<TOrganization extends OrganizationLike>(options: EnsureActiveOrganizationOptions<TOrganization>): Promise<EnsureActiveOrganizationResult>;
|
|
42
|
+
|
|
43
|
+
export { type ActiveOrganizationSessionLike, type EnsureActiveOrganizationOptions, type EnsureActiveOrganizationResult, type OrganizationLike, ensureActiveOrganization };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/organization/ensure-active-organization.ts
|
|
2
|
+
function normalizeOrganizationId(value) {
|
|
3
|
+
if (typeof value !== "string") {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const normalized = value.trim();
|
|
7
|
+
return normalized.length > 0 ? normalized : null;
|
|
8
|
+
}
|
|
9
|
+
function defaultSelectOrganizationId(organizations) {
|
|
10
|
+
for (const organization of organizations) {
|
|
11
|
+
const id = normalizeOrganizationId(organization.id);
|
|
12
|
+
if (id) {
|
|
13
|
+
return id;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
async function ensureActiveOrganization(options) {
|
|
19
|
+
const currentActiveOrganizationId = normalizeOrganizationId(
|
|
20
|
+
options.session?.session?.activeOrganizationId
|
|
21
|
+
);
|
|
22
|
+
if (currentActiveOrganizationId) {
|
|
23
|
+
return {
|
|
24
|
+
activeOrganizationId: currentActiveOrganizationId,
|
|
25
|
+
didSetActiveOrganization: false
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
let organizations;
|
|
29
|
+
try {
|
|
30
|
+
organizations = await options.listOrganizations();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
options.onError?.(error);
|
|
33
|
+
return {
|
|
34
|
+
activeOrganizationId: null,
|
|
35
|
+
didSetActiveOrganization: false
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (organizations.length === 0) {
|
|
39
|
+
return {
|
|
40
|
+
activeOrganizationId: null,
|
|
41
|
+
didSetActiveOrganization: false
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const selectedOrganizationId = normalizeOrganizationId(
|
|
45
|
+
(options.selectOrganizationId ?? defaultSelectOrganizationId)(organizations)
|
|
46
|
+
);
|
|
47
|
+
if (!selectedOrganizationId) {
|
|
48
|
+
return {
|
|
49
|
+
activeOrganizationId: null,
|
|
50
|
+
didSetActiveOrganization: false
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
await options.setActiveOrganization(selectedOrganizationId);
|
|
55
|
+
return {
|
|
56
|
+
activeOrganizationId: selectedOrganizationId,
|
|
57
|
+
didSetActiveOrganization: true
|
|
58
|
+
};
|
|
59
|
+
} catch (error) {
|
|
60
|
+
options.onError?.(error);
|
|
61
|
+
return {
|
|
62
|
+
activeOrganizationId: null,
|
|
63
|
+
didSetActiveOrganization: false
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { ensureActiveOrganization };
|
|
69
|
+
//# sourceMappingURL=organization.js.map
|
|
70
|
+
//# sourceMappingURL=organization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/organization/ensure-active-organization.ts"],"names":[],"mappings":";AAqCA,SAAS,wBAAwB,KAAA,EAAiD;AAChF,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,UAAA,GAAa,MAAM,IAAA,EAAK;AAC9B,EAAA,OAAO,UAAA,CAAW,MAAA,GAAS,CAAA,GAAI,UAAA,GAAa,IAAA;AAC9C;AAEA,SAAS,4BACP,aAAA,EACe;AACf,EAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,IAAA,MAAM,EAAA,GAAK,uBAAA,CAAwB,YAAA,CAAa,EAAE,CAAA;AAClD,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAUA,eAAsB,yBACpB,OAAA,EACyC;AACzC,EAAA,MAAM,2BAAA,GAA8B,uBAAA;AAAA,IAClC,OAAA,CAAQ,SAAS,OAAA,EAAS;AAAA,GAC5B;AAEA,EAAA,IAAI,2BAAA,EAA6B;AAC/B,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,2BAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,aAAA,GAAgB,MAAM,QAAQ,iBAAA,EAAkB;AAAA,EAClD,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,UAAU,KAAK,CAAA;AACvB,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,MAAM,sBAAA,GAAyB,uBAAA;AAAA,IAAA,CAC5B,OAAA,CAAQ,oBAAA,IAAwB,2BAAA,EAA6B,aAAa;AAAA,GAC7E;AAEA,EAAA,IAAI,CAAC,sBAAA,EAAwB;AAC3B,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,CAAQ,sBAAsB,sBAAsB,CAAA;AAC1D,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,sBAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,UAAU,KAAK,CAAA;AACvB,IAAA,OAAO;AAAA,MACL,oBAAA,EAAsB,IAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AAAA,EACF;AACF","file":"organization.js","sourcesContent":["/**\n * Framework-agnostic active-organization bootstrap.\n *\n * Promoted from consumer apps (e.g. speedrun-formations) so product code only\n * supplies list/set-active + optional org selection policy.\n *\n * Does not call Athena Auth routes itself — inject your client's\n * `auth.organization.list` / `setActive` (or any compatible functions).\n */\n\nexport interface ActiveOrganizationSessionLike {\n session?: {\n activeOrganizationId?: string | null\n } | null\n}\n\nexport interface OrganizationLike {\n id: string\n}\n\nexport interface EnsureActiveOrganizationOptions<TOrganization extends OrganizationLike> {\n listOrganizations: () => Promise<readonly TOrganization[]>\n onError?: (error: unknown) => void\n /**\n * Choose which org to activate when the session has none.\n * Default: first organization with a non-empty `id`.\n */\n selectOrganizationId?: (organizations: readonly TOrganization[]) => string | null\n session: ActiveOrganizationSessionLike | null | undefined\n setActiveOrganization: (organizationId: string) => Promise<unknown>\n}\n\nexport interface EnsureActiveOrganizationResult {\n activeOrganizationId: string | null\n didSetActiveOrganization: boolean\n}\n\nfunction normalizeOrganizationId(value: string | null | undefined): string | null {\n if (typeof value !== 'string') {\n return null\n }\n const normalized = value.trim()\n return normalized.length > 0 ? normalized : null\n}\n\nfunction defaultSelectOrganizationId<TOrganization extends OrganizationLike>(\n organizations: readonly TOrganization[],\n): string | null {\n for (const organization of organizations) {\n const id = normalizeOrganizationId(organization.id)\n if (id) {\n return id\n }\n }\n return null\n}\n\n/**\n * Ensure the session has an active organization when memberships exist.\n *\n * - If `session.session.activeOrganizationId` is already set → return it (no network).\n * - Else list organizations; if empty → `{ activeOrganizationId: null, didSetActiveOrganization: false }`.\n * - Else select an id (custom or first) and call `setActiveOrganization`.\n * - List/set failures invoke `onError` and return unset (never throw).\n */\nexport async function ensureActiveOrganization<TOrganization extends OrganizationLike>(\n options: EnsureActiveOrganizationOptions<TOrganization>,\n): Promise<EnsureActiveOrganizationResult> {\n const currentActiveOrganizationId = normalizeOrganizationId(\n options.session?.session?.activeOrganizationId,\n )\n\n if (currentActiveOrganizationId) {\n return {\n activeOrganizationId: currentActiveOrganizationId,\n didSetActiveOrganization: false,\n }\n }\n\n let organizations: readonly TOrganization[]\n try {\n organizations = await options.listOrganizations()\n } catch (error) {\n options.onError?.(error)\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n\n if (organizations.length === 0) {\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n\n const selectedOrganizationId = normalizeOrganizationId(\n (options.selectOrganizationId ?? defaultSelectOrganizationId)(organizations),\n )\n\n if (!selectedOrganizationId) {\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n\n try {\n await options.setActiveOrganization(selectedOrganizationId)\n return {\n activeOrganizationId: selectedOrganizationId,\n didSetActiveOrganization: true,\n }\n } catch (error) {\n options.onError?.(error)\n return {\n activeOrganizationId: null,\n didSetActiveOrganization: false,\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { an as AthenaCreateClientAuthOptions, af as AthenaClientExperimentalOptions, aI as AthenaHeaderBag } from './client-BJjUwDSg.cjs';
|
|
2
|
+
import { o as BackendConfig, p as BackendType } from './types-CH78O90i.cjs';
|
|
3
|
+
|
|
4
|
+
interface AthenaRequestCookiesBag {
|
|
5
|
+
getAll(): Array<{
|
|
6
|
+
name: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
type AthenaRequestHeadersInput = AthenaHeaderBag | Record<string, string | null | undefined>;
|
|
11
|
+
type AthenaRequestCookiesInput = AthenaRequestCookiesBag | string | null | undefined;
|
|
12
|
+
type AthenaAdapterExperimentalOptions = Omit<AthenaClientExperimentalOptions, 'athenaStorageBackend'>;
|
|
13
|
+
interface AthenaAdapterBaseOptions {
|
|
14
|
+
env?: Record<string, string | undefined>;
|
|
15
|
+
url?: string | null | undefined;
|
|
16
|
+
gatewayUrl?: string | null | undefined;
|
|
17
|
+
authUrl?: string | null | undefined;
|
|
18
|
+
chatUrl?: string | null | undefined;
|
|
19
|
+
chatWsUrl?: string | null | undefined;
|
|
20
|
+
storageUrl?: string | null | undefined;
|
|
21
|
+
key?: string | null | undefined;
|
|
22
|
+
client?: string | null | undefined;
|
|
23
|
+
backend?: BackendConfig | BackendType;
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
auth?: AthenaCreateClientAuthOptions;
|
|
26
|
+
forceNoCache?: boolean;
|
|
27
|
+
storage?: boolean;
|
|
28
|
+
experimental?: AthenaAdapterExperimentalOptions;
|
|
29
|
+
}
|
|
30
|
+
interface AthenaServerRequestOptions {
|
|
31
|
+
requestHeaders?: AthenaRequestHeadersInput;
|
|
32
|
+
requestCookies?: AthenaRequestCookiesInput;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Default App Router path for the Athena Auth session cookie bridge.
|
|
37
|
+
*
|
|
38
|
+
* Mount as `app/api/athena-auth/session/route.ts`, or configure another path
|
|
39
|
+
* such as `/api/auth/session` when using catch-all handlers.
|
|
40
|
+
*
|
|
41
|
+
* @see {@link createAthenaAuthSessionBridgeHandlers}
|
|
42
|
+
* @see {@link createAthenaAuthSessionBridgePathHandlers}
|
|
43
|
+
*/
|
|
44
|
+
declare const ATHENA_AUTH_SESSION_BRIDGE_ROUTE = "/api/athena-auth/session";
|
|
45
|
+
/**
|
|
46
|
+
* Primary host-app session cookie written by the bridge.
|
|
47
|
+
*
|
|
48
|
+
* Hyphen form (`session-token`) matches Athena Auth UI and several consumer
|
|
49
|
+
* apps. Underscore form is also cleared on DELETE for cookie-helper parity.
|
|
50
|
+
*
|
|
51
|
+
* @see {@link ATHENA_AUTH_SESSION_COOKIE_NAMES}
|
|
52
|
+
*/
|
|
53
|
+
declare const ATHENA_AUTH_SESSION_COOKIE_NAME = "athena-auth.session-token";
|
|
54
|
+
/**
|
|
55
|
+
* Cookie names cleared on logout / bridge `DELETE`.
|
|
56
|
+
*
|
|
57
|
+
* Includes both hyphen and underscore variants so bridge clear stays aligned
|
|
58
|
+
* with `@xylex-group/athena/cookies` session token lookup.
|
|
59
|
+
*/
|
|
60
|
+
declare const ATHENA_AUTH_SESSION_COOKIE_NAMES: readonly ["athena-auth.session-token", "athena-auth.session_token"];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Minimal session shape accepted when deriving a bridge payload from
|
|
64
|
+
* `auth.getSession()`-style responses.
|
|
65
|
+
*
|
|
66
|
+
* Either nested `session.token` or a top-level `token` may be present depending
|
|
67
|
+
* on the Athena Auth response envelope version.
|
|
68
|
+
*/
|
|
69
|
+
interface AthenaAuthSessionBridgeSource {
|
|
70
|
+
session?: {
|
|
71
|
+
/** ISO-8601 expiry when provided by the auth server. */
|
|
72
|
+
expiresAt?: string | null;
|
|
73
|
+
/** Opaque session token string. */
|
|
74
|
+
token?: string | null;
|
|
75
|
+
} | null;
|
|
76
|
+
/** Some clients surface the token at the envelope root. */
|
|
77
|
+
token?: string | null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Body accepted by the session bridge `POST` handler and by
|
|
81
|
+
* {@link persistAthenaAuthSessionOnAppHost}.
|
|
82
|
+
*/
|
|
83
|
+
interface AthenaAuthSessionBridgePayload {
|
|
84
|
+
/** Non-empty session token to store in the app-host httpOnly cookie. */
|
|
85
|
+
token: string;
|
|
86
|
+
/**
|
|
87
|
+
* Optional cookie `Expires` value (ISO-8601 string).
|
|
88
|
+
* When omitted, the cookie is a session cookie (browser-lifetime).
|
|
89
|
+
*/
|
|
90
|
+
expiresAt?: string | undefined;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Configuration for bridge route handlers and cookie attributes.
|
|
94
|
+
*
|
|
95
|
+
* All fields are optional; defaults match speedrun-formations /
|
|
96
|
+
* Athena Auth UI conventions.
|
|
97
|
+
*/
|
|
98
|
+
interface AthenaAuthSessionBridgeOptions {
|
|
99
|
+
/**
|
|
100
|
+
* Route reported in JSON responses and used by client helpers when not
|
|
101
|
+
* overridden.
|
|
102
|
+
*
|
|
103
|
+
* @defaultValue `/api/athena-auth/session`
|
|
104
|
+
*/
|
|
105
|
+
route?: string | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Cookie name written on successful `POST`.
|
|
108
|
+
*
|
|
109
|
+
* @defaultValue `athena-auth.session-token`
|
|
110
|
+
*/
|
|
111
|
+
cookieName?: string | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Cookie names cleared on `DELETE` (aliases).
|
|
114
|
+
*
|
|
115
|
+
* @defaultValue hyphen + underscore session token names
|
|
116
|
+
*/
|
|
117
|
+
cookieNames?: readonly string[] | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Path attribute for the session cookie.
|
|
120
|
+
*
|
|
121
|
+
* @defaultValue `/`
|
|
122
|
+
*/
|
|
123
|
+
cookiePath?: string | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Cookie SameSite attribute.
|
|
126
|
+
*
|
|
127
|
+
* @defaultValue `lax`
|
|
128
|
+
*/
|
|
129
|
+
sameSite?: 'lax' | 'strict' | 'none' | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Force the `Secure` flag. When omitted, the handlers derive Secure from the
|
|
132
|
+
* request URL scheme and `x-forwarded-proto`.
|
|
133
|
+
*/
|
|
134
|
+
secure?: boolean | undefined;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Options for catch-all / dynamic-segment handlers under `/api/auth/*`.
|
|
138
|
+
*
|
|
139
|
+
* Extends {@link AthenaAuthSessionBridgeOptions} with path matching.
|
|
140
|
+
*/
|
|
141
|
+
interface AthenaAuthSessionBridgePathOptions extends AthenaAuthSessionBridgeOptions {
|
|
142
|
+
/**
|
|
143
|
+
* Pathname suffixes (final URL segments) that activate the bridge.
|
|
144
|
+
*
|
|
145
|
+
* @defaultValue `['session']` — covers `/api/auth/session` and
|
|
146
|
+
* `/api/athena-auth/session`
|
|
147
|
+
*/
|
|
148
|
+
matchPaths?: readonly string[] | undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Options for browser-side bridge fetch helpers.
|
|
153
|
+
*/
|
|
154
|
+
interface AthenaAuthSessionBridgeClientOptions {
|
|
155
|
+
/**
|
|
156
|
+
* Bridge route on the app host.
|
|
157
|
+
*
|
|
158
|
+
* @defaultValue {@link ATHENA_AUTH_SESSION_BRIDGE_ROUTE}
|
|
159
|
+
*/
|
|
160
|
+
route?: string | undefined;
|
|
161
|
+
/**
|
|
162
|
+
* Optional fetch implementation (defaults to global `fetch`).
|
|
163
|
+
* Useful in tests.
|
|
164
|
+
*/
|
|
165
|
+
fetch?: typeof fetch | undefined;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Persist an Athena Auth session token on the app host via the bridge `POST` route.
|
|
169
|
+
*
|
|
170
|
+
* Sends a same-origin JSON POST with `credentials: "same-origin"`. No-ops when
|
|
171
|
+
* `payload` is null/undefined or when not running in a browser.
|
|
172
|
+
*
|
|
173
|
+
* @param payload - Token (+ optional expiry) from {@link resolveSessionBridgePayload}
|
|
174
|
+
* @param options - Route override and fetch implementation
|
|
175
|
+
* @throws {Error} When the bridge responds with a non-OK status
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* await persistAthenaAuthSessionOnAppHost({
|
|
180
|
+
* token: session.session.token,
|
|
181
|
+
* expiresAt: session.session.expiresAt,
|
|
182
|
+
* })
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
declare function persistAthenaAuthSessionOnAppHost(payload: AthenaAuthSessionBridgePayload | null, options?: AthenaAuthSessionBridgeClientOptions): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Clear the bridged session cookie on the app host via `DELETE`.
|
|
188
|
+
*
|
|
189
|
+
* No-ops outside the browser. Pair with `auth.signOut()` so the app-host
|
|
190
|
+
* cookie does not outlive the auth session.
|
|
191
|
+
*
|
|
192
|
+
* @param options - Route override and fetch implementation
|
|
193
|
+
* @throws {Error} When the bridge responds with a non-OK status
|
|
194
|
+
*/
|
|
195
|
+
declare function clearAthenaAuthSessionOnAppHost(options?: AthenaAuthSessionBridgeClientOptions): Promise<void>;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Extract a bridge payload from a session response envelope.
|
|
199
|
+
*
|
|
200
|
+
* Preference order for the token:
|
|
201
|
+
* 1. `payload.session.token`
|
|
202
|
+
* 2. `payload.token`
|
|
203
|
+
*
|
|
204
|
+
* Returns `null` when no non-empty token string is available after trim.
|
|
205
|
+
*
|
|
206
|
+
* @param payload - Result of `auth.getSession()` data or a compatible object
|
|
207
|
+
* @returns Payload suitable for bridge `POST`, or `null`
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* const { data, ok } = await client.auth.getSession()
|
|
212
|
+
* if (ok) {
|
|
213
|
+
* await persistAthenaAuthSessionOnAppHost(resolveSessionBridgePayload(data))
|
|
214
|
+
* }
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
declare function resolveSessionBridgePayload(payload: AthenaAuthSessionBridgeSource | null | undefined): AthenaAuthSessionBridgePayload | null;
|
|
218
|
+
|
|
219
|
+
export { type AthenaAdapterBaseOptions as A, type AthenaAdapterExperimentalOptions as a, ATHENA_AUTH_SESSION_BRIDGE_ROUTE as b, ATHENA_AUTH_SESSION_COOKIE_NAME as c, ATHENA_AUTH_SESSION_COOKIE_NAMES as d, type AthenaAuthSessionBridgeClientOptions as e, type AthenaAuthSessionBridgePayload as f, type AthenaAuthSessionBridgeSource as g, clearAthenaAuthSessionOnAppHost as h, type AthenaAuthSessionBridgeOptions as i, type AthenaAuthSessionBridgePathOptions as j, type AthenaServerRequestOptions as k, persistAthenaAuthSessionOnAppHost as p, resolveSessionBridgePayload as r };
|