@yielded/auth-persistence-drizzle 0.1.0-beta.21 → 0.1.0-beta.23
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/Libsql.d.mts +19 -19
- package/dist/Mysql2.d.mts +14 -14
- package/dist/Pglite.d.mts +14 -14
- package/dist/Postgres.d.mts +6 -6
- package/dist/SqliteBun.d.mts +27 -27
- package/dist/SqliteDo.d.mts +13 -13
- package/dist/SqliteNode.d.mts +23 -23
- package/dist/SqliteWasm.d.mts +13 -13
- package/dist/drizzle/d1-password-prepared.d.mts +3 -3
- package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
- package/dist/drizzle/d1-passwords.d.mts +8 -9
- package/dist/drizzle/d1-passwords.mjs +103 -173
- package/dist/drizzle/d1-passwords.mjs.map +1 -1
- package/dist/drizzle/d1-proofs.d.mts +1 -1
- package/dist/drizzle/d1-sessions.d.mts +1 -1
- package/dist/drizzle/mysql-password-prepared.d.mts +5 -5
- package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
- package/dist/drizzle/mysql-passwords.d.mts +9 -9
- package/dist/drizzle/mysql-passwords.mjs.map +1 -1
- package/dist/drizzle/native-sql-table.mjs +110 -0
- package/dist/drizzle/native-sql-table.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-target.d.mts +5 -5
- package/dist/drizzle/oauth-target.d.mts +1 -1
- package/dist/drizzle/password-model.d.mts +5 -7
- package/dist/drizzle/password-prepared-model.d.mts +5 -5
- package/dist/drizzle/password-prepared-model.mjs.map +1 -1
- package/dist/drizzle/password-sql.mjs +2 -1
- package/dist/drizzle/password-sql.mjs.map +1 -1
- package/dist/drizzle/password-target.mjs +13 -2
- package/dist/drizzle/password-target.mjs.map +1 -1
- package/dist/drizzle/pg-password-prepared.d.mts +5 -5
- package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
- package/dist/drizzle/pg-passwords.d.mts +9 -9
- package/dist/drizzle/pg-passwords.mjs.map +1 -1
- package/dist/drizzle/phone-target.d.mts +1 -1
- package/dist/drizzle/session-sql.mjs +2 -1
- package/dist/drizzle/session-sql.mjs.map +1 -1
- package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
- package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
- package/dist/drizzle/storage-validation.mjs +0 -13
- package/dist/drizzle/storage-validation.mjs.map +1 -1
- package/dist/drizzle/totp-target.d.mts +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/internal/drizzle-postgres.mjs +2 -0
- package/dist/internal/drizzle-postgres.mjs.map +1 -1
- package/dist/internal/drizzle-sqlite.mjs +2 -0
- package/dist/internal/drizzle-sqlite.mjs.map +1 -1
- package/package.json +1 -1
- package/src/drizzle/d1-password-prepared.ts +2 -20
- package/src/drizzle/d1-passwords.ts +232 -519
- package/src/drizzle/mysql-password-prepared.ts +4 -12
- package/src/drizzle/mysql-passwords.ts +5 -15
- package/src/drizzle/native-sql-table.ts +229 -0
- package/src/drizzle/password-model.ts +0 -20
- package/src/drizzle/password-prepared-model.ts +0 -12
- package/src/drizzle/password-sql.ts +3 -0
- package/src/drizzle/password-target.ts +41 -4
- package/src/drizzle/pg-password-prepared.ts +4 -12
- package/src/drizzle/pg-passwords.ts +5 -15
- package/src/drizzle/session-sql.ts +2 -1
- package/src/drizzle/sqlite-password-prepared.ts +4 -48
- package/src/drizzle/sqlite-passwords.ts +7 -21
- package/src/drizzle/storage-validation.ts +0 -8
- package/src/index.ts +0 -4
- package/src/internal/drizzle-postgres.ts +2 -0
- package/src/internal/drizzle-sqlite.ts +2 -0
|
@@ -30,8 +30,6 @@ export const makeMySqlPasswordPreparedPersistenceServices = <
|
|
|
30
30
|
C extends AnyMySqlTable,
|
|
31
31
|
AC extends AnyMySqlTable,
|
|
32
32
|
A extends AnyMySqlTable,
|
|
33
|
-
RS extends AnyMySqlTable,
|
|
34
|
-
CE extends AnyMySqlTable,
|
|
35
33
|
M extends AnyMySqlTable,
|
|
36
34
|
T extends AnyMySqlTable,
|
|
37
35
|
B extends AnyMySqlTable,
|
|
@@ -44,7 +42,7 @@ export const makeMySqlPasswordPreparedPersistenceServices = <
|
|
|
44
42
|
PCr extends AnyMySqlTable = AnyMySqlTable,
|
|
45
43
|
PNativeId = unknown,
|
|
46
44
|
>(
|
|
47
|
-
mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
45
|
+
mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>,
|
|
48
46
|
proofMapping?: PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>,
|
|
49
47
|
) =>
|
|
50
48
|
Effect.flatMap(
|
|
@@ -64,8 +62,6 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
64
62
|
C extends AnyMySqlTable,
|
|
65
63
|
AC extends AnyMySqlTable,
|
|
66
64
|
A extends AnyMySqlTable,
|
|
67
|
-
RS extends AnyMySqlTable,
|
|
68
|
-
CE extends AnyMySqlTable,
|
|
69
65
|
M extends AnyMySqlTable,
|
|
70
66
|
T extends AnyMySqlTable,
|
|
71
67
|
B extends AnyMySqlTable,
|
|
@@ -85,7 +81,7 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
85
81
|
>(
|
|
86
82
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
87
83
|
options: {
|
|
88
|
-
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
84
|
+
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>;
|
|
89
85
|
readonly proofMapping?:
|
|
90
86
|
| PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>
|
|
91
87
|
| undefined;
|
|
@@ -107,8 +103,6 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
107
103
|
C extends AnyMySqlTable,
|
|
108
104
|
AC extends AnyMySqlTable,
|
|
109
105
|
A extends AnyMySqlTable,
|
|
110
|
-
RS extends AnyMySqlTable,
|
|
111
|
-
CE extends AnyMySqlTable,
|
|
112
106
|
M extends AnyMySqlTable,
|
|
113
107
|
T extends AnyMySqlTable,
|
|
114
108
|
B extends AnyMySqlTable,
|
|
@@ -130,7 +124,7 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
130
124
|
>(
|
|
131
125
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
132
126
|
options: {
|
|
133
|
-
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
127
|
+
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>;
|
|
134
128
|
readonly proofMapping?:
|
|
135
129
|
| PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>
|
|
136
130
|
| undefined;
|
|
@@ -152,8 +146,6 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
152
146
|
C extends AnyMySqlTable,
|
|
153
147
|
AC extends AnyMySqlTable,
|
|
154
148
|
A extends AnyMySqlTable,
|
|
155
|
-
RS extends AnyMySqlTable,
|
|
156
|
-
CE extends AnyMySqlTable,
|
|
157
149
|
M extends AnyMySqlTable,
|
|
158
150
|
T extends AnyMySqlTable,
|
|
159
151
|
B extends AnyMySqlTable,
|
|
@@ -175,7 +167,7 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
175
167
|
>(
|
|
176
168
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
177
169
|
options: {
|
|
178
|
-
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
170
|
+
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>;
|
|
179
171
|
readonly proofMapping?:
|
|
180
172
|
| PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>
|
|
181
173
|
| undefined;
|
|
@@ -56,11 +56,9 @@ type Mapping<
|
|
|
56
56
|
C extends AnyMySqlTable,
|
|
57
57
|
AC extends AnyMySqlTable,
|
|
58
58
|
A extends AnyMySqlTable,
|
|
59
|
-
RS extends AnyMySqlTable,
|
|
60
|
-
CE extends AnyMySqlTable,
|
|
61
59
|
M extends AnyMySqlTable,
|
|
62
60
|
NativeId,
|
|
63
|
-
> = PasswordPersistenceMapping<S, I, C, AC, A,
|
|
61
|
+
> = PasswordPersistenceMapping<S, I, C, AC, A, M, NativeId>;
|
|
64
62
|
|
|
65
63
|
export const makeMysqlPasswordPersistenceServices = <
|
|
66
64
|
S extends AnyMySqlTable,
|
|
@@ -68,12 +66,10 @@ export const makeMysqlPasswordPersistenceServices = <
|
|
|
68
66
|
C extends AnyMySqlTable,
|
|
69
67
|
AC extends AnyMySqlTable,
|
|
70
68
|
A extends AnyMySqlTable,
|
|
71
|
-
RS extends AnyMySqlTable,
|
|
72
|
-
CE extends AnyMySqlTable,
|
|
73
69
|
M extends AnyMySqlTable,
|
|
74
70
|
NativeId,
|
|
75
71
|
>(
|
|
76
|
-
mapping: Mapping<S, I, C, AC, A,
|
|
72
|
+
mapping: Mapping<S, I, C, AC, A, M, NativeId>,
|
|
77
73
|
proofMapping?: ProofPersistenceMapping<
|
|
78
74
|
any,
|
|
79
75
|
any,
|
|
@@ -104,8 +100,6 @@ export function coordinateMysqlPasswordPersistence<
|
|
|
104
100
|
C extends AnyMySqlTable,
|
|
105
101
|
AC extends AnyMySqlTable,
|
|
106
102
|
A extends AnyMySqlTable,
|
|
107
|
-
RS extends AnyMySqlTable,
|
|
108
|
-
CE extends AnyMySqlTable,
|
|
109
103
|
M extends AnyMySqlTable,
|
|
110
104
|
NativeId,
|
|
111
105
|
PM extends
|
|
@@ -119,7 +113,7 @@ export function coordinateMysqlPasswordPersistence<
|
|
|
119
113
|
>(
|
|
120
114
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
121
115
|
options: {
|
|
122
|
-
readonly mapping: Mapping<S, I, C, AC, A,
|
|
116
|
+
readonly mapping: Mapping<S, I, C, AC, A, M, NativeId>;
|
|
123
117
|
readonly proofMapping?: PM;
|
|
124
118
|
readonly transaction?: never;
|
|
125
119
|
},
|
|
@@ -137,8 +131,6 @@ export function coordinateMysqlPasswordPersistence<
|
|
|
137
131
|
C extends AnyMySqlTable,
|
|
138
132
|
AC extends AnyMySqlTable,
|
|
139
133
|
A extends AnyMySqlTable,
|
|
140
|
-
RS extends AnyMySqlTable,
|
|
141
|
-
CE extends AnyMySqlTable,
|
|
142
134
|
M extends AnyMySqlTable,
|
|
143
135
|
NativeId,
|
|
144
136
|
PM extends
|
|
@@ -154,7 +146,7 @@ export function coordinateMysqlPasswordPersistence<
|
|
|
154
146
|
>(
|
|
155
147
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
156
148
|
options: {
|
|
157
|
-
readonly mapping: Mapping<S, I, C, AC, A,
|
|
149
|
+
readonly mapping: Mapping<S, I, C, AC, A, M, NativeId>;
|
|
158
150
|
readonly proofMapping?: PM;
|
|
159
151
|
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
160
152
|
},
|
|
@@ -172,8 +164,6 @@ export function coordinateMysqlPasswordPersistence<
|
|
|
172
164
|
C extends AnyMySqlTable,
|
|
173
165
|
AC extends AnyMySqlTable,
|
|
174
166
|
A extends AnyMySqlTable,
|
|
175
|
-
RS extends AnyMySqlTable,
|
|
176
|
-
CE extends AnyMySqlTable,
|
|
177
167
|
M extends AnyMySqlTable,
|
|
178
168
|
NativeId,
|
|
179
169
|
PM extends
|
|
@@ -189,7 +179,7 @@ export function coordinateMysqlPasswordPersistence<
|
|
|
189
179
|
>(
|
|
190
180
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
191
181
|
options: {
|
|
192
|
-
readonly mapping: Mapping<S, I, C, AC, A,
|
|
182
|
+
readonly mapping: Mapping<S, I, C, AC, A, M, NativeId>;
|
|
193
183
|
readonly proofMapping?: PM;
|
|
194
184
|
readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
195
185
|
},
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PersistenceMappingError,
|
|
3
|
+
makeNativeSqlTables,
|
|
4
|
+
nativeSqlAlias,
|
|
5
|
+
type NativeSqlTables,
|
|
6
|
+
type SqlTable,
|
|
7
|
+
} from "@yielded/auth-persistence/Adapter";
|
|
8
|
+
import {
|
|
9
|
+
getTableColumns,
|
|
10
|
+
is,
|
|
11
|
+
Param,
|
|
12
|
+
Placeholder,
|
|
13
|
+
type SQL,
|
|
14
|
+
Table,
|
|
15
|
+
sql,
|
|
16
|
+
type BuildQueryConfig,
|
|
17
|
+
type SQLWrapper,
|
|
18
|
+
} from "drizzle-orm";
|
|
19
|
+
import { Predicate } from "effect";
|
|
20
|
+
import type { SqlClient } from "effect/sql/SqlClient";
|
|
21
|
+
import * as Statement from "effect/sql/Statement";
|
|
22
|
+
|
|
23
|
+
type CapturedDialect = Pick<BuildQueryConfig, "escapeName" | "escapeString" | "codecs">;
|
|
24
|
+
|
|
25
|
+
/** Foreign compiler boundary only: builders are used to materialize SQL, never
|
|
26
|
+
* executed. The select builder exposes the original dialect even through the
|
|
27
|
+
* Durable Object database projection, which retains bound query methods. */
|
|
28
|
+
interface CapturedDatabase {
|
|
29
|
+
readonly select: () => { readonly dialect: CapturedDialect };
|
|
30
|
+
readonly insert: (table: Table) => {
|
|
31
|
+
readonly values: (values: Record<string, unknown>) => SQLWrapper;
|
|
32
|
+
};
|
|
33
|
+
readonly update: (table: Table) => {
|
|
34
|
+
readonly set: (values: Record<string, unknown>) => SQLWrapper;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const invalid = (cause: string): never => {
|
|
39
|
+
throw PersistenceMappingError.make({ operation: "mapping", cause });
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const capture = (
|
|
43
|
+
database: object,
|
|
44
|
+
): { readonly database: CapturedDatabase; readonly dialect: CapturedDialect } => {
|
|
45
|
+
if (
|
|
46
|
+
!Predicate.hasProperty(database, "select") ||
|
|
47
|
+
typeof database.select !== "function" ||
|
|
48
|
+
!Predicate.hasProperty(database, "insert") ||
|
|
49
|
+
typeof database.insert !== "function" ||
|
|
50
|
+
!Predicate.hasProperty(database, "update") ||
|
|
51
|
+
typeof database.update !== "function"
|
|
52
|
+
)
|
|
53
|
+
return invalid("Expected a captured Drizzle database");
|
|
54
|
+
|
|
55
|
+
const selection: unknown = database.select();
|
|
56
|
+
|
|
57
|
+
if (!Predicate.hasProperty(selection, "dialect"))
|
|
58
|
+
return invalid("Expected a captured Drizzle dialect");
|
|
59
|
+
const dialect = selection.dialect;
|
|
60
|
+
|
|
61
|
+
if (
|
|
62
|
+
!Predicate.hasProperty(dialect, "escapeName") ||
|
|
63
|
+
typeof dialect.escapeName !== "function" ||
|
|
64
|
+
!Predicate.hasProperty(dialect, "escapeString") ||
|
|
65
|
+
typeof dialect.escapeString !== "function"
|
|
66
|
+
)
|
|
67
|
+
return invalid("Expected Drizzle dialect escaping methods");
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
Predicate.hasProperty(dialect, "codecs") &&
|
|
71
|
+
dialect.codecs !== undefined &&
|
|
72
|
+
(!Predicate.hasProperty(dialect.codecs, "apply") || typeof dialect.codecs.apply !== "function")
|
|
73
|
+
)
|
|
74
|
+
return invalid("Expected Drizzle dialect codecs");
|
|
75
|
+
|
|
76
|
+
// Drizzle's private dialect and generic query builders are erased only here.
|
|
77
|
+
return { database: database as CapturedDatabase, dialect: dialect as CapturedDialect };
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const compileWith =
|
|
81
|
+
(dialect: CapturedDialect) =>
|
|
82
|
+
(expression: SQL): Statement.Fragment => {
|
|
83
|
+
const slots: string[] = [];
|
|
84
|
+
|
|
85
|
+
const query = expression.toQuery({
|
|
86
|
+
escapeName: (name) => {
|
|
87
|
+
if (name.includes("\0")) return invalid("NUL in SQL identifier");
|
|
88
|
+
|
|
89
|
+
return dialect.escapeName(name);
|
|
90
|
+
},
|
|
91
|
+
escapeString: (value) => {
|
|
92
|
+
if (value.includes("\0")) return invalid("NUL in SQL literal");
|
|
93
|
+
|
|
94
|
+
return dialect.escapeString(value);
|
|
95
|
+
},
|
|
96
|
+
escapeParam: (index) => {
|
|
97
|
+
if (index !== slots.length) return invalid("Invalid Drizzle parameter order");
|
|
98
|
+
const slot = `yielded_parameter_${index}`;
|
|
99
|
+
|
|
100
|
+
slots.push(slot);
|
|
101
|
+
|
|
102
|
+
return `\0${slot}\0`;
|
|
103
|
+
},
|
|
104
|
+
...(dialect.codecs === undefined ? {} : { codecs: dialect.codecs }),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Only compiler-emitted slots are translated. Native Statement parameters
|
|
108
|
+
// receive their final positions when composed; SQL literals containing $1 or
|
|
109
|
+
// ? are never inspected or rewritten. NUL is reserved for this compilation.
|
|
110
|
+
const parts = query.sql.split("\0");
|
|
111
|
+
|
|
112
|
+
if (parts.length !== slots.length * 2 + 1 || query.params.length !== slots.length)
|
|
113
|
+
return invalid("NUL or parameter marker collision in Drizzle SQL");
|
|
114
|
+
|
|
115
|
+
const segments: Statement.Segment[] = [];
|
|
116
|
+
const consumed = new Set<number>();
|
|
117
|
+
|
|
118
|
+
for (let offset = 0; offset < parts.length; offset += 2) {
|
|
119
|
+
segments.push(Statement.literal(parts[offset]));
|
|
120
|
+
if (offset + 1 === parts.length) break;
|
|
121
|
+
const index = slots.indexOf(parts[offset + 1]);
|
|
122
|
+
|
|
123
|
+
if (index < 0 || consumed.has(index))
|
|
124
|
+
return invalid("NUL or parameter marker collision in Drizzle SQL");
|
|
125
|
+
consumed.add(index);
|
|
126
|
+
const value: unknown = query.params[index];
|
|
127
|
+
|
|
128
|
+
if (is(value, Placeholder) || is(value, Param)) return invalid("Unbound Drizzle placeholder");
|
|
129
|
+
if (Statement.isFragment(value)) segments.push(...value.segments);
|
|
130
|
+
else segments.push(Statement.parameter(value));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return Statement.fragment(segments);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/** Preserve native Statement expressions in writes without applying a column
|
|
137
|
+
* codec to them. Ordinary values still pass through Drizzle's own builders. */
|
|
138
|
+
const writeValues = (values: Readonly<Record<string, unknown>>) =>
|
|
139
|
+
Object.fromEntries(
|
|
140
|
+
Object.entries(values).map(([key, value]) => [
|
|
141
|
+
key,
|
|
142
|
+
Statement.isFragment(value) ? sql`${sql.param(value)}` : value,
|
|
143
|
+
]),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
/** Capture the root database's compiler, not a later transaction object's
|
|
147
|
+
* client. Call insert/update inside the operation to materialize hooks once. */
|
|
148
|
+
export const makeDrizzleSqlTables = (
|
|
149
|
+
client: SqlClient,
|
|
150
|
+
capturedDatabase: object,
|
|
151
|
+
): NativeSqlTables => {
|
|
152
|
+
const { database, dialect } = capture(capturedDatabase);
|
|
153
|
+
const compile = compileWith(dialect);
|
|
154
|
+
|
|
155
|
+
return makeNativeSqlTables(client, (_client, physical): SqlTable => {
|
|
156
|
+
if (!is(physical, Table)) return invalid("Expected a Drizzle table");
|
|
157
|
+
const columns = getTableColumns(physical);
|
|
158
|
+
const entries = Object.entries(columns);
|
|
159
|
+
|
|
160
|
+
const getColumn = (key: string) => {
|
|
161
|
+
const column = Object.hasOwn(columns, key) ? columns[key] : undefined;
|
|
162
|
+
|
|
163
|
+
if (column === undefined) return invalid("Missing Drizzle column");
|
|
164
|
+
|
|
165
|
+
return column;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const bind = (alias?: string): SqlTable => {
|
|
169
|
+
const reference = (key: string) => {
|
|
170
|
+
const column = getColumn(key);
|
|
171
|
+
|
|
172
|
+
return alias === undefined
|
|
173
|
+
? sql`${column}`
|
|
174
|
+
: sql`${sql.identifier(alias)}.${sql.identifier(column.name)}`;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
name: compile(
|
|
179
|
+
alias === undefined ? sql`${physical}` : sql`${physical} AS ${sql.identifier(alias)}`,
|
|
180
|
+
),
|
|
181
|
+
as: bind,
|
|
182
|
+
column: (key) => compile(reference(key)),
|
|
183
|
+
fields: (prefix) =>
|
|
184
|
+
compile(
|
|
185
|
+
sql.join(
|
|
186
|
+
entries.map(([key, column], index) => {
|
|
187
|
+
const selection =
|
|
188
|
+
dialect.codecs === undefined
|
|
189
|
+
? reference(key)
|
|
190
|
+
: dialect.codecs.apply(column, "cast", reference(key));
|
|
191
|
+
|
|
192
|
+
return sql`${selection} as ${sql.identifier(nativeSqlAlias(prefix, index))}`;
|
|
193
|
+
}),
|
|
194
|
+
sql`, `,
|
|
195
|
+
),
|
|
196
|
+
),
|
|
197
|
+
decode: (row, prefix) =>
|
|
198
|
+
Object.fromEntries(
|
|
199
|
+
entries.map(([key, column], index) => {
|
|
200
|
+
const alias = nativeSqlAlias(prefix, index);
|
|
201
|
+
|
|
202
|
+
if (!Object.hasOwn(row, alias)) return invalid("Missing SQL projection field");
|
|
203
|
+
const value = row[alias];
|
|
204
|
+
|
|
205
|
+
return [
|
|
206
|
+
key,
|
|
207
|
+
value === null
|
|
208
|
+
? null
|
|
209
|
+
: column.mapFromDriverValue(
|
|
210
|
+
dialect.codecs === undefined
|
|
211
|
+
? value
|
|
212
|
+
: dialect.codecs.apply(column, "normalize", value),
|
|
213
|
+
),
|
|
214
|
+
];
|
|
215
|
+
}),
|
|
216
|
+
),
|
|
217
|
+
value: (key, value) => {
|
|
218
|
+
const column = getColumn(key);
|
|
219
|
+
|
|
220
|
+
return Statement.isFragment(value) ? value : compile(sql`${sql.param(value, column)}`);
|
|
221
|
+
},
|
|
222
|
+
insert: (values) => compile(database.insert(physical).values(writeValues(values)).getSQL()),
|
|
223
|
+
update: (values) => compile(database.update(physical).set(writeValues(values)).getSQL()),
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
return bind();
|
|
228
|
+
});
|
|
229
|
+
};
|
|
@@ -6,8 +6,6 @@ import type { DrizzleTableModel } from "./table-model";
|
|
|
6
6
|
export {
|
|
7
7
|
type PasswordAttemptAction,
|
|
8
8
|
type PasswordAttemptState,
|
|
9
|
-
type PasswordRateScopeKind,
|
|
10
|
-
type PasswordScopeKeys,
|
|
11
9
|
type PasswordAttemptRecord,
|
|
12
10
|
type RequiredPasswordConstraints,
|
|
13
11
|
requiredPasswordConstraints,
|
|
@@ -51,14 +49,6 @@ export type PasswordAttemptTable<
|
|
|
51
49
|
NativeSubjectId,
|
|
52
50
|
> = Shared.PasswordAttemptTable<DrizzleTableModel<Attempt>, NativeSubjectId>;
|
|
53
51
|
|
|
54
|
-
export type PasswordRateScopeTable<RateScope extends Table> = Shared.PasswordRateScopeTable<
|
|
55
|
-
DrizzleTableModel<RateScope>
|
|
56
|
-
>;
|
|
57
|
-
|
|
58
|
-
export type PasswordChargeTable<Charge extends Table> = Shared.PasswordChargeTable<
|
|
59
|
-
DrizzleTableModel<Charge>
|
|
60
|
-
>;
|
|
61
|
-
|
|
62
52
|
export type PasswordCommandTable<Command extends Table> = Shared.PasswordCommandTable<
|
|
63
53
|
DrizzleTableModel<Command>
|
|
64
54
|
>;
|
|
@@ -71,8 +61,6 @@ export type PasswordPersistenceMapping<
|
|
|
71
61
|
Credential extends Table,
|
|
72
62
|
AuthorityCredential extends Table,
|
|
73
63
|
Attempt extends Table,
|
|
74
|
-
RateScope extends Table,
|
|
75
|
-
Charge extends Table,
|
|
76
64
|
Command extends Table,
|
|
77
65
|
NativeSubjectId,
|
|
78
66
|
> = Shared.PasswordPersistenceMapping<
|
|
@@ -81,8 +69,6 @@ export type PasswordPersistenceMapping<
|
|
|
81
69
|
DrizzleTableModel<Credential>,
|
|
82
70
|
DrizzleTableModel<AuthorityCredential>,
|
|
83
71
|
DrizzleTableModel<Attempt>,
|
|
84
|
-
DrizzleTableModel<RateScope>,
|
|
85
|
-
DrizzleTableModel<Charge>,
|
|
86
72
|
DrizzleTableModel<Command>,
|
|
87
73
|
NativeSubjectId,
|
|
88
74
|
SQL
|
|
@@ -94,8 +80,6 @@ export type D1PasswordPersistenceMapping<
|
|
|
94
80
|
Credential extends Table,
|
|
95
81
|
AuthorityCredential extends Table,
|
|
96
82
|
Attempt extends Table,
|
|
97
|
-
RateScope extends Table,
|
|
98
|
-
Charge extends Table,
|
|
99
83
|
Command extends Table,
|
|
100
84
|
NativeSubjectId,
|
|
101
85
|
> = Shared.D1PasswordPersistenceMapping<
|
|
@@ -104,8 +88,6 @@ export type D1PasswordPersistenceMapping<
|
|
|
104
88
|
DrizzleTableModel<Credential>,
|
|
105
89
|
DrizzleTableModel<AuthorityCredential>,
|
|
106
90
|
DrizzleTableModel<Attempt>,
|
|
107
|
-
DrizzleTableModel<RateScope>,
|
|
108
|
-
DrizzleTableModel<Charge>,
|
|
109
91
|
DrizzleTableModel<Command>,
|
|
110
92
|
NativeSubjectId,
|
|
111
93
|
SQL
|
|
@@ -153,8 +135,6 @@ export type AnyPasswordPersistenceMapping = PasswordPersistenceMapping<
|
|
|
153
135
|
Table,
|
|
154
136
|
Table,
|
|
155
137
|
Table,
|
|
156
|
-
Table,
|
|
157
|
-
Table,
|
|
158
138
|
unknown
|
|
159
139
|
>;
|
|
160
140
|
|
|
@@ -87,8 +87,6 @@ export interface PasswordPreparedPersistenceMapping<
|
|
|
87
87
|
Credential extends Table,
|
|
88
88
|
AuthorityCredential extends Table,
|
|
89
89
|
Attempt extends Table,
|
|
90
|
-
RateScope extends Table,
|
|
91
|
-
Charge extends Table,
|
|
92
90
|
Command extends Table,
|
|
93
91
|
Intent extends Table,
|
|
94
92
|
Admission extends Table,
|
|
@@ -100,8 +98,6 @@ export interface PasswordPreparedPersistenceMapping<
|
|
|
100
98
|
Credential,
|
|
101
99
|
AuthorityCredential,
|
|
102
100
|
Attempt,
|
|
103
|
-
RateScope,
|
|
104
|
-
Charge,
|
|
105
101
|
Command,
|
|
106
102
|
NativeSubjectId
|
|
107
103
|
>;
|
|
@@ -119,8 +115,6 @@ export type D1PasswordPreparedPersistenceMapping<
|
|
|
119
115
|
Credential extends Table,
|
|
120
116
|
AuthorityCredential extends Table,
|
|
121
117
|
Attempt extends Table,
|
|
122
|
-
RateScope extends Table,
|
|
123
|
-
Charge extends Table,
|
|
124
118
|
Command extends Table,
|
|
125
119
|
Intent extends Table,
|
|
126
120
|
Admission extends Table,
|
|
@@ -131,8 +125,6 @@ export type D1PasswordPreparedPersistenceMapping<
|
|
|
131
125
|
Credential,
|
|
132
126
|
AuthorityCredential,
|
|
133
127
|
Attempt,
|
|
134
|
-
RateScope,
|
|
135
|
-
Charge,
|
|
136
128
|
Command,
|
|
137
129
|
Intent,
|
|
138
130
|
Admission,
|
|
@@ -146,8 +138,6 @@ export type D1PasswordPreparedPersistenceMapping<
|
|
|
146
138
|
Credential,
|
|
147
139
|
AuthorityCredential,
|
|
148
140
|
Attempt,
|
|
149
|
-
RateScope,
|
|
150
|
-
Charge,
|
|
151
141
|
Command,
|
|
152
142
|
NativeSubjectId
|
|
153
143
|
>;
|
|
@@ -253,7 +243,5 @@ export type AnyPasswordPreparedPersistenceMapping = PasswordPreparedPersistenceM
|
|
|
253
243
|
Table,
|
|
254
244
|
Table,
|
|
255
245
|
Table,
|
|
256
|
-
Table,
|
|
257
|
-
Table,
|
|
258
246
|
unknown
|
|
259
247
|
>;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { makePasswordKernel } from "@yielded/auth-persistence/Adapter";
|
|
2
2
|
|
|
3
|
+
import { makeDrizzleSqlTables } from "./native-sql-table";
|
|
3
4
|
import { completeProofPlanIn } from "./proof-sql";
|
|
4
5
|
import { drizzleQueryOperations } from "./query-operations";
|
|
5
6
|
export type { PasswordSqlQuery } from "@yielded/auth-persistence/Adapter";
|
|
6
7
|
export type { PasswordSqlDatabase } from "@yielded/auth-persistence/Adapter";
|
|
7
8
|
export { CurrentPasswordSql } from "@yielded/auth-persistence/Adapter";
|
|
9
|
+
|
|
8
10
|
export type { PasswordSqlConfiguration } from "@yielded/auth-persistence/Adapter";
|
|
9
11
|
|
|
10
12
|
export const { makeSqlPasswordPersistence, passwordSqlKernel } = makePasswordKernel(
|
|
11
13
|
drizzleQueryOperations,
|
|
12
14
|
{ completeProofPlanIn },
|
|
15
|
+
makeDrizzleSqlTables,
|
|
13
16
|
);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
CurrentPasswordPreparedTransaction,
|
|
3
|
+
type NativeDatabase,
|
|
4
|
+
type PasswordPreparedPostcondition,
|
|
5
|
+
PasswordPreparedPostconditions,
|
|
6
|
+
} from "@yielded/auth-persistence/Adapter";
|
|
2
7
|
import {
|
|
3
8
|
coordinateCommit,
|
|
4
9
|
hasCommitScope,
|
|
@@ -7,7 +12,7 @@ import {
|
|
|
7
12
|
} from "@yielded/auth/Hooks";
|
|
8
13
|
import { PasswordUnavailable, PasswordPersistence } from "@yielded/auth/Password";
|
|
9
14
|
/* oxlint-disable no-explicit-any -- public driver wrappers restore concrete Drizzle generics. */
|
|
10
|
-
import { type Context, Effect, Layer } from "effect";
|
|
15
|
+
import { Cause, type Context, Effect, Layer } from "effect";
|
|
11
16
|
import type * as SqlError from "effect/sql/SqlError";
|
|
12
17
|
|
|
13
18
|
import {
|
|
@@ -154,7 +159,10 @@ export const coordinateTargetPasswordPersistence = <Transaction, A, E, R>(
|
|
|
154
159
|
() =>
|
|
155
160
|
database.transaction((transaction) =>
|
|
156
161
|
Effect.gen(function* () {
|
|
157
|
-
|
|
162
|
+
const postconditions: Array<PasswordPreparedPostcondition> = [];
|
|
163
|
+
let acceptingPostconditions = true;
|
|
164
|
+
|
|
165
|
+
const value = yield* owner(transaction, {
|
|
158
166
|
passwordPersistence: yield* makeSqlPasswordPersistence(
|
|
159
167
|
mapping,
|
|
160
168
|
passwordOptions(configuration, proofMapping, true),
|
|
@@ -164,7 +172,36 @@ export const coordinateTargetPasswordPersistence = <Transaction, A, E, R>(
|
|
|
164
172
|
transaction as unknown as PasswordSqlDatabase,
|
|
165
173
|
),
|
|
166
174
|
),
|
|
167
|
-
})
|
|
175
|
+
}).pipe(
|
|
176
|
+
Effect.provideService(PasswordPreparedPostconditions, {
|
|
177
|
+
register: (check) => {
|
|
178
|
+
if (!acceptingPostconditions) return false;
|
|
179
|
+
postconditions.push(check);
|
|
180
|
+
|
|
181
|
+
return true;
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
184
|
+
Effect.ensuring(
|
|
185
|
+
Effect.sync(() => {
|
|
186
|
+
acceptingPostconditions = false;
|
|
187
|
+
}),
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Application work in this transaction must not change what the
|
|
192
|
+
// password mutations committed to; a failure here rolls back both.
|
|
193
|
+
for (const check of postconditions)
|
|
194
|
+
yield* check.pipe(
|
|
195
|
+
Effect.provideService(
|
|
196
|
+
CurrentPasswordPreparedTransaction,
|
|
197
|
+
transaction as unknown as PasswordSqlDatabase,
|
|
198
|
+
),
|
|
199
|
+
Effect.catchCause((cause) =>
|
|
200
|
+
Effect.failCause(Cause.map(cause, () => PasswordUnavailable.make({}))),
|
|
201
|
+
),
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
return value;
|
|
168
205
|
}),
|
|
169
206
|
),
|
|
170
207
|
{ mode: configuration.mode },
|
|
@@ -31,8 +31,6 @@ export const makePgPasswordPreparedPersistenceServices = <
|
|
|
31
31
|
C extends AnyPgTable,
|
|
32
32
|
AC extends AnyPgTable,
|
|
33
33
|
A extends AnyPgTable,
|
|
34
|
-
RS extends AnyPgTable,
|
|
35
|
-
CE extends AnyPgTable,
|
|
36
34
|
M extends AnyPgTable,
|
|
37
35
|
T extends AnyPgTable,
|
|
38
36
|
B extends AnyPgTable,
|
|
@@ -45,7 +43,7 @@ export const makePgPasswordPreparedPersistenceServices = <
|
|
|
45
43
|
PCr extends AnyPgTable = AnyPgTable,
|
|
46
44
|
PNativeId = unknown,
|
|
47
45
|
>(
|
|
48
|
-
mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
46
|
+
mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>,
|
|
49
47
|
proofMapping?: PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>,
|
|
50
48
|
) =>
|
|
51
49
|
Effect.flatMap(
|
|
@@ -65,8 +63,6 @@ export function coordinatePgPasswordPreparedPersistence<
|
|
|
65
63
|
C extends AnyPgTable,
|
|
66
64
|
AC extends AnyPgTable,
|
|
67
65
|
A extends AnyPgTable,
|
|
68
|
-
RS extends AnyPgTable,
|
|
69
|
-
CE extends AnyPgTable,
|
|
70
66
|
M extends AnyPgTable,
|
|
71
67
|
T extends AnyPgTable,
|
|
72
68
|
B extends AnyPgTable,
|
|
@@ -86,7 +82,7 @@ export function coordinatePgPasswordPreparedPersistence<
|
|
|
86
82
|
>(
|
|
87
83
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
88
84
|
options: {
|
|
89
|
-
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
85
|
+
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>;
|
|
90
86
|
readonly proofMapping?:
|
|
91
87
|
| PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>
|
|
92
88
|
| undefined;
|
|
@@ -108,8 +104,6 @@ export function coordinatePgPasswordPreparedPersistence<
|
|
|
108
104
|
C extends AnyPgTable,
|
|
109
105
|
AC extends AnyPgTable,
|
|
110
106
|
A extends AnyPgTable,
|
|
111
|
-
RS extends AnyPgTable,
|
|
112
|
-
CE extends AnyPgTable,
|
|
113
107
|
M extends AnyPgTable,
|
|
114
108
|
T extends AnyPgTable,
|
|
115
109
|
B extends AnyPgTable,
|
|
@@ -131,7 +125,7 @@ export function coordinatePgPasswordPreparedPersistence<
|
|
|
131
125
|
>(
|
|
132
126
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
133
127
|
options: {
|
|
134
|
-
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
128
|
+
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>;
|
|
135
129
|
readonly proofMapping?:
|
|
136
130
|
| PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>
|
|
137
131
|
| undefined;
|
|
@@ -153,8 +147,6 @@ export function coordinatePgPasswordPreparedPersistence<
|
|
|
153
147
|
C extends AnyPgTable,
|
|
154
148
|
AC extends AnyPgTable,
|
|
155
149
|
A extends AnyPgTable,
|
|
156
|
-
RS extends AnyPgTable,
|
|
157
|
-
CE extends AnyPgTable,
|
|
158
150
|
M extends AnyPgTable,
|
|
159
151
|
T extends AnyPgTable,
|
|
160
152
|
B extends AnyPgTable,
|
|
@@ -176,7 +168,7 @@ export function coordinatePgPasswordPreparedPersistence<
|
|
|
176
168
|
>(
|
|
177
169
|
acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,
|
|
178
170
|
options: {
|
|
179
|
-
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A,
|
|
171
|
+
readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, M, T, B, NativeId>;
|
|
180
172
|
readonly proofMapping?:
|
|
181
173
|
| PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>
|
|
182
174
|
| undefined;
|