@intelligo-dev/auth 1.0.0-beta.1 → 1.0.0-beta.13
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/NOTICE +6 -0
- package/README.md +59 -0
- package/dist/client.js +6 -16
- package/dist/client.js.map +1 -1
- package/dist/edge.js +22 -28
- package/dist/edge.js.map +1 -1
- package/dist/guard-error.js +23 -0
- package/dist/guard-error.js.map +1 -0
- package/dist/helpers.js +77 -97
- package/dist/helpers.js.map +1 -1
- package/dist/impersonation.js +46 -18
- package/dist/impersonation.js.map +1 -1
- package/dist/index.js +21 -27
- package/dist/index.js.map +1 -1
- package/dist/invitation-links.js +13 -0
- package/dist/invitation-links.js.map +1 -0
- package/dist/onboarding/errors.js +4 -14
- package/dist/onboarding/errors.js.map +1 -1
- package/dist/onboarding/schemas.js +3 -15
- package/dist/onboarding/schemas.js.map +1 -1
- package/dist/onboarding/service.js +14 -68
- package/dist/onboarding/service.js.map +1 -1
- package/dist/org-api.js +10 -67
- package/dist/org-api.js.map +1 -1
- package/dist/profile/errors.js +4 -14
- package/dist/profile/errors.js.map +1 -1
- package/dist/profile/schemas.js +1 -10
- package/dist/profile/schemas.js.map +1 -1
- package/dist/profile/service.js +12 -53
- package/dist/profile/service.js.map +1 -1
- package/dist/roles.js +28 -5
- package/dist/roles.js.map +1 -1
- package/dist/server.js +80 -98
- package/dist/server.js.map +1 -1
- package/dist/team/errors.js +4 -13
- package/dist/team/errors.js.map +1 -1
- package/dist/team/schemas.js +4 -18
- package/dist/team/schemas.js.map +1 -1
- package/dist/team/service.js +80 -157
- package/dist/team/service.js.map +1 -1
- package/dist/trusted-origins.js +25 -0
- package/dist/trusted-origins.js.map +1 -0
- package/dist/workspace/errors.js +4 -14
- package/dist/workspace/errors.js.map +1 -1
- package/dist/workspace/schemas.js +2 -18
- package/dist/workspace/schemas.js.map +1 -1
- package/dist/workspace/service.js +31 -91
- package/dist/workspace/service.js.map +1 -1
- package/dist/workspace-bootstrap.js +33 -0
- package/dist/workspace-bootstrap.js.map +1 -0
- package/dist/workspace-init.js +46 -51
- package/dist/workspace-init.js.map +1 -1
- package/dist/workspace-slug.js +29 -0
- package/dist/workspace-slug.js.map +1 -0
- package/package.json +36 -14
- package/src/client.ts +6 -16
- package/src/edge.ts +22 -28
- package/src/guard-error.ts +36 -0
- package/src/helpers.ts +99 -114
- package/src/impersonation.ts +52 -17
- package/src/index.ts +14 -10
- package/src/invitation-links.ts +15 -0
- package/src/onboarding/errors.ts +5 -17
- package/src/onboarding/schemas.ts +3 -15
- package/src/onboarding/service.ts +11 -65
- package/src/org-api.ts +9 -66
- package/src/profile/errors.ts +5 -17
- package/src/profile/schemas.ts +1 -10
- package/src/profile/service.ts +8 -49
- package/src/roles.ts +36 -5
- package/src/server.ts +86 -104
- package/src/team/errors.ts +4 -13
- package/src/team/schemas.ts +4 -18
- package/src/team/service.ts +100 -174
- package/src/trusted-origins.ts +26 -0
- package/src/workspace/errors.ts +4 -14
- package/src/workspace/schemas.ts +2 -18
- package/src/workspace/service.ts +40 -92
- package/src/workspace-bootstrap.ts +57 -0
- package/src/workspace-init.ts +55 -56
- package/src/workspace-slug.ts +32 -0
package/dist/index.js
CHANGED
|
@@ -1,30 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Server-side authentication utilities.
|
|
5
|
-
* For client-side auth, use @intelligo-dev/auth/client
|
|
2
|
+
* Server-side auth. Client components use `@intelligo-dev/auth/client`.
|
|
6
3
|
*/
|
|
7
|
-
export { auth } from "./server";
|
|
8
|
-
export { getAuthSession, requireAuth, getWorkspaceContext, getWorkspaceContextById, requireWorkspace, requireRole, requirePlatformAdmin, } from "./helpers";
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
|
|
15
|
-
export { createTeamService, } from "./team/service";
|
|
16
|
-
export { TeamServiceError, isTeamServiceError, } from "./team/errors";
|
|
17
|
-
export { inviteMemberSchema, updateRoleSchema, } from "./team/schemas";
|
|
18
|
-
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
26
|
-
|
|
27
|
-
export { createOnboardingService, } from "./onboarding/service";
|
|
28
|
-
export { OnboardingServiceError, isOnboardingServiceError, } from "./onboarding/errors";
|
|
29
|
-
export { setStepSchema } from "./onboarding/schemas";
|
|
4
|
+
export { auth } from "./server.js";
|
|
5
|
+
export { getAuthSession, requireAuth, getWorkspaceContext, getWorkspaceContextById, requireWorkspace, requireRole, requirePlatformAdmin, } from "./helpers.js";
|
|
6
|
+
export { AuthGuardError, isAuthGuardError, } from "./guard-error.js";
|
|
7
|
+
export { ensureUserWorkspace } from "./workspace-init.js";
|
|
8
|
+
export { setWorkspaceCreatedHandler, clearWorkspaceCreatedHandler, } from "./workspace-bootstrap.js";
|
|
9
|
+
export { PLATFORM_ADMIN_ROLE } from "./roles.js";
|
|
10
|
+
export { impersonateUser, stopImpersonating, } from "./impersonation.js";
|
|
11
|
+
export { orgApi, } from "./org-api.js";
|
|
12
|
+
export { createTeamService, } from "./team/service.js";
|
|
13
|
+
export { TeamServiceError, isTeamServiceError, } from "./team/errors.js";
|
|
14
|
+
export { inviteMemberSchema, updateRoleSchema, } from "./team/schemas.js";
|
|
15
|
+
export { createWorkspaceService, } from "./workspace/service.js";
|
|
16
|
+
export { WorkspaceServiceError, isWorkspaceServiceError, } from "./workspace/errors.js";
|
|
17
|
+
export { createWorkspaceSchema, updateWorkspaceSchema, } from "./workspace/schemas.js";
|
|
18
|
+
export { createProfileService, } from "./profile/service.js";
|
|
19
|
+
export { ProfileServiceError, isProfileServiceError, } from "./profile/errors.js";
|
|
20
|
+
export { updateProfileSchema, } from "./profile/schemas.js";
|
|
21
|
+
export { createOnboardingService, } from "./onboarding/service.js";
|
|
22
|
+
export { OnboardingServiceError, isOnboardingServiceError, } from "./onboarding/errors.js";
|
|
23
|
+
export { setStepSchema } from "./onboarding/schemas.js";
|
|
30
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EACL,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,gBAAgB,GAEjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,iBAAiB,GAElB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,MAAM,GAOP,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,GAGlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GAGnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GAGjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,sBAAsB,GAIvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAGxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oBAAoB,GAIrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,uBAAuB,GAGxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The links an invitation email carries. Both land on the invitation page,
|
|
3
|
+
* which offers accept and decline to the signed-in invitee; declining is a
|
|
4
|
+
* decision made there, never the effect of following a link.
|
|
5
|
+
*
|
|
6
|
+
* Unprefixed on purpose: the consumer's locale middleware resolves the
|
|
7
|
+
* invitee's locale, so the email does not have to guess one.
|
|
8
|
+
*/
|
|
9
|
+
export function invitationLinks(appUrl, invitationId) {
|
|
10
|
+
const page = `${appUrl.replace(/\/+$/, "")}/accept-invitation/${encodeURIComponent(invitationId)}`;
|
|
11
|
+
return { acceptUrl: page, declineUrl: page };
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=invitation-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invitation-links.js","sourceRoot":"","sources":["../src/invitation-links.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,YAAoB;IAEpB,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,sBAAsB,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;IACnG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Mirrors `../team/errors.ts` and `../workspace/errors.ts`: the
|
|
5
|
-
* onboarding service (./service.ts) throws this for every failure it
|
|
6
|
-
* recognizes rather than returning an ad-hoc `{ success, error }`
|
|
7
|
-
* envelope — that shaping is a transport concern (a Server Action, a
|
|
8
|
-
* route handler) and belongs one layer up, alongside
|
|
9
|
-
* revalidatePath/Sentry/toast/i18n, none of which this package may
|
|
10
|
-
* depend on.
|
|
2
|
+
* Thrown for every failure the onboarding service recognizes. Shaping it for a UI
|
|
3
|
+
* (a `{ success, error }` envelope, i18n, revalidation) is the transport's job.
|
|
11
4
|
*/
|
|
12
5
|
export class OnboardingServiceError extends Error {
|
|
13
6
|
constructor(code, message, options) {
|
|
@@ -15,13 +8,10 @@ export class OnboardingServiceError extends Error {
|
|
|
15
8
|
this.name = "OnboardingServiceError";
|
|
16
9
|
this.code = code;
|
|
17
10
|
if (options?.cause !== undefined) {
|
|
18
|
-
// ES2020 target predates the
|
|
19
|
-
// assign it directly so `instanceof Error` consumers (and Node's
|
|
20
|
-
// own error inspection) still see it.
|
|
11
|
+
// The ES2020 target predates the `cause` constructor option.
|
|
21
12
|
this.cause = options.cause;
|
|
22
13
|
}
|
|
23
|
-
//
|
|
24
|
-
// transpilation targets loses `instanceof`).
|
|
14
|
+
// Extending built-ins loses `instanceof` on some transpilation targets.
|
|
25
15
|
Object.setPrototypeOf(this, OnboardingServiceError.prototype);
|
|
26
16
|
}
|
|
27
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/onboarding/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/onboarding/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAG/C,YACE,IAAgC,EAChC,OAAe,EACf,OAA6B;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,6DAA6D;YAC5D,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAc;IAEd,OAAO,KAAK,YAAY,sBAAsB,CAAC;AACjD,CAAC"}
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `./service.ts` for why this is a bare, bounded string rather than a
|
|
6
|
-
* product-specific enum. Ignite's original
|
|
7
|
-
* `lib/validations/onboarding.ts` pinned this to
|
|
8
|
-
* `z.enum(["role", "profile", "complete"])`, Career's own 3-step wizard
|
|
9
|
-
* shape. The `users.onboarding_step` column itself is untyped `text`,
|
|
10
|
-
* so that enum was a product-level constraint bolted onto a generic
|
|
11
|
-
* column, not something this shared contract should require. A
|
|
12
|
-
* consumer defines its own step ids (typically the `id` field of a
|
|
13
|
-
* steps-config array it owns) and passes them straight through;
|
|
14
|
-
* Ignite's cut-over copy keeps its own enum-shaped schema at the
|
|
15
|
-
* transport layer if it wants stricter validation than "non-empty,
|
|
16
|
-
* bounded string".
|
|
2
|
+
* A step id is a non-empty, bounded string, not an enum: step ids are the
|
|
3
|
+
* consumer's (the `id`s of its own steps config). A consumer wanting
|
|
4
|
+
* stricter validation keeps its own schema at the transport layer.
|
|
17
5
|
*/
|
|
18
6
|
import { z } from "zod";
|
|
19
7
|
export const setStepSchema = z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/onboarding/schemas.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/onboarding/schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC;KAC7B,GAAG,CAAC,EAAE,EAAE,uCAAuC,CAAC,CAAC"}
|
|
@@ -1,63 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Unlike `../team/service.ts` and `../workspace/service.ts`, this
|
|
8
|
-
* service has no Better-Auth organization-plugin calls to make — it
|
|
9
|
-
* reads and writes exactly two columns on `@intelligo-dev/core`'s `users`
|
|
10
|
-
* table (`onboardingCompleted`, `onboardingStep`) directly via Drizzle.
|
|
11
|
-
*
|
|
12
|
-
* No ports: `complete()` and `skip()` only flip those two columns and
|
|
13
|
-
* return the resulting state — they do NOT provision trial credits,
|
|
14
|
-
* record referrals, or perform any other first-workspace bootstrapping.
|
|
15
|
-
* Ignite's original `completeOnboarding()` action did exactly that
|
|
16
|
-
* (`provisionTrialCredits`/`recordReferralSignup`/`grantReferralUpgrade`
|
|
17
|
-
* inline), but that work belongs to the consumer's own
|
|
18
|
-
* `onWorkspaceCreated` binding instead — see `../workspace-init.ts`'s
|
|
19
|
-
* `onWorkspaceCreated` port and the `app-shell` registry item's
|
|
20
|
-
* `lib/workspace-bootstrap.ts`, which already runs once per new
|
|
21
|
-
* workspace. Duplicating it here would either double-provision (it
|
|
22
|
-
* would fire again on every onboarding completion, not just the first
|
|
23
|
-
* workspace) or force this package to depend on `@intelligo-dev/billing`,
|
|
24
|
-
* which the allowlist in
|
|
25
|
-
* `tests/architecture/dependency-direction.test.ts` forbids.
|
|
26
|
-
*
|
|
27
|
-
* ---------------------------------------------------------------------
|
|
28
|
-
* Why `setStep` takes a bare `string`, not an enum
|
|
29
|
-
* ---------------------------------------------------------------------
|
|
30
|
-
* See the doc comment on `./schemas.ts`'s `setStepSchema`. Short
|
|
31
|
-
* version: the `onboarding_step` column is untyped `text`, and a
|
|
32
|
-
* framework-owned service can't know a consumer's step ids in advance
|
|
33
|
-
* — a different product may have two steps, or six. This module
|
|
34
|
-
* accepts any non-empty string up to 64 characters and persists it
|
|
35
|
-
* verbatim.
|
|
36
|
-
*
|
|
37
|
-
* ---------------------------------------------------------------------
|
|
38
|
-
* Why `skip()` has the same durable effect as `complete()`
|
|
39
|
-
* ---------------------------------------------------------------------
|
|
40
|
-
* The `users` table has no separate "skipped" column, so there is
|
|
41
|
-
* nothing else to persist. Ignite's original `skipOnboarding()` action
|
|
42
|
-
* logged an analytics event and then delegated to `completeOnboarding()`
|
|
43
|
-
* unchanged; this service mirrors that shape as two distinct methods
|
|
44
|
-
* (rather than collapsing `skip` into an alias) so a transport can
|
|
45
|
-
* still log/tag the skip differently before or after calling it —
|
|
46
|
-
* that shaping, like everything else transport-level, does not belong
|
|
47
|
-
* in this service.
|
|
48
|
-
*
|
|
49
|
-
* Authorization (`requireAuth`) lives INSIDE each method, not at the
|
|
50
|
-
* transport. Every recognized failure throws `OnboardingServiceError`
|
|
51
|
-
* with a stable `code` — no revalidatePath/Sentry/next-intl/toast here;
|
|
52
|
-
* that shaping is the transport's job (a Server Action, a route
|
|
53
|
-
* handler).
|
|
2
|
+
* The caller's first-run onboarding state: two columns on `users`
|
|
3
|
+
* (`onboardingCompleted`, `onboardingStep`). Completing onboarding has no
|
|
4
|
+
* trial or credit side effects; first-workspace bootstrapping runs once per
|
|
5
|
+
* workspace through `ensureUserWorkspace`'s `onWorkspaceCreated`. Each method
|
|
6
|
+
* authorizes itself and throws `OnboardingServiceError`.
|
|
54
7
|
*/
|
|
55
8
|
import { eq } from "drizzle-orm";
|
|
56
9
|
import { db } from "@intelligo-dev/core/db";
|
|
57
10
|
import { users } from "@intelligo-dev/core/db/schema";
|
|
58
|
-
import { requireAuth } from "../helpers";
|
|
59
|
-
import { setStepSchema } from "./schemas";
|
|
60
|
-
import { OnboardingServiceError, isOnboardingServiceError } from "./errors";
|
|
11
|
+
import { requireAuth } from "../helpers.js";
|
|
12
|
+
import { setStepSchema } from "./schemas.js";
|
|
13
|
+
import { OnboardingServiceError, isOnboardingServiceError } from "./errors.js";
|
|
61
14
|
function errorMessage(error) {
|
|
62
15
|
return error instanceof Error ? error.message : String(error);
|
|
63
16
|
}
|
|
@@ -78,9 +31,7 @@ export function createOnboardingService() {
|
|
|
78
31
|
throw toForbidden(error);
|
|
79
32
|
}
|
|
80
33
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Get the caller's current onboarding state.
|
|
83
|
-
*/
|
|
34
|
+
/** The caller's current onboarding state. */
|
|
84
35
|
async function getState() {
|
|
85
36
|
const { user } = await callRequireAuth();
|
|
86
37
|
const [row] = await db
|
|
@@ -100,9 +51,8 @@ export function createOnboardingService() {
|
|
|
100
51
|
};
|
|
101
52
|
}
|
|
102
53
|
/**
|
|
103
|
-
* Set the caller's current
|
|
104
|
-
*
|
|
105
|
-
* that `step` is a non-empty, bounded string and persists it
|
|
54
|
+
* Set the caller's current step. Step ids are the product's; this only
|
|
55
|
+
* checks for a non-empty string of at most 64 characters and persists it
|
|
106
56
|
* verbatim. Does not touch `onboardingCompleted`.
|
|
107
57
|
*/
|
|
108
58
|
async function setStep(step) {
|
|
@@ -118,10 +68,7 @@ export function createOnboardingService() {
|
|
|
118
68
|
.where(eq(users.id, user.id));
|
|
119
69
|
return { completed: false, currentStep: parsed.data };
|
|
120
70
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Mark onboarding complete and clear the step. No trial/referral
|
|
123
|
-
* side effects — see the module doc comment.
|
|
124
|
-
*/
|
|
71
|
+
/** Mark onboarding complete and clear the step. */
|
|
125
72
|
async function complete() {
|
|
126
73
|
const { user } = await callRequireAuth();
|
|
127
74
|
await db
|
|
@@ -135,9 +82,8 @@ export function createOnboardingService() {
|
|
|
135
82
|
return { completed: true, currentStep: null };
|
|
136
83
|
}
|
|
137
84
|
/**
|
|
138
|
-
* Skip onboarding. Same durable effect as `complete()`
|
|
139
|
-
*
|
|
140
|
-
* alias.
|
|
85
|
+
* Skip onboarding. Same durable effect as `complete()` (there is no
|
|
86
|
+
* "skipped" column); a separate method so a transport can tell them apart.
|
|
141
87
|
*/
|
|
142
88
|
async function skip() {
|
|
143
89
|
return complete();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/onboarding/service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/onboarding/service.ts"],"names":[],"mappings":"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"}
|
package/dist/org-api.js
CHANGED
|
@@ -1,73 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Typed
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `
|
|
7
|
-
* `
|
|
8
|
-
* lose all type information.
|
|
9
|
-
*
|
|
10
|
-
* This module declares the explicit input/output shapes for every
|
|
11
|
-
* organization endpoint the team service calls and exposes them under
|
|
12
|
-
* the plugin's HTTP path names (`/organization/invite-member`, etc.),
|
|
13
|
-
* which is the vocabulary the rest of this package's `team/` module
|
|
14
|
-
* uses.
|
|
15
|
-
*
|
|
16
|
-
* (Ported from the product application’s Better-Auth type wrapper as part of the
|
|
17
|
-
* team-settings backend extraction — packages/auth owns the org-api
|
|
18
|
-
* contract now; ignite's copy is retired at cutover.)
|
|
19
|
-
*
|
|
20
|
-
* IMPORTANT — found while wiring the real-DB integration test for this
|
|
21
|
-
* extraction: ignite's original module built `orgApi` as
|
|
22
|
-
* `auth.api as unknown as OrgApi`, i.e. a bare type-cast that assumes
|
|
23
|
-
* `auth.api` is keyed by these HTTP path strings. It is not. Better-Auth's
|
|
24
|
-
* organization plugin (`better-auth@1.6.30`,
|
|
25
|
-
* `plugins/organization/organization.mjs`) exposes each endpoint on
|
|
26
|
-
* `auth.api` under its own camelCase *server* id, which does not always
|
|
27
|
-
* match the path or the *client* SDK name documented alongside it:
|
|
28
|
-
*
|
|
29
|
-
* path | auth.api key (server) | authClient.organization.* (client)
|
|
30
|
-
* /organization/invite-member | createInvitation | inviteMember
|
|
31
|
-
* /organization/get-invitation | getInvitation | getInvitation
|
|
32
|
-
* /organization/accept-invitation | acceptInvitation | acceptInvitation
|
|
33
|
-
* /organization/reject-invitation | rejectInvitation | rejectInvitation
|
|
34
|
-
* /organization/cancel-invitation | cancelInvitation | cancelInvitation
|
|
35
|
-
* /organization/remove-member | removeMember | removeMember
|
|
36
|
-
* /organization/update-member-role | updateMemberRole | updateMemberRole
|
|
37
|
-
* /organization/leave | leaveOrganization | leave
|
|
38
|
-
* /organization/list | listOrganizations | list
|
|
39
|
-
* /organization/set-active | setActiveOrganization | setActive
|
|
40
|
-
* /organization/list-user-invitations | listUserInvitations | listUserInvitations
|
|
41
|
-
*
|
|
42
|
-
* A bare `auth.api as unknown as OrgApi` cast type-checks (TypeScript
|
|
43
|
-
* cannot see through the cast) but throws `TypeError: ... is not a
|
|
44
|
-
* function` at runtime for every call whose row above differs in the
|
|
45
|
-
* first two columns — i.e. invite-member, leave, list, and set-active
|
|
46
|
-
* unconditionally, since their server ids aren't just a casing change
|
|
47
|
-
* of the path. This was invisible in ignite's test suite because
|
|
48
|
-
* `actions/__tests__/team.test.ts` mocks `@/types/better-auth` (the
|
|
49
|
-
* whole `orgApi` object) rather than exercising the cast against a
|
|
50
|
-
* real `auth.api`, and only surfaced once this extraction's
|
|
51
|
-
* `service.integration.test.ts` called the real thing. It is a live
|
|
52
|
-
* bug in ignite's shipped team-management actions today, not a
|
|
53
|
-
* hypothetical — worth a fix there independent of this migration.
|
|
54
|
-
*
|
|
55
|
-
* `orgApi` below is therefore a real object, not a cast: each path key
|
|
56
|
-
* forwards to the correctly-named `auth.api` method. The `OrgApi`
|
|
57
|
-
* type and every call site elsewhere in this package (`team/service.ts`
|
|
58
|
-
* and its tests) are unaffected — they only ever see the path-keyed
|
|
59
|
-
* shape.
|
|
2
|
+
* Typed access to Better-Auth's organization-plugin endpoints, which the
|
|
3
|
+
* inferred `auth.api` type does not include. Keys are the plugin's HTTP
|
|
4
|
+
* paths; each forwards to the plugin's server id, which is not always the
|
|
5
|
+
* path in camelCase (`/organization/invite-member` is `createInvitation`,
|
|
6
|
+
* `/organization/list` is `listOrganizations`), so a blanket cast of
|
|
7
|
+
* `auth.api` would type-check and then throw "is not a function".
|
|
60
8
|
*/
|
|
61
|
-
import { auth } from "./server";
|
|
9
|
+
import { auth } from "./server.js";
|
|
62
10
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* `OrgApi` member signature at the point of use below, which is the
|
|
67
|
-
* same trust boundary the rest of this codebase already accepts for
|
|
68
|
-
* these calls (see the module doc comment above for why a *blanket*
|
|
69
|
-
* cast is not safe: it hides the wrong key entirely, whereas casting
|
|
70
|
-
* per-member here only relaxes the parameter/return types).
|
|
11
|
+
* Better-Auth types these methods loosely; each is cast to its `OrgApi`
|
|
12
|
+
* member signature below, which relaxes only parameter and return types,
|
|
13
|
+
* never which method a key names.
|
|
71
14
|
*/
|
|
72
15
|
const api = auth.api;
|
|
73
16
|
export const orgApi = {
|
package/dist/org-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"org-api.js","sourceRoot":"","sources":["../src/org-api.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"org-api.js","sourceRoot":"","sources":["../src/org-api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAoGhC;;;;GAIG;AACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAGhB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAW;IAC5B,6BAA6B,EAC3B,GAAG,CAAC,gBAAyD;IAC/D,8BAA8B,EAC5B,GAAG,CAAC,aAAuD;IAC7D,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,6BAA6B,EAC3B,GAAG,CAAC,YAAqD;IAC3D,kCAAkC,EAChC,GAAG,CAAC,gBAA8D;IACpE,qBAAqB,EAAE,GAAG,CAAC,iBAAkD;IAC7E,oBAAoB,EAAE,GAAG,CAAC,iBAAiD;IAC3E,0BAA0B,EACxB,GAAG,CAAC,qBAA2D;IACjE,qCAAqC,EACnC,GAAG,CAAC,mBAAoE;CAC3E,CAAC"}
|
package/dist/profile/errors.js
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* The profile service (./service.ts) throws this for every failure it
|
|
5
|
-
* recognizes rather than returning an ad-hoc `{ success, error }`
|
|
6
|
-
* envelope — that shaping is a transport concern (a Server Action, a
|
|
7
|
-
* route handler) and belongs one layer up, alongside
|
|
8
|
-
* revalidatePath/Sentry/toast/i18n, none of which this package may
|
|
9
|
-
* depend on. Mirrors `TeamServiceError`/`WorkspaceServiceError`
|
|
10
|
-
* (../team/errors.ts, ../workspace/errors.ts).
|
|
2
|
+
* Thrown for every failure the profile service recognizes. Shaping it for a UI
|
|
3
|
+
* (a `{ success, error }` envelope, i18n, revalidation) is the transport's job.
|
|
11
4
|
*/
|
|
12
5
|
export class ProfileServiceError extends Error {
|
|
13
6
|
constructor(code, message, options) {
|
|
@@ -16,13 +9,10 @@ export class ProfileServiceError extends Error {
|
|
|
16
9
|
this.code = code;
|
|
17
10
|
this.meta = options?.meta;
|
|
18
11
|
if (options?.cause !== undefined) {
|
|
19
|
-
// ES2020 target predates the
|
|
20
|
-
// assign it directly so `instanceof Error` consumers (and Node's
|
|
21
|
-
// own error inspection) still see it.
|
|
12
|
+
// The ES2020 target predates the `cause` constructor option.
|
|
22
13
|
this.cause = options.cause;
|
|
23
14
|
}
|
|
24
|
-
//
|
|
25
|
-
// transpilation targets loses `instanceof`).
|
|
15
|
+
// Extending built-ins loses `instanceof` on some transpilation targets.
|
|
26
16
|
Object.setPrototypeOf(this, ProfileServiceError.prototype);
|
|
27
17
|
}
|
|
28
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/profile/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/profile/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAI5C,YACE,IAA6B,EAC7B,OAAe,EACf,OAA6D;QAE7D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,6DAA6D;YAC5D,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAc;IAEd,OAAO,KAAK,YAAY,mBAAmB,CAAC;AAC9C,CAAC"}
|
package/dist/profile/schemas.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Profile Validation Schemas
|
|
3
|
-
*
|
|
4
|
-
* Zod schemas for user profile updates, shared by the profile service
|
|
5
|
-
* and its transports.
|
|
6
|
-
*
|
|
7
|
-
* (Ported from the product application's `lib/validations/profile.ts` —
|
|
8
|
-
* same semantics: optional name, optional-and-nullable image URL.
|
|
9
|
-
* Ignite's copy is retired at cutover.)
|
|
10
|
-
*/
|
|
1
|
+
/** Profile update input, shared by the profile service and its transports. */
|
|
11
2
|
import { z } from "zod";
|
|
12
3
|
export const updateProfileSchema = z.object({
|
|
13
4
|
name: z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/profile/schemas.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/profile/schemas.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;SAC5C,GAAG,CAAC,GAAG,EAAE,qCAAqC,CAAC;SAC/C,QAAQ,EAAE;IACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACzE,CAAC,CAAC"}
|
package/dist/profile/service.js
CHANGED
|
@@ -1,56 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Mirrors `createTeamService(ports)` / `createWorkspaceService(ports)`
|
|
8
|
-
* (../team/service.ts, ../workspace/service.ts) one directory over: a
|
|
9
|
-
* factory over optional ports, so this package's allowlisted dependency
|
|
10
|
-
* (`@intelligo-dev/core` only — see
|
|
11
|
-
* tests/architecture/dependency-direction.test.ts) never grows to
|
|
12
|
-
* include an email-sending concern of its own. A consumer binds the
|
|
13
|
-
* account-deletion confirmation email in at its composition root:
|
|
14
|
-
*
|
|
15
|
-
* const profileService = createProfileService({
|
|
16
|
-
* onAccountDeleted: ({ email, name }) =>
|
|
17
|
-
* sendEmail({ to: email, subject: ..., html: ... }), // @intelligo-dev/core/email
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
|
-
* Authorization (`requireAuth`) lives INSIDE each method, not at the
|
|
21
|
-
* transport. Every recognized failure throws `ProfileServiceError` with
|
|
22
|
-
* a stable `code` — no revalidatePath/Sentry/next-intl/toast here; that
|
|
23
|
-
* shaping is the transport's job (a Server Action, a route handler).
|
|
24
|
-
*
|
|
25
|
-
* ---------------------------------------------------------------------
|
|
26
|
-
* Why the confirmation email is a port, not a direct import
|
|
27
|
-
* ---------------------------------------------------------------------
|
|
28
|
-
* The product application's original `deleteAccount()`
|
|
29
|
-
* calls `sendEmail` from
|
|
30
|
-
* `@intelligo-dev/core/email` directly, inline, with a hardcoded English
|
|
31
|
-
* HTML template. `@intelligo-dev/auth` already imports `@intelligo-dev/core/email`
|
|
32
|
-
* elsewhere (`server.ts`'s Better-Auth hooks — verification, password
|
|
33
|
-
* reset, welcome, invitation emails), so nothing in the allowlist
|
|
34
|
-
* (auth → core only) would technically block importing `sendEmail`
|
|
35
|
-
* here too. The port exists anyway, for the same reason
|
|
36
|
-
* `TeamServicePorts.sendInvitationEmail` and
|
|
37
|
-
* `WorkspaceServicePorts.checkWorkspaceLimit` are ports rather than
|
|
38
|
-
* direct calls: this service should not own *content* — copy, subject
|
|
39
|
-
* lines, template shape — for a side effect a consumer may want to
|
|
40
|
-
* localize, skip, or replace with a different provider. `onAccountDeleted`
|
|
41
|
-
* is fire-and-forget by design (matching ignite's `.catch(console.error)`
|
|
42
|
-
* pattern): a failed confirmation email must never block the deletion
|
|
43
|
-
* that already succeeded.
|
|
2
|
+
* The caller's own profile: read, update, delete the account. Each method
|
|
3
|
+
* authorizes itself and throws `ProfileServiceError`. The confirmation email
|
|
4
|
+
* is the `onAccountDeleted` port so its copy and provider stay the
|
|
5
|
+
* consumer's; it is fire-and-forget, since the deletion has already succeeded.
|
|
44
6
|
*/
|
|
45
|
-
import {
|
|
7
|
+
import { getRequestHeaders } from "@intelligo-dev/core/request-context";
|
|
46
8
|
import { eq } from "drizzle-orm";
|
|
47
9
|
import { createLogger } from "@intelligo-dev/core/logger";
|
|
48
10
|
import { db } from "@intelligo-dev/core/db";
|
|
49
11
|
import { users, sessions } from "@intelligo-dev/core/db/schema";
|
|
50
|
-
import { auth } from "../server";
|
|
51
|
-
import { requireAuth } from "../helpers";
|
|
52
|
-
import { updateProfileSchema } from "./schemas";
|
|
53
|
-
import { ProfileServiceError, isProfileServiceError } from "./errors";
|
|
12
|
+
import { auth } from "../server.js";
|
|
13
|
+
import { requireAuth } from "../helpers.js";
|
|
14
|
+
import { updateProfileSchema } from "./schemas.js";
|
|
15
|
+
import { ProfileServiceError, isProfileServiceError } from "./errors.js";
|
|
54
16
|
const log = createLogger("ProfileService");
|
|
55
17
|
function errorMessage(error) {
|
|
56
18
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -80,9 +42,7 @@ export function createProfileService(ports = {}) {
|
|
|
80
42
|
throw toForbidden(error);
|
|
81
43
|
}
|
|
82
44
|
}
|
|
83
|
-
/**
|
|
84
|
-
* Get the caller's own profile.
|
|
85
|
-
*/
|
|
45
|
+
/** The caller's own profile. */
|
|
86
46
|
async function getProfile() {
|
|
87
47
|
const { user } = await callRequireAuth();
|
|
88
48
|
return {
|
|
@@ -97,13 +57,12 @@ export function createProfileService(ports = {}) {
|
|
|
97
57
|
* Update the caller's own name/image via the Better-Auth user API.
|
|
98
58
|
* Only the fields present in `input` are sent — omitting a field
|
|
99
59
|
* leaves it unchanged; `image: null` is dropped rather than forwarded
|
|
100
|
-
* (Better-Auth's `updateUser` does not accept `null`)
|
|
101
|
-
* ignite's original action.
|
|
60
|
+
* (Better-Auth's `updateUser` does not accept `null`).
|
|
102
61
|
*/
|
|
103
62
|
async function updateProfile(input) {
|
|
104
63
|
await callRequireAuth();
|
|
105
64
|
const validated = parseInput(updateProfileSchema, input);
|
|
106
|
-
const hdrs = await
|
|
65
|
+
const hdrs = await getRequestHeaders();
|
|
107
66
|
const updateData = {};
|
|
108
67
|
if (validated.name !== undefined)
|
|
109
68
|
updateData.name = validated.name;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/profile/service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/profile/service.ts"],"names":[],"mappings":"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"}
|
package/dist/roles.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Deliberately a separate module from helpers.ts and server.ts: both
|
|
5
|
-
* need the constant, and server.ts (the Better-Auth instance) cannot
|
|
6
|
-
* import helpers.ts, which imports server.ts.
|
|
2
|
+
* Its own module because server.ts and helpers.ts both need it, and
|
|
3
|
+
* server.ts cannot import helpers.ts, which imports server.ts.
|
|
7
4
|
*/
|
|
8
5
|
/**
|
|
9
6
|
* Grants the operational console and, through Better-Auth's admin
|
|
@@ -14,4 +11,30 @@
|
|
|
14
11
|
* on it is gated on nothing.
|
|
15
12
|
*/
|
|
16
13
|
export const PLATFORM_ADMIN_ROLE = "platform-admin";
|
|
14
|
+
/**
|
|
15
|
+
* Where a user stands as a platform admin: `hasRole` reads `users.role`
|
|
16
|
+
* (comma-separated), `allowlisted` reads PLATFORM_ADMIN_EMAILS, the
|
|
17
|
+
* bootstrap that `requirePlatformAdmin` promotes into the column.
|
|
18
|
+
*
|
|
19
|
+
* The allowlist names an address, so it counts only once the address
|
|
20
|
+
* is verified: otherwise whoever registers an allowlisted address
|
|
21
|
+
* first — before the real admin, or on a deployment that sends no
|
|
22
|
+
* verification mail — would become an admin.
|
|
23
|
+
*/
|
|
24
|
+
export function platformAdminStanding(user) {
|
|
25
|
+
const allowlist = (process.env.PLATFORM_ADMIN_EMAILS ?? "")
|
|
26
|
+
.split(",")
|
|
27
|
+
.map((e) => e.trim().toLowerCase())
|
|
28
|
+
.filter(Boolean);
|
|
29
|
+
const email = user.email?.toLowerCase();
|
|
30
|
+
const roles = (user.role ?? "")
|
|
31
|
+
.split(",")
|
|
32
|
+
.map((r) => r.trim())
|
|
33
|
+
.filter(Boolean);
|
|
34
|
+
return {
|
|
35
|
+
allowlisted: !!email && user.emailVerified === true && allowlist.includes(email),
|
|
36
|
+
hasRole: roles.includes(PLATFORM_ADMIN_ROLE),
|
|
37
|
+
roles,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
17
40
|
//# sourceMappingURL=roles.js.map
|
package/dist/roles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACC,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;SACxD,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAClC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;SAC5B,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,OAAO;QACL,WAAW,EACT,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC5C,KAAK;KACN,CAAC;AACJ,CAAC"}
|