@storyshelf/auth 0.5.3
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/README.md +43 -0
- package/dist/auth-tables-pg.d.mts +1971 -0
- package/dist/auth-tables-pg.mjs +167 -0
- package/dist/auth-tables-pg.mjs.map +1 -0
- package/dist/auth-tables.d.mts +1092 -0
- package/dist/auth-tables.mjs +122 -0
- package/dist/auth-tables.mjs.map +1 -0
- package/dist/bootstrap.d.mts +15 -0
- package/dist/bootstrap.mjs +40 -0
- package/dist/bootstrap.mjs.map +1 -0
- package/dist/config.d.mts +27 -0
- package/dist/config.mjs +204 -0
- package/dist/config.mjs.map +1 -0
- package/dist/db-bridge.d.mts +20 -0
- package/dist/db-bridge.mjs +208 -0
- package/dist/db-bridge.mjs.map +1 -0
- package/dist/db-values.mjs +41 -0
- package/dist/db-values.mjs.map +1 -0
- package/dist/db-where.mjs +85 -0
- package/dist/db-where.mjs.map +1 -0
- package/dist/engine.d.mts +208 -0
- package/dist/engine.mjs +444 -0
- package/dist/engine.mjs.map +1 -0
- package/dist/groups.d.mts +54 -0
- package/dist/groups.mjs +129 -0
- package/dist/groups.mjs.map +1 -0
- package/dist/index.d.mts +18 -0
- package/dist/index.mjs +17 -0
- package/dist/invites.d.mts +41 -0
- package/dist/invites.mjs +225 -0
- package/dist/invites.mjs.map +1 -0
- package/dist/passkeys.d.mts +21 -0
- package/dist/passkeys.mjs +27 -0
- package/dist/passkeys.mjs.map +1 -0
- package/dist/presets/enterprise.d.mts +24 -0
- package/dist/presets/enterprise.mjs +44 -0
- package/dist/presets/enterprise.mjs.map +1 -0
- package/dist/presets/index.d.mts +5 -0
- package/dist/presets/social.d.mts +34 -0
- package/dist/presets/social.mjs +60 -0
- package/dist/presets/social.mjs.map +1 -0
- package/dist/presets/sso.d.mts +72 -0
- package/dist/presets/sso.mjs +136 -0
- package/dist/presets/sso.mjs.map +1 -0
- package/dist/sessions.d.mts +23 -0
- package/dist/sessions.mjs +51 -0
- package/dist/sessions.mjs.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { boolean, integer, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
5
|
+
//#region src/auth-tables-pg.ts
|
|
6
|
+
/**
|
|
7
|
+
* Auth table definitions for Postgres (pg-core mirrors of `auth-tables.ts`).
|
|
8
|
+
*
|
|
9
|
+
* Same model names, same camelCase keys, same snake_case columns; timestamps
|
|
10
|
+
* ride `timestamp(..., { mode: "string" })` so the bridge keeps exchanging
|
|
11
|
+
* ISO strings, booleans ride native `boolean`. The bridge consumes either
|
|
12
|
+
* dialect through the shared {@link AuthBridgeSchema} registry.
|
|
13
|
+
*/
|
|
14
|
+
/** Narrow `user` table definition (Better Auth base model). */
|
|
15
|
+
const authUserPg = pgTable("user", {
|
|
16
|
+
id: text("id").primaryKey(),
|
|
17
|
+
name: text("name").notNull(),
|
|
18
|
+
email: text("email").notNull().unique(),
|
|
19
|
+
emailVerified: boolean("email_verified").notNull().default(false),
|
|
20
|
+
image: text("image"),
|
|
21
|
+
createdAt: timestamp("created_at", {
|
|
22
|
+
withTimezone: true,
|
|
23
|
+
mode: "string"
|
|
24
|
+
}).notNull(),
|
|
25
|
+
updatedAt: timestamp("updated_at", {
|
|
26
|
+
withTimezone: true,
|
|
27
|
+
mode: "string"
|
|
28
|
+
}).notNull()
|
|
29
|
+
});
|
|
30
|
+
/** Narrow `session` table definition (Better Auth base model). */
|
|
31
|
+
const authSessionPg = pgTable("session", {
|
|
32
|
+
id: text("id").primaryKey(),
|
|
33
|
+
userId: text("user_id").notNull().references(() => authUserPg.id, { onDelete: "cascade" }),
|
|
34
|
+
token: text("token").notNull().unique(),
|
|
35
|
+
expiresAt: timestamp("expires_at", {
|
|
36
|
+
withTimezone: true,
|
|
37
|
+
mode: "string"
|
|
38
|
+
}).notNull(),
|
|
39
|
+
ipAddress: text("ip_address"),
|
|
40
|
+
userAgent: text("user_agent"),
|
|
41
|
+
createdAt: timestamp("created_at", {
|
|
42
|
+
withTimezone: true,
|
|
43
|
+
mode: "string"
|
|
44
|
+
}).notNull(),
|
|
45
|
+
updatedAt: timestamp("updated_at", {
|
|
46
|
+
withTimezone: true,
|
|
47
|
+
mode: "string"
|
|
48
|
+
}).notNull()
|
|
49
|
+
});
|
|
50
|
+
/** Narrow `account` table definition (Better Auth base model). */
|
|
51
|
+
const authAccountPg = pgTable("account", {
|
|
52
|
+
id: text("id").primaryKey(),
|
|
53
|
+
userId: text("user_id").notNull().references(() => authUserPg.id, { onDelete: "cascade" }),
|
|
54
|
+
accountId: text("account_id").notNull(),
|
|
55
|
+
providerId: text("provider_id").notNull(),
|
|
56
|
+
accessToken: text("access_token"),
|
|
57
|
+
refreshToken: text("refresh_token"),
|
|
58
|
+
idToken: text("id_token"),
|
|
59
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at", {
|
|
60
|
+
withTimezone: true,
|
|
61
|
+
mode: "string"
|
|
62
|
+
}),
|
|
63
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at", {
|
|
64
|
+
withTimezone: true,
|
|
65
|
+
mode: "string"
|
|
66
|
+
}),
|
|
67
|
+
scope: text("scope"),
|
|
68
|
+
expiresAt: timestamp("expires_at", {
|
|
69
|
+
withTimezone: true,
|
|
70
|
+
mode: "string"
|
|
71
|
+
}),
|
|
72
|
+
password: text("password"),
|
|
73
|
+
createdAt: timestamp("created_at", {
|
|
74
|
+
withTimezone: true,
|
|
75
|
+
mode: "string"
|
|
76
|
+
}).notNull(),
|
|
77
|
+
updatedAt: timestamp("updated_at", {
|
|
78
|
+
withTimezone: true,
|
|
79
|
+
mode: "string"
|
|
80
|
+
}).notNull()
|
|
81
|
+
});
|
|
82
|
+
/** Narrow `verification` table definition (Better Auth base model). */
|
|
83
|
+
const authVerificationPg = pgTable("verification", {
|
|
84
|
+
id: text("id").primaryKey(),
|
|
85
|
+
identifier: text("identifier").notNull(),
|
|
86
|
+
value: text("value").notNull(),
|
|
87
|
+
expiresAt: timestamp("expires_at", {
|
|
88
|
+
withTimezone: true,
|
|
89
|
+
mode: "string"
|
|
90
|
+
}).notNull(),
|
|
91
|
+
createdAt: timestamp("created_at", {
|
|
92
|
+
withTimezone: true,
|
|
93
|
+
mode: "string"
|
|
94
|
+
}).notNull(),
|
|
95
|
+
updatedAt: timestamp("updated_at", {
|
|
96
|
+
withTimezone: true,
|
|
97
|
+
mode: "string"
|
|
98
|
+
}).notNull()
|
|
99
|
+
});
|
|
100
|
+
/** Narrow `passkey` table definition (passkey plugin model). */
|
|
101
|
+
const authPasskeyPg = pgTable("passkey", {
|
|
102
|
+
id: text("id").primaryKey(),
|
|
103
|
+
name: text("name"),
|
|
104
|
+
publicKey: text("public_key").notNull(),
|
|
105
|
+
userId: text("user_id").notNull().references(() => authUserPg.id, { onDelete: "cascade" }),
|
|
106
|
+
credentialID: text("credential_id").notNull(),
|
|
107
|
+
counter: integer("counter").notNull(),
|
|
108
|
+
deviceType: text("device_type").notNull(),
|
|
109
|
+
backedUp: boolean("backed_up").notNull().default(false),
|
|
110
|
+
transports: text("transports"),
|
|
111
|
+
aaguid: text("aaguid"),
|
|
112
|
+
createdAt: timestamp("created_at", {
|
|
113
|
+
withTimezone: true,
|
|
114
|
+
mode: "string"
|
|
115
|
+
}).notNull(),
|
|
116
|
+
updatedAt: timestamp("updated_at", {
|
|
117
|
+
withTimezone: true,
|
|
118
|
+
mode: "string"
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
/** Narrow `ssoProvider` table definition (SSO plugin model). */
|
|
122
|
+
const authSsoProviderPg = pgTable("ssoProvider", {
|
|
123
|
+
id: text("id").primaryKey(),
|
|
124
|
+
issuer: text("issuer").notNull(),
|
|
125
|
+
oidcConfig: text("oidc_config"),
|
|
126
|
+
samlConfig: text("saml_config"),
|
|
127
|
+
userId: text("user_id").notNull().references(() => authUserPg.id, { onDelete: "cascade" }),
|
|
128
|
+
providerId: text("provider_id").notNull().unique(),
|
|
129
|
+
organizationId: text("organization_id"),
|
|
130
|
+
domain: text("domain").notNull()
|
|
131
|
+
});
|
|
132
|
+
/** Table handles for the Better Auth base models, keyed by model name. */
|
|
133
|
+
const baseAuthTablesPg = {
|
|
134
|
+
user: authUserPg,
|
|
135
|
+
session: authSessionPg,
|
|
136
|
+
account: authAccountPg,
|
|
137
|
+
verification: authVerificationPg,
|
|
138
|
+
passkey: authPasskeyPg,
|
|
139
|
+
ssoProvider: authSsoProviderPg
|
|
140
|
+
};
|
|
141
|
+
/** Date-valued fields per base model (ISO strings at rest, Dates in flight). */
|
|
142
|
+
const baseAuthDateFieldsPg = {
|
|
143
|
+
user: ["createdAt", "updatedAt"],
|
|
144
|
+
session: [
|
|
145
|
+
"expiresAt",
|
|
146
|
+
"createdAt",
|
|
147
|
+
"updatedAt"
|
|
148
|
+
],
|
|
149
|
+
account: [
|
|
150
|
+
"accessTokenExpiresAt",
|
|
151
|
+
"refreshTokenExpiresAt",
|
|
152
|
+
"expiresAt",
|
|
153
|
+
"createdAt",
|
|
154
|
+
"updatedAt"
|
|
155
|
+
],
|
|
156
|
+
verification: [
|
|
157
|
+
"expiresAt",
|
|
158
|
+
"createdAt",
|
|
159
|
+
"updatedAt"
|
|
160
|
+
],
|
|
161
|
+
passkey: ["createdAt", "updatedAt"],
|
|
162
|
+
ssoProvider: []
|
|
163
|
+
};
|
|
164
|
+
//#endregion
|
|
165
|
+
export { authAccountPg, authPasskeyPg, authSessionPg, authSsoProviderPg, authUserPg, authVerificationPg, baseAuthDateFieldsPg, baseAuthTablesPg };
|
|
166
|
+
|
|
167
|
+
//# sourceMappingURL=auth-tables-pg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-tables-pg.mjs","names":[],"sources":["../src/auth-tables-pg.ts"],"sourcesContent":["/**\n * Auth table definitions for Postgres (pg-core mirrors of `auth-tables.ts`).\n *\n * Same model names, same camelCase keys, same snake_case columns; timestamps\n * ride `timestamp(..., { mode: \"string\" })` so the bridge keeps exchanging\n * ISO strings, booleans ride native `boolean`. The bridge consumes either\n * dialect through the shared {@link AuthBridgeSchema} registry.\n */\nimport { boolean, integer, pgTable, text, timestamp } from \"drizzle-orm/pg-core\";\n\n/** Narrow `user` table definition (Better Auth base model). */\nexport const authUserPg = pgTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n email: text(\"email\").notNull().unique(),\n emailVerified: boolean(\"email_verified\").notNull().default(false),\n image: text(\"image\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n});\n\n/** Narrow `session` table definition (Better Auth base model). */\nexport const authSessionPg = pgTable(\"session\", {\n id: text(\"id\").primaryKey(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => authUserPg.id, { onDelete: \"cascade\" }),\n token: text(\"token\").notNull().unique(),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n});\n\n/** Narrow `account` table definition (Better Auth base model). */\nexport const authAccountPg = pgTable(\"account\", {\n id: text(\"id\").primaryKey(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => authUserPg.id, { onDelete: \"cascade\" }),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: timestamp(\"access_token_expires_at\", {\n withTimezone: true,\n mode: \"string\",\n }),\n refreshTokenExpiresAt: timestamp(\"refresh_token_expires_at\", {\n withTimezone: true,\n mode: \"string\",\n }),\n scope: text(\"scope\"),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true, mode: \"string\" }),\n password: text(\"password\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n});\n\n/** Narrow `verification` table definition (Better Auth base model). */\nexport const authVerificationPg = pgTable(\"verification\", {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n});\n\n/** Narrow `passkey` table definition (passkey plugin model). */\nexport const authPasskeyPg = pgTable(\"passkey\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\"),\n publicKey: text(\"public_key\").notNull(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => authUserPg.id, { onDelete: \"cascade\" }),\n credentialID: text(\"credential_id\").notNull(),\n counter: integer(\"counter\").notNull(),\n deviceType: text(\"device_type\").notNull(),\n backedUp: boolean(\"backed_up\").notNull().default(false),\n transports: text(\"transports\"),\n aaguid: text(\"aaguid\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true, mode: \"string\" }).notNull(),\n // Nullable like sqlite: the plugin's registration create omits updatedAt.\n updatedAt: timestamp(\"updated_at\", { withTimezone: true, mode: \"string\" }),\n});\n\n/** Narrow `ssoProvider` table definition (SSO plugin model). */\nexport const authSsoProviderPg = pgTable(\"ssoProvider\", {\n id: text(\"id\").primaryKey(),\n issuer: text(\"issuer\").notNull(),\n oidcConfig: text(\"oidc_config\"),\n samlConfig: text(\"saml_config\"),\n userId: text(\"user_id\")\n .notNull()\n .references(() => authUserPg.id, { onDelete: \"cascade\" }),\n providerId: text(\"provider_id\").notNull().unique(),\n organizationId: text(\"organization_id\"),\n domain: text(\"domain\").notNull(),\n});\n\n/** Table handles for the Better Auth base models, keyed by model name. */\nexport const baseAuthTablesPg = {\n user: authUserPg,\n session: authSessionPg,\n account: authAccountPg,\n verification: authVerificationPg,\n passkey: authPasskeyPg,\n ssoProvider: authSsoProviderPg,\n};\n\n/** Date-valued fields per base model (ISO strings at rest, Dates in flight). */\nexport const baseAuthDateFieldsPg: Record<string, string[]> = {\n user: [\"createdAt\", \"updatedAt\"],\n session: [\"expiresAt\", \"createdAt\", \"updatedAt\"],\n account: [\"accessTokenExpiresAt\", \"refreshTokenExpiresAt\", \"expiresAt\", \"createdAt\", \"updatedAt\"],\n verification: [\"expiresAt\", \"createdAt\", \"updatedAt\"],\n passkey: [\"createdAt\", \"updatedAt\"],\n ssoProvider: [],\n};\n"],"mappings":"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"}
|