@baseworks/account 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { Command } from 'commander';
2
+ import { ApiClient } from '@baseworks/cli/client';
3
+ import { ContextManager } from '@baseworks/cli/context';
4
+
5
+ interface LoginResult {
6
+ token: string;
7
+ user: {
8
+ id: string;
9
+ email: string;
10
+ name: string | null;
11
+ } | null;
12
+ role: string | null;
13
+ org: {
14
+ slug: string;
15
+ id: string;
16
+ };
17
+ workspace: {
18
+ slug: string;
19
+ id: string;
20
+ };
21
+ project: {
22
+ slug: string;
23
+ id: string;
24
+ };
25
+ env: {
26
+ slug: string;
27
+ id: string;
28
+ };
29
+ }
30
+ interface AccountCliDeps {
31
+ http: ApiClient;
32
+ ctx: ContextManager<Record<string, string | undefined>>;
33
+ appBase: string;
34
+ apiBase: string;
35
+ cliName?: string;
36
+ onLoginSuccess: (result: LoginResult) => void;
37
+ }
38
+ declare function buildLoginCommand(deps: AccountCliDeps): Command;
39
+ declare function buildLogoutCommand(deps: AccountCliDeps): Command;
40
+ declare function buildWhoamiCommand(deps: AccountCliDeps): Command;
41
+ declare function buildMeCommand(deps: AccountCliDeps): Command;
42
+ declare function buildMembersCommand(deps: AccountCliDeps): Command;
43
+ declare function buildTokensCommand(deps: AccountCliDeps): Command;
44
+ declare function buildAccountCommand(deps: AccountCliDeps): Command;
45
+
46
+ export { type AccountCliDeps, type LoginResult, buildAccountCommand as accountCommand, buildAccountCommand, buildLoginCommand, buildLogoutCommand, buildMeCommand, buildMembersCommand, buildTokensCommand, buildWhoamiCommand };
package/dist/cli.js ADDED
@@ -0,0 +1,268 @@
1
+ // src/cli.ts
2
+ import { Command } from "commander";
3
+ import { clr, kv, table, success, warn, fatal, printOutput, outputOption } from "@baseworks/cli/display";
4
+ import { fmtDate } from "@baseworks/cli/fmt";
5
+ function buildLoginCommand(deps) {
6
+ const base = deps.apiBase.replace(/\/+$/, "");
7
+ const cmd = new Command("login").description("Log in via browser (OIDC)");
8
+ cmd.addCommand(
9
+ new Command("browser").description("Open browser for OIDC login (default)").action(async () => {
10
+ const { exec } = await import("child_process");
11
+ const startRes = await fetch(`${base}/v1/auth/start`);
12
+ if (!startRes.ok) fatal(`Auth start failed (${startRes.status})`);
13
+ const { state, url: authUrl } = await startRes.json();
14
+ warn(`Login URL: ${clr.cyan}${authUrl}${clr.reset}`);
15
+ warn("Opening browser\u2026");
16
+ const opener = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
17
+ exec(`${opener} "${authUrl}"`);
18
+ warn("Waiting for browser login\u2026 (Ctrl+C to cancel)");
19
+ let token;
20
+ const deadline = Date.now() + 3e5;
21
+ const startedAt = Date.now();
22
+ let attempt = 0;
23
+ while (Date.now() < deadline) {
24
+ await new Promise((r) => setTimeout(r, attempt < 10 ? 1e3 : 2e3));
25
+ attempt++;
26
+ try {
27
+ const pollRes = await fetch(`${base}/v1/auth/poll/${state}`);
28
+ if (!pollRes.ok) continue;
29
+ const body = await pollRes.json();
30
+ if (body.status === "done" && body.token) {
31
+ token = body.token;
32
+ break;
33
+ }
34
+ if (body.status === "expired") fatal("Auth session expired \u2014 run login again.");
35
+ } catch {
36
+ }
37
+ if (attempt % 5 === 0) {
38
+ const elapsed = Math.round((Date.now() - startedAt) / 1e3);
39
+ process.stderr.write(`\r Waiting for browser\u2026 ${elapsed}s`);
40
+ }
41
+ }
42
+ if (!token) {
43
+ process.stderr.write("\n");
44
+ fatal("Login timed out.");
45
+ }
46
+ process.stderr.write("\n");
47
+ const meRes = await fetch(`${base}/v1/account/me`, { headers: { Authorization: `Bearer ${token}` } });
48
+ if (!meRes.ok) fatal(`Failed to fetch user info (${meRes.status})`);
49
+ const me = await meRes.json();
50
+ const orgSlug = me.org.slug;
51
+ let ws = { id: "", slug: "default" };
52
+ let prj = { id: "", slug: "default" };
53
+ let env = { id: "", slug: "production" };
54
+ try {
55
+ const headers = { Authorization: `Bearer ${token}` };
56
+ const wsRes = await fetch(`${base}/v1/orgs/${orgSlug}/workspaces`, { headers });
57
+ if (wsRes.ok) {
58
+ const b = await wsRes.json();
59
+ if (b.workspaces[0]) ws = b.workspaces[0];
60
+ }
61
+ if (ws.id) {
62
+ const prjRes = await fetch(`${base}/v1/orgs/${orgSlug}/workspaces/${ws.slug}/projects`, { headers });
63
+ if (prjRes.ok) {
64
+ const b = await prjRes.json();
65
+ if (b.projects[0]) prj = b.projects[0];
66
+ }
67
+ }
68
+ if (prj.id) {
69
+ const envRes = await fetch(`${base}/v1/orgs/${orgSlug}/workspaces/${ws.slug}/projects/${prj.slug}/envs`, { headers });
70
+ if (envRes.ok) {
71
+ const b = await envRes.json();
72
+ if (b.envs[0]) env = b.envs[0];
73
+ }
74
+ }
75
+ } catch {
76
+ }
77
+ const result = {
78
+ token,
79
+ user: me.user,
80
+ role: me.role,
81
+ org: { id: me.org.id, slug: orgSlug },
82
+ workspace: ws,
83
+ project: prj,
84
+ env
85
+ };
86
+ deps.onLoginSuccess(result);
87
+ success("Logged in.");
88
+ const rows = [];
89
+ if (result.user) {
90
+ rows.push(["user", result.user.email], ["role", result.role ?? "\u2014"]);
91
+ }
92
+ rows.push(
93
+ ["org", result.org.slug],
94
+ ["workspace", result.workspace.slug],
95
+ ["project", result.project.slug],
96
+ ["env", result.env.slug],
97
+ ["token", token.slice(0, 14) + "\u2026"]
98
+ );
99
+ kv(rows);
100
+ })
101
+ );
102
+ cmd.action(async () => {
103
+ const sub = cmd.commands.find((c) => c.name() === "browser");
104
+ await sub.parseAsync([], { from: "user" });
105
+ });
106
+ return cmd;
107
+ }
108
+ function buildLogoutCommand(deps) {
109
+ const { ctx } = deps;
110
+ return new Command("logout").description("Remove saved token and clear active context").option("--all", "Remove all stored org tokens").action((opts) => {
111
+ const cfg = ctx.loadConfig();
112
+ if (opts.all) {
113
+ delete cfg["orgs"];
114
+ delete cfg["activeOrg"];
115
+ } else {
116
+ const activeOrg = cfg["activeOrg"];
117
+ const orgs = cfg["orgs"];
118
+ if (activeOrg && orgs) {
119
+ delete orgs[activeOrg];
120
+ if (Object.keys(orgs).length === 0) delete cfg["orgs"];
121
+ }
122
+ delete cfg["activeOrg"];
123
+ }
124
+ ctx.clearContext();
125
+ ctx.saveConfig(cfg);
126
+ success(opts.all ? "All tokens removed." : "Logged out.");
127
+ });
128
+ }
129
+ function buildWhoamiCommand(deps) {
130
+ const { ctx } = deps;
131
+ const cli = deps.cliName ?? "cli";
132
+ return new Command("whoami").alias("wh").description("Show active token and context").action(() => {
133
+ const cfg = ctx.loadConfig();
134
+ const activeOrg = cfg["activeOrg"];
135
+ const orgs = cfg["orgs"];
136
+ const token = (activeOrg && orgs?.[activeOrg]?.token) ?? cfg["token"];
137
+ if (!token) {
138
+ warn(`No token set. Run: ${cli} login`);
139
+ return;
140
+ }
141
+ const rows = [["token", clr.cyan + token.slice(0, 14) + "\u2026" + clr.reset]];
142
+ if (activeOrg) rows.push(["org", clr.bold + activeOrg + clr.reset]);
143
+ if (orgs && Object.keys(orgs).length > 1) {
144
+ rows.push(["other orgs", clr.dim + Object.keys(orgs).filter((s) => s !== activeOrg).join(", ") + clr.reset]);
145
+ }
146
+ kv(rows);
147
+ });
148
+ }
149
+ function buildMeCommand(deps) {
150
+ const { http } = deps;
151
+ const cli = deps.cliName ?? "cli";
152
+ return new Command("me").description("Current user and org membership").option(...outputOption()).action(async (opts) => {
153
+ const res = await http.get("/v1/account/me").catch((e) => {
154
+ console.error(e.message);
155
+ process.exit(1);
156
+ });
157
+ if (!res.user) {
158
+ warn(`Org-level token (no user identity). Run: ${cli} login`);
159
+ kv([["org_id", res.org.id]]);
160
+ return;
161
+ }
162
+ printOutput(res, opts.output, () => kv([
163
+ ["email", res.user.email],
164
+ ["name", res.user.name ?? "\u2014"],
165
+ ["role", clr.bold + (res.role ?? "\u2014") + clr.reset],
166
+ ["org", res.org.slug ?? res.org.id],
167
+ ["user_id", res.user.id]
168
+ ]));
169
+ });
170
+ }
171
+ function buildMembersCommand(deps) {
172
+ const { http } = deps;
173
+ const cmd = new Command("members").alias("member").description("Org member management").enablePositionalOptions().option(...outputOption()).action(async (opts) => {
174
+ const res = await http.get("/v1/account/members").catch((e) => {
175
+ console.error(e.message);
176
+ process.exit(1);
177
+ });
178
+ printOutput(res.members, opts.output, (wide) => {
179
+ table(res.members, [
180
+ { key: "email", label: "EMAIL" },
181
+ { key: "name", label: "NAME", fmt: (v) => v ?? "\u2014" },
182
+ { key: "role", label: "ROLE" },
183
+ { key: "joinedAt", label: "JOINED", fmt: (v) => fmtDate(v), wide: true },
184
+ { key: "userId", label: "USER ID", wide: true }
185
+ ], { wide, emptyHint: `No members yet.` });
186
+ }, "email");
187
+ });
188
+ cmd.addCommand(
189
+ new Command("role").argument("<ref>").argument("<role>").description("Change member role (admin+). ref = email or userId").action(async (ref, role) => {
190
+ await http.patch(`/v1/account/members/${ref}/role`, { role }).catch((e) => {
191
+ console.error(e.message);
192
+ process.exit(1);
193
+ });
194
+ success(`Role updated \u2192 ${role}`);
195
+ })
196
+ );
197
+ cmd.addCommand(
198
+ new Command("remove").argument("<ref>").description("Remove member from org (admin+). ref = email or userId").action(async (ref) => {
199
+ await http.del(`/v1/account/members/${ref}`).catch((e) => {
200
+ console.error(e.message);
201
+ process.exit(1);
202
+ });
203
+ success("Member removed.");
204
+ })
205
+ );
206
+ return cmd;
207
+ }
208
+ function buildTokensCommand(deps) {
209
+ const { http } = deps;
210
+ const cmd = new Command("tokens").alias("token").description("API token management").enablePositionalOptions().option(...outputOption()).action(async (opts) => {
211
+ const res = await http.get("/v1/account/me/tokens").catch((e) => {
212
+ console.error(e.message);
213
+ process.exit(1);
214
+ });
215
+ printOutput(res.tokens, opts.output, (wide) => {
216
+ table(res.tokens, [
217
+ { key: "keyPrefix", label: "PREFIX" },
218
+ { key: "name", label: "NAME" },
219
+ { key: "lastUsedAt", label: "LAST USED", fmt: (v) => fmtDate(v) },
220
+ { key: "createdAt", label: "CREATED", fmt: (v) => fmtDate(v), wide: true },
221
+ { key: "id", label: "FULL ID", wide: true }
222
+ ], { wide, emptyHint: "No tokens." });
223
+ }, "keyPrefix");
224
+ });
225
+ cmd.addCommand(
226
+ new Command("create").description("Create a new API token").requiredOption("--name <name>", "Token name").action(async (opts) => {
227
+ const res = await http.post("/v1/account/me/tokens", { name: opts.name }).catch((e) => {
228
+ console.error(e.message);
229
+ process.exit(1);
230
+ });
231
+ success("Token created \u2014 save it now, it will not be shown again:");
232
+ console.log(`
233
+ ${clr.cyan}${clr.bold}${res.token.raw}${clr.reset}
234
+ `);
235
+ kv([["prefix", res.token.keyPrefix], ["name", res.token.name]]);
236
+ })
237
+ );
238
+ cmd.addCommand(
239
+ new Command("revoke").argument("<ref>").description("Revoke a token. ref = prefix or full id").action(async (ref) => {
240
+ await http.del(`/v1/account/me/tokens/${ref}`).catch((e) => {
241
+ console.error(e.message);
242
+ process.exit(1);
243
+ });
244
+ success(`Token ${ref} revoked.`);
245
+ })
246
+ );
247
+ return cmd;
248
+ }
249
+ function buildAccountCommand(deps) {
250
+ const cmd = new Command("account").alias("acc").description("Identity, members, and token management");
251
+ cmd.addCommand(buildLoginCommand(deps));
252
+ cmd.addCommand(buildLogoutCommand(deps));
253
+ cmd.addCommand(buildWhoamiCommand(deps));
254
+ cmd.addCommand(buildMeCommand(deps));
255
+ cmd.addCommand(buildMembersCommand(deps));
256
+ cmd.addCommand(buildTokensCommand(deps));
257
+ return cmd;
258
+ }
259
+ export {
260
+ buildAccountCommand as accountCommand,
261
+ buildAccountCommand,
262
+ buildLoginCommand,
263
+ buildLogoutCommand,
264
+ buildMeCommand,
265
+ buildMembersCommand,
266
+ buildTokensCommand,
267
+ buildWhoamiCommand
268
+ };
@@ -0,0 +1,91 @@
1
+ import { O as OrgRole } from './memberships-Re0HbIz4.js';
2
+ import 'drizzle-orm/pg-core';
3
+
4
+ interface User {
5
+ id: string;
6
+ subject: string;
7
+ issuer: string;
8
+ email: string;
9
+ name: string | null;
10
+ picture: string | null;
11
+ createdAt: number;
12
+ updatedAt: number;
13
+ }
14
+ interface OrgMembership {
15
+ id: string;
16
+ userId: string;
17
+ organizationId: string;
18
+ role: string;
19
+ createdAt: number;
20
+ updatedAt: number;
21
+ }
22
+ interface ApiToken {
23
+ id: string;
24
+ organizationId: string;
25
+ userId: string | null;
26
+ name: string;
27
+ tokenHash: string;
28
+ keyPrefix: string;
29
+ scopes: string;
30
+ lastUsedAt: number | null;
31
+ expiresAt: number | null;
32
+ revokedAt: number | null;
33
+ createdAt: number;
34
+ updatedAt: number;
35
+ }
36
+ interface OidcIdentity {
37
+ subject: string;
38
+ issuer: string;
39
+ email: string;
40
+ name?: string;
41
+ picture?: string;
42
+ }
43
+
44
+ type AnyDB$2 = any;
45
+ declare function createUserRepo(db: AnyDB$2, schema: {
46
+ users: any;
47
+ }): {
48
+ upsert(identity: OidcIdentity): Promise<User>;
49
+ findById(id: string): Promise<User | undefined>;
50
+ findBySubject(issuer: string, subject: string): Promise<User | undefined>;
51
+ findByEmail(email: string): Promise<User | undefined>;
52
+ };
53
+ type UserRepo = ReturnType<typeof createUserRepo>;
54
+
55
+ type AnyDB$1 = any;
56
+ declare function createOrgMembershipRepo(db: AnyDB$1, schema: {
57
+ orgMemberships: any;
58
+ }): {
59
+ add(userId: string, organizationId: string, role: OrgRole): Promise<OrgMembership>;
60
+ updateRole(userId: string, organizationId: string, role: OrgRole): Promise<void>;
61
+ remove(userId: string, organizationId: string): Promise<void>;
62
+ find(userId: string, organizationId: string): Promise<OrgMembership | undefined>;
63
+ listByUser(userId: string): Promise<OrgMembership[]>;
64
+ listByOrg(organizationId: string): Promise<OrgMembership[]>;
65
+ firstForUser(userId: string): Promise<OrgMembership | undefined>;
66
+ };
67
+ type OrgMembershipRepo = ReturnType<typeof createOrgMembershipRepo>;
68
+
69
+ type AnyDB = any;
70
+ declare function createApiTokenRepo(db: AnyDB, schema: {
71
+ apiTokens: any;
72
+ }): {
73
+ create(data: {
74
+ organizationId: string;
75
+ name: string;
76
+ tokenHash: string;
77
+ keyPrefix: string;
78
+ userId?: string;
79
+ scopes?: string[];
80
+ expiresAt?: number;
81
+ }): Promise<ApiToken>;
82
+ findByHash(tokenHash: string): Promise<ApiToken | undefined>;
83
+ touch(id: string): Promise<void>;
84
+ revoke(id: string): Promise<void>;
85
+ listByOrg(organizationId: string): Promise<ApiToken[]>;
86
+ listByUser(userId: string): Promise<ApiToken[]>;
87
+ countActive(organizationId: string, userId?: string): Promise<number>;
88
+ };
89
+ type ApiTokenRepo = ReturnType<typeof createApiTokenRepo>;
90
+
91
+ export { type ApiToken, type ApiTokenRepo, type OidcIdentity, type OrgMembership, type OrgMembershipRepo, OrgRole, type User, type UserRepo, createApiTokenRepo, createOrgMembershipRepo, createUserRepo };
package/dist/index.js ADDED
@@ -0,0 +1,135 @@
1
+ // src/repo/users.ts
2
+ import { and, eq } from "drizzle-orm";
3
+ import { generateId } from "@baseworks/core";
4
+ function createUserRepo(db, schema) {
5
+ const { users } = schema;
6
+ return {
7
+ async upsert(identity) {
8
+ const now = Date.now();
9
+ const existing = await db.select().from(users).where(and(eq(users.subject, identity.subject), eq(users.issuer, identity.issuer))).limit(1).then((r) => r[0]);
10
+ if (existing) {
11
+ await db.update(users).set({ email: identity.email, name: identity.name ?? null, picture: identity.picture ?? null, updatedAt: now }).where(eq(users.id, existing.id));
12
+ return { ...existing, email: identity.email, name: identity.name ?? null, picture: identity.picture ?? null, updatedAt: now };
13
+ }
14
+ const row = {
15
+ id: generateId(),
16
+ subject: identity.subject,
17
+ issuer: identity.issuer,
18
+ email: identity.email,
19
+ name: identity.name ?? null,
20
+ picture: identity.picture ?? null,
21
+ createdAt: now,
22
+ updatedAt: now
23
+ };
24
+ await db.insert(users).values(row);
25
+ return row;
26
+ },
27
+ async findById(id) {
28
+ const rows = await db.select().from(users).where(eq(users.id, id)).limit(1);
29
+ return rows[0];
30
+ },
31
+ async findBySubject(issuer, subject) {
32
+ const rows = await db.select().from(users).where(and(eq(users.issuer, issuer), eq(users.subject, subject))).limit(1);
33
+ return rows[0];
34
+ },
35
+ async findByEmail(email) {
36
+ const rows = await db.select().from(users).where(eq(users.email, email)).limit(1);
37
+ return rows[0];
38
+ }
39
+ };
40
+ }
41
+
42
+ // src/repo/memberships.ts
43
+ import { and as and2, eq as eq2 } from "drizzle-orm";
44
+ import { generateId as generateId2 } from "@baseworks/core";
45
+ function createOrgMembershipRepo(db, schema) {
46
+ const { orgMemberships } = schema;
47
+ return {
48
+ async add(userId, organizationId, role) {
49
+ const now = Date.now();
50
+ const row = { id: generateId2(), userId, organizationId, role, createdAt: now, updatedAt: now };
51
+ await db.insert(orgMemberships).values(row).onConflictDoNothing();
52
+ return row;
53
+ },
54
+ async updateRole(userId, organizationId, role) {
55
+ await db.update(orgMemberships).set({ role, updatedAt: Date.now() }).where(and2(eq2(orgMemberships.userId, userId), eq2(orgMemberships.organizationId, organizationId)));
56
+ },
57
+ async remove(userId, organizationId) {
58
+ await db.delete(orgMemberships).where(and2(eq2(orgMemberships.userId, userId), eq2(orgMemberships.organizationId, organizationId)));
59
+ },
60
+ async find(userId, organizationId) {
61
+ const rows = await db.select().from(orgMemberships).where(and2(eq2(orgMemberships.userId, userId), eq2(orgMemberships.organizationId, organizationId))).limit(1);
62
+ return rows[0];
63
+ },
64
+ async listByUser(userId) {
65
+ return db.select().from(orgMemberships).where(eq2(orgMemberships.userId, userId));
66
+ },
67
+ async listByOrg(organizationId) {
68
+ return db.select().from(orgMemberships).where(eq2(orgMemberships.organizationId, organizationId));
69
+ },
70
+ async firstForUser(userId) {
71
+ const rows = await db.select().from(orgMemberships).where(eq2(orgMemberships.userId, userId)).limit(1);
72
+ return rows[0];
73
+ }
74
+ };
75
+ }
76
+
77
+ // src/repo/api-tokens.ts
78
+ import { and as and3, eq as eq3, isNull } from "drizzle-orm";
79
+ import { generateId as generateId3 } from "@baseworks/core";
80
+ function createApiTokenRepo(db, schema) {
81
+ const { apiTokens } = schema;
82
+ return {
83
+ async create(data) {
84
+ const now = Date.now();
85
+ const row = {
86
+ id: generateId3(),
87
+ organizationId: data.organizationId,
88
+ userId: data.userId ?? null,
89
+ name: data.name,
90
+ tokenHash: data.tokenHash,
91
+ keyPrefix: data.keyPrefix,
92
+ scopes: JSON.stringify(data.scopes ?? []),
93
+ lastUsedAt: null,
94
+ expiresAt: data.expiresAt ?? null,
95
+ revokedAt: null,
96
+ createdAt: now,
97
+ updatedAt: now
98
+ };
99
+ await db.insert(apiTokens).values(row);
100
+ return row;
101
+ },
102
+ async findByHash(tokenHash) {
103
+ const rows = await db.select().from(apiTokens).where(and3(eq3(apiTokens.tokenHash, tokenHash), isNull(apiTokens.revokedAt))).limit(1);
104
+ return rows[0];
105
+ },
106
+ async touch(id) {
107
+ await db.update(apiTokens).set({ lastUsedAt: Date.now(), updatedAt: Date.now() }).where(eq3(apiTokens.id, id));
108
+ },
109
+ async revoke(id) {
110
+ const now = Date.now();
111
+ await db.update(apiTokens).set({ revokedAt: now, updatedAt: now }).where(eq3(apiTokens.id, id));
112
+ },
113
+ async listByOrg(organizationId) {
114
+ return db.select().from(apiTokens).where(and3(eq3(apiTokens.organizationId, organizationId), isNull(apiTokens.revokedAt)));
115
+ },
116
+ async listByUser(userId) {
117
+ return db.select().from(apiTokens).where(and3(eq3(apiTokens.userId, userId), isNull(apiTokens.revokedAt)));
118
+ },
119
+ async countActive(organizationId, userId) {
120
+ const rows = await db.select({ id: apiTokens.id }).from(apiTokens).where(
121
+ and3(
122
+ eq3(apiTokens.organizationId, organizationId),
123
+ isNull(apiTokens.revokedAt),
124
+ userId ? eq3(apiTokens.userId, userId) : isNull(apiTokens.userId)
125
+ )
126
+ );
127
+ return rows.length;
128
+ }
129
+ };
130
+ }
131
+ export {
132
+ createApiTokenRepo,
133
+ createOrgMembershipRepo,
134
+ createUserRepo
135
+ };
@@ -0,0 +1,117 @@
1
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
2
+
3
+ declare const OrgRoles: readonly ["admin", "member", "viewer"];
4
+ type OrgRole = typeof OrgRoles[number];
5
+ declare const orgMemberships: drizzle_orm_pg_core.PgTableWithColumns<{
6
+ name: "org_memberships";
7
+ schema: undefined;
8
+ columns: {
9
+ id: drizzle_orm_pg_core.PgColumn<{
10
+ name: "id";
11
+ tableName: "org_memberships";
12
+ dataType: "string";
13
+ columnType: "PgText";
14
+ data: string;
15
+ driverParam: string;
16
+ notNull: true;
17
+ hasDefault: false;
18
+ isPrimaryKey: true;
19
+ isAutoincrement: false;
20
+ hasRuntimeDefault: false;
21
+ enumValues: [string, ...string[]];
22
+ baseColumn: never;
23
+ identity: undefined;
24
+ generated: undefined;
25
+ }, {}, {}>;
26
+ userId: drizzle_orm_pg_core.PgColumn<{
27
+ name: "user_id";
28
+ tableName: "org_memberships";
29
+ dataType: "string";
30
+ columnType: "PgText";
31
+ data: string;
32
+ driverParam: string;
33
+ notNull: true;
34
+ hasDefault: false;
35
+ isPrimaryKey: false;
36
+ isAutoincrement: false;
37
+ hasRuntimeDefault: false;
38
+ enumValues: [string, ...string[]];
39
+ baseColumn: never;
40
+ identity: undefined;
41
+ generated: undefined;
42
+ }, {}, {}>;
43
+ organizationId: drizzle_orm_pg_core.PgColumn<{
44
+ name: "organization_id";
45
+ tableName: "org_memberships";
46
+ dataType: "string";
47
+ columnType: "PgText";
48
+ data: string;
49
+ driverParam: string;
50
+ notNull: true;
51
+ hasDefault: false;
52
+ isPrimaryKey: false;
53
+ isAutoincrement: false;
54
+ hasRuntimeDefault: false;
55
+ enumValues: [string, ...string[]];
56
+ baseColumn: never;
57
+ identity: undefined;
58
+ generated: undefined;
59
+ }, {}, {}>;
60
+ role: drizzle_orm_pg_core.PgColumn<{
61
+ name: "role";
62
+ tableName: "org_memberships";
63
+ dataType: "string";
64
+ columnType: "PgText";
65
+ data: "admin" | "member" | "viewer";
66
+ driverParam: string;
67
+ notNull: true;
68
+ hasDefault: false;
69
+ isPrimaryKey: false;
70
+ isAutoincrement: false;
71
+ hasRuntimeDefault: false;
72
+ enumValues: [string, ...string[]];
73
+ baseColumn: never;
74
+ identity: undefined;
75
+ generated: undefined;
76
+ }, {}, {
77
+ $type: "admin" | "member" | "viewer";
78
+ }>;
79
+ createdAt: drizzle_orm_pg_core.PgColumn<{
80
+ name: "created_at";
81
+ tableName: "org_memberships";
82
+ dataType: "number";
83
+ columnType: "PgBigInt53";
84
+ data: number;
85
+ driverParam: string | number;
86
+ notNull: true;
87
+ hasDefault: false;
88
+ isPrimaryKey: false;
89
+ isAutoincrement: false;
90
+ hasRuntimeDefault: false;
91
+ enumValues: undefined;
92
+ baseColumn: never;
93
+ identity: undefined;
94
+ generated: undefined;
95
+ }, {}, {}>;
96
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
97
+ name: "updated_at";
98
+ tableName: "org_memberships";
99
+ dataType: "number";
100
+ columnType: "PgBigInt53";
101
+ data: number;
102
+ driverParam: string | number;
103
+ notNull: true;
104
+ hasDefault: false;
105
+ isPrimaryKey: false;
106
+ isAutoincrement: false;
107
+ hasRuntimeDefault: false;
108
+ enumValues: undefined;
109
+ baseColumn: never;
110
+ identity: undefined;
111
+ generated: undefined;
112
+ }, {}, {}>;
113
+ };
114
+ dialect: "pg";
115
+ }>;
116
+
117
+ export { type OrgRole as O, OrgRoles as a, orgMemberships as o };