@shipfox/api-workspaces 7.0.1 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +59 -0
  3. package/README.md +1 -5
  4. package/dist/core/entities/workspace.d.ts +1 -0
  5. package/dist/core/entities/workspace.d.ts.map +1 -1
  6. package/dist/core/entities/workspace.js.map +1 -1
  7. package/dist/core/workspaces.d.ts +3 -0
  8. package/dist/core/workspaces.d.ts.map +1 -1
  9. package/dist/core/workspaces.js +6 -1
  10. package/dist/core/workspaces.js.map +1 -1
  11. package/dist/db/db.d.ts +34 -0
  12. package/dist/db/db.d.ts.map +1 -1
  13. package/dist/db/schema/common.d.ts.map +1 -1
  14. package/dist/db/schema/common.js +1 -1
  15. package/dist/db/schema/common.js.map +1 -1
  16. package/dist/db/schema/workspaces.d.ts +17 -0
  17. package/dist/db/schema/workspaces.d.ts.map +1 -1
  18. package/dist/db/schema/workspaces.js +3 -1
  19. package/dist/db/schema/workspaces.js.map +1 -1
  20. package/dist/index.js +2 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/presentation/inter-module.d.ts.map +1 -1
  23. package/dist/presentation/inter-module.js +15 -1
  24. package/dist/presentation/inter-module.js.map +1 -1
  25. package/dist/tsconfig.test.tsbuildinfo +1 -1
  26. package/drizzle/0000_initial.sql +50 -1
  27. package/drizzle/meta/0000_snapshot.json +377 -3
  28. package/drizzle/meta/_journal.json +0 -28
  29. package/package.json +17 -31
  30. package/src/core/entities/workspace.ts +1 -0
  31. package/src/core/workspaces.ts +9 -1
  32. package/src/db/schema/common.ts +1 -3
  33. package/src/db/schema/workspaces.ts +3 -1
  34. package/src/index.ts +1 -1
  35. package/src/presentation/inter-module.test.ts +71 -0
  36. package/src/presentation/inter-module.ts +15 -1
  37. package/test/factories/workspace.ts +1 -0
  38. package/test/globalSetup.ts +1 -1
  39. package/tsconfig.build.tsbuildinfo +1 -1
  40. package/drizzle/0001_memberships_invitations.sql +0 -30
  41. package/drizzle/0002_membership_user_snapshots.sql +0 -40
  42. package/drizzle/0003_outgoing_enchantress.sql +0 -16
  43. package/drizzle/0004_tired_talon.sql +0 -1
  44. package/drizzle/meta/0001_snapshot.json +0 -705
  45. package/drizzle/meta/0003_snapshot.json +0 -442
  46. package/drizzle/meta/0004_snapshot.json +0 -448
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 48 files with swc (546.37ms)
2
+ Successfully compiled: 48 files with swc (446.41ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # @shipfox/api-workspaces
2
2
 
3
+ ## 9.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 475ce59: Republishes all public packages after restoring release authorization.
8
+ - cd28a05: Prefixes the Workspaces root table in the migration baseline.
9
+ - Updated dependencies [475ce59]
10
+ - Updated dependencies [154e03f]
11
+ - @shipfox/api-auth-context@9.0.1
12
+ - @shipfox/api-common-dto@9.0.1
13
+ - @shipfox/api-workspaces-dto@9.0.1
14
+ - @shipfox/config@1.2.3
15
+ - @shipfox/inter-module@0.2.1
16
+ - @shipfox/node-drizzle@0.3.3
17
+ - @shipfox/node-email@0.3.2
18
+ - @shipfox/node-fastify@0.3.1
19
+ - @shipfox/node-mailer@0.2.2
20
+ - @shipfox/node-module@1.0.0
21
+ - @shipfox/node-opentelemetry@0.6.1
22
+ - @shipfox/node-outbox@0.2.5
23
+ - @shipfox/node-postgres@0.4.3
24
+ - @shipfox/node-tokens@0.3.1
25
+
26
+ ## 9.0.0
27
+
28
+ ### Minor Changes
29
+
30
+ - 9c9d266: Adds a producer-owned workspace creator lookup for inter-module consumers.
31
+
32
+ ### Patch Changes
33
+
34
+ - Updated dependencies [9c9d266]
35
+ - @shipfox/api-workspaces-dto@9.0.0
36
+ - @shipfox/api-auth-context@9.0.0
37
+ - @shipfox/api-common-dto@6.0.0
38
+ - @shipfox/config@1.2.2
39
+ - @shipfox/inter-module@0.2.0
40
+ - @shipfox/node-drizzle@0.3.2
41
+ - @shipfox/node-email@0.3.1
42
+ - @shipfox/node-fastify@0.3.0
43
+ - @shipfox/node-mailer@0.2.1
44
+ - @shipfox/node-module@0.5.0
45
+ - @shipfox/node-opentelemetry@0.6.0
46
+ - @shipfox/node-outbox@0.2.4
47
+ - @shipfox/node-postgres@0.4.2
48
+ - @shipfox/node-tokens@0.3.0
49
+
50
+ ## 7.1.0
51
+
52
+ ### Patch Changes
53
+
54
+ - Updated dependencies [ac42c96]
55
+ - Updated dependencies [6ce08c0]
56
+ - @shipfox/node-fastify@0.3.0
57
+ - @shipfox/node-module@0.5.0
58
+ - @shipfox/node-opentelemetry@0.6.0
59
+ - @shipfox/api-auth-context@7.1.0
60
+ - @shipfox/node-mailer@0.2.1
61
+
3
62
  ## 7.0.1
4
63
 
5
64
  ### Patch Changes
package/README.md CHANGED
@@ -76,11 +76,7 @@ turbo type --filter=@shipfox/api-workspaces
76
76
  turbo test --filter=@shipfox/api-workspaces
77
77
  ```
78
78
 
79
- Tests use Vitest and PostgreSQL. Start local services before the suite:
80
-
81
- ```sh
82
- docker compose up -d
83
- ```
79
+ For repository test conventions, read the [testing guide](../../../docs/guides/testing.md).
84
80
 
85
81
  ## License
86
82
 
@@ -4,6 +4,7 @@ export interface Workspace {
4
4
  name: string;
5
5
  status: WorkspaceStatus;
6
6
  settings: Record<string, unknown>;
7
+ createdBy: string | null;
7
8
  createdAt: Date;
8
9
  updatedAt: Date;
9
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/core/entities/workspace.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/core/entities/workspace.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/entities/workspace.ts"],"sourcesContent":["export type WorkspaceStatus = 'active' | 'suspended' | 'deleted';\n\nexport interface Workspace {\n id: string;\n name: string;\n status: WorkspaceStatus;\n settings: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n"],"names":[],"mappings":"AAEA,WAOC"}
1
+ {"version":3,"sources":["../../../src/core/entities/workspace.ts"],"sourcesContent":["export type WorkspaceStatus = 'active' | 'suspended' | 'deleted';\n\nexport interface Workspace {\n id: string;\n name: string;\n status: WorkspaceStatus;\n settings: Record<string, unknown>;\n createdBy: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n"],"names":[],"mappings":"AAEA,WAQC"}
@@ -23,6 +23,9 @@ export declare function createWorkspaceForUser(params: {
23
23
  export declare function getWorkspace(params: {
24
24
  workspaceId: string;
25
25
  }): Promise<Workspace>;
26
+ export declare function getWorkspaceCreator(params: {
27
+ workspaceId: string;
28
+ }): Promise<string | null>;
26
29
  export declare function listUserWorkspaceMemberships(params: {
27
30
  userId: string;
28
31
  }): Promise<MembershipWithWorkspace[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/core/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAE7B,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAC;AASvD,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,gCAAgC;IAC/C,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,gCAAgC,GACvC,OAAO,CAAC,gCAAgC,CAAC,CAe3C;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC,GAAG,OAAO,CAAC,SAAS,CAAC,CAuBrB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAOpF;AAED,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAErC;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;CAC5D,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQhC;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/core/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAE7B,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAC;AASvD,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,gCAAgC;IAC/C,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,gCAAgC,GACvC,OAAO,CAAC,gCAAgC,CAAC,CAe3C;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC,GAAG,OAAO,CAAC,SAAS,CAAC,CA0BrB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAOpF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAG/F;AAED,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAErC;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;CAC5D,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQhC;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB"}
@@ -29,7 +29,8 @@ export async function requireWorkspaceMembership(params) {
29
29
  export async function createWorkspaceForUser(params) {
30
30
  return await db().transaction(async (tx)=>{
31
31
  const [workspaceRow] = await tx.insert(workspaces).values({
32
- name: params.name
32
+ name: params.name,
33
+ createdBy: params.userId
33
34
  }).returning();
34
35
  if (!workspaceRow) throw new Error('Insert returned no rows');
35
36
  await tx.insert(memberships).values({
@@ -57,6 +58,10 @@ export async function getWorkspace(params) {
57
58
  }
58
59
  return workspace;
59
60
  }
61
+ export async function getWorkspaceCreator(params) {
62
+ const workspace = await getWorkspace(params);
63
+ return workspace.createdBy;
64
+ }
60
65
  export async function listUserWorkspaceMemberships(params) {
61
66
  return await listMembershipsByUser({
62
67
  userId: params.userId
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/workspaces.ts"],"sourcesContent":["import type {UserContextMembership} from '@shipfox/api-auth-context';\nimport {\n WORKSPACES_WORKSPACE_CREATED,\n type WorkspaceRole,\n type WorkspacesEventMap,\n} from '@shipfox/api-workspaces-dto';\nimport {writeOutboxEvent} from '@shipfox/node-outbox';\nimport {db} from '#db/db.js';\nimport {\n findMembership,\n listMembershipsByUser,\n listMembershipsByWorkspace,\n type MembershipWithUser,\n type MembershipWithWorkspace,\n removeMembership,\n} from '#db/memberships.js';\nimport {memberships} from '#db/schema/memberships.js';\nimport {workspacesOutbox} from '#db/schema/outbox.js';\nimport {toWorkspace, workspaces} from '#db/schema/workspaces.js';\nimport {getWorkspaceById} from '#db/workspaces.js';\nimport type {Workspace} from './entities/workspace.js';\nimport {\n MembershipNotFoundError,\n MembershipRequiredError,\n SelfRemovalNotAllowedError,\n WorkspaceInactiveError,\n WorkspaceNotFoundError,\n} from './errors.js';\n\nexport interface RequireWorkspaceMembershipParams {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<UserContextMembership>;\n}\n\nexport interface RequireWorkspaceMembershipResult {\n workspace: Workspace;\n workspaceId: string;\n userId: string;\n role: WorkspaceRole;\n}\n\nexport async function requireWorkspaceMembership(\n params: RequireWorkspaceMembershipParams,\n): Promise<RequireWorkspaceMembershipResult> {\n const membership = params.memberships.find((m) => m.workspaceId === params.workspaceId);\n if (!membership) {\n throw new MembershipRequiredError(params.workspaceId);\n }\n\n const workspace = await getWorkspaceById(params.workspaceId);\n if (!workspace) {\n throw new WorkspaceNotFoundError(params.workspaceId);\n }\n if (workspace.status !== 'active') {\n throw new WorkspaceInactiveError(params.workspaceId);\n }\n\n return {workspace, workspaceId: workspace.id, userId: params.userId, role: membership.role};\n}\n\nexport async function createWorkspaceForUser(params: {\n name: string;\n userId: string;\n userEmail?: string | undefined;\n userName?: string | null | undefined;\n}): Promise<Workspace> {\n return await db().transaction(async (tx) => {\n const [workspaceRow] = await tx.insert(workspaces).values({name: params.name}).returning();\n if (!workspaceRow) throw new Error('Insert returned no rows');\n await tx.insert(memberships).values({\n userId: params.userId,\n userEmail: params.userEmail ?? `user-${params.userId}@example.local`,\n userName: params.userName ?? null,\n workspaceId: workspaceRow.id,\n });\n const workspace = toWorkspace(workspaceRow);\n\n await writeOutboxEvent<WorkspacesEventMap>(tx, workspacesOutbox, {\n type: WORKSPACES_WORKSPACE_CREATED,\n payload: {\n workspaceId: workspace.id,\n name: workspace.name,\n creatorUserId: params.userId,\n },\n });\n\n return workspace;\n });\n}\n\nexport async function getWorkspace(params: {workspaceId: string}): Promise<Workspace> {\n const workspace = await getWorkspaceById(params.workspaceId);\n if (!workspace) {\n throw new WorkspaceNotFoundError(params.workspaceId);\n }\n\n return workspace;\n}\n\nexport async function listUserWorkspaceMemberships(params: {\n userId: string;\n}): Promise<MembershipWithWorkspace[]> {\n return await listMembershipsByUser({userId: params.userId});\n}\n\nexport async function listWorkspaceMembers(params: {\n workspaceId: string;\n requesterUserId: string;\n requesterMemberships: ReadonlyArray<UserContextMembership>;\n}): Promise<MembershipWithUser[]> {\n await requireWorkspaceMembership({\n workspaceId: params.workspaceId,\n userId: params.requesterUserId,\n memberships: params.requesterMemberships,\n });\n\n return listMembershipsByWorkspace({workspaceId: params.workspaceId});\n}\n\nexport async function removeWorkspaceMember(params: {\n workspaceId: string;\n requesterUserId: string;\n requesterMemberships: ReadonlyArray<UserContextMembership>;\n userId: string;\n}): Promise<void> {\n await requireWorkspaceMembership({\n workspaceId: params.workspaceId,\n userId: params.requesterUserId,\n memberships: params.requesterMemberships,\n });\n\n if (params.userId === params.requesterUserId) {\n throw new SelfRemovalNotAllowedError();\n }\n\n const target = await findMembership({userId: params.userId, workspaceId: params.workspaceId});\n if (!target) {\n throw new MembershipNotFoundError(params.userId, params.workspaceId);\n }\n\n await removeMembership({userId: params.userId, workspaceId: params.workspaceId});\n}\n"],"names":["WORKSPACES_WORKSPACE_CREATED","writeOutboxEvent","db","findMembership","listMembershipsByUser","listMembershipsByWorkspace","removeMembership","memberships","workspacesOutbox","toWorkspace","workspaces","getWorkspaceById","MembershipNotFoundError","MembershipRequiredError","SelfRemovalNotAllowedError","WorkspaceInactiveError","WorkspaceNotFoundError","requireWorkspaceMembership","params","membership","find","m","workspaceId","workspace","status","id","userId","role","createWorkspaceForUser","transaction","tx","workspaceRow","insert","values","name","returning","Error","userEmail","userName","type","payload","creatorUserId","getWorkspace","listUserWorkspaceMemberships","listWorkspaceMembers","requesterUserId","requesterMemberships","removeWorkspaceMember","target"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/workspaces.ts"],"sourcesContent":["import type {UserContextMembership} from '@shipfox/api-auth-context';\nimport {\n WORKSPACES_WORKSPACE_CREATED,\n type WorkspaceRole,\n type WorkspacesEventMap,\n} from '@shipfox/api-workspaces-dto';\nimport {writeOutboxEvent} from '@shipfox/node-outbox';\nimport {db} from '#db/db.js';\nimport {\n findMembership,\n listMembershipsByUser,\n listMembershipsByWorkspace,\n type MembershipWithUser,\n type MembershipWithWorkspace,\n removeMembership,\n} from '#db/memberships.js';\nimport {memberships} from '#db/schema/memberships.js';\nimport {workspacesOutbox} from '#db/schema/outbox.js';\nimport {toWorkspace, workspaces} from '#db/schema/workspaces.js';\nimport {getWorkspaceById} from '#db/workspaces.js';\nimport type {Workspace} from './entities/workspace.js';\nimport {\n MembershipNotFoundError,\n MembershipRequiredError,\n SelfRemovalNotAllowedError,\n WorkspaceInactiveError,\n WorkspaceNotFoundError,\n} from './errors.js';\n\nexport interface RequireWorkspaceMembershipParams {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<UserContextMembership>;\n}\n\nexport interface RequireWorkspaceMembershipResult {\n workspace: Workspace;\n workspaceId: string;\n userId: string;\n role: WorkspaceRole;\n}\n\nexport async function requireWorkspaceMembership(\n params: RequireWorkspaceMembershipParams,\n): Promise<RequireWorkspaceMembershipResult> {\n const membership = params.memberships.find((m) => m.workspaceId === params.workspaceId);\n if (!membership) {\n throw new MembershipRequiredError(params.workspaceId);\n }\n\n const workspace = await getWorkspaceById(params.workspaceId);\n if (!workspace) {\n throw new WorkspaceNotFoundError(params.workspaceId);\n }\n if (workspace.status !== 'active') {\n throw new WorkspaceInactiveError(params.workspaceId);\n }\n\n return {workspace, workspaceId: workspace.id, userId: params.userId, role: membership.role};\n}\n\nexport async function createWorkspaceForUser(params: {\n name: string;\n userId: string;\n userEmail?: string | undefined;\n userName?: string | null | undefined;\n}): Promise<Workspace> {\n return await db().transaction(async (tx) => {\n const [workspaceRow] = await tx\n .insert(workspaces)\n .values({name: params.name, createdBy: params.userId})\n .returning();\n if (!workspaceRow) throw new Error('Insert returned no rows');\n await tx.insert(memberships).values({\n userId: params.userId,\n userEmail: params.userEmail ?? `user-${params.userId}@example.local`,\n userName: params.userName ?? null,\n workspaceId: workspaceRow.id,\n });\n const workspace = toWorkspace(workspaceRow);\n\n await writeOutboxEvent<WorkspacesEventMap>(tx, workspacesOutbox, {\n type: WORKSPACES_WORKSPACE_CREATED,\n payload: {\n workspaceId: workspace.id,\n name: workspace.name,\n creatorUserId: params.userId,\n },\n });\n\n return workspace;\n });\n}\n\nexport async function getWorkspace(params: {workspaceId: string}): Promise<Workspace> {\n const workspace = await getWorkspaceById(params.workspaceId);\n if (!workspace) {\n throw new WorkspaceNotFoundError(params.workspaceId);\n }\n\n return workspace;\n}\n\nexport async function getWorkspaceCreator(params: {workspaceId: string}): Promise<string | null> {\n const workspace = await getWorkspace(params);\n return workspace.createdBy;\n}\n\nexport async function listUserWorkspaceMemberships(params: {\n userId: string;\n}): Promise<MembershipWithWorkspace[]> {\n return await listMembershipsByUser({userId: params.userId});\n}\n\nexport async function listWorkspaceMembers(params: {\n workspaceId: string;\n requesterUserId: string;\n requesterMemberships: ReadonlyArray<UserContextMembership>;\n}): Promise<MembershipWithUser[]> {\n await requireWorkspaceMembership({\n workspaceId: params.workspaceId,\n userId: params.requesterUserId,\n memberships: params.requesterMemberships,\n });\n\n return listMembershipsByWorkspace({workspaceId: params.workspaceId});\n}\n\nexport async function removeWorkspaceMember(params: {\n workspaceId: string;\n requesterUserId: string;\n requesterMemberships: ReadonlyArray<UserContextMembership>;\n userId: string;\n}): Promise<void> {\n await requireWorkspaceMembership({\n workspaceId: params.workspaceId,\n userId: params.requesterUserId,\n memberships: params.requesterMemberships,\n });\n\n if (params.userId === params.requesterUserId) {\n throw new SelfRemovalNotAllowedError();\n }\n\n const target = await findMembership({userId: params.userId, workspaceId: params.workspaceId});\n if (!target) {\n throw new MembershipNotFoundError(params.userId, params.workspaceId);\n }\n\n await removeMembership({userId: params.userId, workspaceId: params.workspaceId});\n}\n"],"names":["WORKSPACES_WORKSPACE_CREATED","writeOutboxEvent","db","findMembership","listMembershipsByUser","listMembershipsByWorkspace","removeMembership","memberships","workspacesOutbox","toWorkspace","workspaces","getWorkspaceById","MembershipNotFoundError","MembershipRequiredError","SelfRemovalNotAllowedError","WorkspaceInactiveError","WorkspaceNotFoundError","requireWorkspaceMembership","params","membership","find","m","workspaceId","workspace","status","id","userId","role","createWorkspaceForUser","transaction","tx","workspaceRow","insert","values","name","createdBy","returning","Error","userEmail","userName","type","payload","creatorUserId","getWorkspace","getWorkspaceCreator","listUserWorkspaceMemberships","listWorkspaceMembers","requesterUserId","requesterMemberships","removeWorkspaceMember","target"],"mappings":"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"}
package/dist/db/db.d.ts CHANGED
@@ -72,6 +72,23 @@ export declare const schema: {
72
72
  identity: undefined;
73
73
  generated: undefined;
74
74
  }, {}, {}>;
75
+ createdBy: import("drizzle-orm/pg-core").PgColumn<{
76
+ name: "created_by";
77
+ tableName: "workspaces";
78
+ dataType: "string";
79
+ columnType: "PgUUID";
80
+ data: string;
81
+ driverParam: string;
82
+ notNull: false;
83
+ hasDefault: false;
84
+ isPrimaryKey: false;
85
+ isAutoincrement: false;
86
+ hasRuntimeDefault: false;
87
+ enumValues: undefined;
88
+ baseColumn: never;
89
+ identity: undefined;
90
+ generated: undefined;
91
+ }, {}, {}>;
75
92
  createdAt: import("drizzle-orm/pg-core").PgColumn<{
76
93
  name: "created_at";
77
94
  tableName: "workspaces";
@@ -714,6 +731,23 @@ export declare function db(): NodePgDatabase<{
714
731
  identity: undefined;
715
732
  generated: undefined;
716
733
  }, {}, {}>;
734
+ createdBy: import("drizzle-orm/pg-core").PgColumn<{
735
+ name: "created_by";
736
+ tableName: "workspaces";
737
+ dataType: "string";
738
+ columnType: "PgUUID";
739
+ data: string;
740
+ driverParam: string;
741
+ notNull: false;
742
+ hasDefault: false;
743
+ isPrimaryKey: false;
744
+ isAutoincrement: false;
745
+ hasRuntimeDefault: false;
746
+ enumValues: undefined;
747
+ baseColumn: never;
748
+ identity: undefined;
749
+ generated: undefined;
750
+ }, {}, {}>;
717
751
  createdAt: import("drizzle-orm/pg-core").PgColumn<{
718
752
  name: "created_at";
719
753
  tableName: "workspaces";
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAOnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKlB,CAAC;AAIF,wBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjB;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAOnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKlB,CAAC;AAIF,wBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjB;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/db/schema/common.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,oDAEnB,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/db/schema/common.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,oDAAiD,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import { pgTableCreator } from 'drizzle-orm/pg-core';
2
- export const pgTable = pgTableCreator((name)=>name === 'workspaces' ? name : `workspaces_${name}`);
2
+ export const pgTable = pgTableCreator((name)=>`workspaces_${name}`);
3
3
 
4
4
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/common.ts"],"sourcesContent":["import {pgTableCreator} from 'drizzle-orm/pg-core';\n\nexport const pgTable = pgTableCreator((name) =>\n name === 'workspaces' ? name : `workspaces_${name}`,\n);\n"],"names":["pgTableCreator","pgTable","name"],"mappings":"AAAA,SAAQA,cAAc,QAAO,sBAAsB;AAEnD,OAAO,MAAMC,UAAUD,eAAe,CAACE,OACrCA,SAAS,eAAeA,OAAO,CAAC,WAAW,EAAEA,MAAM,EACnD"}
1
+ {"version":3,"sources":["../../../src/db/schema/common.ts"],"sourcesContent":["import {pgTableCreator} from 'drizzle-orm/pg-core';\n\nexport const pgTable = pgTableCreator((name) => `workspaces_${name}`);\n"],"names":["pgTableCreator","pgTable","name"],"mappings":"AAAA,SAAQA,cAAc,QAAO,sBAAsB;AAEnD,OAAO,MAAMC,UAAUD,eAAe,CAACE,OAAS,CAAC,WAAW,EAAEA,MAAM,EAAE"}
@@ -72,6 +72,23 @@ export declare const workspaces: import("drizzle-orm/pg-core").PgTableWithColumn
72
72
  identity: undefined;
73
73
  generated: undefined;
74
74
  }, {}, {}>;
75
+ createdBy: import("drizzle-orm/pg-core").PgColumn<{
76
+ name: "created_by";
77
+ tableName: "workspaces";
78
+ dataType: "string";
79
+ columnType: "PgUUID";
80
+ data: string;
81
+ driverParam: string;
82
+ notNull: false;
83
+ hasDefault: false;
84
+ isPrimaryKey: false;
85
+ isAutoincrement: false;
86
+ hasRuntimeDefault: false;
87
+ enumValues: undefined;
88
+ baseColumn: never;
89
+ identity: undefined;
90
+ generated: undefined;
91
+ }, {}, {}>;
75
92
  createdAt: import("drizzle-orm/pg-core").PgColumn<{
76
93
  name: "created_at";
77
94
  tableName: "workspaces";
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../../src/db/schema/workspaces.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,SAAS,EAAkB,MAAM,6BAA6B,CAAC;AAG5E,eAAO,MAAM,mBAAmB,0EAI9B,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,UAAU,CAAC,YAAY,CAAC;AACzD,MAAM,MAAM,iBAAiB,GAAG,OAAO,UAAU,CAAC,YAAY,CAAC;AAE/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,CASvD"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../../src/db/schema/workspaces.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,SAAS,EAAkB,MAAM,6BAA6B,CAAC;AAG5E,eAAO,MAAM,mBAAmB,0EAI9B,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,UAAU,CAAC,YAAY,CAAC;AACzD,MAAM,MAAM,iBAAiB,GAAG,OAAO,UAAU,CAAC,YAAY,CAAC;AAE/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,CAUvD"}
@@ -1,5 +1,5 @@
1
1
  import { uuidv7PrimaryKey } from '@shipfox/node-drizzle';
2
- import { jsonb, pgEnum, text, timestamp } from 'drizzle-orm/pg-core';
2
+ import { jsonb, pgEnum, text, timestamp, uuid } from 'drizzle-orm/pg-core';
3
3
  import { pgTable } from './common.js';
4
4
  export const workspaceStatusEnum = pgEnum('workspaces_workspace_status', [
5
5
  'active',
@@ -11,6 +11,7 @@ export const workspaces = pgTable('workspaces', {
11
11
  name: text('name').notNull(),
12
12
  status: workspaceStatusEnum('status').notNull().default('active'),
13
13
  settings: jsonb('settings').notNull().default({}),
14
+ createdBy: uuid('created_by'),
14
15
  createdAt: timestamp('created_at', {
15
16
  withTimezone: true
16
17
  }).notNull().defaultNow(),
@@ -24,6 +25,7 @@ export function toWorkspace(row) {
24
25
  name: row.name,
25
26
  status: row.status,
26
27
  settings: row.settings,
28
+ createdBy: row.createdBy,
27
29
  createdAt: row.createdAt,
28
30
  updatedAt: row.updatedAt
29
31
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/workspaces.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {jsonb, pgEnum, text, timestamp} from 'drizzle-orm/pg-core';\nimport type {Workspace, WorkspaceStatus} from '#core/entities/workspace.js';\nimport {pgTable} from './common.js';\n\nexport const workspaceStatusEnum = pgEnum('workspaces_workspace_status', [\n 'active',\n 'suspended',\n 'deleted',\n]);\n\nexport const workspaces = pgTable('workspaces', {\n id: uuidv7PrimaryKey(),\n name: text('name').notNull(),\n status: workspaceStatusEnum('status').notNull().default('active'),\n settings: jsonb('settings').notNull().default({}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n});\n\nexport type WorkspaceDb = typeof workspaces.$inferSelect;\nexport type WorkspaceCreateDb = typeof workspaces.$inferInsert;\n\nexport function toWorkspace(row: WorkspaceDb): Workspace {\n return {\n id: row.id,\n name: row.name,\n status: row.status as WorkspaceStatus,\n settings: row.settings as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","jsonb","pgEnum","text","timestamp","pgTable","workspaceStatusEnum","workspaces","id","name","notNull","status","default","settings","createdAt","withTimezone","defaultNow","updatedAt","toWorkspace","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,MAAM,EAAEC,IAAI,EAAEC,SAAS,QAAO,sBAAsB;AAEnE,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,sBAAsBJ,OAAO,+BAA+B;IACvE;IACA;IACA;CACD,EAAE;AAEH,OAAO,MAAMK,aAAaF,QAAQ,cAAc;IAC9CG,IAAIR;IACJS,MAAMN,KAAK,QAAQO,OAAO;IAC1BC,QAAQL,oBAAoB,UAAUI,OAAO,GAAGE,OAAO,CAAC;IACxDC,UAAUZ,MAAM,YAAYS,OAAO,GAAGE,OAAO,CAAC,CAAC;IAC/CE,WAAWV,UAAU,cAAc;QAACW,cAAc;IAAI,GAAGL,OAAO,GAAGM,UAAU;IAC7EC,WAAWb,UAAU,cAAc;QAACW,cAAc;IAAI,GAAGL,OAAO,GAAGM,UAAU;AAC/E,GAAG;AAKH,OAAO,SAASE,YAAYC,GAAgB;IAC1C,OAAO;QACLX,IAAIW,IAAIX,EAAE;QACVC,MAAMU,IAAIV,IAAI;QACdE,QAAQQ,IAAIR,MAAM;QAClBE,UAAUM,IAAIN,QAAQ;QACtBC,WAAWK,IAAIL,SAAS;QACxBG,WAAWE,IAAIF,SAAS;IAC1B;AACF"}
1
+ {"version":3,"sources":["../../../src/db/schema/workspaces.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {jsonb, pgEnum, text, timestamp, uuid} from 'drizzle-orm/pg-core';\nimport type {Workspace, WorkspaceStatus} from '#core/entities/workspace.js';\nimport {pgTable} from './common.js';\n\nexport const workspaceStatusEnum = pgEnum('workspaces_workspace_status', [\n 'active',\n 'suspended',\n 'deleted',\n]);\n\nexport const workspaces = pgTable('workspaces', {\n id: uuidv7PrimaryKey(),\n name: text('name').notNull(),\n status: workspaceStatusEnum('status').notNull().default('active'),\n settings: jsonb('settings').notNull().default({}),\n createdBy: uuid('created_by'),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n});\n\nexport type WorkspaceDb = typeof workspaces.$inferSelect;\nexport type WorkspaceCreateDb = typeof workspaces.$inferInsert;\n\nexport function toWorkspace(row: WorkspaceDb): Workspace {\n return {\n id: row.id,\n name: row.name,\n status: row.status as WorkspaceStatus,\n settings: row.settings as Record<string, unknown>,\n createdBy: row.createdBy,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","jsonb","pgEnum","text","timestamp","uuid","pgTable","workspaceStatusEnum","workspaces","id","name","notNull","status","default","settings","createdBy","createdAt","withTimezone","defaultNow","updatedAt","toWorkspace","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAEC,IAAI,QAAO,sBAAsB;AAEzE,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,sBAAsBL,OAAO,+BAA+B;IACvE;IACA;IACA;CACD,EAAE;AAEH,OAAO,MAAMM,aAAaF,QAAQ,cAAc;IAC9CG,IAAIT;IACJU,MAAMP,KAAK,QAAQQ,OAAO;IAC1BC,QAAQL,oBAAoB,UAAUI,OAAO,GAAGE,OAAO,CAAC;IACxDC,UAAUb,MAAM,YAAYU,OAAO,GAAGE,OAAO,CAAC,CAAC;IAC/CE,WAAWV,KAAK;IAChBW,WAAWZ,UAAU,cAAc;QAACa,cAAc;IAAI,GAAGN,OAAO,GAAGO,UAAU;IAC7EC,WAAWf,UAAU,cAAc;QAACa,cAAc;IAAI,GAAGN,OAAO,GAAGO,UAAU;AAC/E,GAAG;AAKH,OAAO,SAASE,YAAYC,GAAgB;IAC1C,OAAO;QACLZ,IAAIY,IAAIZ,EAAE;QACVC,MAAMW,IAAIX,IAAI;QACdE,QAAQS,IAAIT,MAAM;QAClBE,UAAUO,IAAIP,QAAQ;QACtBC,WAAWM,IAAIN,SAAS;QACxBC,WAAWK,IAAIL,SAAS;QACxBG,WAAWE,IAAIF,SAAS;IAC1B;AACF"}
package/dist/index.js CHANGED
@@ -18,7 +18,8 @@ export const workspacesModule = {
18
18
  name: 'workspaces',
19
19
  database: {
20
20
  db,
21
- migrationsPath
21
+ migrationsPath,
22
+ databaseNamespace: 'workspaces'
22
23
  },
23
24
  routes: workspacesRoutes,
24
25
  e2eRoutes: [
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n WORKSPACES_INVITATION_SEND_REQUESTED,\n type WorkspacesEventMap,\n workspacesEventSchemas,\n} from '@shipfox/api-workspaces-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {db, migrationsPath, workspacesOutbox} from '#db/index.js';\nimport {registerWorkspacesServiceMetrics} from '#metrics/index.js';\nimport {workspacesE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createWorkspacesInterModulePresentation} from '#presentation/inter-module.js';\nimport {workspacesRoutes} from '#presentation/routes/index.js';\nimport {onInvitationSendRequested} from '#presentation/subscribers/index.js';\n\nexport type {Invitation} from '#core/entities/invitation.js';\nexport type {Membership} from '#core/entities/membership.js';\nexport type {Workspace, WorkspaceStatus} from '#core/entities/workspace.js';\nexport {\n InvitationEmailMismatchError,\n TokenAlreadyUsedError,\n TokenExpiredError,\n TokenInvalidError,\n WorkspaceNotFoundError,\n} from '#core/errors.js';\nexport {\n acceptWorkspaceInvitation,\n peekInvitationByRawToken,\n reconcileWorkspaceInvitationAcceptance,\n type WorkspaceInvitationReconciliation,\n} from '#core/invitations.js';\nexport {type EnsureMembershipParams, ensureMembership} from '#core/memberships.js';\nexport {getWorkspace, requireWorkspaceMembership} from '#core/workspaces.js';\nexport {db, migrationsPath} from '#db/index.js';\nexport {listMembershipsByUser} from '#db/memberships.js';\nexport {workspacesRoutes as routes} from '#presentation/routes/index.js';\n\nconst subscriber = subscriberFactory<WorkspacesEventMap>();\n\nexport const workspacesModule: ShipfoxModule = {\n name: 'workspaces',\n database: {db, migrationsPath},\n routes: workspacesRoutes,\n e2eRoutes: [workspacesE2eRoutes],\n publishers: [\n {name: 'workspaces', table: workspacesOutbox, db, eventSchemas: workspacesEventSchemas},\n ],\n subscribers: [subscriber(WORKSPACES_INVITATION_SEND_REQUESTED, onInvitationSendRequested)],\n metrics: registerWorkspacesServiceMetrics,\n interModulePresentations: [createWorkspacesInterModulePresentation()],\n};\n"],"names":["WORKSPACES_INVITATION_SEND_REQUESTED","workspacesEventSchemas","subscriberFactory","db","migrationsPath","workspacesOutbox","registerWorkspacesServiceMetrics","workspacesE2eRoutes","createWorkspacesInterModulePresentation","workspacesRoutes","onInvitationSendRequested","InvitationEmailMismatchError","TokenAlreadyUsedError","TokenExpiredError","TokenInvalidError","WorkspaceNotFoundError","acceptWorkspaceInvitation","peekInvitationByRawToken","reconcileWorkspaceInvitationAcceptance","ensureMembership","getWorkspace","requireWorkspaceMembership","listMembershipsByUser","routes","subscriber","workspacesModule","name","database","e2eRoutes","publishers","table","eventSchemas","subscribers","metrics","interModulePresentations"],"mappings":"AAAA,SACEA,oCAAoC,EAEpCC,sBAAsB,QACjB,8BAA8B;AAErC,SAAQC,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,EAAE,EAAEC,cAAc,EAAEC,gBAAgB,QAAO,eAAe;AAClE,SAAQC,gCAAgC,QAAO,oBAAoB;AACnE,SAAQC,mBAAmB,QAAO,mCAAmC;AACrE,SAAQC,uCAAuC,QAAO,gCAAgC;AACtF,SAAQC,gBAAgB,QAAO,gCAAgC;AAC/D,SAAQC,yBAAyB,QAAO,qCAAqC;AAK7E,SACEC,4BAA4B,EAC5BC,qBAAqB,EACrBC,iBAAiB,EACjBC,iBAAiB,EACjBC,sBAAsB,QACjB,kBAAkB;AACzB,SACEC,yBAAyB,EACzBC,wBAAwB,EACxBC,sCAAsC,QAEjC,uBAAuB;AAC9B,SAAqCC,gBAAgB,QAAO,uBAAuB;AACnF,SAAQC,YAAY,EAAEC,0BAA0B,QAAO,sBAAsB;AAC7E,SAAQlB,EAAE,EAAEC,cAAc,QAAO,eAAe;AAChD,SAAQkB,qBAAqB,QAAO,qBAAqB;AACzD,SAAQb,oBAAoBc,MAAM,QAAO,gCAAgC;AAEzE,MAAMC,aAAatB;AAEnB,OAAO,MAAMuB,mBAAkC;IAC7CC,MAAM;IACNC,UAAU;QAACxB;QAAIC;IAAc;IAC7BmB,QAAQd;IACRmB,WAAW;QAACrB;KAAoB;IAChCsB,YAAY;QACV;YAACH,MAAM;YAAcI,OAAOzB;YAAkBF;YAAI4B,cAAc9B;QAAsB;KACvF;IACD+B,aAAa;QAACR,WAAWxB,sCAAsCU;KAA2B;IAC1FuB,SAAS3B;IACT4B,0BAA0B;QAAC1B;KAA0C;AACvE,EAAE"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n WORKSPACES_INVITATION_SEND_REQUESTED,\n type WorkspacesEventMap,\n workspacesEventSchemas,\n} from '@shipfox/api-workspaces-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {db, migrationsPath, workspacesOutbox} from '#db/index.js';\nimport {registerWorkspacesServiceMetrics} from '#metrics/index.js';\nimport {workspacesE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createWorkspacesInterModulePresentation} from '#presentation/inter-module.js';\nimport {workspacesRoutes} from '#presentation/routes/index.js';\nimport {onInvitationSendRequested} from '#presentation/subscribers/index.js';\n\nexport type {Invitation} from '#core/entities/invitation.js';\nexport type {Membership} from '#core/entities/membership.js';\nexport type {Workspace, WorkspaceStatus} from '#core/entities/workspace.js';\nexport {\n InvitationEmailMismatchError,\n TokenAlreadyUsedError,\n TokenExpiredError,\n TokenInvalidError,\n WorkspaceNotFoundError,\n} from '#core/errors.js';\nexport {\n acceptWorkspaceInvitation,\n peekInvitationByRawToken,\n reconcileWorkspaceInvitationAcceptance,\n type WorkspaceInvitationReconciliation,\n} from '#core/invitations.js';\nexport {type EnsureMembershipParams, ensureMembership} from '#core/memberships.js';\nexport {getWorkspace, requireWorkspaceMembership} from '#core/workspaces.js';\nexport {db, migrationsPath} from '#db/index.js';\nexport {listMembershipsByUser} from '#db/memberships.js';\nexport {workspacesRoutes as routes} from '#presentation/routes/index.js';\n\nconst subscriber = subscriberFactory<WorkspacesEventMap>();\n\nexport const workspacesModule: ShipfoxModule = {\n name: 'workspaces',\n database: {db, migrationsPath, databaseNamespace: 'workspaces'},\n routes: workspacesRoutes,\n e2eRoutes: [workspacesE2eRoutes],\n publishers: [\n {name: 'workspaces', table: workspacesOutbox, db, eventSchemas: workspacesEventSchemas},\n ],\n subscribers: [subscriber(WORKSPACES_INVITATION_SEND_REQUESTED, onInvitationSendRequested)],\n metrics: registerWorkspacesServiceMetrics,\n interModulePresentations: [createWorkspacesInterModulePresentation()],\n};\n"],"names":["WORKSPACES_INVITATION_SEND_REQUESTED","workspacesEventSchemas","subscriberFactory","db","migrationsPath","workspacesOutbox","registerWorkspacesServiceMetrics","workspacesE2eRoutes","createWorkspacesInterModulePresentation","workspacesRoutes","onInvitationSendRequested","InvitationEmailMismatchError","TokenAlreadyUsedError","TokenExpiredError","TokenInvalidError","WorkspaceNotFoundError","acceptWorkspaceInvitation","peekInvitationByRawToken","reconcileWorkspaceInvitationAcceptance","ensureMembership","getWorkspace","requireWorkspaceMembership","listMembershipsByUser","routes","subscriber","workspacesModule","name","database","databaseNamespace","e2eRoutes","publishers","table","eventSchemas","subscribers","metrics","interModulePresentations"],"mappings":"AAAA,SACEA,oCAAoC,EAEpCC,sBAAsB,QACjB,8BAA8B;AAErC,SAAQC,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,EAAE,EAAEC,cAAc,EAAEC,gBAAgB,QAAO,eAAe;AAClE,SAAQC,gCAAgC,QAAO,oBAAoB;AACnE,SAAQC,mBAAmB,QAAO,mCAAmC;AACrE,SAAQC,uCAAuC,QAAO,gCAAgC;AACtF,SAAQC,gBAAgB,QAAO,gCAAgC;AAC/D,SAAQC,yBAAyB,QAAO,qCAAqC;AAK7E,SACEC,4BAA4B,EAC5BC,qBAAqB,EACrBC,iBAAiB,EACjBC,iBAAiB,EACjBC,sBAAsB,QACjB,kBAAkB;AACzB,SACEC,yBAAyB,EACzBC,wBAAwB,EACxBC,sCAAsC,QAEjC,uBAAuB;AAC9B,SAAqCC,gBAAgB,QAAO,uBAAuB;AACnF,SAAQC,YAAY,EAAEC,0BAA0B,QAAO,sBAAsB;AAC7E,SAAQlB,EAAE,EAAEC,cAAc,QAAO,eAAe;AAChD,SAAQkB,qBAAqB,QAAO,qBAAqB;AACzD,SAAQb,oBAAoBc,MAAM,QAAO,gCAAgC;AAEzE,MAAMC,aAAatB;AAEnB,OAAO,MAAMuB,mBAAkC;IAC7CC,MAAM;IACNC,UAAU;QAACxB;QAAIC;QAAgBwB,mBAAmB;IAAY;IAC9DL,QAAQd;IACRoB,WAAW;QAACtB;KAAoB;IAChCuB,YAAY;QACV;YAACJ,MAAM;YAAcK,OAAO1B;YAAkBF;YAAI6B,cAAc/B;QAAsB;KACvF;IACDgC,aAAa;QAACT,WAAWxB,sCAAsCU;KAA2B;IAC1FwB,SAAS5B;IACT6B,0BAA0B;QAAC3B;KAA0C;AACvE,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,6BAA6B,EAAC,MAAM,0CAA0C,CAAC;AACvF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAc/B,wBAAgB,uCAAuC,IAAI,uBAAuB,CAChF,OAAO,6BAA6B,CACrC,CAwDA"}
1
+ {"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,6BAA6B,EAAC,MAAM,0CAA0C,CAAC;AACvF,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAc/B,wBAAgB,uCAAuC,IAAI,uBAAuB,CAChF,OAAO,6BAA6B,CACrC,CAsEA"}
@@ -2,7 +2,7 @@ import { workspacesInterModuleContract } from '@shipfox/api-workspaces-dto/inter
2
2
  import { createInterModuleKnownError, defineInterModulePresentation } from '@shipfox/inter-module';
3
3
  import { InvitationEmailMismatchError, MembershipRequiredError, TokenAlreadyUsedError, TokenExpiredError, TokenInvalidError, WorkspaceInactiveError, WorkspaceNotFoundError } from '#core/errors.js';
4
4
  import { acceptWorkspaceInvitation, peekInvitationByRawToken } from '#core/invitations.js';
5
- import { requireWorkspaceMembership } from '#core/workspaces.js';
5
+ import { getWorkspaceCreator, requireWorkspaceMembership } from '#core/workspaces.js';
6
6
  import { listMembershipsByUser } from '#db/memberships.js';
7
7
  export function createWorkspacesInterModulePresentation() {
8
8
  return defineInterModulePresentation(workspacesInterModuleContract, {
@@ -14,6 +14,20 @@ export function createWorkspacesInterModulePresentation() {
14
14
  role: 'admin'
15
15
  }))
16
16
  }),
17
+ getWorkspaceCreator: async (input)=>{
18
+ try {
19
+ return {
20
+ creatorUserId: await getWorkspaceCreator(input)
21
+ };
22
+ } catch (error) {
23
+ if (error instanceof WorkspaceNotFoundError) {
24
+ throw createInterModuleKnownError(workspacesInterModuleContract.methods.getWorkspaceCreator, 'workspace-not-found', {
25
+ workspaceId: input.workspaceId
26
+ });
27
+ }
28
+ throw error;
29
+ }
30
+ },
17
31
  preflightInvitationAcceptance: async (input)=>{
18
32
  try {
19
33
  const invitation = await peekInvitationByRawToken({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {workspacesInterModuleContract} from '@shipfox/api-workspaces-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {\n InvitationEmailMismatchError,\n MembershipRequiredError,\n TokenAlreadyUsedError,\n TokenExpiredError,\n TokenInvalidError,\n WorkspaceInactiveError,\n WorkspaceNotFoundError,\n} from '#core/errors.js';\nimport {acceptWorkspaceInvitation, peekInvitationByRawToken} from '#core/invitations.js';\nimport {requireWorkspaceMembership} from '#core/workspaces.js';\nimport {listMembershipsByUser} from '#db/memberships.js';\n\nexport function createWorkspacesInterModulePresentation(): InterModulePresentation<\n typeof workspacesInterModuleContract\n> {\n return defineInterModulePresentation(workspacesInterModuleContract, {\n listMembershipsForTokenClaims: async ({userId}) => ({\n memberships: (await listMembershipsByUser({userId})).map(({workspaceId}) => ({\n workspaceId,\n role: 'admin' as const,\n })),\n }),\n preflightInvitationAcceptance: async (input) => {\n try {\n const invitation = await peekInvitationByRawToken({token: input.token});\n if (!invitation) throw new TokenInvalidError('Invitation token is invalid');\n if (invitation.acceptedAt !== null) throw new TokenAlreadyUsedError();\n if (invitation.expiresAt.getTime() <= Date.now()) throw new TokenExpiredError();\n if (invitation.email !== input.email) throw new InvitationEmailMismatchError();\n return {};\n } catch (error) {\n throw toInvitationKnownError('preflightInvitationAcceptance', error);\n }\n },\n acceptInvitation: async (input) => {\n try {\n const result = await acceptWorkspaceInvitation(input);\n return {\n membership: {\n id: result.membership.id,\n userId: result.membership.userId,\n workspaceId: result.membership.workspaceId,\n },\n };\n } catch (error) {\n throw toInvitationKnownError('acceptInvitation', error);\n }\n },\n requireActiveMembership: async (input) => {\n try {\n await requireWorkspaceMembership(input);\n return {};\n } catch (error) {\n const method = workspacesInterModuleContract.methods.requireActiveMembership;\n if (error instanceof MembershipRequiredError)\n throw createInterModuleKnownError(method, 'membership-required', {\n workspaceId: input.workspaceId,\n });\n if (error instanceof WorkspaceNotFoundError)\n throw createInterModuleKnownError(method, 'workspace-not-found', {\n workspaceId: input.workspaceId,\n });\n if (error instanceof WorkspaceInactiveError)\n throw createInterModuleKnownError(method, 'workspace-inactive', {\n workspaceId: input.workspaceId,\n });\n throw error;\n }\n },\n });\n}\n\nfunction toInvitationKnownError(\n methodName: 'preflightInvitationAcceptance' | 'acceptInvitation',\n error: unknown,\n): unknown {\n const method = workspacesInterModuleContract.methods[methodName];\n if (error instanceof TokenInvalidError)\n return createInterModuleKnownError(method, 'invitation-token-invalid', {});\n if (error instanceof TokenAlreadyUsedError)\n return createInterModuleKnownError(method, 'invitation-token-used', {});\n if (error instanceof TokenExpiredError)\n return createInterModuleKnownError(method, 'invitation-token-expired', {});\n if (error instanceof InvitationEmailMismatchError)\n return createInterModuleKnownError(method, 'invitation-email-mismatch', {});\n return error;\n}\n"],"names":["workspacesInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","InvitationEmailMismatchError","MembershipRequiredError","TokenAlreadyUsedError","TokenExpiredError","TokenInvalidError","WorkspaceInactiveError","WorkspaceNotFoundError","acceptWorkspaceInvitation","peekInvitationByRawToken","requireWorkspaceMembership","listMembershipsByUser","createWorkspacesInterModulePresentation","listMembershipsForTokenClaims","userId","memberships","map","workspaceId","role","preflightInvitationAcceptance","input","invitation","token","acceptedAt","expiresAt","getTime","Date","now","email","error","toInvitationKnownError","acceptInvitation","result","membership","id","requireActiveMembership","method","methods","methodName"],"mappings":"AAAA,SAAQA,6BAA6B,QAAO,2CAA2C;AACvF,SACEC,2BAA2B,EAC3BC,6BAA6B,QAExB,wBAAwB;AAC/B,SACEC,4BAA4B,EAC5BC,uBAAuB,EACvBC,qBAAqB,EACrBC,iBAAiB,EACjBC,iBAAiB,EACjBC,sBAAsB,EACtBC,sBAAsB,QACjB,kBAAkB;AACzB,SAAQC,yBAAyB,EAAEC,wBAAwB,QAAO,uBAAuB;AACzF,SAAQC,0BAA0B,QAAO,sBAAsB;AAC/D,SAAQC,qBAAqB,QAAO,qBAAqB;AAEzD,OAAO,SAASC;IAGd,OAAOZ,8BAA8BF,+BAA+B;QAClEe,+BAA+B,OAAO,EAACC,MAAM,EAAC,GAAM,CAAA;gBAClDC,aAAa,AAAC,CAAA,MAAMJ,sBAAsB;oBAACG;gBAAM,EAAC,EAAGE,GAAG,CAAC,CAAC,EAACC,WAAW,EAAC,GAAM,CAAA;wBAC3EA;wBACAC,MAAM;oBACR,CAAA;YACF,CAAA;QACAC,+BAA+B,OAAOC;YACpC,IAAI;gBACF,MAAMC,aAAa,MAAMZ,yBAAyB;oBAACa,OAAOF,MAAME,KAAK;gBAAA;gBACrE,IAAI,CAACD,YAAY,MAAM,IAAIhB,kBAAkB;gBAC7C,IAAIgB,WAAWE,UAAU,KAAK,MAAM,MAAM,IAAIpB;gBAC9C,IAAIkB,WAAWG,SAAS,CAACC,OAAO,MAAMC,KAAKC,GAAG,IAAI,MAAM,IAAIvB;gBAC5D,IAAIiB,WAAWO,KAAK,KAAKR,MAAMQ,KAAK,EAAE,MAAM,IAAI3B;gBAChD,OAAO,CAAC;YACV,EAAE,OAAO4B,OAAO;gBACd,MAAMC,uBAAuB,iCAAiCD;YAChE;QACF;QACAE,kBAAkB,OAAOX;YACvB,IAAI;gBACF,MAAMY,SAAS,MAAMxB,0BAA0BY;gBAC/C,OAAO;oBACLa,YAAY;wBACVC,IAAIF,OAAOC,UAAU,CAACC,EAAE;wBACxBpB,QAAQkB,OAAOC,UAAU,CAACnB,MAAM;wBAChCG,aAAae,OAAOC,UAAU,CAAChB,WAAW;oBAC5C;gBACF;YACF,EAAE,OAAOY,OAAO;gBACd,MAAMC,uBAAuB,oBAAoBD;YACnD;QACF;QACAM,yBAAyB,OAAOf;YAC9B,IAAI;gBACF,MAAMV,2BAA2BU;gBACjC,OAAO,CAAC;YACV,EAAE,OAAOS,OAAO;gBACd,MAAMO,SAAStC,8BAA8BuC,OAAO,CAACF,uBAAuB;gBAC5E,IAAIN,iBAAiB3B,yBACnB,MAAMH,4BAA4BqC,QAAQ,uBAAuB;oBAC/DnB,aAAaG,MAAMH,WAAW;gBAChC;gBACF,IAAIY,iBAAiBtB,wBACnB,MAAMR,4BAA4BqC,QAAQ,uBAAuB;oBAC/DnB,aAAaG,MAAMH,WAAW;gBAChC;gBACF,IAAIY,iBAAiBvB,wBACnB,MAAMP,4BAA4BqC,QAAQ,sBAAsB;oBAC9DnB,aAAaG,MAAMH,WAAW;gBAChC;gBACF,MAAMY;YACR;QACF;IACF;AACF;AAEA,SAASC,uBACPQ,UAAgE,EAChET,KAAc;IAEd,MAAMO,SAAStC,8BAA8BuC,OAAO,CAACC,WAAW;IAChE,IAAIT,iBAAiBxB,mBACnB,OAAON,4BAA4BqC,QAAQ,4BAA4B,CAAC;IAC1E,IAAIP,iBAAiB1B,uBACnB,OAAOJ,4BAA4BqC,QAAQ,yBAAyB,CAAC;IACvE,IAAIP,iBAAiBzB,mBACnB,OAAOL,4BAA4BqC,QAAQ,4BAA4B,CAAC;IAC1E,IAAIP,iBAAiB5B,8BACnB,OAAOF,4BAA4BqC,QAAQ,6BAA6B,CAAC;IAC3E,OAAOP;AACT"}
1
+ {"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {workspacesInterModuleContract} from '@shipfox/api-workspaces-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {\n InvitationEmailMismatchError,\n MembershipRequiredError,\n TokenAlreadyUsedError,\n TokenExpiredError,\n TokenInvalidError,\n WorkspaceInactiveError,\n WorkspaceNotFoundError,\n} from '#core/errors.js';\nimport {acceptWorkspaceInvitation, peekInvitationByRawToken} from '#core/invitations.js';\nimport {getWorkspaceCreator, requireWorkspaceMembership} from '#core/workspaces.js';\nimport {listMembershipsByUser} from '#db/memberships.js';\n\nexport function createWorkspacesInterModulePresentation(): InterModulePresentation<\n typeof workspacesInterModuleContract\n> {\n return defineInterModulePresentation(workspacesInterModuleContract, {\n listMembershipsForTokenClaims: async ({userId}) => ({\n memberships: (await listMembershipsByUser({userId})).map(({workspaceId}) => ({\n workspaceId,\n role: 'admin' as const,\n })),\n }),\n getWorkspaceCreator: async (input) => {\n try {\n return {creatorUserId: await getWorkspaceCreator(input)};\n } catch (error) {\n if (error instanceof WorkspaceNotFoundError) {\n throw createInterModuleKnownError(\n workspacesInterModuleContract.methods.getWorkspaceCreator,\n 'workspace-not-found',\n {workspaceId: input.workspaceId},\n );\n }\n throw error;\n }\n },\n preflightInvitationAcceptance: async (input) => {\n try {\n const invitation = await peekInvitationByRawToken({token: input.token});\n if (!invitation) throw new TokenInvalidError('Invitation token is invalid');\n if (invitation.acceptedAt !== null) throw new TokenAlreadyUsedError();\n if (invitation.expiresAt.getTime() <= Date.now()) throw new TokenExpiredError();\n if (invitation.email !== input.email) throw new InvitationEmailMismatchError();\n return {};\n } catch (error) {\n throw toInvitationKnownError('preflightInvitationAcceptance', error);\n }\n },\n acceptInvitation: async (input) => {\n try {\n const result = await acceptWorkspaceInvitation(input);\n return {\n membership: {\n id: result.membership.id,\n userId: result.membership.userId,\n workspaceId: result.membership.workspaceId,\n },\n };\n } catch (error) {\n throw toInvitationKnownError('acceptInvitation', error);\n }\n },\n requireActiveMembership: async (input) => {\n try {\n await requireWorkspaceMembership(input);\n return {};\n } catch (error) {\n const method = workspacesInterModuleContract.methods.requireActiveMembership;\n if (error instanceof MembershipRequiredError)\n throw createInterModuleKnownError(method, 'membership-required', {\n workspaceId: input.workspaceId,\n });\n if (error instanceof WorkspaceNotFoundError)\n throw createInterModuleKnownError(method, 'workspace-not-found', {\n workspaceId: input.workspaceId,\n });\n if (error instanceof WorkspaceInactiveError)\n throw createInterModuleKnownError(method, 'workspace-inactive', {\n workspaceId: input.workspaceId,\n });\n throw error;\n }\n },\n });\n}\n\nfunction toInvitationKnownError(\n methodName: 'preflightInvitationAcceptance' | 'acceptInvitation',\n error: unknown,\n): unknown {\n const method = workspacesInterModuleContract.methods[methodName];\n if (error instanceof TokenInvalidError)\n return createInterModuleKnownError(method, 'invitation-token-invalid', {});\n if (error instanceof TokenAlreadyUsedError)\n return createInterModuleKnownError(method, 'invitation-token-used', {});\n if (error instanceof TokenExpiredError)\n return createInterModuleKnownError(method, 'invitation-token-expired', {});\n if (error instanceof InvitationEmailMismatchError)\n return createInterModuleKnownError(method, 'invitation-email-mismatch', {});\n return error;\n}\n"],"names":["workspacesInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","InvitationEmailMismatchError","MembershipRequiredError","TokenAlreadyUsedError","TokenExpiredError","TokenInvalidError","WorkspaceInactiveError","WorkspaceNotFoundError","acceptWorkspaceInvitation","peekInvitationByRawToken","getWorkspaceCreator","requireWorkspaceMembership","listMembershipsByUser","createWorkspacesInterModulePresentation","listMembershipsForTokenClaims","userId","memberships","map","workspaceId","role","input","creatorUserId","error","methods","preflightInvitationAcceptance","invitation","token","acceptedAt","expiresAt","getTime","Date","now","email","toInvitationKnownError","acceptInvitation","result","membership","id","requireActiveMembership","method","methodName"],"mappings":"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"}