@headless-lms/core 0.1.0 → 0.2.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/dist/assets/events.d.ts +66 -3
- package/dist/assets/events.js +19 -3
- package/dist/assets/events.js.map +1 -1
- package/dist/assets/service.js +5 -3
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.d.ts +11 -3
- package/dist/automations/actions.js +38 -5
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.d.ts +4 -1
- package/dist/automations/catalog.js +289 -188
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/events.d.ts +46 -24
- package/dist/automations/events.js +5 -5
- package/dist/automations/events.js.map +1 -1
- package/dist/automations/index.d.ts +5 -5
- package/dist/automations/index.js +2 -2
- package/dist/automations/model.d.ts +13 -3
- package/dist/automations/model.js +23 -3
- package/dist/automations/model.js.map +1 -1
- package/dist/automations/ports.d.ts +23 -8
- package/dist/automations/service.d.ts +21 -5
- package/dist/automations/service.js +267 -47
- package/dist/automations/service.js.map +1 -1
- package/dist/automations/types.d.ts +2 -2
- package/dist/automations/webhook-signing.d.ts +7 -0
- package/dist/automations/webhook-signing.js +22 -0
- package/dist/automations/webhook-signing.js.map +1 -0
- package/dist/content/events.d.ts +401 -25
- package/dist/content/events.js +125 -19
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +5 -5
- package/dist/content/index.js +2 -2
- package/dist/content/model.d.ts +2 -2
- package/dist/content/ports.d.ts +42 -11
- package/dist/content/service.d.ts +15 -9
- package/dist/content/service.js +153 -45
- package/dist/content/service.js.map +1 -1
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/events.d.ts +60 -4
- package/dist/discussion/events.js +30 -4
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/model.d.ts +1 -2
- package/dist/discussion/ports.d.ts +1 -1
- package/dist/discussion/service.d.ts +1 -1
- package/dist/discussion/service.js +11 -10
- package/dist/discussion/service.js.map +1 -1
- package/dist/entitlements/events.d.ts +96 -12
- package/dist/entitlements/events.js +21 -4
- package/dist/entitlements/events.js.map +1 -1
- package/dist/entitlements/service.js +1 -0
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/events.d.ts +17 -3
- package/dist/identity/events.js +12 -2
- package/dist/identity/events.js.map +1 -1
- package/dist/identity/ports.d.ts +3 -0
- package/dist/identity/service.d.ts +3 -0
- package/dist/identity/service.js +12 -1
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/events.d.ts +27 -3
- package/dist/integrations/events.js +15 -3
- package/dist/integrations/events.js.map +1 -1
- package/dist/integrations/service.js +1 -1
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/events.d.ts +178 -11
- package/dist/organizations/events.js +52 -9
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +3 -3
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/ports.d.ts +6 -10
- package/dist/organizations/roles.js.map +1 -1
- package/dist/organizations/service.d.ts +9 -4
- package/dist/organizations/service.js +131 -72
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +2 -2
- package/dist/progress/events.d.ts +34 -2
- package/dist/progress/events.js +15 -2
- package/dist/progress/events.js.map +1 -1
- package/dist/progress/service.d.ts +2 -2
- package/dist/progress/service.js +4 -2
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/courses/index.d.ts +4 -0
- package/dist/reporting/courses/index.js +2 -0
- package/dist/reporting/courses/model.d.ts +24 -0
- package/dist/reporting/courses/model.js +1 -0
- package/dist/reporting/courses/ports.d.ts +13 -0
- package/dist/reporting/courses/ports.js +1 -0
- package/dist/reporting/courses/service.d.ts +19 -0
- package/dist/reporting/courses/service.js +20 -0
- package/dist/reporting/courses/service.js.map +1 -0
- package/dist/reporting/learn/model.d.ts +2 -2
- package/dist/reporting/learn/ports.d.ts +2 -1
- package/dist/reporting/learn/service.d.ts +2 -1
- package/dist/reporting/learn/service.js +5 -0
- package/dist/reporting/learn/service.js.map +1 -1
- package/dist/reporting/students/index.d.ts +2 -2
- package/dist/reporting/students/model.d.ts +21 -1
- package/dist/reporting/students/ports.d.ts +3 -1
- package/dist/reporting/students/service.d.ts +2 -1
- package/dist/reporting/students/service.js +3 -0
- package/dist/reporting/students/service.js.map +1 -1
- package/dist/shared/events.d.ts +5 -3
- package/dist/shared/events.js +1 -0
- package/dist/shared/events.js.map +1 -1
- package/dist/shared/id.d.ts +1 -0
- package/dist/shared/id.js +1 -0
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/mailer.d.ts +2 -0
- package/dist/shared/mailer.js.map +1 -1
- package/dist/shared/settings.js.map +1 -1
- package/dist/types/automations.d.ts +13 -2
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +3 -2
- package/dist/types/email-templates.d.ts +3 -1
- package/dist/types/events.d.ts +3 -3
- package/dist/types/index.d.ts +6 -6
- package/dist/types/organizations.d.ts +2 -2
- package/dist/types/ports.d.ts +1 -1
- package/dist/types/schemas/assets.d.ts +3 -0
- package/dist/types/schemas/assets.js +2 -1
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/automations.d.ts +71 -4
- package/dist/types/schemas/automations.js +35 -4
- package/dist/types/schemas/automations.js.map +1 -1
- package/dist/types/schemas/content.d.ts +51 -18
- package/dist/types/schemas/content.js +40 -13
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/credentials.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +10 -2
- package/dist/types/schemas/discussion.js +12 -5
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +8 -2
- package/dist/types/schemas/entitlements.js +10 -4
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/identity.d.ts +4 -4
- package/dist/types/schemas/identity.js +5 -5
- package/dist/types/schemas/identity.js.map +1 -1
- package/dist/types/schemas/index.d.ts +6 -6
- package/dist/types/schemas/index.js +6 -6
- package/dist/types/schemas/integrations.js.map +1 -1
- package/dist/types/schemas/organizations.d.ts +19 -5
- package/dist/types/schemas/organizations.js +12 -7
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/outbox.d.ts +1 -0
- package/dist/types/schemas/outbox.js +1 -0
- package/dist/types/schemas/outbox.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +1 -0
- package/dist/types/schemas/progress.js +1 -0
- package/dist/types/schemas/progress.js.map +1 -1
- package/dist/types/schemas/settings.js.map +1 -1
- package/dist/types/schemas/shared.d.ts +2 -1
- package/dist/types/schemas/shared.js +3 -1
- package/dist/types/schemas/shared.js.map +1 -1
- package/dist/types/shared.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../src/identity/service.ts"],"sourcesContent":["import type { IdentityRepository, IdentityService, IdentityUnitOfWork } from './ports.js';\nimport type { User } from './model.js';\nimport type { CreateUserInput, UpdateUserInput } from './types.js';\nimport type { Logger } from '../shared/ports.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { ConflictError, NotFoundError } from '../shared/errors.js';\nimport type { Mailer } from '../shared/mailer.js';\nimport { identityEvents } from './events.js';\n\nexport class IdentityServiceImpl implements IdentityService {\n private readonly repo: IdentityRepository;\n private readonly logger: Logger;\n private readonly uow: IdentityUnitOfWork;\n private readonly mailer: Pick<Mailer, 'send'>;\n\n constructor(input: {\n repo: IdentityRepository;\n logger?: Logger;\n mailer: Mailer;\n uow: IdentityUnitOfWork;\n }) {\n this.repo = input.repo;\n this.mailer = input.mailer;\n this.logger = input.logger ?? noopLogger;\n this.uow = input.uow;\n }\n\n async createUser(input: CreateUserInput): Promise<User> {\n const created = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.insertUser(input);\n await outbox.append([
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../src/identity/service.ts"],"sourcesContent":["import type { IdentityRepository, IdentityService, IdentityUnitOfWork } from './ports.js';\nimport type { User } from './model.js';\nimport type { CreateUserInput, UpdateUserInput } from './types.js';\nimport type { Logger } from '../shared/ports.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { genId } from '../shared/id.js';\nimport { ConflictError, NotFoundError } from '../shared/errors.js';\nimport type { Mailer } from '../shared/mailer.js';\nimport { identityEvents } from './events.js';\n\nexport class IdentityServiceImpl implements IdentityService {\n private readonly repo: IdentityRepository;\n private readonly logger: Logger;\n private readonly uow: IdentityUnitOfWork;\n private readonly mailer: Pick<Mailer, 'send'>;\n\n constructor(input: {\n repo: IdentityRepository;\n logger?: Logger;\n mailer: Mailer;\n uow: IdentityUnitOfWork;\n }) {\n this.repo = input.repo;\n this.mailer = input.mailer;\n this.logger = input.logger ?? noopLogger;\n this.uow = input.uow;\n }\n\n async createUser(input: CreateUserInput): Promise<User> {\n const created = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.insertUser(input);\n await outbox.append([identityEvents.userCreated.make({ orgId: '-', data: user })]);\n return user;\n });\n this.logger.info('user created', { user: created });\n return created;\n }\n\n async linkOrCreateUser(input: CreateUserInput): Promise<User> {\n const existing = await this.repo.findUserByEmail(input.email);\n if (!existing) {\n const id = input.id ?? genId('user');\n return this.createUser({ ...input, id, externalId: id });\n }\n if (existing.externalId !== null) {\n throw new ConflictError('That email already has an account');\n }\n // Existing user without external link, so invited. update the user with the\n // id.\n const linked = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.updateUser(existing.id, {\n externalId: existing.id,\n ...(input.firstName !== undefined && { firstName: input.firstName }),\n ...(input.lastName !== undefined && { lastName: input.lastName }),\n });\n await outbox.append([identityEvents.userUpdated.make({ orgId: '-', data: user! })]);\n return user!;\n });\n this.logger.info('user linked to auth account', { user: linked });\n return linked;\n }\n\n async updateUser(id: string, input: UpdateUserInput): Promise<User> {\n const person = await this.repo.findUserById(id);\n if (!person) {\n throw new NotFoundError('User', id);\n }\n\n const updated = await this.uow.run(async ({ identity, outbox }) => {\n const user = await identity.updateUser(id, input);\n await outbox.append([identityEvents.userUpdated.make({ orgId: '-', data: user! })]);\n return user!;\n });\n this.logger.info('user updated', { user: updated });\n return updated;\n }\n\n async getUserByExternalId(externalId: string): Promise<User | null> {\n return this.repo.findUserByExternalId(externalId);\n }\n\n async getUserByEmail(email: string): Promise<User | null> {\n return this.repo.findUserByEmail(email);\n }\n\n async getUserById(id: string): Promise<User | null> {\n return this.repo.findUserById(id);\n }\n\n async sendPasswordReset(input: { email: string; url: string }): Promise<void> {\n await this.mailer.send(input.email, 'passwordReset', { resetUrl: input.url });\n }\n\n async sendPasswordChanged(input: { email: string }): Promise<void> {\n await this.mailer.send(input.email, 'passwordChanged', {});\n }\n\n async sendMagicLink(input: { email: string; url: string }): Promise<void> {\n await this.mailer.send(input.email, 'magicLink', { url: input.url });\n }\n}\n"],"mappings":";;;;;AAUA,IAAa,sBAAb,MAA4D;CAC1D;CACA;CACA;CACA;CAEA,YAAY,OAKT;EACD,KAAK,OAAO,MAAM;EAClB,KAAK,SAAS,MAAM;EACpB,KAAK,SAAS,MAAM,UAAU;EAC9B,KAAK,MAAM,MAAM;CACnB;CAEA,MAAM,WAAW,OAAuC;EACtD,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,UAAU,aAAa;GACjE,MAAM,OAAO,MAAM,SAAS,WAAW,KAAK;GAC5C,MAAM,OAAO,OAAO,CAAC,eAAe,YAAY,KAAK;IAAE,OAAO;IAAK,MAAM;GAAK,CAAC,CAAC,CAAC;GACjF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,gBAAgB,EAAE,MAAM,QAAQ,CAAC;EAClD,OAAO;CACT;CAEA,MAAM,iBAAiB,OAAuC;EAC5D,MAAM,WAAW,MAAM,KAAK,KAAK,gBAAgB,MAAM,KAAK;EAC5D,IAAI,CAAC,UAAU;GACb,MAAM,KAAK,MAAM,MAAM,MAAM,MAAM;GACnC,OAAO,KAAK,WAAW;IAAE,GAAG;IAAO;IAAI,YAAY;GAAG,CAAC;EACzD;EACA,IAAI,SAAS,eAAe,MAC1B,MAAM,IAAI,cAAc,mCAAmC;EAI7D,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,UAAU,aAAa;GAChE,MAAM,OAAO,MAAM,SAAS,WAAW,SAAS,IAAI;IAClD,YAAY,SAAS;IACrB,GAAI,MAAM,cAAc,KAAA,KAAa,EAAE,WAAW,MAAM,UAAU;IAClE,GAAI,MAAM,aAAa,KAAA,KAAa,EAAE,UAAU,MAAM,SAAS;GACjE,CAAC;GACD,MAAM,OAAO,OAAO,CAAC,eAAe,YAAY,KAAK;IAAE,OAAO;IAAK,MAAM;GAAM,CAAC,CAAC,CAAC;GAClF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,+BAA+B,EAAE,MAAM,OAAO,CAAC;EAChE,OAAO;CACT;CAEA,MAAM,WAAW,IAAY,OAAuC;EAElE,IAAI,CAAC,MADgB,KAAK,KAAK,aAAa,EAAE,GAE5C,MAAM,IAAI,cAAc,QAAQ,EAAE;EAGpC,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,UAAU,aAAa;GACjE,MAAM,OAAO,MAAM,SAAS,WAAW,IAAI,KAAK;GAChD,MAAM,OAAO,OAAO,CAAC,eAAe,YAAY,KAAK;IAAE,OAAO;IAAK,MAAM;GAAM,CAAC,CAAC,CAAC;GAClF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,gBAAgB,EAAE,MAAM,QAAQ,CAAC;EAClD,OAAO;CACT;CAEA,MAAM,oBAAoB,YAA0C;EAClE,OAAO,KAAK,KAAK,qBAAqB,UAAU;CAClD;CAEA,MAAM,eAAe,OAAqC;EACxD,OAAO,KAAK,KAAK,gBAAgB,KAAK;CACxC;CAEA,MAAM,YAAY,IAAkC;EAClD,OAAO,KAAK,KAAK,aAAa,EAAE;CAClC;CAEA,MAAM,kBAAkB,OAAsD;EAC5E,MAAM,KAAK,OAAO,KAAK,MAAM,OAAO,iBAAiB,EAAE,UAAU,MAAM,IAAI,CAAC;CAC9E;CAEA,MAAM,oBAAoB,OAAyC;EACjE,MAAM,KAAK,OAAO,KAAK,MAAM,OAAO,mBAAmB,CAAC,CAAC;CAC3D;CAEA,MAAM,cAAc,OAAsD;EACxE,MAAM,KAAK,OAAO,KAAK,MAAM,OAAO,aAAa,EAAE,KAAK,MAAM,IAAI,CAAC;CACrE;AACF"}
|
|
@@ -21,7 +21,15 @@ declare const integrationEvents: {
|
|
|
21
21
|
credentialRef: string;
|
|
22
22
|
createdAt: unknown;
|
|
23
23
|
updatedAt: unknown;
|
|
24
|
-
}
|
|
24
|
+
}, import("zod").ZodObject<{
|
|
25
|
+
orgId: import("zod").ZodString;
|
|
26
|
+
id: import("zod").ZodString;
|
|
27
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
28
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
29
|
+
active: import("zod").ZodBoolean;
|
|
30
|
+
integrationId: import("zod").ZodString;
|
|
31
|
+
config: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<JsonValue, unknown>>>;
|
|
32
|
+
}, import("zod/v4/core").$strip>>;
|
|
25
33
|
connectionUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
26
34
|
orgId: string;
|
|
27
35
|
id: string;
|
|
@@ -40,7 +48,15 @@ declare const integrationEvents: {
|
|
|
40
48
|
credentialRef: string;
|
|
41
49
|
createdAt: unknown;
|
|
42
50
|
updatedAt: unknown;
|
|
43
|
-
}
|
|
51
|
+
}, import("zod").ZodObject<{
|
|
52
|
+
orgId: import("zod").ZodString;
|
|
53
|
+
id: import("zod").ZodString;
|
|
54
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
55
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
56
|
+
active: import("zod").ZodBoolean;
|
|
57
|
+
integrationId: import("zod").ZodString;
|
|
58
|
+
config: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<JsonValue, unknown>>>;
|
|
59
|
+
}, import("zod/v4/core").$strip>>;
|
|
44
60
|
connectionRemoved: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
45
61
|
orgId: string;
|
|
46
62
|
id: string;
|
|
@@ -59,7 +75,15 @@ declare const integrationEvents: {
|
|
|
59
75
|
credentialRef: string;
|
|
60
76
|
createdAt: unknown;
|
|
61
77
|
updatedAt: unknown;
|
|
62
|
-
}
|
|
78
|
+
}, import("zod").ZodObject<{
|
|
79
|
+
orgId: import("zod").ZodString;
|
|
80
|
+
id: import("zod").ZodString;
|
|
81
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
82
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
83
|
+
active: import("zod").ZodBoolean;
|
|
84
|
+
integrationId: import("zod").ZodString;
|
|
85
|
+
config: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodType<JsonValue, unknown, import("zod/v4/core").$ZodTypeInternals<JsonValue, unknown>>>;
|
|
86
|
+
}, import("zod/v4/core").$strip>>;
|
|
63
87
|
};
|
|
64
88
|
type ConnectionCreated = EventOf<typeof integrationEvents.connectionCreated>;
|
|
65
89
|
type ConnectionUpdated = EventOf<typeof integrationEvents.connectionUpdated>;
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { connectionSchema } from "../types/schemas/integrations.js";
|
|
2
2
|
import { defineEvent } from "../shared/events.js";
|
|
3
3
|
//#region src/integrations/events.ts
|
|
4
|
+
const publicConnection = connectionSchema.pick({
|
|
5
|
+
orgId: true,
|
|
6
|
+
id: true,
|
|
7
|
+
integrationId: true,
|
|
8
|
+
config: true,
|
|
9
|
+
active: true,
|
|
10
|
+
createdAt: true,
|
|
11
|
+
updatedAt: true
|
|
12
|
+
}).strip();
|
|
4
13
|
const integrationEvents = {
|
|
5
14
|
connectionCreated: defineEvent({
|
|
6
15
|
type: "integration.connection.created",
|
|
7
16
|
version: 1,
|
|
8
|
-
data: connectionSchema
|
|
17
|
+
data: connectionSchema,
|
|
18
|
+
publicData: publicConnection
|
|
9
19
|
}),
|
|
10
20
|
connectionUpdated: defineEvent({
|
|
11
21
|
type: "integration.connection.updated",
|
|
12
22
|
version: 1,
|
|
13
|
-
data: connectionSchema
|
|
23
|
+
data: connectionSchema,
|
|
24
|
+
publicData: publicConnection
|
|
14
25
|
}),
|
|
15
26
|
connectionRemoved: defineEvent({
|
|
16
27
|
type: "integration.connection.removed",
|
|
17
28
|
version: 1,
|
|
18
|
-
data: connectionSchema
|
|
29
|
+
data: connectionSchema,
|
|
30
|
+
publicData: publicConnection
|
|
19
31
|
})
|
|
20
32
|
};
|
|
21
33
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","names":[],"sources":["../../src/integrations/events.ts"],"sourcesContent":["import { connectionSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nexport const integrationEvents = {\n connectionCreated: defineEvent({\n type: 'integration.connection.created',\n version: 1,\n data: connectionSchema,\n }),\n connectionUpdated: defineEvent({\n type: 'integration.connection.updated',\n version: 1,\n data: connectionSchema,\n }),\n connectionRemoved: defineEvent({\n type: 'integration.connection.removed',\n version: 1,\n data: connectionSchema,\n }),\n};\n\nexport type ConnectionCreated = EventOf<typeof integrationEvents.connectionCreated>;\nexport type ConnectionUpdated = EventOf<typeof integrationEvents.connectionUpdated>;\nexport type ConnectionRemoved = EventOf<typeof integrationEvents.connectionRemoved>;\nexport type IntegrationEvent = EventOfValues<typeof integrationEvents>;\n"],"mappings":";;;AAGA,MAAa,oBAAoB;CAC/B,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;
|
|
1
|
+
{"version":3,"file":"events.js","names":[],"sources":["../../src/integrations/events.ts"],"sourcesContent":["import { connectionSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nconst publicConnection = connectionSchema\n .pick({\n orgId: true,\n id: true,\n integrationId: true,\n config: true,\n active: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nexport const integrationEvents = {\n connectionCreated: defineEvent({\n type: 'integration.connection.created',\n version: 1,\n data: connectionSchema,\n publicData: publicConnection,\n }),\n connectionUpdated: defineEvent({\n type: 'integration.connection.updated',\n version: 1,\n data: connectionSchema,\n publicData: publicConnection,\n }),\n connectionRemoved: defineEvent({\n type: 'integration.connection.removed',\n version: 1,\n data: connectionSchema,\n publicData: publicConnection,\n }),\n};\n\nexport type ConnectionCreated = EventOf<typeof integrationEvents.connectionCreated>;\nexport type ConnectionUpdated = EventOf<typeof integrationEvents.connectionUpdated>;\nexport type ConnectionRemoved = EventOf<typeof integrationEvents.connectionRemoved>;\nexport type IntegrationEvent = EventOfValues<typeof integrationEvents>;\n"],"mappings":";;;AAGA,MAAM,mBAAmB,iBACtB,KAAK;CACJ,OAAO;CACP,IAAI;CACJ,eAAe;CACf,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAa,oBAAoB;CAC/B,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,mBAAmB,YAAY;EAC7B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;AACH"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { genId } from "../shared/id.js";
|
|
2
1
|
import { noopLogger } from "../shared/logger.js";
|
|
2
|
+
import { genId } from "../shared/id.js";
|
|
3
3
|
import { ConflictError, NotFoundError } from "../shared/errors.js";
|
|
4
4
|
import { ActionInvocationError, AlreadyConnectedError, InvalidConfigError, UnknownIntegrationError } from "./model.js";
|
|
5
5
|
import { integrationEvents } from "./events.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../src/integrations/service.ts"],"sourcesContent":["// integrations context — service implementation (inbound port). Owns the\n// connection lifecycle; credentials live in the shared secure credential store\n// (this service holds only the ref). The integrations the system supports are\n// declared at startup via the IntegrationsRegistry: connect/configure reject\n// unknown integration ids and validate config with the integration's own\n// validator. The domain never calls the external service — consumers take the\n// connection, reveal the credential at point of use, and build their own adapter.\n//\n// Mutations run inside the context's UnitOfWork: credential writes, connection\n// writes, and the outbox append commit in ONE transaction (transactional\n// outbox; this also closed the historical orphan-credential window). The\n// outbox relay — not this service — publishes to the EventBus.\nimport { genId } from '../shared/id.js';\nimport {\n ActionInvocationError,\n AlreadyConnectedError,\n InvalidConfigError,\n UnknownIntegrationError,\n type ConfigureInput,\n type ConnectInput,\n type Connection,\n} from './model.js';\nimport type {\n ConnectionsRepository,\n IntegrationsRegistry,\n IntegrationsService,\n IntegrationsUnitOfWork,\n} from './ports.js';\nimport type { CredentialStore, Logger } from '../shared/ports.js';\nimport { ConflictError, NotFoundError } from '../shared/errors.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { integrationEvents } from './events.js';\n\nexport type IntegrationsServiceParams = {\n registry: IntegrationsRegistry;\n /** Read-only access (find/list) — runs outside any transaction. */\n repo: ConnectionsRepository;\n /** Atomic write scope: tx-bound connections repo + credential store + outbox. */\n uow: IntegrationsUnitOfWork;\n /** Point-of-use credential reveal for action invocation — reads only. */\n credentials: CredentialStore;\n logger?: Logger;\n};\n\nexport class IntegrationsServiceImpl implements IntegrationsService {\n private readonly registry: IntegrationsRegistry;\n private readonly repo: ConnectionsRepository;\n private readonly uow: IntegrationsUnitOfWork;\n private readonly credentials: CredentialStore;\n private readonly logger: Logger;\n\n constructor(params: IntegrationsServiceParams) {\n this.registry = params.registry;\n this.repo = params.repo;\n this.uow = params.uow;\n this.credentials = params.credentials;\n this.logger = params.logger ?? noopLogger;\n }\n\n available() {\n return this.registry.list().map((integration) => ({\n id: integration.id,\n configSchema: integration.configSchema(),\n secretsSchema: integration.secretsSchema(),\n actions: integration.actions.map((action) => ({\n id: action.id,\n description: action.description,\n inputSchema: action.inputSchema(),\n outputSchema: action.outputSchema(),\n })),\n }));\n }\n\n private validate(integrationId: string, config: Record<string, unknown>): void {\n const integration = this.registry.get(integrationId);\n if (!integration) {\n this.logger.warn('unknown integration rejected', { integrationId });\n throw new UnknownIntegrationError(integrationId);\n }\n const result = integration.validateConfig(config);\n if (!result.ok) {\n this.logger.warn('invalid integration config rejected', {\n integrationId,\n errors: result.errors,\n });\n throw new InvalidConfigError(integrationId, result.errors);\n }\n }\n\n async connect(orgId: string, input: ConnectInput): Promise<Connection> {\n const config = input.config ?? {};\n this.validate(input.integrationId, config);\n const existing = await this.repo.findByIntegration(orgId, input.integrationId);\n if (existing) {\n this.logger.warn('duplicate connection rejected', {\n orgId,\n integrationId: input.integrationId,\n });\n throw new AlreadyConnectedError(input.integrationId);\n }\n const connection = await this.uow.run(async ({ connections, credentials, outbox }) => {\n const credentialRef = await credentials.store(orgId, input.secrets);\n const at = new Date();\n const created = await connections.insert(orgId, {\n orgId,\n id: genId('connection'),\n integrationId: input.integrationId,\n config,\n active: true,\n credentialRef,\n createdAt: at,\n updatedAt: at,\n });\n await outbox.append([\n integrationEvents.connectionCreated.make({\n orgId,\n data: created,\n }),\n ]);\n return created;\n });\n this.logger.info('integration connected', {\n orgId,\n integrationId: connection.integrationId,\n connectionId: connection.id,\n });\n return connection;\n }\n\n async reconnect(\n orgId: string,\n id: string,\n secrets: Record<string, unknown>,\n ): Promise<Connection | null> {\n const connection = await this.repo.findById(orgId, id);\n if (!connection) {\n return null;\n }\n const updated = await this.uow.run(async ({ connections, credentials, outbox }) => {\n await credentials.update(orgId, connection.credentialRef, secrets);\n const result = await connections.update(orgId, id, { updatedAt: new Date() });\n if (result) {\n await outbox.append([\n integrationEvents.connectionUpdated.make({ orgId, data: result }),\n ]);\n }\n return result;\n });\n this.logger.info('integration credentials rotated', {\n orgId,\n connectionId: id,\n integrationId: connection.integrationId,\n });\n return updated;\n }\n\n async configure(orgId: string, id: string, input: ConfigureInput): Promise<Connection | null> {\n const connection = await this.repo.findById(orgId, id);\n if (!connection) {\n return null;\n }\n if (input.config !== undefined) {\n this.validate(connection.integrationId, input.config);\n }\n const updated = await this.uow.run(async ({ connections, outbox }) => {\n const result = await connections.update(orgId, id, {\n ...(input.config !== undefined ? { config: input.config } : {}),\n ...(input.active !== undefined ? { active: input.active } : {}),\n updatedAt: new Date(),\n });\n if (result) {\n await outbox.append([\n integrationEvents.connectionUpdated.make({ orgId, data: result }),\n ]);\n }\n return result;\n });\n this.logger.info('integration configured', {\n orgId,\n connectionId: id,\n integrationId: connection.integrationId,\n });\n return updated;\n }\n\n async disconnect(orgId: string, id: string): Promise<boolean> {\n const connection = await this.repo.findById(orgId, id);\n if (!connection) {\n return false;\n }\n const deleted = await this.uow.run(async ({ connections, credentials, outbox }) => {\n // Connection first: it holds the FK onto the credential row.\n const ok = await connections.delete(orgId, id);\n await credentials.destroy(orgId, connection.credentialRef);\n await outbox.append([\n integrationEvents.connectionRemoved.make({ orgId, data: connection }),\n ]);\n return ok;\n });\n this.logger.info('integration disconnected', {\n orgId,\n connectionId: id,\n integrationId: connection.integrationId,\n });\n return deleted;\n }\n\n list(orgId: string): Promise<Connection[]> {\n return this.repo.list(orgId);\n }\n\n get(orgId: string, id: string): Promise<Connection | null> {\n return this.repo.findById(orgId, id);\n }\n\n getByIntegration(orgId: string, integrationId: string): Promise<Connection | null> {\n return this.repo.findByIntegration(orgId, integrationId);\n }\n\n async invoke(\n orgId: string,\n connectionId: string,\n actionId: string,\n input: Record<string, unknown>,\n ): Promise<unknown> {\n const connection = await this.repo.findById(orgId, connectionId);\n if (!connection) {\n throw new NotFoundError('Connection', connectionId);\n }\n if (!connection.active) {\n throw new ConflictError(`connection \"${connectionId}\" is inactive`);\n }\n const integration = this.registry.get(connection.integrationId);\n if (!integration) {\n throw new UnknownIntegrationError(connection.integrationId);\n }\n const action = integration.actions.find((a) => a.id === actionId);\n if (!action) {\n throw new NotFoundError('Action', actionId);\n }\n const secrets = await this.credentials.reveal(orgId, connection.credentialRef);\n if (!secrets) {\n throw new NotFoundError('Credential', connectionId);\n }\n try {\n return await action.invoke({ secrets, config: connection.config }, input);\n } catch (err) {\n this.logger.warn('integration action failed', {\n orgId,\n connectionId,\n integrationId: connection.integrationId,\n actionId,\n error: err instanceof Error ? err.message : String(err),\n });\n throw new ActionInvocationError(connection.integrationId, actionId, err);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../src/integrations/service.ts"],"sourcesContent":["// integrations context — service implementation (inbound port). Owns the\n// connection lifecycle; credentials live in the shared secure credential store\n// (this service holds only the ref). The integrations the system supports are\n// declared at startup via the IntegrationsRegistry: connect/configure reject\n// unknown integration ids and validate config with the integration's own\n// validator. The domain never calls the external service — consumers take the\n// connection, reveal the credential at point of use, and build their own adapter.\n//\n// Mutations run inside the context's UnitOfWork: credential writes, connection\n// writes, and the outbox append commit in ONE transaction (transactional\n// outbox; this also closed the historical orphan-credential window). The\n// outbox relay — not this service — publishes to the EventBus.\nimport { genId } from '../shared/id.js';\nimport {\n ActionInvocationError,\n AlreadyConnectedError,\n InvalidConfigError,\n UnknownIntegrationError,\n type ConfigureInput,\n type ConnectInput,\n type Connection,\n} from './model.js';\nimport type {\n ConnectionsRepository,\n IntegrationsRegistry,\n IntegrationsService,\n IntegrationsUnitOfWork,\n} from './ports.js';\nimport type { CredentialStore, Logger } from '../shared/ports.js';\nimport { ConflictError, NotFoundError } from '../shared/errors.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { integrationEvents } from './events.js';\n\nexport type IntegrationsServiceParams = {\n registry: IntegrationsRegistry;\n /** Read-only access (find/list) — runs outside any transaction. */\n repo: ConnectionsRepository;\n /** Atomic write scope: tx-bound connections repo + credential store + outbox. */\n uow: IntegrationsUnitOfWork;\n /** Point-of-use credential reveal for action invocation — reads only. */\n credentials: CredentialStore;\n logger?: Logger;\n};\n\nexport class IntegrationsServiceImpl implements IntegrationsService {\n private readonly registry: IntegrationsRegistry;\n private readonly repo: ConnectionsRepository;\n private readonly uow: IntegrationsUnitOfWork;\n private readonly credentials: CredentialStore;\n private readonly logger: Logger;\n\n constructor(params: IntegrationsServiceParams) {\n this.registry = params.registry;\n this.repo = params.repo;\n this.uow = params.uow;\n this.credentials = params.credentials;\n this.logger = params.logger ?? noopLogger;\n }\n\n available() {\n return this.registry.list().map((integration) => ({\n id: integration.id,\n configSchema: integration.configSchema(),\n secretsSchema: integration.secretsSchema(),\n actions: integration.actions.map((action) => ({\n id: action.id,\n description: action.description,\n inputSchema: action.inputSchema(),\n outputSchema: action.outputSchema(),\n })),\n }));\n }\n\n private validate(integrationId: string, config: Record<string, unknown>): void {\n const integration = this.registry.get(integrationId);\n if (!integration) {\n this.logger.warn('unknown integration rejected', { integrationId });\n throw new UnknownIntegrationError(integrationId);\n }\n const result = integration.validateConfig(config);\n if (!result.ok) {\n this.logger.warn('invalid integration config rejected', {\n integrationId,\n errors: result.errors,\n });\n throw new InvalidConfigError(integrationId, result.errors);\n }\n }\n\n async connect(orgId: string, input: ConnectInput): Promise<Connection> {\n const config = input.config ?? {};\n this.validate(input.integrationId, config);\n const existing = await this.repo.findByIntegration(orgId, input.integrationId);\n if (existing) {\n this.logger.warn('duplicate connection rejected', {\n orgId,\n integrationId: input.integrationId,\n });\n throw new AlreadyConnectedError(input.integrationId);\n }\n const connection = await this.uow.run(async ({ connections, credentials, outbox }) => {\n const credentialRef = await credentials.store(orgId, input.secrets);\n const at = new Date();\n const created = await connections.insert(orgId, {\n orgId,\n id: genId('connection'),\n integrationId: input.integrationId,\n config,\n active: true,\n credentialRef,\n createdAt: at,\n updatedAt: at,\n });\n await outbox.append([\n integrationEvents.connectionCreated.make({\n orgId,\n data: created,\n }),\n ]);\n return created;\n });\n this.logger.info('integration connected', {\n orgId,\n integrationId: connection.integrationId,\n connectionId: connection.id,\n });\n return connection;\n }\n\n async reconnect(\n orgId: string,\n id: string,\n secrets: Record<string, unknown>,\n ): Promise<Connection | null> {\n const connection = await this.repo.findById(orgId, id);\n if (!connection) {\n return null;\n }\n const updated = await this.uow.run(async ({ connections, credentials, outbox }) => {\n await credentials.update(orgId, connection.credentialRef, secrets);\n const result = await connections.update(orgId, id, { updatedAt: new Date() });\n if (result) {\n await outbox.append([integrationEvents.connectionUpdated.make({ orgId, data: result })]);\n }\n return result;\n });\n this.logger.info('integration credentials rotated', {\n orgId,\n connectionId: id,\n integrationId: connection.integrationId,\n });\n return updated;\n }\n\n async configure(orgId: string, id: string, input: ConfigureInput): Promise<Connection | null> {\n const connection = await this.repo.findById(orgId, id);\n if (!connection) {\n return null;\n }\n if (input.config !== undefined) {\n this.validate(connection.integrationId, input.config);\n }\n const updated = await this.uow.run(async ({ connections, outbox }) => {\n const result = await connections.update(orgId, id, {\n ...(input.config !== undefined ? { config: input.config } : {}),\n ...(input.active !== undefined ? { active: input.active } : {}),\n updatedAt: new Date(),\n });\n if (result) {\n await outbox.append([integrationEvents.connectionUpdated.make({ orgId, data: result })]);\n }\n return result;\n });\n this.logger.info('integration configured', {\n orgId,\n connectionId: id,\n integrationId: connection.integrationId,\n });\n return updated;\n }\n\n async disconnect(orgId: string, id: string): Promise<boolean> {\n const connection = await this.repo.findById(orgId, id);\n if (!connection) {\n return false;\n }\n const deleted = await this.uow.run(async ({ connections, credentials, outbox }) => {\n // Connection first: it holds the FK onto the credential row.\n const ok = await connections.delete(orgId, id);\n await credentials.destroy(orgId, connection.credentialRef);\n await outbox.append([integrationEvents.connectionRemoved.make({ orgId, data: connection })]);\n return ok;\n });\n this.logger.info('integration disconnected', {\n orgId,\n connectionId: id,\n integrationId: connection.integrationId,\n });\n return deleted;\n }\n\n list(orgId: string): Promise<Connection[]> {\n return this.repo.list(orgId);\n }\n\n get(orgId: string, id: string): Promise<Connection | null> {\n return this.repo.findById(orgId, id);\n }\n\n getByIntegration(orgId: string, integrationId: string): Promise<Connection | null> {\n return this.repo.findByIntegration(orgId, integrationId);\n }\n\n async invoke(\n orgId: string,\n connectionId: string,\n actionId: string,\n input: Record<string, unknown>,\n ): Promise<unknown> {\n const connection = await this.repo.findById(orgId, connectionId);\n if (!connection) {\n throw new NotFoundError('Connection', connectionId);\n }\n if (!connection.active) {\n throw new ConflictError(`connection \"${connectionId}\" is inactive`);\n }\n const integration = this.registry.get(connection.integrationId);\n if (!integration) {\n throw new UnknownIntegrationError(connection.integrationId);\n }\n const action = integration.actions.find((a) => a.id === actionId);\n if (!action) {\n throw new NotFoundError('Action', actionId);\n }\n const secrets = await this.credentials.reveal(orgId, connection.credentialRef);\n if (!secrets) {\n throw new NotFoundError('Credential', connectionId);\n }\n try {\n return await action.invoke({ secrets, config: connection.config }, input);\n } catch (err) {\n this.logger.warn('integration action failed', {\n orgId,\n connectionId,\n integrationId: connection.integrationId,\n actionId,\n error: err instanceof Error ? err.message : String(err),\n });\n throw new ActionInvocationError(connection.integrationId, actionId, err);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -18,7 +18,14 @@ declare const organizationEvents: {
|
|
|
18
18
|
ownerId: string;
|
|
19
19
|
createdAt: unknown;
|
|
20
20
|
updatedAt: unknown;
|
|
21
|
-
}
|
|
21
|
+
}, import("zod").ZodObject<{
|
|
22
|
+
id: import("zod").ZodString;
|
|
23
|
+
name: import("zod").ZodString;
|
|
24
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
25
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
26
|
+
slug: import("zod").ZodString;
|
|
27
|
+
ownerId: import("zod").ZodString;
|
|
28
|
+
}, import("zod/v4/core").$strip>>;
|
|
22
29
|
organizationUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
23
30
|
id: string;
|
|
24
31
|
externalId: string | null;
|
|
@@ -35,7 +42,14 @@ declare const organizationEvents: {
|
|
|
35
42
|
ownerId: string;
|
|
36
43
|
createdAt: unknown;
|
|
37
44
|
updatedAt: unknown;
|
|
38
|
-
}
|
|
45
|
+
}, import("zod").ZodObject<{
|
|
46
|
+
id: import("zod").ZodString;
|
|
47
|
+
name: import("zod").ZodString;
|
|
48
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
49
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
50
|
+
slug: import("zod").ZodString;
|
|
51
|
+
ownerId: import("zod").ZodString;
|
|
52
|
+
}, import("zod/v4/core").$strip>>;
|
|
39
53
|
organizationDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
40
54
|
id: string;
|
|
41
55
|
externalId: string | null;
|
|
@@ -52,7 +66,14 @@ declare const organizationEvents: {
|
|
|
52
66
|
ownerId: string;
|
|
53
67
|
createdAt: unknown;
|
|
54
68
|
updatedAt: unknown;
|
|
55
|
-
}
|
|
69
|
+
}, import("zod").ZodObject<{
|
|
70
|
+
id: import("zod").ZodString;
|
|
71
|
+
name: import("zod").ZodString;
|
|
72
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
73
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
74
|
+
slug: import("zod").ZodString;
|
|
75
|
+
ownerId: import("zod").ZodString;
|
|
76
|
+
}, import("zod/v4/core").$strip>>;
|
|
56
77
|
orgUserLinked: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
57
78
|
id: string;
|
|
58
79
|
orgId: string;
|
|
@@ -69,7 +90,23 @@ declare const organizationEvents: {
|
|
|
69
90
|
status: "active" | "invited";
|
|
70
91
|
createdAt: unknown;
|
|
71
92
|
updatedAt: unknown;
|
|
72
|
-
}
|
|
93
|
+
}, import("zod").ZodObject<{
|
|
94
|
+
orgId: import("zod").ZodString;
|
|
95
|
+
id: import("zod").ZodString;
|
|
96
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
97
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
98
|
+
status: import("zod").ZodEnum<{
|
|
99
|
+
active: "active";
|
|
100
|
+
invited: "invited";
|
|
101
|
+
}>;
|
|
102
|
+
userId: import("zod").ZodString;
|
|
103
|
+
role: import("zod").ZodEnum<{
|
|
104
|
+
owner: "owner";
|
|
105
|
+
admin: "admin";
|
|
106
|
+
instructor: "instructor";
|
|
107
|
+
student: "student";
|
|
108
|
+
}>;
|
|
109
|
+
}, import("zod/v4/core").$strip>>;
|
|
73
110
|
orgUserDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
74
111
|
id: string;
|
|
75
112
|
orgId: string;
|
|
@@ -86,7 +123,23 @@ declare const organizationEvents: {
|
|
|
86
123
|
status: "active" | "invited";
|
|
87
124
|
createdAt: unknown;
|
|
88
125
|
updatedAt: unknown;
|
|
89
|
-
}
|
|
126
|
+
}, import("zod").ZodObject<{
|
|
127
|
+
orgId: import("zod").ZodString;
|
|
128
|
+
id: import("zod").ZodString;
|
|
129
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
130
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
131
|
+
status: import("zod").ZodEnum<{
|
|
132
|
+
active: "active";
|
|
133
|
+
invited: "invited";
|
|
134
|
+
}>;
|
|
135
|
+
userId: import("zod").ZodString;
|
|
136
|
+
role: import("zod").ZodEnum<{
|
|
137
|
+
owner: "owner";
|
|
138
|
+
admin: "admin";
|
|
139
|
+
instructor: "instructor";
|
|
140
|
+
student: "student";
|
|
141
|
+
}>;
|
|
142
|
+
}, import("zod/v4/core").$strip>>;
|
|
90
143
|
inviteCreated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
91
144
|
id: string;
|
|
92
145
|
orgId: string;
|
|
@@ -97,6 +150,7 @@ declare const organizationEvents: {
|
|
|
97
150
|
tokenHash: string | null;
|
|
98
151
|
expiresAt: Date | null;
|
|
99
152
|
createdAt: Date;
|
|
153
|
+
updatedAt: Date;
|
|
100
154
|
}, "organization.invite.created", 1>, {
|
|
101
155
|
id: string;
|
|
102
156
|
orgId: string;
|
|
@@ -107,7 +161,27 @@ declare const organizationEvents: {
|
|
|
107
161
|
tokenHash: string | null;
|
|
108
162
|
expiresAt: unknown;
|
|
109
163
|
createdAt: unknown;
|
|
110
|
-
|
|
164
|
+
updatedAt: unknown;
|
|
165
|
+
}, import("zod").ZodObject<{
|
|
166
|
+
orgId: import("zod").ZodString;
|
|
167
|
+
id: import("zod").ZodString;
|
|
168
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
169
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
170
|
+
status: import("zod").ZodEnum<{
|
|
171
|
+
pending: "pending";
|
|
172
|
+
accepted: "accepted";
|
|
173
|
+
rejected: "rejected";
|
|
174
|
+
canceled: "canceled";
|
|
175
|
+
}>;
|
|
176
|
+
expiresAt: import("zod").ZodNullable<import("zod").ZodCoercedDate<unknown>>;
|
|
177
|
+
email: import("zod").ZodEmail;
|
|
178
|
+
role: import("zod").ZodEnum<{
|
|
179
|
+
admin: "admin";
|
|
180
|
+
instructor: "instructor";
|
|
181
|
+
student: "student";
|
|
182
|
+
}>;
|
|
183
|
+
invitedBy: import("zod").ZodString;
|
|
184
|
+
}, import("zod/v4/core").$strip>>;
|
|
111
185
|
inviteAccepted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
112
186
|
id: string;
|
|
113
187
|
orgId: string;
|
|
@@ -118,6 +192,7 @@ declare const organizationEvents: {
|
|
|
118
192
|
tokenHash: string | null;
|
|
119
193
|
expiresAt: Date | null;
|
|
120
194
|
createdAt: Date;
|
|
195
|
+
updatedAt: Date;
|
|
121
196
|
}, "organization.invite.accepted", 1>, {
|
|
122
197
|
id: string;
|
|
123
198
|
orgId: string;
|
|
@@ -128,7 +203,50 @@ declare const organizationEvents: {
|
|
|
128
203
|
tokenHash: string | null;
|
|
129
204
|
expiresAt: unknown;
|
|
130
205
|
createdAt: unknown;
|
|
131
|
-
|
|
206
|
+
updatedAt: unknown;
|
|
207
|
+
}, import("zod").ZodObject<{
|
|
208
|
+
orgId: import("zod").ZodString;
|
|
209
|
+
id: import("zod").ZodString;
|
|
210
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
211
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
212
|
+
status: import("zod").ZodEnum<{
|
|
213
|
+
pending: "pending";
|
|
214
|
+
accepted: "accepted";
|
|
215
|
+
rejected: "rejected";
|
|
216
|
+
canceled: "canceled";
|
|
217
|
+
}>;
|
|
218
|
+
expiresAt: import("zod").ZodNullable<import("zod").ZodCoercedDate<unknown>>;
|
|
219
|
+
email: import("zod").ZodEmail;
|
|
220
|
+
role: import("zod").ZodEnum<{
|
|
221
|
+
admin: "admin";
|
|
222
|
+
instructor: "instructor";
|
|
223
|
+
student: "student";
|
|
224
|
+
}>;
|
|
225
|
+
invitedBy: import("zod").ZodString;
|
|
226
|
+
}, import("zod/v4/core").$strip>>;
|
|
227
|
+
inviteCanceled: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
228
|
+
id: string;
|
|
229
|
+
orgId: string;
|
|
230
|
+
email: string;
|
|
231
|
+
role: "admin" | "instructor" | "student";
|
|
232
|
+
status: "pending" | "accepted" | "rejected" | "canceled";
|
|
233
|
+
invitedBy: string;
|
|
234
|
+
tokenHash: string | null;
|
|
235
|
+
expiresAt: Date | null;
|
|
236
|
+
createdAt: Date;
|
|
237
|
+
updatedAt: Date;
|
|
238
|
+
}, "organization.invite.canceled", 1>, {
|
|
239
|
+
id: string;
|
|
240
|
+
orgId: string;
|
|
241
|
+
email: string;
|
|
242
|
+
role: "admin" | "instructor" | "student";
|
|
243
|
+
status: "pending" | "accepted" | "rejected" | "canceled";
|
|
244
|
+
invitedBy: string;
|
|
245
|
+
tokenHash: string | null;
|
|
246
|
+
expiresAt: unknown;
|
|
247
|
+
createdAt: unknown;
|
|
248
|
+
updatedAt: unknown;
|
|
249
|
+
}, undefined>;
|
|
132
250
|
studentCreated: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
133
251
|
id: string;
|
|
134
252
|
orgId: string;
|
|
@@ -145,7 +263,23 @@ declare const organizationEvents: {
|
|
|
145
263
|
status: "active" | "invited";
|
|
146
264
|
createdAt: unknown;
|
|
147
265
|
updatedAt: unknown;
|
|
148
|
-
}
|
|
266
|
+
}, import("zod").ZodObject<{
|
|
267
|
+
orgId: import("zod").ZodString;
|
|
268
|
+
id: import("zod").ZodString;
|
|
269
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
270
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
271
|
+
status: import("zod").ZodEnum<{
|
|
272
|
+
active: "active";
|
|
273
|
+
invited: "invited";
|
|
274
|
+
}>;
|
|
275
|
+
userId: import("zod").ZodString;
|
|
276
|
+
role: import("zod").ZodEnum<{
|
|
277
|
+
owner: "owner";
|
|
278
|
+
admin: "admin";
|
|
279
|
+
instructor: "instructor";
|
|
280
|
+
student: "student";
|
|
281
|
+
}>;
|
|
282
|
+
}, import("zod/v4/core").$strip>>;
|
|
149
283
|
studentDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
150
284
|
id: string;
|
|
151
285
|
orgId: string;
|
|
@@ -162,7 +296,23 @@ declare const organizationEvents: {
|
|
|
162
296
|
status: "active" | "invited";
|
|
163
297
|
createdAt: unknown;
|
|
164
298
|
updatedAt: unknown;
|
|
165
|
-
}
|
|
299
|
+
}, import("zod").ZodObject<{
|
|
300
|
+
orgId: import("zod").ZodString;
|
|
301
|
+
id: import("zod").ZodString;
|
|
302
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
303
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
304
|
+
status: import("zod").ZodEnum<{
|
|
305
|
+
active: "active";
|
|
306
|
+
invited: "invited";
|
|
307
|
+
}>;
|
|
308
|
+
userId: import("zod").ZodString;
|
|
309
|
+
role: import("zod").ZodEnum<{
|
|
310
|
+
owner: "owner";
|
|
311
|
+
admin: "admin";
|
|
312
|
+
instructor: "instructor";
|
|
313
|
+
student: "student";
|
|
314
|
+
}>;
|
|
315
|
+
}, import("zod/v4/core").$strip>>;
|
|
166
316
|
studentLinked: RuntimeEventDefinition<VersionedDomainEvent<{
|
|
167
317
|
id: string;
|
|
168
318
|
orgId: string;
|
|
@@ -179,7 +329,23 @@ declare const organizationEvents: {
|
|
|
179
329
|
status: "active" | "invited";
|
|
180
330
|
createdAt: unknown;
|
|
181
331
|
updatedAt: unknown;
|
|
182
|
-
}
|
|
332
|
+
}, import("zod").ZodObject<{
|
|
333
|
+
orgId: import("zod").ZodString;
|
|
334
|
+
id: import("zod").ZodString;
|
|
335
|
+
createdAt: import("zod").ZodCoercedDate<unknown>;
|
|
336
|
+
updatedAt: import("zod").ZodCoercedDate<unknown>;
|
|
337
|
+
status: import("zod").ZodEnum<{
|
|
338
|
+
active: "active";
|
|
339
|
+
invited: "invited";
|
|
340
|
+
}>;
|
|
341
|
+
userId: import("zod").ZodString;
|
|
342
|
+
role: import("zod").ZodEnum<{
|
|
343
|
+
owner: "owner";
|
|
344
|
+
admin: "admin";
|
|
345
|
+
instructor: "instructor";
|
|
346
|
+
student: "student";
|
|
347
|
+
}>;
|
|
348
|
+
}, import("zod/v4/core").$strip>>;
|
|
183
349
|
};
|
|
184
350
|
type OrganizationCreated = EventOf<typeof organizationEvents.organizationCreated>;
|
|
185
351
|
type OrganizationUpdated = EventOf<typeof organizationEvents.organizationUpdated>;
|
|
@@ -188,10 +354,11 @@ type OrgUserLinked = EventOf<typeof organizationEvents.orgUserLinked>;
|
|
|
188
354
|
type OrgUserDeleted = EventOf<typeof organizationEvents.orgUserDeleted>;
|
|
189
355
|
type InviteCreated = EventOf<typeof organizationEvents.inviteCreated>;
|
|
190
356
|
type InviteAccepted = EventOf<typeof organizationEvents.inviteAccepted>;
|
|
357
|
+
type InviteCanceled = EventOf<typeof organizationEvents.inviteCanceled>;
|
|
191
358
|
type StudentCreated = EventOf<typeof organizationEvents.studentCreated>;
|
|
192
359
|
type StudentDeleted = EventOf<typeof organizationEvents.studentDeleted>;
|
|
193
360
|
type StudentLinked = EventOf<typeof organizationEvents.studentLinked>;
|
|
194
361
|
type OrganizationEvent = EventOfValues<typeof organizationEvents>;
|
|
195
362
|
//#endregion
|
|
196
|
-
export { InviteAccepted, InviteCreated, OrgUserDeleted, OrgUserLinked, OrganizationCreated, OrganizationDeleted, OrganizationEvent, OrganizationUpdated, StudentCreated, StudentDeleted, StudentLinked, organizationEvents };
|
|
363
|
+
export { InviteAccepted, InviteCanceled, InviteCreated, OrgUserDeleted, OrgUserLinked, OrganizationCreated, OrganizationDeleted, OrganizationEvent, OrganizationUpdated, StudentCreated, StudentDeleted, StudentLinked, organizationEvents };
|
|
197
364
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1,56 +1,99 @@
|
|
|
1
1
|
import { inviteSchema, orgUserSchema, organizationSchema } from "../types/schemas/organizations.js";
|
|
2
2
|
import { defineEvent } from "../shared/events.js";
|
|
3
3
|
//#region src/organizations/events.ts
|
|
4
|
+
const publicOrganization = organizationSchema.pick({
|
|
5
|
+
id: true,
|
|
6
|
+
name: true,
|
|
7
|
+
slug: true,
|
|
8
|
+
ownerId: true,
|
|
9
|
+
createdAt: true,
|
|
10
|
+
updatedAt: true
|
|
11
|
+
}).strip();
|
|
12
|
+
const publicOrgUser = orgUserSchema.pick({
|
|
13
|
+
id: true,
|
|
14
|
+
orgId: true,
|
|
15
|
+
userId: true,
|
|
16
|
+
role: true,
|
|
17
|
+
status: true,
|
|
18
|
+
createdAt: true,
|
|
19
|
+
updatedAt: true
|
|
20
|
+
}).strip();
|
|
21
|
+
const publicInvite = inviteSchema.pick({
|
|
22
|
+
id: true,
|
|
23
|
+
orgId: true,
|
|
24
|
+
email: true,
|
|
25
|
+
role: true,
|
|
26
|
+
status: true,
|
|
27
|
+
invitedBy: true,
|
|
28
|
+
expiresAt: true,
|
|
29
|
+
createdAt: true,
|
|
30
|
+
updatedAt: true
|
|
31
|
+
}).strip();
|
|
4
32
|
const organizationEvents = {
|
|
5
33
|
organizationCreated: defineEvent({
|
|
6
34
|
type: "organization.created",
|
|
7
35
|
version: 1,
|
|
8
|
-
data: organizationSchema
|
|
36
|
+
data: organizationSchema,
|
|
37
|
+
publicData: publicOrganization
|
|
9
38
|
}),
|
|
10
39
|
organizationUpdated: defineEvent({
|
|
11
40
|
type: "organization.updated",
|
|
12
41
|
version: 1,
|
|
13
|
-
data: organizationSchema
|
|
42
|
+
data: organizationSchema,
|
|
43
|
+
publicData: publicOrganization
|
|
14
44
|
}),
|
|
15
45
|
organizationDeleted: defineEvent({
|
|
16
46
|
type: "organization.deleted",
|
|
17
47
|
version: 1,
|
|
18
|
-
data: organizationSchema
|
|
48
|
+
data: organizationSchema,
|
|
49
|
+
publicData: publicOrganization
|
|
19
50
|
}),
|
|
20
51
|
orgUserLinked: defineEvent({
|
|
21
52
|
type: "organization.user.linked",
|
|
22
53
|
version: 1,
|
|
23
|
-
data: orgUserSchema
|
|
54
|
+
data: orgUserSchema,
|
|
55
|
+
publicData: publicOrgUser
|
|
24
56
|
}),
|
|
25
57
|
orgUserDeleted: defineEvent({
|
|
26
58
|
type: "organization.user.deleted",
|
|
27
59
|
version: 1,
|
|
28
|
-
data: orgUserSchema
|
|
60
|
+
data: orgUserSchema,
|
|
61
|
+
publicData: publicOrgUser
|
|
29
62
|
}),
|
|
30
63
|
inviteCreated: defineEvent({
|
|
31
64
|
type: "organization.invite.created",
|
|
32
65
|
version: 1,
|
|
33
|
-
data: inviteSchema
|
|
66
|
+
data: inviteSchema,
|
|
67
|
+
publicData: publicInvite
|
|
34
68
|
}),
|
|
35
69
|
inviteAccepted: defineEvent({
|
|
36
70
|
type: "organization.invite.accepted",
|
|
37
71
|
version: 1,
|
|
72
|
+
data: inviteSchema,
|
|
73
|
+
publicData: publicInvite
|
|
74
|
+
}),
|
|
75
|
+
inviteCanceled: defineEvent({
|
|
76
|
+
type: "organization.invite.canceled",
|
|
77
|
+
version: 1,
|
|
38
78
|
data: inviteSchema
|
|
39
79
|
}),
|
|
40
80
|
studentCreated: defineEvent({
|
|
41
81
|
type: "organization.student.created",
|
|
42
82
|
version: 1,
|
|
43
|
-
data: orgUserSchema
|
|
83
|
+
data: orgUserSchema,
|
|
84
|
+
publicData: publicOrgUser
|
|
44
85
|
}),
|
|
45
86
|
studentDeleted: defineEvent({
|
|
46
87
|
type: "organization.student.deleted",
|
|
47
88
|
version: 1,
|
|
48
|
-
data: orgUserSchema
|
|
89
|
+
data: orgUserSchema,
|
|
90
|
+
publicData: publicOrgUser
|
|
49
91
|
}),
|
|
50
92
|
studentLinked: defineEvent({
|
|
51
93
|
type: "organization.student.linked",
|
|
52
94
|
version: 1,
|
|
53
|
-
data: orgUserSchema
|
|
95
|
+
data: orgUserSchema,
|
|
96
|
+
publicData: publicOrgUser
|
|
54
97
|
})
|
|
55
98
|
};
|
|
56
99
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","names":[],"sources":["../../src/organizations/events.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"events.js","names":[],"sources":["../../src/organizations/events.ts"],"sourcesContent":["import { inviteSchema, organizationSchema, orgUserSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nconst publicOrganization = organizationSchema\n .pick({\n id: true,\n name: true,\n slug: true,\n ownerId: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nconst publicOrgUser = orgUserSchema\n .pick({\n id: true,\n orgId: true,\n userId: true,\n role: true,\n status: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nconst publicInvite = inviteSchema\n .pick({\n id: true,\n orgId: true,\n email: true,\n role: true,\n status: true,\n invitedBy: true,\n expiresAt: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nexport const organizationEvents = {\n organizationCreated: defineEvent({\n type: 'organization.created',\n version: 1,\n data: organizationSchema,\n publicData: publicOrganization,\n }),\n organizationUpdated: defineEvent({\n type: 'organization.updated',\n version: 1,\n data: organizationSchema,\n publicData: publicOrganization,\n }),\n organizationDeleted: defineEvent({\n type: 'organization.deleted',\n version: 1,\n data: organizationSchema,\n publicData: publicOrganization,\n }),\n orgUserLinked: defineEvent({\n type: 'organization.user.linked',\n version: 1,\n data: orgUserSchema,\n publicData: publicOrgUser,\n }),\n orgUserDeleted: defineEvent({\n type: 'organization.user.deleted',\n version: 1,\n data: orgUserSchema,\n publicData: publicOrgUser,\n }),\n inviteCreated: defineEvent({\n type: 'organization.invite.created',\n version: 1,\n data: inviteSchema,\n publicData: publicInvite,\n }),\n inviteAccepted: defineEvent({\n type: 'organization.invite.accepted',\n version: 1,\n data: inviteSchema,\n publicData: publicInvite,\n }),\n inviteCanceled: defineEvent({\n type: 'organization.invite.canceled',\n version: 1,\n data: inviteSchema,\n }),\n studentCreated: defineEvent({\n type: 'organization.student.created',\n version: 1,\n data: orgUserSchema,\n publicData: publicOrgUser,\n }),\n studentDeleted: defineEvent({\n type: 'organization.student.deleted',\n version: 1,\n data: orgUserSchema,\n publicData: publicOrgUser,\n }),\n studentLinked: defineEvent({\n type: 'organization.student.linked',\n version: 1,\n data: orgUserSchema,\n publicData: publicOrgUser,\n }),\n};\n\nexport type OrganizationCreated = EventOf<typeof organizationEvents.organizationCreated>;\nexport type OrganizationUpdated = EventOf<typeof organizationEvents.organizationUpdated>;\nexport type OrganizationDeleted = EventOf<typeof organizationEvents.organizationDeleted>;\nexport type OrgUserLinked = EventOf<typeof organizationEvents.orgUserLinked>;\nexport type OrgUserDeleted = EventOf<typeof organizationEvents.orgUserDeleted>;\nexport type InviteCreated = EventOf<typeof organizationEvents.inviteCreated>;\nexport type InviteAccepted = EventOf<typeof organizationEvents.inviteAccepted>;\nexport type InviteCanceled = EventOf<typeof organizationEvents.inviteCanceled>;\nexport type StudentCreated = EventOf<typeof organizationEvents.studentCreated>;\nexport type StudentDeleted = EventOf<typeof organizationEvents.studentDeleted>;\nexport type StudentLinked = EventOf<typeof organizationEvents.studentLinked>;\nexport type OrganizationEvent = EventOfValues<typeof organizationEvents>;\n"],"mappings":";;;AAGA,MAAM,qBAAqB,mBACxB,KAAK;CACJ,IAAI;CACJ,MAAM;CACN,MAAM;CACN,SAAS;CACT,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAM,gBAAgB,cACnB,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAM,eAAe,aAClB,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,MAAM;CACN,QAAQ;CACR,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAa,qBAAqB;CAChC,qBAAqB,YAAY;EAC/B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,qBAAqB,YAAY;EAC/B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,qBAAqB,YAAY;EAC/B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,eAAe,YAAY;EACzB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,eAAe,YAAY;EACzB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,eAAe,YAAY;EACzB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;AACH"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { AcceptInviteInput, AddOrgUserInput, CreateInviteInput, CreateOrgUserInput, Invite, InviteRole, NewOrganizationInput, OrgUser, OrgUserStatus, Organization, Role } from "../types/schemas/organizations.js";
|
|
1
|
+
import { AcceptInviteInput, AddOrgUserInput, CreateInviteInput, CreateOrgUserInput, Invite, InviteRole, NewOrganizationInput, OrgUser, OrgUserStatus, Organization, Role, UpdateOrgUserInput } from "../types/schemas/organizations.js";
|
|
2
2
|
import { InviteId, OrgUserId, OrganizationId } from "../types/organizations.js";
|
|
3
3
|
import { AuthHeaders } from "../identity/ports.js";
|
|
4
|
-
import { InviteAccepted, InviteCreated, OrgUserDeleted, OrgUserLinked, OrganizationCreated, OrganizationDeleted, OrganizationEvent, OrganizationUpdated, StudentCreated, StudentDeleted, StudentLinked, organizationEvents } from "./events.js";
|
|
4
|
+
import { InviteAccepted, InviteCanceled, InviteCreated, OrgUserDeleted, OrgUserLinked, OrganizationCreated, OrganizationDeleted, OrganizationEvent, OrganizationUpdated, StudentCreated, StudentDeleted, StudentLinked, organizationEvents } from "./events.js";
|
|
5
5
|
import "./model.js";
|
|
6
6
|
import { Capability, Permission, ROLES, STAFF_ROLES, STUDENT_ROLE, StaffRole, capability, isRole, isStaffRole, normalizeRole, parseRole } from "./roles.js";
|
|
7
7
|
import { Member, MemberStatus, MembersQuery, OrganizationRuleError, Page } from "./members.js";
|
|
8
8
|
import { CreateOrganizationInput, LinkOrgUserInput, ResendStudentInviteInput, UnlinkOrgUserInput, UpdateOrganizationInput, UpdatePersonInput, UpdateStudentInput } from "./types.js";
|
|
9
9
|
import { AuthOrganization, MemberRecord, MemberWriteContext, MembersRepository, NewInviteRow, NewOrganizationRow, OrgAdmin, OrganizationService, OrganizationsRepository } from "./ports.js";
|
|
10
10
|
import { OrganizationServiceImpl } from "./service.js";
|
|
11
|
-
export { type AcceptInviteInput, type AddOrgUserInput, type AuthHeaders, type AuthOrganization, type Capability, type CreateInviteInput, type CreateOrgUserInput, type CreateOrganizationInput, type Invite, type InviteAccepted, type InviteCreated, type InviteId, type InviteRole, type LinkOrgUserInput, type Member, type MemberRecord, type MemberStatus, type MemberWriteContext, type MembersQuery, type MembersRepository, type NewInviteRow, type NewOrganizationInput, type NewOrganizationRow, type OrgAdmin, type OrgUser, type OrgUserDeleted, type OrgUserId, type OrgUserLinked, type OrgUserStatus, type Organization, type OrganizationCreated, type OrganizationDeleted, type OrganizationEvent, type OrganizationId, OrganizationRuleError, type OrganizationService, OrganizationServiceImpl, type OrganizationUpdated, type OrganizationsRepository, type Page, type Permission, ROLES, type ResendStudentInviteInput, type Role, STAFF_ROLES, STUDENT_ROLE, type StaffRole, type StudentCreated, type StudentDeleted, type StudentLinked, type UnlinkOrgUserInput, type UpdateOrganizationInput, type UpdatePersonInput, type UpdateStudentInput, capability, isRole, isStaffRole, normalizeRole, organizationEvents, parseRole };
|
|
11
|
+
export { type AcceptInviteInput, type AddOrgUserInput, type AuthHeaders, type AuthOrganization, type Capability, type CreateInviteInput, type CreateOrgUserInput, type CreateOrganizationInput, type Invite, type InviteAccepted, type InviteCanceled, type InviteCreated, type InviteId, type InviteRole, type LinkOrgUserInput, type Member, type MemberRecord, type MemberStatus, type MemberWriteContext, type MembersQuery, type MembersRepository, type NewInviteRow, type NewOrganizationInput, type NewOrganizationRow, type OrgAdmin, type OrgUser, type OrgUserDeleted, type OrgUserId, type OrgUserLinked, type OrgUserStatus, type Organization, type OrganizationCreated, type OrganizationDeleted, type OrganizationEvent, type OrganizationId, OrganizationRuleError, type OrganizationService, OrganizationServiceImpl, type OrganizationUpdated, type OrganizationsRepository, type Page, type Permission, ROLES, type ResendStudentInviteInput, type Role, STAFF_ROLES, STUDENT_ROLE, type StaffRole, type StudentCreated, type StudentDeleted, type StudentLinked, type UnlinkOrgUserInput, type UpdateOrgUserInput, type UpdateOrganizationInput, type UpdatePersonInput, type UpdateStudentInput, capability, isRole, isStaffRole, normalizeRole, organizationEvents, parseRole };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"members.js","names":[],"sources":["../../src/organizations/members.ts"],"sourcesContent":["// organizations context — member-management types (invite / change-role / remove).\n// The operational surface over the org's members and pending invites. Roles\n// come from ./roles.ts (the single role model); writes go through Better Auth.\nimport type { StaffRole } from './roles.js';\nimport type { OrgUserProfile } from '../types/index.js';\n\nexport type MemberStatus = 'active' | 'invited';\n\nexport interface Member extends OrgUserProfile {\n role: StaffRole;\n status: MemberStatus;\n joinedAt: string | null;\n invitedAt: string | null;\n}\n\nexport interface MembersQuery {\n page: number;\n pageSize: number;\n search?: string | undefined;\n sort?: string | undefined;\n role?: StaffRole | undefined;\n status?: MemberStatus | undefined;\n}\n\nexport interface Page<T> {\n rows: T[];\n total: number;\n page: number;\n pageSize: number;\n}\n\
|
|
1
|
+
{"version":3,"file":"members.js","names":[],"sources":["../../src/organizations/members.ts"],"sourcesContent":["// organizations context — member-management types (invite / change-role / remove).\n// The operational surface over the org's members and pending invites. Roles\n// come from ./roles.ts (the single role model); writes go through Better Auth.\nimport type { StaffRole } from './roles.js';\nimport type { OrgUserProfile } from '../types/index.js';\n\nexport type MemberStatus = 'active' | 'invited';\n\nexport interface Member extends OrgUserProfile {\n role: StaffRole;\n status: MemberStatus;\n joinedAt: string | null;\n invitedAt: string | null;\n}\n\nexport interface MembersQuery {\n page: number;\n pageSize: number;\n search?: string | undefined;\n sort?: string | undefined;\n role?: StaffRole | undefined;\n status?: MemberStatus | undefined;\n}\n\nexport interface Page<T> {\n rows: T[];\n total: number;\n page: number;\n pageSize: number;\n}\n\nexport class OrganizationRuleError extends Error {}\nexport class InviteError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InviteError';\n }\n}\n"],"mappings":";AA+BA,IAAa,wBAAb,cAA2C,MAAM,CAAC;AAClD,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
|