@holeauth/idp-drizzle 0.0.1-alpha.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/LICENSE +21 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/pg/index.cjs +415 -0
- package/dist/pg/index.cjs.map +1 -0
- package/dist/pg/index.d.cts +981 -0
- package/dist/pg/index.d.ts +981 -0
- package/dist/pg/index.js +412 -0
- package/dist/pg/index.js.map +1 -0
- package/package.json +65 -0
package/dist/pg/index.js
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { pgTable, timestamp, text, index, primaryKey, boolean, uniqueIndex, jsonb } from 'drizzle-orm/pg-core';
|
|
2
|
+
import { relations, eq, desc, and, sql } from 'drizzle-orm';
|
|
3
|
+
|
|
4
|
+
// src/pg/index.ts
|
|
5
|
+
function createIdpTables(opts) {
|
|
6
|
+
const { usersTable, prefix = "holeauth_idp_" } = opts;
|
|
7
|
+
const p = (s) => `${prefix}${s}`;
|
|
8
|
+
const teams = pgTable(p("team"), {
|
|
9
|
+
id: text("id").primaryKey(),
|
|
10
|
+
name: text("name").notNull(),
|
|
11
|
+
createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }).notNull().defaultNow()
|
|
12
|
+
});
|
|
13
|
+
const teamMembers = pgTable(
|
|
14
|
+
p("team_member"),
|
|
15
|
+
{
|
|
16
|
+
teamId: text("team_id").notNull().references(() => teams.id, { onDelete: "cascade" }),
|
|
17
|
+
userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
|
|
18
|
+
role: text("role").notNull().$type(),
|
|
19
|
+
addedAt: timestamp("added_at", { withTimezone: true, mode: "date" }).notNull().defaultNow()
|
|
20
|
+
},
|
|
21
|
+
(t) => ({
|
|
22
|
+
pk: primaryKey({ columns: [t.teamId, t.userId] }),
|
|
23
|
+
userIdx: index().on(t.userId)
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
const apps = pgTable(
|
|
27
|
+
p("app"),
|
|
28
|
+
{
|
|
29
|
+
id: text("id").primaryKey(),
|
|
30
|
+
teamId: text("team_id").notNull().references(() => teams.id, { onDelete: "cascade" }),
|
|
31
|
+
name: text("name").notNull(),
|
|
32
|
+
description: text("description"),
|
|
33
|
+
logoUrl: text("logo_url"),
|
|
34
|
+
type: text("type").notNull().$type(),
|
|
35
|
+
clientSecretHash: text("client_secret_hash"),
|
|
36
|
+
redirectUris: text("redirect_uris").array().notNull().default([]),
|
|
37
|
+
allowedScopes: text("allowed_scopes").array().notNull().default([]),
|
|
38
|
+
requirePkce: boolean("require_pkce").notNull().default(true),
|
|
39
|
+
createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }).notNull().defaultNow(),
|
|
40
|
+
updatedAt: timestamp("updated_at", { withTimezone: true, mode: "date" }).notNull().defaultNow(),
|
|
41
|
+
disabledAt: timestamp("disabled_at", { withTimezone: true, mode: "date" })
|
|
42
|
+
},
|
|
43
|
+
(t) => ({
|
|
44
|
+
teamIdx: index().on(t.teamId)
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
const authorizationCodes = pgTable(
|
|
48
|
+
p("authorization_code"),
|
|
49
|
+
{
|
|
50
|
+
codeHash: text("code_hash").primaryKey(),
|
|
51
|
+
appId: text("app_id").notNull().references(() => apps.id, { onDelete: "cascade" }),
|
|
52
|
+
userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
|
|
53
|
+
redirectUri: text("redirect_uri").notNull(),
|
|
54
|
+
scope: text("scope").notNull(),
|
|
55
|
+
nonce: text("nonce"),
|
|
56
|
+
codeChallenge: text("code_challenge"),
|
|
57
|
+
codeChallengeMethod: text("code_challenge_method"),
|
|
58
|
+
expiresAt: timestamp("expires_at", { withTimezone: true, mode: "date" }).notNull(),
|
|
59
|
+
consumedAt: timestamp("consumed_at", { withTimezone: true, mode: "date" })
|
|
60
|
+
},
|
|
61
|
+
(t) => ({
|
|
62
|
+
expiresIdx: index().on(t.expiresAt)
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
const refreshTokens = pgTable(
|
|
66
|
+
p("refresh_token"),
|
|
67
|
+
{
|
|
68
|
+
id: text("id").primaryKey(),
|
|
69
|
+
tokenHash: text("token_hash").notNull(),
|
|
70
|
+
appId: text("app_id").notNull().references(() => apps.id, { onDelete: "cascade" }),
|
|
71
|
+
userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
|
|
72
|
+
familyId: text("family_id").notNull(),
|
|
73
|
+
scope: text("scope").notNull(),
|
|
74
|
+
expiresAt: timestamp("expires_at", { withTimezone: true, mode: "date" }).notNull(),
|
|
75
|
+
createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }).notNull().defaultNow(),
|
|
76
|
+
revokedAt: timestamp("revoked_at", { withTimezone: true, mode: "date" })
|
|
77
|
+
},
|
|
78
|
+
(t) => ({
|
|
79
|
+
hashIdx: uniqueIndex().on(t.tokenHash),
|
|
80
|
+
familyIdx: index().on(t.familyId),
|
|
81
|
+
userIdx: index().on(t.userId),
|
|
82
|
+
appIdx: index().on(t.appId)
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
const consents = pgTable(
|
|
86
|
+
p("consent"),
|
|
87
|
+
{
|
|
88
|
+
userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
|
|
89
|
+
appId: text("app_id").notNull().references(() => apps.id, { onDelete: "cascade" }),
|
|
90
|
+
scopesGranted: text("scopes_granted").array().notNull().default([]),
|
|
91
|
+
grantedAt: timestamp("granted_at", { withTimezone: true, mode: "date" }).notNull().defaultNow()
|
|
92
|
+
},
|
|
93
|
+
(t) => ({
|
|
94
|
+
pk: primaryKey({ columns: [t.userId, t.appId] })
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
const signingKeys = pgTable(p("signing_key"), {
|
|
98
|
+
kid: text("kid").primaryKey(),
|
|
99
|
+
alg: text("alg").notNull().$type(),
|
|
100
|
+
publicJwk: jsonb("public_jwk").notNull().$type(),
|
|
101
|
+
privateJwk: jsonb("private_jwk").notNull().$type(),
|
|
102
|
+
active: boolean("active").notNull().default(true),
|
|
103
|
+
createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }).notNull().defaultNow(),
|
|
104
|
+
rotatedAt: timestamp("rotated_at", { withTimezone: true, mode: "date" })
|
|
105
|
+
});
|
|
106
|
+
const teamMembersRelations = relations(teamMembers, ({ one }) => ({
|
|
107
|
+
team: one(teams, { fields: [teamMembers.teamId], references: [teams.id] }),
|
|
108
|
+
user: one(usersTable, { fields: [teamMembers.userId], references: [usersTable.id] })
|
|
109
|
+
}));
|
|
110
|
+
const appsRelations = relations(apps, ({ one }) => ({
|
|
111
|
+
team: one(teams, { fields: [apps.teamId], references: [teams.id] })
|
|
112
|
+
}));
|
|
113
|
+
return {
|
|
114
|
+
tables: {
|
|
115
|
+
teams,
|
|
116
|
+
teamMembers,
|
|
117
|
+
apps,
|
|
118
|
+
authorizationCodes,
|
|
119
|
+
refreshTokens,
|
|
120
|
+
consents,
|
|
121
|
+
signingKeys
|
|
122
|
+
},
|
|
123
|
+
relations: { teamMembersRelations, appsRelations }
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
var appRow = (r) => ({
|
|
127
|
+
id: String(r.id),
|
|
128
|
+
teamId: String(r.teamId),
|
|
129
|
+
name: String(r.name),
|
|
130
|
+
description: r.description ?? null,
|
|
131
|
+
logoUrl: r.logoUrl ?? null,
|
|
132
|
+
type: r.type,
|
|
133
|
+
clientSecretHash: r.clientSecretHash ?? null,
|
|
134
|
+
redirectUris: r.redirectUris ?? [],
|
|
135
|
+
allowedScopes: r.allowedScopes ?? [],
|
|
136
|
+
requirePkce: Boolean(r.requirePkce),
|
|
137
|
+
createdAt: r.createdAt,
|
|
138
|
+
updatedAt: r.updatedAt,
|
|
139
|
+
disabledAt: r.disabledAt ?? null
|
|
140
|
+
});
|
|
141
|
+
var teamRow = (r) => ({
|
|
142
|
+
id: String(r.id),
|
|
143
|
+
name: String(r.name),
|
|
144
|
+
createdAt: r.createdAt
|
|
145
|
+
});
|
|
146
|
+
var memberRow = (r) => ({
|
|
147
|
+
teamId: String(r.teamId),
|
|
148
|
+
userId: String(r.userId),
|
|
149
|
+
role: r.role,
|
|
150
|
+
addedAt: r.addedAt
|
|
151
|
+
});
|
|
152
|
+
var codeRow = (r) => ({
|
|
153
|
+
codeHash: String(r.codeHash),
|
|
154
|
+
appId: String(r.appId),
|
|
155
|
+
userId: String(r.userId),
|
|
156
|
+
redirectUri: String(r.redirectUri),
|
|
157
|
+
scope: String(r.scope),
|
|
158
|
+
nonce: r.nonce ?? null,
|
|
159
|
+
codeChallenge: r.codeChallenge ?? null,
|
|
160
|
+
codeChallengeMethod: r.codeChallengeMethod ?? null,
|
|
161
|
+
expiresAt: r.expiresAt,
|
|
162
|
+
consumedAt: r.consumedAt ?? null
|
|
163
|
+
});
|
|
164
|
+
var refreshRow = (r) => ({
|
|
165
|
+
id: String(r.id),
|
|
166
|
+
tokenHash: String(r.tokenHash),
|
|
167
|
+
appId: String(r.appId),
|
|
168
|
+
userId: String(r.userId),
|
|
169
|
+
familyId: String(r.familyId),
|
|
170
|
+
scope: String(r.scope),
|
|
171
|
+
expiresAt: r.expiresAt,
|
|
172
|
+
createdAt: r.createdAt,
|
|
173
|
+
revokedAt: r.revokedAt ?? null
|
|
174
|
+
});
|
|
175
|
+
var consentRow = (r) => ({
|
|
176
|
+
userId: String(r.userId),
|
|
177
|
+
appId: String(r.appId),
|
|
178
|
+
scopesGranted: r.scopesGranted ?? [],
|
|
179
|
+
grantedAt: r.grantedAt
|
|
180
|
+
});
|
|
181
|
+
var keyRow = (r) => ({
|
|
182
|
+
kid: String(r.kid),
|
|
183
|
+
alg: r.alg,
|
|
184
|
+
publicJwk: r.publicJwk,
|
|
185
|
+
privateJwk: r.privateJwk,
|
|
186
|
+
active: Boolean(r.active),
|
|
187
|
+
createdAt: r.createdAt,
|
|
188
|
+
rotatedAt: r.rotatedAt ?? null
|
|
189
|
+
});
|
|
190
|
+
function createIdpAdapter(opts) {
|
|
191
|
+
const { db, tables, generateId = () => crypto.randomUUID() } = opts;
|
|
192
|
+
const { teams, teamMembers, apps, authorizationCodes, refreshTokens, consents, signingKeys } = tables;
|
|
193
|
+
return {
|
|
194
|
+
teams: {
|
|
195
|
+
async create(input) {
|
|
196
|
+
const id = generateId();
|
|
197
|
+
const [row] = await db.insert(teams).values({ id, name: input.name }).returning();
|
|
198
|
+
await db.insert(teamMembers).values({ teamId: id, userId: input.ownerUserId, role: "owner" });
|
|
199
|
+
return teamRow(row);
|
|
200
|
+
},
|
|
201
|
+
async getById(teamId) {
|
|
202
|
+
const rows = await db.select().from(teams).where(eq(teams.id, teamId)).limit(1);
|
|
203
|
+
if (!rows.length) return null;
|
|
204
|
+
return teamRow(rows[0]);
|
|
205
|
+
},
|
|
206
|
+
async delete(teamId) {
|
|
207
|
+
await db.delete(teams).where(eq(teams.id, teamId));
|
|
208
|
+
},
|
|
209
|
+
async listForUser(userId) {
|
|
210
|
+
const rows = await db.select({
|
|
211
|
+
id: teams.id,
|
|
212
|
+
name: teams.name,
|
|
213
|
+
createdAt: teams.createdAt,
|
|
214
|
+
role: teamMembers.role
|
|
215
|
+
}).from(teamMembers).innerJoin(teams, eq(teamMembers.teamId, teams.id)).where(eq(teamMembers.userId, userId));
|
|
216
|
+
return rows.map((r) => ({
|
|
217
|
+
...teamRow(r),
|
|
218
|
+
role: r.role
|
|
219
|
+
}));
|
|
220
|
+
},
|
|
221
|
+
async listMembers(teamId) {
|
|
222
|
+
const rows = await db.select().from(teamMembers).where(eq(teamMembers.teamId, teamId));
|
|
223
|
+
return rows.map(memberRow);
|
|
224
|
+
},
|
|
225
|
+
async getMembership(teamId, userId) {
|
|
226
|
+
const rows = await db.select().from(teamMembers).where(and(eq(teamMembers.teamId, teamId), eq(teamMembers.userId, userId))).limit(1);
|
|
227
|
+
if (!rows.length) return null;
|
|
228
|
+
return memberRow(rows[0]);
|
|
229
|
+
},
|
|
230
|
+
async addMember(teamId, userId, role) {
|
|
231
|
+
await db.insert(teamMembers).values({ teamId, userId, role }).onConflictDoUpdate({
|
|
232
|
+
target: [teamMembers.teamId, teamMembers.userId],
|
|
233
|
+
set: { role }
|
|
234
|
+
});
|
|
235
|
+
},
|
|
236
|
+
async removeMember(teamId, userId) {
|
|
237
|
+
await db.delete(teamMembers).where(and(eq(teamMembers.teamId, teamId), eq(teamMembers.userId, userId)));
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
apps: {
|
|
241
|
+
async create(input) {
|
|
242
|
+
const [row] = await db.insert(apps).values({
|
|
243
|
+
id: input.id,
|
|
244
|
+
teamId: input.teamId,
|
|
245
|
+
name: input.name,
|
|
246
|
+
description: input.description ?? null,
|
|
247
|
+
logoUrl: input.logoUrl ?? null,
|
|
248
|
+
type: input.type,
|
|
249
|
+
clientSecretHash: input.clientSecretHash ?? null,
|
|
250
|
+
redirectUris: input.redirectUris,
|
|
251
|
+
allowedScopes: input.allowedScopes,
|
|
252
|
+
requirePkce: input.requirePkce
|
|
253
|
+
}).returning();
|
|
254
|
+
return appRow(row);
|
|
255
|
+
},
|
|
256
|
+
async getById(appId) {
|
|
257
|
+
const rows = await db.select().from(apps).where(eq(apps.id, appId)).limit(1);
|
|
258
|
+
if (!rows.length) return null;
|
|
259
|
+
return appRow(rows[0]);
|
|
260
|
+
},
|
|
261
|
+
async listAll(_opts) {
|
|
262
|
+
const rows = await db.select().from(apps).orderBy(desc(apps.createdAt));
|
|
263
|
+
return rows.map(appRow);
|
|
264
|
+
},
|
|
265
|
+
async listForTeam(teamId) {
|
|
266
|
+
const rows = await db.select().from(apps).where(eq(apps.teamId, teamId)).orderBy(desc(apps.createdAt));
|
|
267
|
+
return rows.map(appRow);
|
|
268
|
+
},
|
|
269
|
+
async listForUser(userId) {
|
|
270
|
+
const rows = await db.select({
|
|
271
|
+
id: apps.id,
|
|
272
|
+
teamId: apps.teamId,
|
|
273
|
+
name: apps.name,
|
|
274
|
+
description: apps.description,
|
|
275
|
+
logoUrl: apps.logoUrl,
|
|
276
|
+
type: apps.type,
|
|
277
|
+
clientSecretHash: apps.clientSecretHash,
|
|
278
|
+
redirectUris: apps.redirectUris,
|
|
279
|
+
allowedScopes: apps.allowedScopes,
|
|
280
|
+
requirePkce: apps.requirePkce,
|
|
281
|
+
createdAt: apps.createdAt,
|
|
282
|
+
updatedAt: apps.updatedAt,
|
|
283
|
+
disabledAt: apps.disabledAt
|
|
284
|
+
}).from(apps).innerJoin(teamMembers, eq(teamMembers.teamId, apps.teamId)).where(eq(teamMembers.userId, userId)).orderBy(desc(apps.createdAt));
|
|
285
|
+
return rows.map(appRow);
|
|
286
|
+
},
|
|
287
|
+
async update(appId, patch) {
|
|
288
|
+
const set = { updatedAt: /* @__PURE__ */ new Date() };
|
|
289
|
+
if (patch.name !== void 0) set.name = patch.name;
|
|
290
|
+
if (patch.description !== void 0) set.description = patch.description;
|
|
291
|
+
if (patch.logoUrl !== void 0) set.logoUrl = patch.logoUrl;
|
|
292
|
+
if (patch.redirectUris !== void 0) set.redirectUris = patch.redirectUris;
|
|
293
|
+
if (patch.allowedScopes !== void 0) set.allowedScopes = patch.allowedScopes;
|
|
294
|
+
if (patch.requirePkce !== void 0) set.requirePkce = patch.requirePkce;
|
|
295
|
+
if (patch.clientSecretHash !== void 0) set.clientSecretHash = patch.clientSecretHash;
|
|
296
|
+
if (patch.disabledAt !== void 0) set.disabledAt = patch.disabledAt;
|
|
297
|
+
const [row] = await db.update(apps).set(set).where(eq(apps.id, appId)).returning();
|
|
298
|
+
return appRow(row);
|
|
299
|
+
},
|
|
300
|
+
async delete(appId) {
|
|
301
|
+
await db.delete(apps).where(eq(apps.id, appId));
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
codes: {
|
|
305
|
+
async create(input) {
|
|
306
|
+
await db.insert(authorizationCodes).values({
|
|
307
|
+
codeHash: input.codeHash,
|
|
308
|
+
appId: input.appId,
|
|
309
|
+
userId: input.userId,
|
|
310
|
+
redirectUri: input.redirectUri,
|
|
311
|
+
scope: input.scope,
|
|
312
|
+
nonce: input.nonce,
|
|
313
|
+
codeChallenge: input.codeChallenge,
|
|
314
|
+
codeChallengeMethod: input.codeChallengeMethod,
|
|
315
|
+
expiresAt: input.expiresAt
|
|
316
|
+
});
|
|
317
|
+
},
|
|
318
|
+
async consume(codeHash) {
|
|
319
|
+
const rows = await db.update(authorizationCodes).set({ consumedAt: /* @__PURE__ */ new Date() }).where(
|
|
320
|
+
and(
|
|
321
|
+
eq(authorizationCodes.codeHash, codeHash),
|
|
322
|
+
sql`${authorizationCodes.consumedAt} IS NULL`,
|
|
323
|
+
sql`${authorizationCodes.expiresAt} > NOW()`
|
|
324
|
+
)
|
|
325
|
+
).returning();
|
|
326
|
+
if (!rows.length) return null;
|
|
327
|
+
return codeRow(rows[0]);
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
refresh: {
|
|
331
|
+
async create(input) {
|
|
332
|
+
const [row] = await db.insert(refreshTokens).values({
|
|
333
|
+
id: input.id,
|
|
334
|
+
tokenHash: input.tokenHash,
|
|
335
|
+
appId: input.appId,
|
|
336
|
+
userId: input.userId,
|
|
337
|
+
familyId: input.familyId,
|
|
338
|
+
scope: input.scope,
|
|
339
|
+
expiresAt: input.expiresAt
|
|
340
|
+
}).returning();
|
|
341
|
+
return refreshRow(row);
|
|
342
|
+
},
|
|
343
|
+
async getByHash(hash) {
|
|
344
|
+
const rows = await db.select().from(refreshTokens).where(eq(refreshTokens.tokenHash, hash)).limit(1);
|
|
345
|
+
if (!rows.length) return null;
|
|
346
|
+
return refreshRow(rows[0]);
|
|
347
|
+
},
|
|
348
|
+
async markRevoked(id) {
|
|
349
|
+
await db.update(refreshTokens).set({ revokedAt: /* @__PURE__ */ new Date() }).where(and(eq(refreshTokens.id, id), sql`${refreshTokens.revokedAt} IS NULL`));
|
|
350
|
+
},
|
|
351
|
+
async revokeFamily(familyId) {
|
|
352
|
+
await db.update(refreshTokens).set({ revokedAt: /* @__PURE__ */ new Date() }).where(
|
|
353
|
+
and(eq(refreshTokens.familyId, familyId), sql`${refreshTokens.revokedAt} IS NULL`)
|
|
354
|
+
);
|
|
355
|
+
},
|
|
356
|
+
async revokeAllForUser(userId) {
|
|
357
|
+
await db.update(refreshTokens).set({ revokedAt: /* @__PURE__ */ new Date() }).where(and(eq(refreshTokens.userId, userId), sql`${refreshTokens.revokedAt} IS NULL`));
|
|
358
|
+
},
|
|
359
|
+
async revokeAllForApp(appId) {
|
|
360
|
+
await db.update(refreshTokens).set({ revokedAt: /* @__PURE__ */ new Date() }).where(and(eq(refreshTokens.appId, appId), sql`${refreshTokens.revokedAt} IS NULL`));
|
|
361
|
+
},
|
|
362
|
+
async listForApp(appId) {
|
|
363
|
+
const rows = await db.select().from(refreshTokens).where(eq(refreshTokens.appId, appId)).orderBy(desc(refreshTokens.createdAt));
|
|
364
|
+
return rows.map(refreshRow);
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
consent: {
|
|
368
|
+
async get(userId, appId) {
|
|
369
|
+
const rows = await db.select().from(consents).where(and(eq(consents.userId, userId), eq(consents.appId, appId))).limit(1);
|
|
370
|
+
if (!rows.length) return null;
|
|
371
|
+
return consentRow(rows[0]);
|
|
372
|
+
},
|
|
373
|
+
async upsert(userId, appId, scopesGranted) {
|
|
374
|
+
await db.insert(consents).values({ userId, appId, scopesGranted }).onConflictDoUpdate({
|
|
375
|
+
target: [consents.userId, consents.appId],
|
|
376
|
+
set: { scopesGranted, grantedAt: /* @__PURE__ */ new Date() }
|
|
377
|
+
});
|
|
378
|
+
},
|
|
379
|
+
async revoke(userId, appId) {
|
|
380
|
+
await db.delete(consents).where(and(eq(consents.userId, userId), eq(consents.appId, appId)));
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
keys: {
|
|
384
|
+
async listActive() {
|
|
385
|
+
const rows = await db.select().from(signingKeys).where(eq(signingKeys.active, true)).orderBy(desc(signingKeys.createdAt));
|
|
386
|
+
return rows.map(keyRow);
|
|
387
|
+
},
|
|
388
|
+
async getActive() {
|
|
389
|
+
const rows = await db.select().from(signingKeys).where(eq(signingKeys.active, true)).orderBy(desc(signingKeys.createdAt)).limit(1);
|
|
390
|
+
if (!rows.length) return null;
|
|
391
|
+
return keyRow(rows[0]);
|
|
392
|
+
},
|
|
393
|
+
async create(input) {
|
|
394
|
+
const [row] = await db.insert(signingKeys).values({
|
|
395
|
+
kid: input.kid,
|
|
396
|
+
alg: input.alg,
|
|
397
|
+
publicJwk: input.publicJwk,
|
|
398
|
+
privateJwk: input.privateJwk,
|
|
399
|
+
active: true
|
|
400
|
+
}).returning();
|
|
401
|
+
return keyRow(row);
|
|
402
|
+
},
|
|
403
|
+
async markRotated(kid) {
|
|
404
|
+
await db.update(signingKeys).set({ active: false, rotatedAt: /* @__PURE__ */ new Date() }).where(eq(signingKeys.kid, kid));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export { createIdpAdapter, createIdpTables };
|
|
411
|
+
//# sourceMappingURL=index.js.map
|
|
412
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pg/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Postgres adapter for @holeauth/plugin-idp.\n *\n * Exports:\n * - `createIdpTables({ usersTable, prefix? })` — returns drizzle tables\n * + relations. The `usersTable` must have at minimum an `id` column;\n * team memberships reference users and cascade on delete.\n * - `createIdpAdapter({ db, tables })` — constructs an IdpAdapter.\n *\n * The schema covers: teams + members, apps, authorization codes, refresh\n * tokens (with family ids), user × app consents, and signing keys (JWKs).\n */\nimport {\n pgTable,\n text,\n boolean,\n timestamp,\n jsonb,\n primaryKey,\n index,\n uniqueIndex,\n type PgTableWithColumns,\n} from 'drizzle-orm/pg-core';\nimport { relations, eq, and, sql, desc } from 'drizzle-orm';\nimport type {\n IdpAdapter,\n IdpApp,\n IdpAuthorizationCode,\n IdpConsent,\n IdpRefreshToken,\n IdpSigningKey,\n IdpTeam,\n IdpTeamMember,\n SigningAlg,\n TeamRole,\n AppType,\n} from '@holeauth/plugin-idp';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PgUsersTable = PgTableWithColumns<any> & { id: any };\n\nexport interface CreateIdpTablesOptions<U extends PgUsersTable> {\n usersTable: U;\n prefix?: string;\n}\n\nexport function createIdpTables<U extends PgUsersTable>(opts: CreateIdpTablesOptions<U>) {\n const { usersTable, prefix = 'holeauth_idp_' } = opts;\n const p = (s: string) => `${prefix}${s}`;\n\n const teams = pgTable(p('team'), {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n });\n\n const teamMembers = pgTable(\n p('team_member'),\n {\n teamId: text('team_id')\n .notNull()\n .references(() => teams.id, { onDelete: 'cascade' }),\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n role: text('role').notNull().$type<TeamRole>(),\n addedAt: timestamp('added_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.teamId, t.userId] }),\n userIdx: index().on(t.userId),\n }),\n );\n\n const apps = pgTable(\n p('app'),\n {\n id: text('id').primaryKey(),\n teamId: text('team_id')\n .notNull()\n .references(() => teams.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n description: text('description'),\n logoUrl: text('logo_url'),\n type: text('type').notNull().$type<AppType>(),\n clientSecretHash: text('client_secret_hash'),\n redirectUris: text('redirect_uris').array().notNull().default([]),\n allowedScopes: text('allowed_scopes').array().notNull().default([]),\n requirePkce: boolean('require_pkce').notNull().default(true),\n createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n disabledAt: timestamp('disabled_at', { withTimezone: true, mode: 'date' }),\n },\n (t) => ({\n teamIdx: index().on(t.teamId),\n }),\n );\n\n const authorizationCodes = pgTable(\n p('authorization_code'),\n {\n codeHash: text('code_hash').primaryKey(),\n appId: text('app_id')\n .notNull()\n .references(() => apps.id, { onDelete: 'cascade' }),\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n redirectUri: text('redirect_uri').notNull(),\n scope: text('scope').notNull(),\n nonce: text('nonce'),\n codeChallenge: text('code_challenge'),\n codeChallengeMethod: text('code_challenge_method'),\n expiresAt: timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull(),\n consumedAt: timestamp('consumed_at', { withTimezone: true, mode: 'date' }),\n },\n (t) => ({\n expiresIdx: index().on(t.expiresAt),\n }),\n );\n\n const refreshTokens = pgTable(\n p('refresh_token'),\n {\n id: text('id').primaryKey(),\n tokenHash: text('token_hash').notNull(),\n appId: text('app_id')\n .notNull()\n .references(() => apps.id, { onDelete: 'cascade' }),\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n familyId: text('family_id').notNull(),\n scope: text('scope').notNull(),\n expiresAt: timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull(),\n createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n revokedAt: timestamp('revoked_at', { withTimezone: true, mode: 'date' }),\n },\n (t) => ({\n hashIdx: uniqueIndex().on(t.tokenHash),\n familyIdx: index().on(t.familyId),\n userIdx: index().on(t.userId),\n appIdx: index().on(t.appId),\n }),\n );\n\n const consents = pgTable(\n p('consent'),\n {\n userId: text('user_id')\n .notNull()\n .references(() => usersTable.id, { onDelete: 'cascade' }),\n appId: text('app_id')\n .notNull()\n .references(() => apps.id, { onDelete: 'cascade' }),\n scopesGranted: text('scopes_granted').array().notNull().default([]),\n grantedAt: timestamp('granted_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.userId, t.appId] }),\n }),\n );\n\n const signingKeys = pgTable(p('signing_key'), {\n kid: text('kid').primaryKey(),\n alg: text('alg').notNull().$type<SigningAlg>(),\n publicJwk: jsonb('public_jwk').notNull().$type<Record<string, unknown>>(),\n privateJwk: jsonb('private_jwk').notNull().$type<Record<string, unknown>>(),\n active: boolean('active').notNull().default(true),\n createdAt: timestamp('created_at', { withTimezone: true, mode: 'date' })\n .notNull()\n .defaultNow(),\n rotatedAt: timestamp('rotated_at', { withTimezone: true, mode: 'date' }),\n });\n\n const teamMembersRelations = relations(teamMembers, ({ one }) => ({\n team: one(teams, { fields: [teamMembers.teamId], references: [teams.id] }),\n user: one(usersTable, { fields: [teamMembers.userId], references: [usersTable.id] }),\n }));\n const appsRelations = relations(apps, ({ one }) => ({\n team: one(teams, { fields: [apps.teamId], references: [teams.id] }),\n }));\n\n return {\n tables: {\n teams,\n teamMembers,\n apps,\n authorizationCodes,\n refreshTokens,\n consents,\n signingKeys,\n },\n relations: { teamMembersRelations, appsRelations },\n };\n}\n\n/* ────────────────────────── adapter ────────────────────────── */\n\ntype Tables = ReturnType<typeof createIdpTables>['tables'];\n\nexport interface CreateIdpAdapterOptions {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n db: any;\n tables: Tables;\n generateId?: () => string;\n}\n\nconst appRow = (r: Record<string, unknown>): IdpApp => ({\n id: String(r.id),\n teamId: String(r.teamId),\n name: String(r.name),\n description: (r.description as string | null) ?? null,\n logoUrl: (r.logoUrl as string | null) ?? null,\n type: r.type as AppType,\n clientSecretHash: (r.clientSecretHash as string | null) ?? null,\n redirectUris: (r.redirectUris as string[] | null) ?? [],\n allowedScopes: (r.allowedScopes as string[] | null) ?? [],\n requirePkce: Boolean(r.requirePkce),\n createdAt: r.createdAt as Date,\n updatedAt: r.updatedAt as Date,\n disabledAt: (r.disabledAt as Date | null) ?? null,\n});\n\nconst teamRow = (r: Record<string, unknown>): IdpTeam => ({\n id: String(r.id),\n name: String(r.name),\n createdAt: r.createdAt as Date,\n});\n\nconst memberRow = (r: Record<string, unknown>): IdpTeamMember => ({\n teamId: String(r.teamId),\n userId: String(r.userId),\n role: r.role as TeamRole,\n addedAt: r.addedAt as Date,\n});\n\nconst codeRow = (r: Record<string, unknown>): IdpAuthorizationCode => ({\n codeHash: String(r.codeHash),\n appId: String(r.appId),\n userId: String(r.userId),\n redirectUri: String(r.redirectUri),\n scope: String(r.scope),\n nonce: (r.nonce as string | null) ?? null,\n codeChallenge: (r.codeChallenge as string | null) ?? null,\n codeChallengeMethod: (r.codeChallengeMethod as 'S256' | 'plain' | null) ?? null,\n expiresAt: r.expiresAt as Date,\n consumedAt: (r.consumedAt as Date | null) ?? null,\n});\n\nconst refreshRow = (r: Record<string, unknown>): IdpRefreshToken => ({\n id: String(r.id),\n tokenHash: String(r.tokenHash),\n appId: String(r.appId),\n userId: String(r.userId),\n familyId: String(r.familyId),\n scope: String(r.scope),\n expiresAt: r.expiresAt as Date,\n createdAt: r.createdAt as Date,\n revokedAt: (r.revokedAt as Date | null) ?? null,\n});\n\nconst consentRow = (r: Record<string, unknown>): IdpConsent => ({\n userId: String(r.userId),\n appId: String(r.appId),\n scopesGranted: (r.scopesGranted as string[] | null) ?? [],\n grantedAt: r.grantedAt as Date,\n});\n\nconst keyRow = (r: Record<string, unknown>): IdpSigningKey => ({\n kid: String(r.kid),\n alg: r.alg as SigningAlg,\n publicJwk: r.publicJwk as Record<string, unknown>,\n privateJwk: r.privateJwk as Record<string, unknown>,\n active: Boolean(r.active),\n createdAt: r.createdAt as Date,\n rotatedAt: (r.rotatedAt as Date | null) ?? null,\n});\n\nexport function createIdpAdapter(opts: CreateIdpAdapterOptions): IdpAdapter {\n const { db, tables, generateId = () => crypto.randomUUID() } = opts;\n const { teams, teamMembers, apps, authorizationCodes, refreshTokens, consents, signingKeys } =\n tables;\n\n return {\n teams: {\n async create(input) {\n const id = generateId();\n const [row] = await db\n .insert(teams)\n .values({ id, name: input.name })\n .returning();\n await db\n .insert(teamMembers)\n .values({ teamId: id, userId: input.ownerUserId, role: 'owner' });\n return teamRow(row as Record<string, unknown>);\n },\n async getById(teamId) {\n const rows = await db.select().from(teams).where(eq(teams.id, teamId)).limit(1);\n if (!rows.length) return null;\n return teamRow(rows[0] as Record<string, unknown>);\n },\n async delete(teamId) {\n await db.delete(teams).where(eq(teams.id, teamId));\n },\n async listForUser(userId) {\n const rows = await db\n .select({\n id: teams.id,\n name: teams.name,\n createdAt: teams.createdAt,\n role: teamMembers.role,\n })\n .from(teamMembers)\n .innerJoin(teams, eq(teamMembers.teamId, teams.id))\n .where(eq(teamMembers.userId, userId));\n return (rows as Record<string, unknown>[]).map((r) => ({\n ...teamRow(r),\n role: r.role as TeamRole,\n }));\n },\n async listMembers(teamId) {\n const rows = await db.select().from(teamMembers).where(eq(teamMembers.teamId, teamId));\n return (rows as Record<string, unknown>[]).map(memberRow);\n },\n async getMembership(teamId, userId) {\n const rows = await db\n .select()\n .from(teamMembers)\n .where(and(eq(teamMembers.teamId, teamId), eq(teamMembers.userId, userId)))\n .limit(1);\n if (!rows.length) return null;\n return memberRow(rows[0] as Record<string, unknown>);\n },\n async addMember(teamId, userId, role) {\n await db\n .insert(teamMembers)\n .values({ teamId, userId, role })\n .onConflictDoUpdate({\n target: [teamMembers.teamId, teamMembers.userId],\n set: { role },\n });\n },\n async removeMember(teamId, userId) {\n await db\n .delete(teamMembers)\n .where(and(eq(teamMembers.teamId, teamId), eq(teamMembers.userId, userId)));\n },\n },\n\n apps: {\n async create(input) {\n const [row] = await db\n .insert(apps)\n .values({\n id: input.id,\n teamId: input.teamId,\n name: input.name,\n description: input.description ?? null,\n logoUrl: input.logoUrl ?? null,\n type: input.type,\n clientSecretHash: input.clientSecretHash ?? null,\n redirectUris: input.redirectUris,\n allowedScopes: input.allowedScopes,\n requirePkce: input.requirePkce,\n })\n .returning();\n return appRow(row as Record<string, unknown>);\n },\n async getById(appId) {\n const rows = await db.select().from(apps).where(eq(apps.id, appId)).limit(1);\n if (!rows.length) return null;\n return appRow(rows[0] as Record<string, unknown>);\n },\n async listAll(_opts) {\n const rows = await db.select().from(apps).orderBy(desc(apps.createdAt));\n return (rows as Record<string, unknown>[]).map(appRow);\n },\n async listForTeam(teamId) {\n const rows = await db\n .select()\n .from(apps)\n .where(eq(apps.teamId, teamId))\n .orderBy(desc(apps.createdAt));\n return (rows as Record<string, unknown>[]).map(appRow);\n },\n async listForUser(userId) {\n const rows = await db\n .select({\n id: apps.id,\n teamId: apps.teamId,\n name: apps.name,\n description: apps.description,\n logoUrl: apps.logoUrl,\n type: apps.type,\n clientSecretHash: apps.clientSecretHash,\n redirectUris: apps.redirectUris,\n allowedScopes: apps.allowedScopes,\n requirePkce: apps.requirePkce,\n createdAt: apps.createdAt,\n updatedAt: apps.updatedAt,\n disabledAt: apps.disabledAt,\n })\n .from(apps)\n .innerJoin(teamMembers, eq(teamMembers.teamId, apps.teamId))\n .where(eq(teamMembers.userId, userId))\n .orderBy(desc(apps.createdAt));\n return (rows as Record<string, unknown>[]).map(appRow);\n },\n async update(appId, patch) {\n const set: Record<string, unknown> = { updatedAt: new Date() };\n if (patch.name !== undefined) set.name = patch.name;\n if (patch.description !== undefined) set.description = patch.description;\n if (patch.logoUrl !== undefined) set.logoUrl = patch.logoUrl;\n if (patch.redirectUris !== undefined) set.redirectUris = patch.redirectUris;\n if (patch.allowedScopes !== undefined) set.allowedScopes = patch.allowedScopes;\n if (patch.requirePkce !== undefined) set.requirePkce = patch.requirePkce;\n if (patch.clientSecretHash !== undefined) set.clientSecretHash = patch.clientSecretHash;\n if (patch.disabledAt !== undefined) set.disabledAt = patch.disabledAt;\n const [row] = await db.update(apps).set(set).where(eq(apps.id, appId)).returning();\n return appRow(row as Record<string, unknown>);\n },\n async delete(appId) {\n await db.delete(apps).where(eq(apps.id, appId));\n },\n },\n\n codes: {\n async create(input) {\n await db.insert(authorizationCodes).values({\n codeHash: input.codeHash,\n appId: input.appId,\n userId: input.userId,\n redirectUri: input.redirectUri,\n scope: input.scope,\n nonce: input.nonce,\n codeChallenge: input.codeChallenge,\n codeChallengeMethod: input.codeChallengeMethod,\n expiresAt: input.expiresAt,\n });\n },\n async consume(codeHash) {\n // Atomic single-statement claim: only returns if row exists,\n // was not already consumed, and has not yet expired.\n const rows = await db\n .update(authorizationCodes)\n .set({ consumedAt: new Date() })\n .where(\n and(\n eq(authorizationCodes.codeHash, codeHash),\n sql`${authorizationCodes.consumedAt} IS NULL`,\n sql`${authorizationCodes.expiresAt} > NOW()`,\n ),\n )\n .returning();\n if (!rows.length) return null;\n return codeRow(rows[0] as Record<string, unknown>);\n },\n },\n\n refresh: {\n async create(input) {\n const [row] = await db\n .insert(refreshTokens)\n .values({\n id: input.id,\n tokenHash: input.tokenHash,\n appId: input.appId,\n userId: input.userId,\n familyId: input.familyId,\n scope: input.scope,\n expiresAt: input.expiresAt,\n })\n .returning();\n return refreshRow(row as Record<string, unknown>);\n },\n async getByHash(hash) {\n const rows = await db\n .select()\n .from(refreshTokens)\n .where(eq(refreshTokens.tokenHash, hash))\n .limit(1);\n if (!rows.length) return null;\n return refreshRow(rows[0] as Record<string, unknown>);\n },\n async markRevoked(id) {\n await db\n .update(refreshTokens)\n .set({ revokedAt: new Date() })\n .where(and(eq(refreshTokens.id, id), sql`${refreshTokens.revokedAt} IS NULL`));\n },\n async revokeFamily(familyId) {\n await db\n .update(refreshTokens)\n .set({ revokedAt: new Date() })\n .where(\n and(eq(refreshTokens.familyId, familyId), sql`${refreshTokens.revokedAt} IS NULL`),\n );\n },\n async revokeAllForUser(userId) {\n await db\n .update(refreshTokens)\n .set({ revokedAt: new Date() })\n .where(and(eq(refreshTokens.userId, userId), sql`${refreshTokens.revokedAt} IS NULL`));\n },\n async revokeAllForApp(appId) {\n await db\n .update(refreshTokens)\n .set({ revokedAt: new Date() })\n .where(and(eq(refreshTokens.appId, appId), sql`${refreshTokens.revokedAt} IS NULL`));\n },\n async listForApp(appId) {\n const rows = await db\n .select()\n .from(refreshTokens)\n .where(eq(refreshTokens.appId, appId))\n .orderBy(desc(refreshTokens.createdAt));\n return (rows as Record<string, unknown>[]).map(refreshRow);\n },\n },\n\n consent: {\n async get(userId, appId) {\n const rows = await db\n .select()\n .from(consents)\n .where(and(eq(consents.userId, userId), eq(consents.appId, appId)))\n .limit(1);\n if (!rows.length) return null;\n return consentRow(rows[0] as Record<string, unknown>);\n },\n async upsert(userId, appId, scopesGranted) {\n await db\n .insert(consents)\n .values({ userId, appId, scopesGranted })\n .onConflictDoUpdate({\n target: [consents.userId, consents.appId],\n set: { scopesGranted, grantedAt: new Date() },\n });\n },\n async revoke(userId, appId) {\n await db\n .delete(consents)\n .where(and(eq(consents.userId, userId), eq(consents.appId, appId)));\n },\n },\n\n keys: {\n async listActive() {\n const rows = await db\n .select()\n .from(signingKeys)\n .where(eq(signingKeys.active, true))\n .orderBy(desc(signingKeys.createdAt));\n return (rows as Record<string, unknown>[]).map(keyRow);\n },\n async getActive() {\n const rows = await db\n .select()\n .from(signingKeys)\n .where(eq(signingKeys.active, true))\n .orderBy(desc(signingKeys.createdAt))\n .limit(1);\n if (!rows.length) return null;\n return keyRow(rows[0] as Record<string, unknown>);\n },\n async create(input) {\n const [row] = await db\n .insert(signingKeys)\n .values({\n kid: input.kid,\n alg: input.alg,\n publicJwk: input.publicJwk,\n privateJwk: input.privateJwk,\n active: true,\n })\n .returning();\n return keyRow(row as Record<string, unknown>);\n },\n async markRotated(kid) {\n await db\n .update(signingKeys)\n .set({ active: false, rotatedAt: new Date() })\n .where(eq(signingKeys.kid, kid));\n },\n },\n };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@holeauth/idp-drizzle",
|
|
3
|
+
"version": "0.0.1-alpha.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/robert-kratz/holeauth.git",
|
|
7
|
+
"directory": "packages/idp-drizzle"
|
|
8
|
+
},
|
|
9
|
+
"description": "Drizzle adapter for @holeauth/plugin-idp (OpenID Connect IdP).",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "Robert Kratz",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
},
|
|
21
|
+
"./pg": {
|
|
22
|
+
"types": "./dist/pg/index.d.ts",
|
|
23
|
+
"import": "./dist/pg/index.js",
|
|
24
|
+
"require": "./dist/pg/index.cjs"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public",
|
|
35
|
+
"provenance": true
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"drizzle-orm": ">=0.33.0",
|
|
39
|
+
"@holeauth/plugin-idp": "0.0.1-alpha.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@testcontainers/postgresql": "^11.14.0",
|
|
43
|
+
"@types/node": "^20.16.10",
|
|
44
|
+
"@types/pg": "^8.11.10",
|
|
45
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
46
|
+
"drizzle-orm": "^0.36.0",
|
|
47
|
+
"pg": "^8.13.0",
|
|
48
|
+
"testcontainers": "^11.14.0",
|
|
49
|
+
"tsup": "^8.3.0",
|
|
50
|
+
"typescript": "^5.6.2",
|
|
51
|
+
"vitest": "^2.1.2",
|
|
52
|
+
"@holeauth/eslint-config": "0.0.0",
|
|
53
|
+
"@holeauth/plugin-idp": "0.0.1-alpha.0",
|
|
54
|
+
"@holeauth/tsconfig": "0.0.0"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsup",
|
|
58
|
+
"dev": "tsup --watch",
|
|
59
|
+
"clean": "rm -rf dist .turbo",
|
|
60
|
+
"lint": "echo 'lint skipped'",
|
|
61
|
+
"typecheck": "tsc --noEmit",
|
|
62
|
+
"test": "vitest run --passWithNoTests",
|
|
63
|
+
"test:coverage": "vitest run --coverage"
|
|
64
|
+
}
|
|
65
|
+
}
|