@shipfox/api-workspaces 11.0.0 → 12.0.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +34 -0
- package/README.md +27 -4
- package/dist/core/entities/workspace.d.ts +1 -0
- package/dist/core/entities/workspace.d.ts.map +1 -1
- package/dist/core/entities/workspace.js.map +1 -1
- package/dist/core/errors.d.ts +3 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +6 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/invitations.js +1 -1
- package/dist/core/invitations.js.map +1 -1
- package/dist/core/rate-limit.d.ts +39 -0
- package/dist/core/rate-limit.d.ts.map +1 -0
- package/dist/core/rate-limit.js +70 -0
- package/dist/core/rate-limit.js.map +1 -0
- package/dist/core/workspaces.d.ts +7 -0
- package/dist/core/workspaces.d.ts.map +1 -1
- package/dist/core/workspaces.js +42 -4
- package/dist/core/workspaces.js.map +1 -1
- package/dist/db/db.d.ts +320 -0
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +3 -1
- package/dist/db/db.js.map +1 -1
- package/dist/db/index.d.ts +4 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +3 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/memberships.d.ts +1 -0
- package/dist/db/memberships.d.ts.map +1 -1
- package/dist/db/memberships.js +2 -0
- package/dist/db/memberships.js.map +1 -1
- package/dist/db/rate-limits.d.ts +9 -0
- package/dist/db/rate-limits.d.ts.map +1 -0
- package/dist/db/rate-limits.js +43 -0
- package/dist/db/rate-limits.js.map +1 -0
- package/dist/db/schema/rate-limits.d.ts +145 -0
- package/dist/db/schema/rate-limits.d.ts.map +1 -0
- package/dist/db/schema/rate-limits.js +25 -0
- package/dist/db/schema/rate-limits.js.map +1 -0
- package/dist/db/schema/workspaces.d.ts +17 -0
- package/dist/db/schema/workspaces.d.ts.map +1 -1
- package/dist/db/schema/workspaces.js +5 -2
- package/dist/db/schema/workspaces.js.map +1 -1
- package/dist/db/workspaces.d.ts +11 -1
- package/dist/db/workspaces.d.ts.map +1 -1
- package/dist/db/workspaces.js +12 -3
- package/dist/db/workspaces.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/instance.d.ts +6 -0
- package/dist/metrics/instance.d.ts.map +1 -1
- package/dist/metrics/instance.js +12 -0
- package/dist/metrics/instance.js.map +1 -1
- package/dist/presentation/dto/membership.d.ts.map +1 -1
- package/dist/presentation/dto/membership.js +1 -0
- package/dist/presentation/dto/membership.js.map +1 -1
- package/dist/presentation/dto/workspace.d.ts.map +1 -1
- package/dist/presentation/dto/workspace.js +1 -0
- package/dist/presentation/dto/workspace.js.map +1 -1
- package/dist/presentation/e2eRoutes/create-workspace.d.ts.map +1 -1
- package/dist/presentation/e2eRoutes/create-workspace.js +11 -1
- package/dist/presentation/e2eRoutes/create-workspace.js.map +1 -1
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +3 -1
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/rate-limit.d.ts +3 -0
- package/dist/presentation/routes/rate-limit.d.ts.map +1 -0
- package/dist/presentation/routes/rate-limit.js +42 -0
- package/dist/presentation/routes/rate-limit.js.map +1 -0
- package/dist/presentation/routes/workspaces/create.d.ts.map +1 -1
- package/dist/presentation/routes/workspaces/create.js +11 -1
- package/dist/presentation/routes/workspaces/create.js.map +1 -1
- package/dist/presentation/routes/workspaces/index.d.ts +2 -0
- package/dist/presentation/routes/workspaces/index.d.ts.map +1 -1
- package/dist/presentation/routes/workspaces/index.js +2 -0
- package/dist/presentation/routes/workspaces/index.js.map +1 -1
- package/dist/presentation/routes/workspaces/slug-availability.d.ts +2 -0
- package/dist/presentation/routes/workspaces/slug-availability.d.ts.map +1 -0
- package/dist/presentation/routes/workspaces/slug-availability.js +31 -0
- package/dist/presentation/routes/workspaces/slug-availability.js.map +1 -0
- package/dist/presentation/routes/workspaces/update.d.ts +2 -0
- package/dist/presentation/routes/workspaces/update.d.ts.map +1 -0
- package/dist/presentation/routes/workspaces/update.js +49 -0
- package/dist/presentation/routes/workspaces/update.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +2 -0
- package/drizzle/0003_dapper_talos.sql +13 -0
- package/drizzle/meta/0000_snapshot.json +23 -1
- package/drizzle/meta/0003_snapshot.json +689 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +14 -12
- package/src/core/entities/workspace.ts +1 -0
- package/src/core/errors.ts +7 -0
- package/src/core/index.ts +3 -0
- package/src/core/invitations.ts +1 -1
- package/src/core/rate-limit.test.ts +113 -0
- package/src/core/rate-limit.ts +119 -0
- package/src/core/workspaces.test.ts +9 -0
- package/src/core/workspaces.ts +47 -3
- package/src/db/db.ts +2 -0
- package/src/db/index.ts +10 -0
- package/src/db/memberships.ts +3 -0
- package/src/db/rate-limits.test.ts +74 -0
- package/src/db/rate-limits.ts +59 -0
- package/src/db/schema/rate-limits.ts +27 -0
- package/src/db/schema/workspaces.ts +7 -2
- package/src/db/workspaces.ts +21 -1
- package/src/index.test.ts +2 -0
- package/src/index.ts +1 -0
- package/src/metrics/instance.ts +26 -0
- package/src/presentation/dto/membership.ts +1 -0
- package/src/presentation/dto/workspace.ts +1 -0
- package/src/presentation/e2eRoutes/create-workspace.ts +9 -1
- package/src/presentation/inter-module.test.ts +22 -4
- package/src/presentation/routes/index.ts +8 -1
- package/src/presentation/routes/rate-limit.ts +45 -0
- package/src/presentation/routes/workspaces/create.test.ts +33 -3
- package/src/presentation/routes/workspaces/create.ts +9 -1
- package/src/presentation/routes/workspaces/index.ts +2 -0
- package/src/presentation/routes/workspaces/list.test.ts +1 -0
- package/src/presentation/routes/workspaces/slug-availability.test.ts +159 -0
- package/src/presentation/routes/workspaces/slug-availability.ts +30 -0
- package/src/presentation/routes/workspaces/update.test.ts +114 -0
- package/src/presentation/routes/workspaces/update.ts +41 -0
- package/test/env.ts +1 -0
- package/test/factories/workspace.ts +3 -1
- package/test/globalSetup.ts +1 -1
- package/test/routes.ts +18 -4
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -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 enforceWorkspaceStatus?: boolean;\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 (params.enforceWorkspaceStatus !== false && 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 getWorkspaceOperatingState(params: {\n workspaceId: string;\n}): Promise<Workspace['status']> {\n const workspace = await getWorkspace(params);\n return workspace.status;\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 enforceWorkspaceStatus: false,\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 enforceWorkspaceStatus: false,\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","enforceWorkspaceStatus","status","id","userId","role","createWorkspaceForUser","transaction","tx","workspaceRow","insert","values","name","createdBy","returning","Error","userEmail","userName","type","payload","creatorUserId","getWorkspace","getWorkspaceCreator","getWorkspaceOperatingState","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 WORKSPACES_WORKSPACE_UPDATED,\n type WorkspaceRole,\n type WorkspacesEventMap,\n} from '@shipfox/api-workspaces-dto';\nimport {isUniqueViolation} from '@shipfox/node-drizzle';\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, isWorkspaceSlugAvailable, updateWorkspace} from '#db/workspaces.js';\nimport type {Workspace} from './entities/workspace.js';\nimport {\n MembershipNotFoundError,\n MembershipRequiredError,\n SelfRemovalNotAllowedError,\n WorkspaceInactiveError,\n WorkspaceNotFoundError,\n WorkspaceSlugConflictError,\n} from './errors.js';\n\nexport interface RequireWorkspaceMembershipParams {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<UserContextMembership>;\n enforceWorkspaceStatus?: boolean;\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 (params.enforceWorkspaceStatus !== false && 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 slug: 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, slug: params.slug, createdBy: params.userId})\n .onConflictDoNothing({target: workspaces.slug})\n .returning();\n if (!workspaceRow) {\n throw new WorkspaceSlugConflictError(params.slug);\n }\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 slug: workspace.slug,\n creatorUserId: params.userId,\n },\n });\n\n return workspace;\n });\n}\n\nexport async function checkWorkspaceSlugAvailability(slug: string): Promise<boolean> {\n return await isWorkspaceSlugAvailable(slug);\n}\n\nexport async function updateWorkspaceDetails(params: {\n workspaceId: string;\n name?: string | undefined;\n slug?: string | undefined;\n}): Promise<Workspace> {\n try {\n return await db().transaction(async (tx) => {\n const workspace = await updateWorkspace(\n {id: params.workspaceId, name: params.name, slug: params.slug},\n {tx},\n );\n if (!workspace) throw new WorkspaceNotFoundError(params.workspaceId);\n\n await writeOutboxEvent<WorkspacesEventMap>(tx, workspacesOutbox, {\n type: WORKSPACES_WORKSPACE_UPDATED,\n payload: {\n workspaceId: workspace.id,\n name: workspace.name,\n slug: workspace.slug,\n },\n });\n\n return workspace;\n });\n } catch (error) {\n if (isUniqueViolation(error, 'workspaces_slug_unique') && params.slug) {\n throw new WorkspaceSlugConflictError(params.slug);\n }\n throw error;\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 getWorkspaceOperatingState(params: {\n workspaceId: string;\n}): Promise<Workspace['status']> {\n const workspace = await getWorkspace(params);\n return workspace.status;\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 enforceWorkspaceStatus: false,\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 enforceWorkspaceStatus: false,\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","WORKSPACES_WORKSPACE_UPDATED","isUniqueViolation","writeOutboxEvent","db","findMembership","listMembershipsByUser","listMembershipsByWorkspace","removeMembership","memberships","workspacesOutbox","toWorkspace","workspaces","getWorkspaceById","isWorkspaceSlugAvailable","updateWorkspace","MembershipNotFoundError","MembershipRequiredError","SelfRemovalNotAllowedError","WorkspaceInactiveError","WorkspaceNotFoundError","WorkspaceSlugConflictError","requireWorkspaceMembership","params","membership","find","m","workspaceId","workspace","enforceWorkspaceStatus","status","id","userId","role","createWorkspaceForUser","transaction","tx","workspaceRow","insert","values","name","slug","createdBy","onConflictDoNothing","target","returning","userEmail","userName","type","payload","creatorUserId","checkWorkspaceSlugAvailability","updateWorkspaceDetails","error","getWorkspace","getWorkspaceCreator","getWorkspaceOperatingState","listUserWorkspaceMemberships","listWorkspaceMembers","requesterUserId","requesterMemberships","removeWorkspaceMember"],"mappings":"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"}
|
package/dist/db/db.d.ts
CHANGED
|
@@ -166,6 +166,23 @@ export declare const schema: {
|
|
|
166
166
|
identity: undefined;
|
|
167
167
|
generated: undefined;
|
|
168
168
|
}, {}, {}>;
|
|
169
|
+
slug: import("drizzle-orm/pg-core").PgColumn<{
|
|
170
|
+
name: "slug";
|
|
171
|
+
tableName: "workspaces";
|
|
172
|
+
dataType: "string";
|
|
173
|
+
columnType: "PgText";
|
|
174
|
+
data: string;
|
|
175
|
+
driverParam: string;
|
|
176
|
+
notNull: true;
|
|
177
|
+
hasDefault: false;
|
|
178
|
+
isPrimaryKey: false;
|
|
179
|
+
isAutoincrement: false;
|
|
180
|
+
hasRuntimeDefault: false;
|
|
181
|
+
enumValues: [string, ...string[]];
|
|
182
|
+
baseColumn: never;
|
|
183
|
+
identity: undefined;
|
|
184
|
+
generated: undefined;
|
|
185
|
+
}, {}, {}>;
|
|
169
186
|
status: import("drizzle-orm/pg-core").PgColumn<{
|
|
170
187
|
name: "status";
|
|
171
188
|
tableName: "workspaces";
|
|
@@ -785,6 +802,149 @@ export declare const schema: {
|
|
|
785
802
|
};
|
|
786
803
|
dialect: "pg";
|
|
787
804
|
}>;
|
|
805
|
+
workspacesRateLimits: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
806
|
+
name: "rate_limits";
|
|
807
|
+
schema: undefined;
|
|
808
|
+
columns: {
|
|
809
|
+
action: import("drizzle-orm/pg-core").PgColumn<{
|
|
810
|
+
name: "action";
|
|
811
|
+
tableName: "rate_limits";
|
|
812
|
+
dataType: "string";
|
|
813
|
+
columnType: "PgText";
|
|
814
|
+
data: string;
|
|
815
|
+
driverParam: string;
|
|
816
|
+
notNull: true;
|
|
817
|
+
hasDefault: false;
|
|
818
|
+
isPrimaryKey: false;
|
|
819
|
+
isAutoincrement: false;
|
|
820
|
+
hasRuntimeDefault: false;
|
|
821
|
+
enumValues: [string, ...string[]];
|
|
822
|
+
baseColumn: never;
|
|
823
|
+
identity: undefined;
|
|
824
|
+
generated: undefined;
|
|
825
|
+
}, {}, {}>;
|
|
826
|
+
scope: import("drizzle-orm/pg-core").PgColumn<{
|
|
827
|
+
name: "scope";
|
|
828
|
+
tableName: "rate_limits";
|
|
829
|
+
dataType: "string";
|
|
830
|
+
columnType: "PgText";
|
|
831
|
+
data: string;
|
|
832
|
+
driverParam: string;
|
|
833
|
+
notNull: true;
|
|
834
|
+
hasDefault: false;
|
|
835
|
+
isPrimaryKey: false;
|
|
836
|
+
isAutoincrement: false;
|
|
837
|
+
hasRuntimeDefault: false;
|
|
838
|
+
enumValues: [string, ...string[]];
|
|
839
|
+
baseColumn: never;
|
|
840
|
+
identity: undefined;
|
|
841
|
+
generated: undefined;
|
|
842
|
+
}, {}, {}>;
|
|
843
|
+
identifierHmac: import("drizzle-orm/pg-core").PgColumn<{
|
|
844
|
+
name: "identifier_hmac";
|
|
845
|
+
tableName: "rate_limits";
|
|
846
|
+
dataType: "string";
|
|
847
|
+
columnType: "PgText";
|
|
848
|
+
data: string;
|
|
849
|
+
driverParam: string;
|
|
850
|
+
notNull: true;
|
|
851
|
+
hasDefault: false;
|
|
852
|
+
isPrimaryKey: false;
|
|
853
|
+
isAutoincrement: false;
|
|
854
|
+
hasRuntimeDefault: false;
|
|
855
|
+
enumValues: [string, ...string[]];
|
|
856
|
+
baseColumn: never;
|
|
857
|
+
identity: undefined;
|
|
858
|
+
generated: undefined;
|
|
859
|
+
}, {}, {}>;
|
|
860
|
+
windowStart: import("drizzle-orm/pg-core").PgColumn<{
|
|
861
|
+
name: "window_start";
|
|
862
|
+
tableName: "rate_limits";
|
|
863
|
+
dataType: "date";
|
|
864
|
+
columnType: "PgTimestamp";
|
|
865
|
+
data: Date;
|
|
866
|
+
driverParam: string;
|
|
867
|
+
notNull: true;
|
|
868
|
+
hasDefault: false;
|
|
869
|
+
isPrimaryKey: false;
|
|
870
|
+
isAutoincrement: false;
|
|
871
|
+
hasRuntimeDefault: false;
|
|
872
|
+
enumValues: undefined;
|
|
873
|
+
baseColumn: never;
|
|
874
|
+
identity: undefined;
|
|
875
|
+
generated: undefined;
|
|
876
|
+
}, {}, {}>;
|
|
877
|
+
count: import("drizzle-orm/pg-core").PgColumn<{
|
|
878
|
+
name: "count";
|
|
879
|
+
tableName: "rate_limits";
|
|
880
|
+
dataType: "number";
|
|
881
|
+
columnType: "PgInteger";
|
|
882
|
+
data: number;
|
|
883
|
+
driverParam: string | number;
|
|
884
|
+
notNull: true;
|
|
885
|
+
hasDefault: true;
|
|
886
|
+
isPrimaryKey: false;
|
|
887
|
+
isAutoincrement: false;
|
|
888
|
+
hasRuntimeDefault: false;
|
|
889
|
+
enumValues: undefined;
|
|
890
|
+
baseColumn: never;
|
|
891
|
+
identity: undefined;
|
|
892
|
+
generated: undefined;
|
|
893
|
+
}, {}, {}>;
|
|
894
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
895
|
+
name: "expires_at";
|
|
896
|
+
tableName: "rate_limits";
|
|
897
|
+
dataType: "date";
|
|
898
|
+
columnType: "PgTimestamp";
|
|
899
|
+
data: Date;
|
|
900
|
+
driverParam: string;
|
|
901
|
+
notNull: true;
|
|
902
|
+
hasDefault: false;
|
|
903
|
+
isPrimaryKey: false;
|
|
904
|
+
isAutoincrement: false;
|
|
905
|
+
hasRuntimeDefault: false;
|
|
906
|
+
enumValues: undefined;
|
|
907
|
+
baseColumn: never;
|
|
908
|
+
identity: undefined;
|
|
909
|
+
generated: undefined;
|
|
910
|
+
}, {}, {}>;
|
|
911
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
912
|
+
name: "created_at";
|
|
913
|
+
tableName: "rate_limits";
|
|
914
|
+
dataType: "date";
|
|
915
|
+
columnType: "PgTimestamp";
|
|
916
|
+
data: Date;
|
|
917
|
+
driverParam: string;
|
|
918
|
+
notNull: true;
|
|
919
|
+
hasDefault: true;
|
|
920
|
+
isPrimaryKey: false;
|
|
921
|
+
isAutoincrement: false;
|
|
922
|
+
hasRuntimeDefault: false;
|
|
923
|
+
enumValues: undefined;
|
|
924
|
+
baseColumn: never;
|
|
925
|
+
identity: undefined;
|
|
926
|
+
generated: undefined;
|
|
927
|
+
}, {}, {}>;
|
|
928
|
+
updatedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
929
|
+
name: "updated_at";
|
|
930
|
+
tableName: "rate_limits";
|
|
931
|
+
dataType: "date";
|
|
932
|
+
columnType: "PgTimestamp";
|
|
933
|
+
data: Date;
|
|
934
|
+
driverParam: string;
|
|
935
|
+
notNull: true;
|
|
936
|
+
hasDefault: true;
|
|
937
|
+
isPrimaryKey: false;
|
|
938
|
+
isAutoincrement: false;
|
|
939
|
+
hasRuntimeDefault: false;
|
|
940
|
+
enumValues: undefined;
|
|
941
|
+
baseColumn: never;
|
|
942
|
+
identity: undefined;
|
|
943
|
+
generated: undefined;
|
|
944
|
+
}, {}, {}>;
|
|
945
|
+
};
|
|
946
|
+
dialect: "pg";
|
|
947
|
+
}>;
|
|
788
948
|
};
|
|
789
949
|
export declare function db(): NodePgDatabase<{
|
|
790
950
|
workspacesAdminCommandResults: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
@@ -953,6 +1113,23 @@ export declare function db(): NodePgDatabase<{
|
|
|
953
1113
|
identity: undefined;
|
|
954
1114
|
generated: undefined;
|
|
955
1115
|
}, {}, {}>;
|
|
1116
|
+
slug: import("drizzle-orm/pg-core").PgColumn<{
|
|
1117
|
+
name: "slug";
|
|
1118
|
+
tableName: "workspaces";
|
|
1119
|
+
dataType: "string";
|
|
1120
|
+
columnType: "PgText";
|
|
1121
|
+
data: string;
|
|
1122
|
+
driverParam: string;
|
|
1123
|
+
notNull: true;
|
|
1124
|
+
hasDefault: false;
|
|
1125
|
+
isPrimaryKey: false;
|
|
1126
|
+
isAutoincrement: false;
|
|
1127
|
+
hasRuntimeDefault: false;
|
|
1128
|
+
enumValues: [string, ...string[]];
|
|
1129
|
+
baseColumn: never;
|
|
1130
|
+
identity: undefined;
|
|
1131
|
+
generated: undefined;
|
|
1132
|
+
}, {}, {}>;
|
|
956
1133
|
status: import("drizzle-orm/pg-core").PgColumn<{
|
|
957
1134
|
name: "status";
|
|
958
1135
|
tableName: "workspaces";
|
|
@@ -1572,6 +1749,149 @@ export declare function db(): NodePgDatabase<{
|
|
|
1572
1749
|
};
|
|
1573
1750
|
dialect: "pg";
|
|
1574
1751
|
}>;
|
|
1752
|
+
workspacesRateLimits: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1753
|
+
name: "rate_limits";
|
|
1754
|
+
schema: undefined;
|
|
1755
|
+
columns: {
|
|
1756
|
+
action: import("drizzle-orm/pg-core").PgColumn<{
|
|
1757
|
+
name: "action";
|
|
1758
|
+
tableName: "rate_limits";
|
|
1759
|
+
dataType: "string";
|
|
1760
|
+
columnType: "PgText";
|
|
1761
|
+
data: string;
|
|
1762
|
+
driverParam: string;
|
|
1763
|
+
notNull: true;
|
|
1764
|
+
hasDefault: false;
|
|
1765
|
+
isPrimaryKey: false;
|
|
1766
|
+
isAutoincrement: false;
|
|
1767
|
+
hasRuntimeDefault: false;
|
|
1768
|
+
enumValues: [string, ...string[]];
|
|
1769
|
+
baseColumn: never;
|
|
1770
|
+
identity: undefined;
|
|
1771
|
+
generated: undefined;
|
|
1772
|
+
}, {}, {}>;
|
|
1773
|
+
scope: import("drizzle-orm/pg-core").PgColumn<{
|
|
1774
|
+
name: "scope";
|
|
1775
|
+
tableName: "rate_limits";
|
|
1776
|
+
dataType: "string";
|
|
1777
|
+
columnType: "PgText";
|
|
1778
|
+
data: string;
|
|
1779
|
+
driverParam: string;
|
|
1780
|
+
notNull: true;
|
|
1781
|
+
hasDefault: false;
|
|
1782
|
+
isPrimaryKey: false;
|
|
1783
|
+
isAutoincrement: false;
|
|
1784
|
+
hasRuntimeDefault: false;
|
|
1785
|
+
enumValues: [string, ...string[]];
|
|
1786
|
+
baseColumn: never;
|
|
1787
|
+
identity: undefined;
|
|
1788
|
+
generated: undefined;
|
|
1789
|
+
}, {}, {}>;
|
|
1790
|
+
identifierHmac: import("drizzle-orm/pg-core").PgColumn<{
|
|
1791
|
+
name: "identifier_hmac";
|
|
1792
|
+
tableName: "rate_limits";
|
|
1793
|
+
dataType: "string";
|
|
1794
|
+
columnType: "PgText";
|
|
1795
|
+
data: string;
|
|
1796
|
+
driverParam: string;
|
|
1797
|
+
notNull: true;
|
|
1798
|
+
hasDefault: false;
|
|
1799
|
+
isPrimaryKey: false;
|
|
1800
|
+
isAutoincrement: false;
|
|
1801
|
+
hasRuntimeDefault: false;
|
|
1802
|
+
enumValues: [string, ...string[]];
|
|
1803
|
+
baseColumn: never;
|
|
1804
|
+
identity: undefined;
|
|
1805
|
+
generated: undefined;
|
|
1806
|
+
}, {}, {}>;
|
|
1807
|
+
windowStart: import("drizzle-orm/pg-core").PgColumn<{
|
|
1808
|
+
name: "window_start";
|
|
1809
|
+
tableName: "rate_limits";
|
|
1810
|
+
dataType: "date";
|
|
1811
|
+
columnType: "PgTimestamp";
|
|
1812
|
+
data: Date;
|
|
1813
|
+
driverParam: string;
|
|
1814
|
+
notNull: true;
|
|
1815
|
+
hasDefault: false;
|
|
1816
|
+
isPrimaryKey: false;
|
|
1817
|
+
isAutoincrement: false;
|
|
1818
|
+
hasRuntimeDefault: false;
|
|
1819
|
+
enumValues: undefined;
|
|
1820
|
+
baseColumn: never;
|
|
1821
|
+
identity: undefined;
|
|
1822
|
+
generated: undefined;
|
|
1823
|
+
}, {}, {}>;
|
|
1824
|
+
count: import("drizzle-orm/pg-core").PgColumn<{
|
|
1825
|
+
name: "count";
|
|
1826
|
+
tableName: "rate_limits";
|
|
1827
|
+
dataType: "number";
|
|
1828
|
+
columnType: "PgInteger";
|
|
1829
|
+
data: number;
|
|
1830
|
+
driverParam: string | number;
|
|
1831
|
+
notNull: true;
|
|
1832
|
+
hasDefault: true;
|
|
1833
|
+
isPrimaryKey: false;
|
|
1834
|
+
isAutoincrement: false;
|
|
1835
|
+
hasRuntimeDefault: false;
|
|
1836
|
+
enumValues: undefined;
|
|
1837
|
+
baseColumn: never;
|
|
1838
|
+
identity: undefined;
|
|
1839
|
+
generated: undefined;
|
|
1840
|
+
}, {}, {}>;
|
|
1841
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1842
|
+
name: "expires_at";
|
|
1843
|
+
tableName: "rate_limits";
|
|
1844
|
+
dataType: "date";
|
|
1845
|
+
columnType: "PgTimestamp";
|
|
1846
|
+
data: Date;
|
|
1847
|
+
driverParam: string;
|
|
1848
|
+
notNull: true;
|
|
1849
|
+
hasDefault: false;
|
|
1850
|
+
isPrimaryKey: false;
|
|
1851
|
+
isAutoincrement: false;
|
|
1852
|
+
hasRuntimeDefault: false;
|
|
1853
|
+
enumValues: undefined;
|
|
1854
|
+
baseColumn: never;
|
|
1855
|
+
identity: undefined;
|
|
1856
|
+
generated: undefined;
|
|
1857
|
+
}, {}, {}>;
|
|
1858
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1859
|
+
name: "created_at";
|
|
1860
|
+
tableName: "rate_limits";
|
|
1861
|
+
dataType: "date";
|
|
1862
|
+
columnType: "PgTimestamp";
|
|
1863
|
+
data: Date;
|
|
1864
|
+
driverParam: string;
|
|
1865
|
+
notNull: true;
|
|
1866
|
+
hasDefault: true;
|
|
1867
|
+
isPrimaryKey: false;
|
|
1868
|
+
isAutoincrement: false;
|
|
1869
|
+
hasRuntimeDefault: false;
|
|
1870
|
+
enumValues: undefined;
|
|
1871
|
+
baseColumn: never;
|
|
1872
|
+
identity: undefined;
|
|
1873
|
+
generated: undefined;
|
|
1874
|
+
}, {}, {}>;
|
|
1875
|
+
updatedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1876
|
+
name: "updated_at";
|
|
1877
|
+
tableName: "rate_limits";
|
|
1878
|
+
dataType: "date";
|
|
1879
|
+
columnType: "PgTimestamp";
|
|
1880
|
+
data: Date;
|
|
1881
|
+
driverParam: string;
|
|
1882
|
+
notNull: true;
|
|
1883
|
+
hasDefault: true;
|
|
1884
|
+
isPrimaryKey: false;
|
|
1885
|
+
isAutoincrement: false;
|
|
1886
|
+
hasRuntimeDefault: false;
|
|
1887
|
+
enumValues: undefined;
|
|
1888
|
+
baseColumn: never;
|
|
1889
|
+
identity: undefined;
|
|
1890
|
+
generated: undefined;
|
|
1891
|
+
}, {}, {}>;
|
|
1892
|
+
};
|
|
1893
|
+
dialect: "pg";
|
|
1894
|
+
}>;
|
|
1575
1895
|
}>;
|
|
1576
1896
|
export declare function closeDb(): void;
|
|
1577
1897
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/db/db.d.ts.map
CHANGED
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AASnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOlB,CAAC;AAIF,wBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjB;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
|
package/dist/db/db.js
CHANGED
|
@@ -4,13 +4,15 @@ import { workspacesAdminCommandResults } from './schema/admin-command-results.js
|
|
|
4
4
|
import { invitations } from './schema/invitations.js';
|
|
5
5
|
import { memberships } from './schema/memberships.js';
|
|
6
6
|
import { workspacesOutbox } from './schema/outbox.js';
|
|
7
|
+
import { workspacesRateLimits } from './schema/rate-limits.js';
|
|
7
8
|
import { workspaces } from './schema/workspaces.js';
|
|
8
9
|
export const schema = {
|
|
9
10
|
workspacesAdminCommandResults,
|
|
10
11
|
workspaces,
|
|
11
12
|
memberships,
|
|
12
13
|
invitations,
|
|
13
|
-
workspacesOutbox
|
|
14
|
+
workspacesOutbox,
|
|
15
|
+
workspacesRateLimits
|
|
14
16
|
};
|
|
15
17
|
let _db;
|
|
16
18
|
export function db() {
|
package/dist/db/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/db.ts"],"sourcesContent":["import {drizzle, type NodePgDatabase} from '@shipfox/node-drizzle';\nimport {pgClient} from '@shipfox/node-postgres';\nimport {workspacesAdminCommandResults} from './schema/admin-command-results.js';\nimport {invitations} from './schema/invitations.js';\nimport {memberships} from './schema/memberships.js';\nimport {workspacesOutbox} from './schema/outbox.js';\nimport {workspaces} from './schema/workspaces.js';\n\nexport const schema = {\n workspacesAdminCommandResults,\n workspaces,\n memberships,\n invitations,\n workspacesOutbox,\n};\n\nlet _db: NodePgDatabase<typeof schema> | undefined;\n\nexport function db() {\n if (!_db) _db = drizzle(pgClient(), {schema});\n return _db;\n}\n\nexport function closeDb(): void {\n _db = undefined;\n}\n"],"names":["drizzle","pgClient","workspacesAdminCommandResults","invitations","memberships","workspacesOutbox","workspaces","schema","_db","db","closeDb","undefined"],"mappings":"AAAA,SAAQA,OAAO,QAA4B,wBAAwB;AACnE,SAAQC,QAAQ,QAAO,yBAAyB;AAChD,SAAQC,6BAA6B,QAAO,oCAAoC;AAChF,SAAQC,WAAW,QAAO,0BAA0B;AACpD,SAAQC,WAAW,QAAO,0BAA0B;AACpD,SAAQC,gBAAgB,QAAO,qBAAqB;AACpD,SAAQC,UAAU,QAAO,yBAAyB;AAElD,OAAO,MAAMC,SAAS;
|
|
1
|
+
{"version":3,"sources":["../../src/db/db.ts"],"sourcesContent":["import {drizzle, type NodePgDatabase} from '@shipfox/node-drizzle';\nimport {pgClient} from '@shipfox/node-postgres';\nimport {workspacesAdminCommandResults} from './schema/admin-command-results.js';\nimport {invitations} from './schema/invitations.js';\nimport {memberships} from './schema/memberships.js';\nimport {workspacesOutbox} from './schema/outbox.js';\nimport {workspacesRateLimits} from './schema/rate-limits.js';\nimport {workspaces} from './schema/workspaces.js';\n\nexport const schema = {\n workspacesAdminCommandResults,\n workspaces,\n memberships,\n invitations,\n workspacesOutbox,\n workspacesRateLimits,\n};\n\nlet _db: NodePgDatabase<typeof schema> | undefined;\n\nexport function db() {\n if (!_db) _db = drizzle(pgClient(), {schema});\n return _db;\n}\n\nexport function closeDb(): void {\n _db = undefined;\n}\n"],"names":["drizzle","pgClient","workspacesAdminCommandResults","invitations","memberships","workspacesOutbox","workspacesRateLimits","workspaces","schema","_db","db","closeDb","undefined"],"mappings":"AAAA,SAAQA,OAAO,QAA4B,wBAAwB;AACnE,SAAQC,QAAQ,QAAO,yBAAyB;AAChD,SAAQC,6BAA6B,QAAO,oCAAoC;AAChF,SAAQC,WAAW,QAAO,0BAA0B;AACpD,SAAQC,WAAW,QAAO,0BAA0B;AACpD,SAAQC,gBAAgB,QAAO,qBAAqB;AACpD,SAAQC,oBAAoB,QAAO,0BAA0B;AAC7D,SAAQC,UAAU,QAAO,yBAAyB;AAElD,OAAO,MAAMC,SAAS;IACpBN;IACAK;IACAH;IACAD;IACAE;IACAC;AACF,EAAE;AAEF,IAAIG;AAEJ,OAAO,SAASC;IACd,IAAI,CAACD,KAAKA,MAAMT,QAAQC,YAAY;QAACO;IAAM;IAC3C,OAAOC;AACT;AAEA,OAAO,SAASE;IACdF,MAAMG;AACR"}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -3,9 +3,12 @@ export type { CreateInvitationParams } from './invitations.js';
|
|
|
3
3
|
export { createInvitation, findInvitationByToken, listOpenInvitationsByWorkspace, revokeInvitation, } from './invitations.js';
|
|
4
4
|
export type { CreateMembershipParams, MembershipWithUser, MembershipWithWorkspace, RemoveMembershipParams, } from './memberships.js';
|
|
5
5
|
export { createMembership, findMembership, listMembershipsByUser, listMembershipsByWorkspace, removeMembership, } from './memberships.js';
|
|
6
|
+
export type { ConsumeWorkspacesRateLimitParams, ConsumeWorkspacesRateLimitResult, } from './rate-limits.js';
|
|
7
|
+
export { consumeWorkspacesRateLimit, pruneExpiredWorkspacesRateLimits, } from './rate-limits.js';
|
|
6
8
|
export { workspacesAdminCommandResults } from './schema/admin-command-results.js';
|
|
7
9
|
export { workspacesOutbox } from './schema/outbox.js';
|
|
10
|
+
export { workspacesRateLimits } from './schema/rate-limits.js';
|
|
8
11
|
export type { AdminWorkspaceRow, CreateWorkspaceParams, ListAdminWorkspaceParams, ListAdminWorkspaceResult, UpdateWorkspaceParams, WorkspaceServiceMetrics, } from './workspaces.js';
|
|
9
|
-
export { createWorkspace, getWorkspaceById, getWorkspaceServiceMetrics, listAdminWorkspaces, updateWorkspace, } from './workspaces.js';
|
|
12
|
+
export { createWorkspace, getWorkspaceById, getWorkspaceServiceMetrics, isWorkspaceSlugAvailable, listAdminWorkspaces, updateWorkspace, } from './workspaces.js';
|
|
10
13
|
export declare const migrationsPath: string;
|
|
11
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,8BAA8B,EAC9B,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,6BAA6B,EAAC,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,cAAc,QAAoE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,8BAA8B,EAC9B,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,6BAA6B,EAAC,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,EACxB,mBAAmB,EACnB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,cAAc,QAAoE,CAAC"}
|
package/dist/db/index.js
CHANGED
|
@@ -3,9 +3,11 @@ import { fileURLToPath } from 'node:url';
|
|
|
3
3
|
export { closeDb, db, schema } from './db.js';
|
|
4
4
|
export { createInvitation, findInvitationByToken, listOpenInvitationsByWorkspace, revokeInvitation } from './invitations.js';
|
|
5
5
|
export { createMembership, findMembership, listMembershipsByUser, listMembershipsByWorkspace, removeMembership } from './memberships.js';
|
|
6
|
+
export { consumeWorkspacesRateLimit, pruneExpiredWorkspacesRateLimits } from './rate-limits.js';
|
|
6
7
|
export { workspacesAdminCommandResults } from './schema/admin-command-results.js';
|
|
7
8
|
export { workspacesOutbox } from './schema/outbox.js';
|
|
8
|
-
export {
|
|
9
|
+
export { workspacesRateLimits } from './schema/rate-limits.js';
|
|
10
|
+
export { createWorkspace, getWorkspaceById, getWorkspaceServiceMetrics, isWorkspaceSlugAvailable, listAdminWorkspaces, updateWorkspace } from './workspaces.js';
|
|
9
11
|
export const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');
|
|
10
12
|
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {closeDb, db, schema} from './db.js';\nexport type {CreateInvitationParams} from './invitations.js';\nexport {\n createInvitation,\n findInvitationByToken,\n listOpenInvitationsByWorkspace,\n revokeInvitation,\n} from './invitations.js';\nexport type {\n CreateMembershipParams,\n MembershipWithUser,\n MembershipWithWorkspace,\n RemoveMembershipParams,\n} from './memberships.js';\nexport {\n createMembership,\n findMembership,\n listMembershipsByUser,\n listMembershipsByWorkspace,\n removeMembership,\n} from './memberships.js';\nexport {workspacesAdminCommandResults} from './schema/admin-command-results.js';\nexport {workspacesOutbox} from './schema/outbox.js';\nexport type {\n AdminWorkspaceRow,\n CreateWorkspaceParams,\n ListAdminWorkspaceParams,\n ListAdminWorkspaceResult,\n UpdateWorkspaceParams,\n WorkspaceServiceMetrics,\n} from './workspaces.js';\nexport {\n createWorkspace,\n getWorkspaceById,\n getWorkspaceServiceMetrics,\n listAdminWorkspaces,\n updateWorkspace,\n} from './workspaces.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","closeDb","db","schema","createInvitation","findInvitationByToken","listOpenInvitationsByWorkspace","revokeInvitation","createMembership","findMembership","listMembershipsByUser","listMembershipsByWorkspace","removeMembership","workspacesAdminCommandResults","workspacesOutbox","createWorkspace","getWorkspaceById","getWorkspaceServiceMetrics","listAdminWorkspaces","updateWorkspace","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAE5C,SACEC,gBAAgB,EAChBC,qBAAqB,EACrBC,8BAA8B,EAC9BC,gBAAgB,QACX,mBAAmB;AAO1B,SACEC,gBAAgB,EAChBC,cAAc,EACdC,qBAAqB,EACrBC,0BAA0B,EAC1BC,gBAAgB,QACX,mBAAmB;AAC1B,SAAQC,6BAA6B,QAAO,oCAAoC;AAChF,SAAQC,gBAAgB,QAAO,qBAAqB;
|
|
1
|
+
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {closeDb, db, schema} from './db.js';\nexport type {CreateInvitationParams} from './invitations.js';\nexport {\n createInvitation,\n findInvitationByToken,\n listOpenInvitationsByWorkspace,\n revokeInvitation,\n} from './invitations.js';\nexport type {\n CreateMembershipParams,\n MembershipWithUser,\n MembershipWithWorkspace,\n RemoveMembershipParams,\n} from './memberships.js';\nexport {\n createMembership,\n findMembership,\n listMembershipsByUser,\n listMembershipsByWorkspace,\n removeMembership,\n} from './memberships.js';\nexport type {\n ConsumeWorkspacesRateLimitParams,\n ConsumeWorkspacesRateLimitResult,\n} from './rate-limits.js';\nexport {\n consumeWorkspacesRateLimit,\n pruneExpiredWorkspacesRateLimits,\n} from './rate-limits.js';\nexport {workspacesAdminCommandResults} from './schema/admin-command-results.js';\nexport {workspacesOutbox} from './schema/outbox.js';\nexport {workspacesRateLimits} from './schema/rate-limits.js';\nexport type {\n AdminWorkspaceRow,\n CreateWorkspaceParams,\n ListAdminWorkspaceParams,\n ListAdminWorkspaceResult,\n UpdateWorkspaceParams,\n WorkspaceServiceMetrics,\n} from './workspaces.js';\nexport {\n createWorkspace,\n getWorkspaceById,\n getWorkspaceServiceMetrics,\n isWorkspaceSlugAvailable,\n listAdminWorkspaces,\n updateWorkspace,\n} from './workspaces.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","closeDb","db","schema","createInvitation","findInvitationByToken","listOpenInvitationsByWorkspace","revokeInvitation","createMembership","findMembership","listMembershipsByUser","listMembershipsByWorkspace","removeMembership","consumeWorkspacesRateLimit","pruneExpiredWorkspacesRateLimits","workspacesAdminCommandResults","workspacesOutbox","workspacesRateLimits","createWorkspace","getWorkspaceById","getWorkspaceServiceMetrics","isWorkspaceSlugAvailable","listAdminWorkspaces","updateWorkspace","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SAAQC,OAAO,EAAEC,EAAE,EAAEC,MAAM,QAAO,UAAU;AAE5C,SACEC,gBAAgB,EAChBC,qBAAqB,EACrBC,8BAA8B,EAC9BC,gBAAgB,QACX,mBAAmB;AAO1B,SACEC,gBAAgB,EAChBC,cAAc,EACdC,qBAAqB,EACrBC,0BAA0B,EAC1BC,gBAAgB,QACX,mBAAmB;AAK1B,SACEC,0BAA0B,EAC1BC,gCAAgC,QAC3B,mBAAmB;AAC1B,SAAQC,6BAA6B,QAAO,oCAAoC;AAChF,SAAQC,gBAAgB,QAAO,qBAAqB;AACpD,SAAQC,oBAAoB,QAAO,0BAA0B;AAS7D,SACEC,eAAe,EACfC,gBAAgB,EAChBC,0BAA0B,EAC1BC,wBAAwB,EACxBC,mBAAmB,EACnBC,eAAe,QACV,kBAAkB;AAEzB,OAAO,MAAMC,iBAAiBzB,QAAQD,QAAQE,cAAc,YAAYyB,GAAG,IAAI,iBAAiB"}
|
package/dist/db/memberships.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare function createMembership(params: CreateMembershipParams): Promis
|
|
|
22
22
|
export declare function ensureMembership(params: EnsureMembershipParams): Promise<Membership>;
|
|
23
23
|
export interface MembershipWithWorkspace extends Membership {
|
|
24
24
|
workspaceName: string;
|
|
25
|
+
workspaceSlug: string;
|
|
25
26
|
workspaceStatus: Workspace['status'];
|
|
26
27
|
}
|
|
27
28
|
export declare function listMembershipsByUser(params: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memberships.d.ts","sourceRoot":"","sources":["../../src/db/memberships.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,6BAA6B,CAAC;AAO3D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB;;;;;EAO9D;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAO1F;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAgB1F;AAED,MAAM,WAAW,uBAAwB,SAAQ,UAAU;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;CACtC;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"memberships.d.ts","sourceRoot":"","sources":["../../src/db/memberships.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,6BAA6B,CAAC;AAO3D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB;;;;;EAO9D;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAO1F;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAgB1F;AAED,MAAM,WAAW,uBAAwB,SAAQ,UAAU;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;CACtC;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAmBrC;AAED,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAOhC;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAYlC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBpF"}
|
package/dist/db/memberships.js
CHANGED
|
@@ -39,11 +39,13 @@ export async function listMembershipsByUser(params) {
|
|
|
39
39
|
const rows = await db().select({
|
|
40
40
|
membership: memberships,
|
|
41
41
|
workspaceName: workspaces.name,
|
|
42
|
+
workspaceSlug: workspaces.slug,
|
|
42
43
|
workspaceStatus: workspaces.status
|
|
43
44
|
}).from(memberships).innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId)).where(eq(memberships.userId, params.userId)).orderBy(workspaces.name);
|
|
44
45
|
return rows.map((row)=>({
|
|
45
46
|
...toMembership(row.membership),
|
|
46
47
|
workspaceName: row.workspaceName,
|
|
48
|
+
workspaceSlug: row.workspaceSlug,
|
|
47
49
|
workspaceStatus: row.workspaceStatus
|
|
48
50
|
}));
|
|
49
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/memberships.ts"],"sourcesContent":["import {and, eq, sql} from 'drizzle-orm';\nimport type {Membership} from '#core/entities/membership.js';\nimport type {Workspace} from '#core/entities/workspace.js';\nimport {LastMemberError} from '#core/errors.js';\nimport {recordWorkspaceMembershipChanged} from '#metrics/instance.js';\nimport {db} from './db.js';\nimport {memberships, toMembership} from './schema/memberships.js';\nimport {workspaces} from './schema/workspaces.js';\n\nexport interface CreateMembershipParams {\n userId: string;\n userEmail?: string | undefined;\n userName?: string | null | undefined;\n workspaceId: string;\n}\n\nexport interface EnsureMembershipParams {\n userId: string;\n userEmail: string;\n userName: string | null;\n workspaceId: string;\n}\n\nexport function membershipValues(params: CreateMembershipParams) {\n return {\n userId: params.userId,\n userEmail: params.userEmail ?? `user-${params.userId}@example.local`,\n userName: params.userName ?? null,\n workspaceId: params.workspaceId,\n };\n}\n\nexport async function createMembership(params: CreateMembershipParams): Promise<Membership> {\n const rows = await db().insert(memberships).values(membershipValues(params)).returning();\n\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n recordWorkspaceMembershipChanged('added');\n return toMembership(row);\n}\n\nexport async function ensureMembership(params: EnsureMembershipParams): Promise<Membership> {\n const rows = await db()\n .insert(memberships)\n .values(membershipValues(params))\n .onConflictDoNothing({target: [memberships.userId, memberships.workspaceId]})\n .returning();\n\n const row = rows[0];\n if (row) {\n recordWorkspaceMembershipChanged('added');\n return toMembership(row);\n }\n\n const existing = await findMembership(params);\n if (existing) return existing;\n throw new Error('Membership conflict returned no membership');\n}\n\nexport interface MembershipWithWorkspace extends Membership {\n workspaceName: string;\n workspaceStatus: Workspace['status'];\n}\n\nexport async function listMembershipsByUser(params: {\n userId: string;\n}): Promise<MembershipWithWorkspace[]> {\n const rows = await db()\n .select({\n membership: memberships,\n workspaceName: workspaces.name,\n workspaceStatus: workspaces.status,\n })\n .from(memberships)\n .innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId))\n .where(eq(memberships.userId, params.userId))\n .orderBy(workspaces.name);\n\n return rows.map((row) => ({\n ...toMembership(row.membership),\n workspaceName: row.workspaceName,\n workspaceStatus: row.workspaceStatus,\n }));\n}\n\nexport interface MembershipWithUser extends Membership {\n userEmail: string;\n userName: string | null;\n}\n\nexport async function listMembershipsByWorkspace(params: {\n workspaceId: string;\n}): Promise<MembershipWithUser[]> {\n const rows = await db()\n .select()\n .from(memberships)\n .where(eq(memberships.workspaceId, params.workspaceId));\n\n return rows.map(toMembership);\n}\n\nexport async function findMembership(params: {\n userId: string;\n workspaceId: string;\n}): Promise<Membership | undefined> {\n const rows = await db()\n .select()\n .from(memberships)\n .where(\n and(eq(memberships.userId, params.userId), eq(memberships.workspaceId, params.workspaceId)),\n )\n .limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toMembership(row);\n}\n\nexport interface RemoveMembershipParams {\n userId: string;\n workspaceId: string;\n}\n\nexport async function removeMembership(params: RemoveMembershipParams): Promise<void> {\n const removed = await db().transaction(async (tx) => {\n const countResult = await tx\n .select({count: sql<number>`count(*)::int`})\n .from(memberships)\n .where(eq(memberships.workspaceId, params.workspaceId));\n const total = countResult[0]?.count ?? 0;\n if (total <= 1) {\n throw new LastMemberError(params.workspaceId);\n }\n\n const deleted = await tx\n .delete(memberships)\n .where(\n and(eq(memberships.userId, params.userId), eq(memberships.workspaceId, params.workspaceId)),\n )\n .returning({id: memberships.id});\n\n return deleted.length > 0;\n });\n\n if (removed) recordWorkspaceMembershipChanged('removed');\n}\n"],"names":["and","eq","sql","LastMemberError","recordWorkspaceMembershipChanged","db","memberships","toMembership","workspaces","membershipValues","params","userId","userEmail","userName","workspaceId","createMembership","rows","insert","values","returning","row","Error","ensureMembership","onConflictDoNothing","target","existing","findMembership","listMembershipsByUser","select","membership","workspaceName","name","workspaceStatus","status","from","innerJoin","id","where","orderBy","map","listMembershipsByWorkspace","limit","undefined","removeMembership","removed","transaction","tx","countResult","count","total","deleted","delete","length"],"mappings":"AAAA,SAAQA,GAAG,EAAEC,EAAE,EAAEC,GAAG,QAAO,cAAc;AAGzC,SAAQC,eAAe,QAAO,kBAAkB;AAChD,SAAQC,gCAAgC,QAAO,uBAAuB;AACtE,SAAQC,EAAE,QAAO,UAAU;AAC3B,SAAQC,WAAW,EAAEC,YAAY,QAAO,0BAA0B;AAClE,SAAQC,UAAU,QAAO,yBAAyB;AAgBlD,OAAO,SAASC,iBAAiBC,MAA8B;IAC7D,OAAO;QACLC,QAAQD,OAAOC,MAAM;QACrBC,WAAWF,OAAOE,SAAS,IAAI,CAAC,KAAK,EAAEF,OAAOC,MAAM,CAAC,cAAc,CAAC;QACpEE,UAAUH,OAAOG,QAAQ,IAAI;QAC7BC,aAAaJ,OAAOI,WAAW;IACjC;AACF;AAEA,OAAO,eAAeC,iBAAiBL,MAA8B;IACnE,MAAMM,OAAO,MAAMX,KAAKY,MAAM,CAACX,aAAaY,MAAM,CAACT,iBAAiBC,SAASS,SAAS;IAEtF,MAAMC,MAAMJ,IAAI,CAAC,EAAE;IACnB,IAAI,CAACI,KAAK,MAAM,IAAIC,MAAM;IAC1BjB,iCAAiC;IACjC,OAAOG,aAAaa;AACtB;AAEA,OAAO,eAAeE,iBAAiBZ,MAA8B;IACnE,MAAMM,OAAO,MAAMX,KAChBY,MAAM,CAACX,aACPY,MAAM,CAACT,iBAAiBC,SACxBa,mBAAmB,CAAC;QAACC,QAAQ;YAAClB,YAAYK,MAAM;YAAEL,YAAYQ,WAAW;SAAC;IAAA,GAC1EK,SAAS;IAEZ,MAAMC,MAAMJ,IAAI,CAAC,EAAE;IACnB,IAAII,KAAK;QACPhB,iCAAiC;QACjC,OAAOG,aAAaa;IACtB;IAEA,MAAMK,WAAW,MAAMC,eAAehB;IACtC,IAAIe,UAAU,OAAOA;IACrB,MAAM,IAAIJ,MAAM;AAClB;
|
|
1
|
+
{"version":3,"sources":["../../src/db/memberships.ts"],"sourcesContent":["import {and, eq, sql} from 'drizzle-orm';\nimport type {Membership} from '#core/entities/membership.js';\nimport type {Workspace} from '#core/entities/workspace.js';\nimport {LastMemberError} from '#core/errors.js';\nimport {recordWorkspaceMembershipChanged} from '#metrics/instance.js';\nimport {db} from './db.js';\nimport {memberships, toMembership} from './schema/memberships.js';\nimport {workspaces} from './schema/workspaces.js';\n\nexport interface CreateMembershipParams {\n userId: string;\n userEmail?: string | undefined;\n userName?: string | null | undefined;\n workspaceId: string;\n}\n\nexport interface EnsureMembershipParams {\n userId: string;\n userEmail: string;\n userName: string | null;\n workspaceId: string;\n}\n\nexport function membershipValues(params: CreateMembershipParams) {\n return {\n userId: params.userId,\n userEmail: params.userEmail ?? `user-${params.userId}@example.local`,\n userName: params.userName ?? null,\n workspaceId: params.workspaceId,\n };\n}\n\nexport async function createMembership(params: CreateMembershipParams): Promise<Membership> {\n const rows = await db().insert(memberships).values(membershipValues(params)).returning();\n\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n recordWorkspaceMembershipChanged('added');\n return toMembership(row);\n}\n\nexport async function ensureMembership(params: EnsureMembershipParams): Promise<Membership> {\n const rows = await db()\n .insert(memberships)\n .values(membershipValues(params))\n .onConflictDoNothing({target: [memberships.userId, memberships.workspaceId]})\n .returning();\n\n const row = rows[0];\n if (row) {\n recordWorkspaceMembershipChanged('added');\n return toMembership(row);\n }\n\n const existing = await findMembership(params);\n if (existing) return existing;\n throw new Error('Membership conflict returned no membership');\n}\n\nexport interface MembershipWithWorkspace extends Membership {\n workspaceName: string;\n workspaceSlug: string;\n workspaceStatus: Workspace['status'];\n}\n\nexport async function listMembershipsByUser(params: {\n userId: string;\n}): Promise<MembershipWithWorkspace[]> {\n const rows = await db()\n .select({\n membership: memberships,\n workspaceName: workspaces.name,\n workspaceSlug: workspaces.slug,\n workspaceStatus: workspaces.status,\n })\n .from(memberships)\n .innerJoin(workspaces, eq(workspaces.id, memberships.workspaceId))\n .where(eq(memberships.userId, params.userId))\n .orderBy(workspaces.name);\n\n return rows.map((row) => ({\n ...toMembership(row.membership),\n workspaceName: row.workspaceName,\n workspaceSlug: row.workspaceSlug,\n workspaceStatus: row.workspaceStatus,\n }));\n}\n\nexport interface MembershipWithUser extends Membership {\n userEmail: string;\n userName: string | null;\n}\n\nexport async function listMembershipsByWorkspace(params: {\n workspaceId: string;\n}): Promise<MembershipWithUser[]> {\n const rows = await db()\n .select()\n .from(memberships)\n .where(eq(memberships.workspaceId, params.workspaceId));\n\n return rows.map(toMembership);\n}\n\nexport async function findMembership(params: {\n userId: string;\n workspaceId: string;\n}): Promise<Membership | undefined> {\n const rows = await db()\n .select()\n .from(memberships)\n .where(\n and(eq(memberships.userId, params.userId), eq(memberships.workspaceId, params.workspaceId)),\n )\n .limit(1);\n\n const row = rows[0];\n if (!row) return undefined;\n return toMembership(row);\n}\n\nexport interface RemoveMembershipParams {\n userId: string;\n workspaceId: string;\n}\n\nexport async function removeMembership(params: RemoveMembershipParams): Promise<void> {\n const removed = await db().transaction(async (tx) => {\n const countResult = await tx\n .select({count: sql<number>`count(*)::int`})\n .from(memberships)\n .where(eq(memberships.workspaceId, params.workspaceId));\n const total = countResult[0]?.count ?? 0;\n if (total <= 1) {\n throw new LastMemberError(params.workspaceId);\n }\n\n const deleted = await tx\n .delete(memberships)\n .where(\n and(eq(memberships.userId, params.userId), eq(memberships.workspaceId, params.workspaceId)),\n )\n .returning({id: memberships.id});\n\n return deleted.length > 0;\n });\n\n if (removed) recordWorkspaceMembershipChanged('removed');\n}\n"],"names":["and","eq","sql","LastMemberError","recordWorkspaceMembershipChanged","db","memberships","toMembership","workspaces","membershipValues","params","userId","userEmail","userName","workspaceId","createMembership","rows","insert","values","returning","row","Error","ensureMembership","onConflictDoNothing","target","existing","findMembership","listMembershipsByUser","select","membership","workspaceName","name","workspaceSlug","slug","workspaceStatus","status","from","innerJoin","id","where","orderBy","map","listMembershipsByWorkspace","limit","undefined","removeMembership","removed","transaction","tx","countResult","count","total","deleted","delete","length"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ConsumeRateLimitParams, type ConsumeRateLimitResult } from '@shipfox/node-rate-limit';
|
|
2
|
+
export type ConsumeWorkspacesRateLimitParams = ConsumeRateLimitParams<string, string>;
|
|
3
|
+
export type ConsumeWorkspacesRateLimitResult = ConsumeRateLimitResult;
|
|
4
|
+
export declare const consumeWorkspacesRateLimit: (params: ConsumeRateLimitParams<string, string>) => Promise<ConsumeRateLimitResult>;
|
|
5
|
+
export declare const pruneExpiredWorkspacesRateLimits: (params?: {
|
|
6
|
+
now?: Date | undefined;
|
|
7
|
+
minIntervalMs?: number | undefined;
|
|
8
|
+
}) => Promise<number | undefined>;
|
|
9
|
+
//# sourceMappingURL=rate-limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limits.d.ts","sourceRoot":"","sources":["../../src/db/rate-limits.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAE5B,MAAM,0BAA0B,CAAC;AAmDlC,MAAM,MAAM,gCAAgC,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtF,MAAM,MAAM,gCAAgC,GAAG,sBAAsB,CAAC;AACtE,eAAO,MAAM,0BAA0B,qFAAsB,CAAC;AAC9D,eAAO,MAAM,gCAAgC;;;iCAAoB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createRateLimitPersistence } from '@shipfox/node-rate-limit';
|
|
2
|
+
import { lt, sql } from 'drizzle-orm';
|
|
3
|
+
import { db } from './db.js';
|
|
4
|
+
import { workspacesRateLimits } from './schema/rate-limits.js';
|
|
5
|
+
const persistence = createRateLimitPersistence({
|
|
6
|
+
transaction: (callback)=>db().transaction(callback),
|
|
7
|
+
setStatementTimeout: async (transaction, timeoutMs)=>{
|
|
8
|
+
await transaction.execute(sql`select set_config('statement_timeout', ${`${timeoutMs}ms`}, true)`);
|
|
9
|
+
},
|
|
10
|
+
consume: async (transaction, params)=>{
|
|
11
|
+
const rows = await transaction.insert(workspacesRateLimits).values({
|
|
12
|
+
action: params.action,
|
|
13
|
+
scope: params.scope,
|
|
14
|
+
identifierHmac: params.identifierHmac,
|
|
15
|
+
windowStart: params.windowStart,
|
|
16
|
+
count: 1,
|
|
17
|
+
expiresAt: params.expiresAt
|
|
18
|
+
}).onConflictDoUpdate({
|
|
19
|
+
target: [
|
|
20
|
+
workspacesRateLimits.action,
|
|
21
|
+
workspacesRateLimits.scope,
|
|
22
|
+
workspacesRateLimits.identifierHmac,
|
|
23
|
+
workspacesRateLimits.windowStart
|
|
24
|
+
],
|
|
25
|
+
set: {
|
|
26
|
+
count: sql`${workspacesRateLimits.count} + 1`,
|
|
27
|
+
updatedAt: sql`now()`
|
|
28
|
+
}
|
|
29
|
+
}).returning({
|
|
30
|
+
count: workspacesRateLimits.count,
|
|
31
|
+
expiresAt: workspacesRateLimits.expiresAt
|
|
32
|
+
});
|
|
33
|
+
return rows[0];
|
|
34
|
+
},
|
|
35
|
+
prune: async (now)=>{
|
|
36
|
+
const result = await db().delete(workspacesRateLimits).where(lt(workspacesRateLimits.expiresAt, now));
|
|
37
|
+
return result.rowCount ?? 0;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
export const consumeWorkspacesRateLimit = persistence.consume;
|
|
41
|
+
export const pruneExpiredWorkspacesRateLimits = persistence.prune;
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=rate-limits.js.map
|