@yielded/auth-persistence-drizzle 0.1.0-beta.22 → 0.1.0-beta.24

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.
Files changed (200) hide show
  1. package/README.md +3 -0
  2. package/dist/D1.d.mts +11 -11
  3. package/dist/D1.mjs +2 -1
  4. package/dist/D1.mjs.map +1 -1
  5. package/dist/Libsql.d.mts +40 -56
  6. package/dist/Libsql.mjs +2 -1
  7. package/dist/Libsql.mjs.map +1 -1
  8. package/dist/Mysql2.d.mts +16 -17
  9. package/dist/Pglite.d.mts +18 -18
  10. package/dist/Pglite.mjs +2 -1
  11. package/dist/Pglite.mjs.map +1 -1
  12. package/dist/Postgres.d.mts +24 -24
  13. package/dist/Postgres.mjs +2 -1
  14. package/dist/Postgres.mjs.map +1 -1
  15. package/dist/SqliteBun.d.mts +39 -55
  16. package/dist/SqliteBun.mjs +2 -1
  17. package/dist/SqliteBun.mjs.map +1 -1
  18. package/dist/SqliteDo.d.mts +48 -64
  19. package/dist/SqliteDo.mjs +2 -1
  20. package/dist/SqliteDo.mjs.map +1 -1
  21. package/dist/SqliteNode.d.mts +45 -61
  22. package/dist/SqliteNode.mjs +2 -1
  23. package/dist/SqliteNode.mjs.map +1 -1
  24. package/dist/SqliteWasm.d.mts +48 -64
  25. package/dist/SqliteWasm.mjs +2 -1
  26. package/dist/SqliteWasm.mjs.map +1 -1
  27. package/dist/drizzle/crypto.mjs +1 -1
  28. package/dist/drizzle/d1-emails.d.mts +1 -1
  29. package/dist/drizzle/d1-oauth.d.mts +14 -14
  30. package/dist/drizzle/d1-passkey.d.mts +1 -1
  31. package/dist/drizzle/d1-password-prepared.d.mts +4 -4
  32. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  33. package/dist/drizzle/d1-passwords.d.mts +18 -35
  34. package/dist/drizzle/d1-passwords.mjs +78 -290
  35. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  36. package/dist/drizzle/d1-phone.d.mts +1 -1
  37. package/dist/drizzle/d1-proofs.d.mts +2 -2
  38. package/dist/drizzle/d1-sessions.d.mts +3 -3
  39. package/dist/drizzle/d1-sessions.mjs +11 -6
  40. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  41. package/dist/drizzle/d1-totp.d.mts +1 -1
  42. package/dist/drizzle/mysql-password-prepared.d.mts +5 -5
  43. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
  44. package/dist/drizzle/mysql-passwords.d.mts +16 -32
  45. package/dist/drizzle/mysql-passwords.mjs.map +1 -1
  46. package/dist/drizzle/mysql-sessions.d.mts +1 -1
  47. package/dist/drizzle/native-sql-table.mjs +135 -0
  48. package/dist/drizzle/native-sql-table.mjs.map +1 -0
  49. package/dist/drizzle/oauth-connected-model.d.mts +20 -281
  50. package/dist/drizzle/oauth-connected-model.mjs +3 -17
  51. package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
  52. package/dist/drizzle/oauth-connected-reference.d.mts +1 -3
  53. package/dist/drizzle/oauth-connected-reference.mjs +4 -53
  54. package/dist/drizzle/oauth-connected-reference.mjs.map +1 -1
  55. package/dist/drizzle/oauth-connected-target.d.mts +3 -990
  56. package/dist/drizzle/oauth-connected-target.mjs +8 -92
  57. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  58. package/dist/drizzle/oauth-kernel.mjs +11 -0
  59. package/dist/drizzle/oauth-kernel.mjs.map +1 -0
  60. package/dist/drizzle/oauth-model.d.mts +35 -438
  61. package/dist/drizzle/oauth-model.mjs +6 -44
  62. package/dist/drizzle/oauth-model.mjs.map +1 -1
  63. package/dist/drizzle/oauth-mysql.mjs +2 -2
  64. package/dist/drizzle/oauth-mysql.mjs.map +1 -1
  65. package/dist/drizzle/oauth-proxy.d.mts +10 -0
  66. package/dist/drizzle/oauth-proxy.mjs +54 -0
  67. package/dist/drizzle/oauth-proxy.mjs.map +1 -0
  68. package/dist/drizzle/oauth-target.d.mts +6 -107
  69. package/dist/drizzle/oauth-target.mjs +15 -245
  70. package/dist/drizzle/oauth-target.mjs.map +1 -1
  71. package/dist/drizzle/password-model.d.mts +5 -8
  72. package/dist/drizzle/password-prepared-model.d.mts +5 -5
  73. package/dist/drizzle/password-prepared-model.mjs.map +1 -1
  74. package/dist/drizzle/password-prepared-state.mjs +1 -1
  75. package/dist/drizzle/password-sql.mjs +2 -1
  76. package/dist/drizzle/password-sql.mjs.map +1 -1
  77. package/dist/drizzle/password-target.mjs +13 -2
  78. package/dist/drizzle/password-target.mjs.map +1 -1
  79. package/dist/drizzle/pg-password-prepared.d.mts +5 -5
  80. package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
  81. package/dist/drizzle/pg-passwords.d.mts +16 -32
  82. package/dist/drizzle/pg-passwords.mjs.map +1 -1
  83. package/dist/drizzle/pg-sessions.d.mts +1 -1
  84. package/dist/drizzle/phone-target.d.mts +2 -2
  85. package/dist/drizzle/phone-target.mjs +1 -1
  86. package/dist/drizzle/query-operations.mjs +3 -1
  87. package/dist/drizzle/query-operations.mjs.map +1 -1
  88. package/dist/drizzle/session-sql.mjs +2 -1
  89. package/dist/drizzle/session-sql.mjs.map +1 -1
  90. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
  91. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  92. package/dist/drizzle/storage-validation.mjs +10 -198
  93. package/dist/drizzle/storage-validation.mjs.map +1 -1
  94. package/dist/drizzle/totp-target.d.mts +3 -3
  95. package/dist/drizzle/totp-target.mjs +2 -2
  96. package/dist/drizzle/transaction-execution.d.mts +2 -2
  97. package/dist/drizzle/transaction-owner.d.mts +1 -2
  98. package/dist/index.d.mts +3 -2
  99. package/dist/internal/drizzle-postgres-oauth-proxy.d.mts +138 -0
  100. package/dist/internal/drizzle-postgres-oauth-proxy.mjs +29 -0
  101. package/dist/internal/drizzle-postgres-oauth-proxy.mjs.map +1 -0
  102. package/dist/internal/drizzle-postgres.mjs +2 -0
  103. package/dist/internal/drizzle-postgres.mjs.map +1 -1
  104. package/dist/internal/drizzle-sqlite-oauth-proxy.d.mts +146 -0
  105. package/dist/internal/drizzle-sqlite-oauth-proxy.mjs +29 -0
  106. package/dist/internal/drizzle-sqlite-oauth-proxy.mjs.map +1 -0
  107. package/dist/internal/drizzle-sqlite.mjs +2 -0
  108. package/dist/internal/drizzle-sqlite.mjs.map +1 -1
  109. package/package.json +1 -1
  110. package/src/D1.ts +2 -0
  111. package/src/Libsql.ts +2 -0
  112. package/src/Pglite.ts +2 -0
  113. package/src/Postgres.ts +2 -0
  114. package/src/SqliteBun.ts +2 -0
  115. package/src/SqliteDo.ts +2 -0
  116. package/src/SqliteNode.ts +2 -0
  117. package/src/SqliteWasm.ts +2 -0
  118. package/src/drizzle/d1-password-prepared.ts +2 -23
  119. package/src/drizzle/d1-passwords.ts +158 -780
  120. package/src/drizzle/d1-sessions.ts +21 -6
  121. package/src/drizzle/mysql-password-prepared.ts +4 -16
  122. package/src/drizzle/mysql-passwords.ts +5 -20
  123. package/src/drizzle/native-sql-table.ts +259 -0
  124. package/src/drizzle/oauth-connected-model.ts +97 -315
  125. package/src/drizzle/oauth-connected-reference.ts +13 -93
  126. package/src/drizzle/oauth-connected-target.ts +14 -271
  127. package/src/drizzle/oauth-kernel.ts +10 -0
  128. package/src/drizzle/oauth-model.ts +188 -541
  129. package/src/drizzle/oauth-mysql.ts +2 -2
  130. package/src/drizzle/oauth-proxy.ts +101 -0
  131. package/src/drizzle/oauth-target.ts +33 -737
  132. package/src/drizzle/password-model.ts +0 -33
  133. package/src/drizzle/password-prepared-model.ts +0 -18
  134. package/src/drizzle/password-sql.ts +3 -0
  135. package/src/drizzle/password-target.ts +41 -4
  136. package/src/drizzle/pg-password-prepared.ts +4 -16
  137. package/src/drizzle/pg-passwords.ts +5 -20
  138. package/src/drizzle/query-operations.ts +4 -0
  139. package/src/drizzle/session-sql.ts +2 -1
  140. package/src/drizzle/sqlite-password-prepared.ts +4 -52
  141. package/src/drizzle/sqlite-passwords.ts +7 -28
  142. package/src/drizzle/storage-validation.ts +13 -222
  143. package/src/index.ts +2 -8
  144. package/src/internal/drizzle-postgres-oauth-proxy.ts +37 -0
  145. package/src/internal/drizzle-postgres.ts +2 -0
  146. package/src/internal/drizzle-sqlite-oauth-proxy.ts +44 -0
  147. package/src/internal/drizzle-sqlite.ts +2 -0
  148. package/dist/_virtual/_rolldown/runtime.mjs +0 -13
  149. package/dist/drizzle/oauth-accounts.mjs +0 -359
  150. package/dist/drizzle/oauth-accounts.mjs.map +0 -1
  151. package/dist/drizzle/oauth-connected-access.mjs +0 -212
  152. package/dist/drizzle/oauth-connected-access.mjs.map +0 -1
  153. package/dist/drizzle/oauth-connected-collection.mjs +0 -202
  154. package/dist/drizzle/oauth-connected-collection.mjs.map +0 -1
  155. package/dist/drizzle/oauth-connected-custody.mjs +0 -147
  156. package/dist/drizzle/oauth-connected-custody.mjs.map +0 -1
  157. package/dist/drizzle/oauth-connected-flow.mjs +0 -297
  158. package/dist/drizzle/oauth-connected-flow.mjs.map +0 -1
  159. package/dist/drizzle/oauth-connected-input.mjs +0 -122
  160. package/dist/drizzle/oauth-connected-input.mjs.map +0 -1
  161. package/dist/drizzle/oauth-connected-maintenance.mjs +0 -214
  162. package/dist/drizzle/oauth-connected-maintenance.mjs.map +0 -1
  163. package/dist/drizzle/oauth-connected-management.mjs +0 -229
  164. package/dist/drizzle/oauth-connected-management.mjs.map +0 -1
  165. package/dist/drizzle/oauth-connected-settlement.mjs +0 -128
  166. package/dist/drizzle/oauth-connected-settlement.mjs.map +0 -1
  167. package/dist/drizzle/oauth-connected-sign-in.mjs +0 -265
  168. package/dist/drizzle/oauth-connected-sign-in.mjs.map +0 -1
  169. package/dist/drizzle/oauth-connected-state.d.mts +0 -2062
  170. package/dist/drizzle/oauth-connected-state.mjs +0 -430
  171. package/dist/drizzle/oauth-connected-state.mjs.map +0 -1
  172. package/dist/drizzle/oauth-flow.d.mts +0 -22
  173. package/dist/drizzle/oauth-flow.mjs +0 -253
  174. package/dist/drizzle/oauth-flow.mjs.map +0 -1
  175. package/dist/drizzle/oauth-input.mjs +0 -127
  176. package/dist/drizzle/oauth-input.mjs.map +0 -1
  177. package/dist/drizzle/oauth-owner.d.mts +0 -10
  178. package/dist/drizzle/oauth-owner.mjs +0 -10
  179. package/dist/drizzle/oauth-owner.mjs.map +0 -1
  180. package/dist/drizzle/oauth-registration.d.mts +0 -5
  181. package/dist/drizzle/oauth-registration.mjs +0 -374
  182. package/dist/drizzle/oauth-registration.mjs.map +0 -1
  183. package/dist/drizzle/oauth-state.mjs +0 -107
  184. package/dist/drizzle/oauth-state.mjs.map +0 -1
  185. package/src/drizzle/oauth-accounts.ts +0 -805
  186. package/src/drizzle/oauth-connected-access.ts +0 -361
  187. package/src/drizzle/oauth-connected-collection.ts +0 -324
  188. package/src/drizzle/oauth-connected-custody.ts +0 -279
  189. package/src/drizzle/oauth-connected-flow.ts +0 -529
  190. package/src/drizzle/oauth-connected-input.ts +0 -147
  191. package/src/drizzle/oauth-connected-maintenance.ts +0 -346
  192. package/src/drizzle/oauth-connected-management.ts +0 -365
  193. package/src/drizzle/oauth-connected-settlement.ts +0 -251
  194. package/src/drizzle/oauth-connected-sign-in.ts +0 -443
  195. package/src/drizzle/oauth-connected-state.ts +0 -872
  196. package/src/drizzle/oauth-flow.ts +0 -462
  197. package/src/drizzle/oauth-input.ts +0 -201
  198. package/src/drizzle/oauth-owner.ts +0 -29
  199. package/src/drizzle/oauth-registration.ts +0 -640
  200. package/src/drizzle/oauth-state.ts +0 -218
@@ -1,461 +1,58 @@
1
- import { PersistenceMappingError, SubjectIdCodec } from "./model.mjs";
2
- import { InferInsertModel, InferSelectModel, SQL, Table } from "drizzle-orm";
3
- import { Crypto, Effect, PlatformError } from "effect";
4
- import { AuthenticationRequirement, SecurityRevision } from "@yielded/auth/Sessions";
5
- import { OAuthAccountRevision, OAuthActionAuthorization, OAuthCredentialSnapshot, OAuthExternalIdentity, OAuthRegistrationIntent } from "@yielded/auth/OAuth";
6
- import { AuthenticationFactor } from "@yielded/auth/Operations";
1
+ import { DrizzleTableModel } from "./table-model.mjs";
2
+ import * as Shared from "@yielded/auth-persistence/Adapter";
3
+ import { OAuthAction, OAuthD1Mapping, OAuthEligibilityFact, OAuthFlowState, OAuthRegistrationAuthority, OAuthRegistrationState, OAuthTupleState, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints } from "@yielded/auth-persistence/Adapter";
4
+ import { SQL, Table } from "drizzle-orm";
7
5
  //#region src/drizzle/oauth-model.d.ts
8
- type Column<T extends Table> = Extract<keyof T["_"]["columns"], string>;
9
- export type OAuthFlowState = "Pending" | "Claimed" | "Verified" | "RegistrationIssued" | "Linked" | "Cancelled" | "Rejected" | "Ambiguous" | "Conflict";
10
- export type OAuthTupleState = "Unowned" | "Reserved" | "Owned";
11
- export type OAuthRegistrationState = "Unbound" | "Registered" | "ProvisioningPending" | "Rejected";
12
- export type OAuthAction = OAuthActionAuthorization["challenge"]["action"];
13
6
  /** The engine writes every critical column explicitly after applying the pure
14
7
  * consumer encoder. Native instant values must roundtrip without precision loss. */
15
- export interface OAuthClock {
16
- readonly encodeInstant: (millis: number) => unknown;
17
- readonly decodeInstant: (value: unknown) => number;
18
- /** Actual engine wall clock sampled after locks, not transaction-start time.
19
- * PostgreSQL uses clock_timestamp(), never now()/CURRENT_TIMESTAMP. D1 repeats
20
- * its primary-engine sample bounds in final guards. Return integer milliseconds. */
21
- readonly engineNowMillis: SQL;
22
- }
23
- export interface OAuthSubjectReadTable<S extends Table> {
24
- readonly table: S;
25
- readonly id: Column<S>;
26
- readonly status: Column<S>;
27
- readonly securityRevision: Column<S>;
28
- readonly isActiveStatus: (value: unknown) => boolean;
29
- readonly activeCondition: SQL;
30
- }
31
- export interface OAuthSubjectTable<S extends Table> extends OAuthSubjectReadTable<S> {
32
- readonly decodeActionRequirement: (row: InferSelectModel<S>, action: OAuthAction) => AuthenticationRequirement;
33
- readonly decodeAuthenticationRequirement: (row: InferSelectModel<S>) => AuthenticationRequirement;
34
- readonly nextSecurityRevision: (current: SecurityRevision) => SecurityRevision;
35
- }
36
- export interface OAuthOwnershipReadTable<O extends Table, N> {
37
- readonly table: O;
38
- readonly identityKey: Column<O>;
39
- readonly provider: Column<O>;
40
- readonly issuer: Column<O>;
41
- readonly externalSubject: Column<O>;
42
- readonly subjectId: Column<O>;
43
- /** Includes Owned state when authority and ownership share a physical table. */
44
- readonly ownedCondition: SQL;
45
- readonly decodeSubjectId: (row: InferSelectModel<O>) => N;
46
- }
47
- export interface OAuthOwnershipTable<O extends Table, N> extends OAuthOwnershipReadTable<O, N> {
48
- readonly encodeInsert: (input: {
49
- readonly identity: typeof OAuthExternalIdentity.Type;
50
- readonly identityKey: string;
51
- readonly subjectId: N;
52
- }) => InferInsertModel<O>;
53
- }
54
- export interface OAuthCredentialReadTable<C extends Table> {
55
- readonly table: C;
56
- readonly moduleId: Column<C>;
57
- readonly credentialId: Column<C>;
58
- readonly subjectId: Column<C>;
59
- readonly identityKey: Column<C>;
60
- readonly credentialRevision: Column<C>;
61
- readonly status: Column<C>;
62
- readonly isActiveStatus: (value: unknown) => boolean;
63
- readonly activeCondition: SQL;
64
- }
65
- export interface OAuthCredentialTable<C extends Table, N> extends OAuthCredentialReadTable<C> {
66
- readonly encodeInsert: (input: {
67
- readonly moduleId: string;
68
- readonly subjectId: N;
69
- readonly identityKey: string;
70
- readonly credentialId: string;
71
- readonly credentialRevision: SecurityRevision;
72
- }) => InferInsertModel<C>;
73
- /** This slice removes login rows. Historical records belong in separate audit storage. */
74
- readonly removal: "delete";
75
- }
76
- export interface OAuthAuthorityReadTable<C extends Table> {
77
- readonly table: C;
78
- readonly subjectId: Column<C>;
79
- readonly credentialId: Column<C>;
80
- readonly revision: Column<C>;
81
- readonly status: Column<C>;
82
- readonly isActiveStatus: (value: unknown) => boolean;
83
- readonly activeCondition: SQL;
84
- }
85
- export interface OAuthAuthorityTable<C extends Table, N> extends OAuthAuthorityReadTable<C> {
86
- readonly encodeInsert: (input: {
87
- readonly subjectId: N;
88
- readonly credentialId: string;
89
- readonly revision: SecurityRevision;
90
- }) => InferInsertModel<C>;
91
- }
8
+ export type OAuthClock = Shared.OAuthClock<SQL>;
9
+ export type OAuthSubjectReadTable<S extends Table> = Shared.OAuthSubjectReadTable<DrizzleTableModel<S>, SQL>;
10
+ export type OAuthSubjectTable<S extends Table> = Shared.OAuthSubjectTable<DrizzleTableModel<S>, SQL>;
11
+ export type OAuthOwnershipReadTable<O extends Table, N> = Shared.OAuthOwnershipReadTable<DrizzleTableModel<O>, N, SQL>;
12
+ export type OAuthOwnershipTable<O extends Table, N> = Shared.OAuthOwnershipTable<DrizzleTableModel<O>, N, SQL>;
13
+ export type OAuthCredentialReadTable<C extends Table> = Shared.OAuthCredentialReadTable<DrizzleTableModel<C>, SQL>;
14
+ export type OAuthCredentialTable<C extends Table, N> = Shared.OAuthCredentialTable<DrizzleTableModel<C>, N, SQL>;
15
+ export type OAuthAuthorityReadTable<C extends Table> = Shared.OAuthAuthorityReadTable<DrizzleTableModel<C>, SQL>;
16
+ export type OAuthAuthorityTable<C extends Table, N> = Shared.OAuthAuthorityTable<DrizzleTableModel<C>, N, SQL>;
92
17
  /** Both purposes may use the same physical table. Shared tables share module/flow
93
18
  * and module/command uniqueness. The snapshot has the exact purpose-specific core
94
19
  * codec; terminal writes erase it, while identity, claim and retention columns remain. */
95
- export interface OAuthFlowTable<F extends Table> {
96
- readonly table: F;
97
- readonly moduleId: Column<F>;
98
- readonly flowId: Column<F>;
99
- readonly commandId: Column<F>;
100
- readonly purpose: Column<F>;
101
- readonly generation: Column<F>;
102
- readonly state: Column<F>;
103
- readonly version: Column<F>;
104
- readonly stateDigest: Column<F>;
105
- readonly binderVerifier: Column<F>;
106
- readonly binderExpiresAt: Column<F>;
107
- readonly snapshot: Column<F>;
108
- readonly issuedAt: Column<F>;
109
- readonly expiresAt: Column<F>;
110
- readonly claimId: Column<F>;
111
- readonly claimedAt: Column<F>;
112
- readonly claimExpiresAt: Column<F>;
113
- readonly retentionUntil: Column<F>;
114
- readonly encodeInsert: (input: {
115
- readonly moduleId: string;
116
- readonly flowId: string;
117
- readonly purpose: "sign-in" | "link";
118
- }) => InferInsertModel<F>;
119
- }
120
- export interface OAuthTupleAuthorityTable<T extends Table, N> {
121
- readonly table: T;
122
- readonly identityKey: Column<T>;
123
- readonly provider: Column<T>;
124
- readonly issuer: Column<T>;
125
- readonly externalSubject: Column<T>;
126
- readonly state: Column<T>;
127
- readonly version: Column<T>;
128
- readonly subjectId: Column<T>;
129
- /** Exact reservation identity; no application payload or bearer. */
130
- readonly reservation: Column<T>;
131
- readonly encodeInsert: (input: {
132
- readonly identityKey: string;
133
- readonly identity: typeof OAuthExternalIdentity.Type;
134
- readonly subjectId?: N;
135
- }) => InferInsertModel<T>;
136
- }
137
- export interface OAuthRegistrationIntentTable<I extends Table> {
138
- readonly table: I;
139
- readonly moduleId: Column<I>;
140
- readonly reference: Column<I>;
141
- readonly flowId: Column<I>;
142
- readonly claimId: Column<I>;
143
- readonly identityKey: Column<I>;
144
- readonly version: Column<I>;
145
- readonly state: Column<I>;
146
- readonly snapshot: Column<I>;
147
- readonly commandId: Column<I>;
148
- readonly fingerprint: Column<I>;
149
- readonly pendingReference: Column<I>;
150
- readonly expiresAt: Column<I>;
151
- readonly retentionUntil: Column<I>;
152
- readonly encodeInsert: (intent: OAuthRegistrationIntent) => InferInsertModel<I>;
153
- }
154
- export interface OAuthRegistrationCommandTable<R extends Table, Registration> {
155
- readonly table: R;
156
- readonly moduleId: Column<R>;
157
- readonly commandId: Column<R>;
158
- readonly reference: Column<R>;
159
- readonly identityKey: Column<R>;
160
- readonly fingerprint: Column<R>;
161
- readonly intentSnapshot: Column<R>;
162
- readonly applicationSnapshot: Column<R>;
163
- readonly provisioningIdentity: Column<R>;
164
- readonly decision: Column<R>;
165
- readonly retentionUntil: Column<R>;
166
- /** Persists exact detached Type before protected pending work can start. */
167
- readonly encodeInsert: (input: {
168
- readonly intent: OAuthRegistrationIntent;
169
- readonly commandId: string;
170
- readonly fingerprint: string;
171
- readonly registration: Registration;
172
- readonly provisioningIdentity: string;
173
- }) => InferInsertModel<R>;
174
- }
175
- export interface OAuthUnlinkCommandTable<U extends Table> {
176
- readonly table: U;
177
- readonly moduleId: Column<U>;
178
- readonly commandId: Column<U>;
179
- readonly subjectId: Column<U>;
180
- readonly credentialId: Column<U>;
181
- readonly intentSnapshot: Column<U>;
182
- readonly decision: Column<U>;
183
- readonly retentionUntil: Column<U>;
184
- readonly encodeInsert: (input: {
185
- readonly moduleId: string;
186
- readonly commandId: string;
187
- readonly credential: OAuthCredentialSnapshot;
188
- }) => InferInsertModel<U>;
189
- }
190
- export interface OAuthEligibilityFact {
191
- readonly credentialId: string;
192
- readonly revision: SecurityRevision;
193
- readonly usablePrimary: boolean;
194
- readonly factors: ReadonlyArray<AuthenticationFactor>;
195
- readonly userVerified: boolean;
196
- readonly phishingResistant: boolean;
197
- }
20
+ export type OAuthFlowTable<F extends Table> = Shared.OAuthFlowTable<DrizzleTableModel<F>>;
21
+ export type OAuthTupleAuthorityTable<T extends Table, N> = Shared.OAuthTupleAuthorityTable<DrizzleTableModel<T>, N>;
22
+ export type OAuthRegistrationIntentTable<I extends Table> = Shared.OAuthRegistrationIntentTable<DrizzleTableModel<I>>;
23
+ export type OAuthRegistrationCommandTable<R extends Table, Registration> = Shared.OAuthRegistrationCommandTable<DrizzleTableModel<R>, Registration>;
24
+ export type OAuthUnlinkCommandTable<U extends Table> = Shared.OAuthUnlinkCommandTable<DrizzleTableModel<U>>;
198
25
  /** Each descriptor reads only its own subject-scoped method rows. The native row
199
26
  * projector and SQL condition must express the same installed method eligibility.
200
27
  * All source/identifier/policy mutations advance subject securityRevision. D1 also
201
28
  * guards exact selected IDs/versions and absence/count assumptions, never just a
202
29
  * stale boolean. An over-limit graph fails closed rather than truncating. */
203
- export interface OAuthEligibilityTable<T extends Table, N> {
204
- readonly table: T;
205
- readonly subjectId: Column<T>;
206
- readonly credentialId: Column<T>;
207
- readonly revision: Column<T>;
208
- readonly scope: string;
209
- readonly condition: (subjectId: N) => SQL;
210
- readonly decode: (row: InferSelectModel<T>) => OAuthEligibilityFact | undefined;
211
- }
30
+ export type OAuthEligibilityTable<T extends Table, N> = Shared.OAuthEligibilityTable<DrizzleTableModel<T>, N, SQL>;
212
31
  /** Authenticated command replay uses current subject status and this additional
213
32
  * nonconsuming SQL policy. It never consumes a fresh action factor. */
214
- export interface OAuthMetadataPolicy<N> {
215
- readonly condition: (subjectId: N) => SQL;
216
- }
217
- export interface OAuthCleanupTable<T extends Table, N> {
218
- readonly table: T;
219
- readonly subjectId: Column<T>;
220
- /** Bound to this subject's old revision; no opaque independently committing service. */
221
- readonly condition: (input: {
222
- readonly subjectId: N;
223
- readonly revision: OAuthAccountRevision;
224
- readonly removedCredentialId?: string;
225
- }) => SQL;
226
- readonly disposition: "delete";
227
- }
228
- export interface OAuthRegistrationEligibility<N> {
229
- /** Pure SQL guards for mutable app policy; evaluated again after app writes. */
230
- readonly condition: (input: {
231
- readonly intent: OAuthRegistrationIntent;
232
- readonly nativeSubjectId?: N;
233
- }) => SQL;
234
- }
235
- export interface OAuthD1Mapping {
236
- readonly d1: {
237
- readonly primary: true;
238
- };
239
- }
240
- export declare const requiredOAuthSignInConstraints: {
241
- readonly flow: "unique(flow.moduleId,flow.flowId)";
242
- readonly command: "unique(flow.moduleId,flow.commandId)";
243
- readonly stateDigest: "unique(flow.stateDigest)";
244
- readonly ownership: "unique(ownership.identityKey)";
245
- readonly credentialId: "unique(credential.credentialId)";
246
- readonly credentialIdentity: "unique(credential.identityKey)";
247
- readonly authorityCredential: "unique(authority.subjectId,authority.credentialId)";
248
- };
249
- export declare const requiredOAuthTupleConstraints: {
250
- readonly identityKey: "unique(tuple.identityKey)";
251
- };
252
- export declare const requiredOAuthRegistrationConstraints: {
253
- readonly intentReference: "unique(intent.moduleId,intent.reference)";
254
- readonly intentFlow: "unique(intent.moduleId,intent.flowId)";
255
- readonly command: "unique(registrationCommand.moduleId,registrationCommand.commandId)";
256
- };
257
- export declare const requiredOAuthAccountsConstraints: {
258
- readonly unlinkCommand: "unique(unlinkCommand.moduleId,unlinkCommand.commandId)";
259
- };
260
- export interface OAuthSignInMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, N> {
261
- readonly subject: OAuthSubjectReadTable<S>;
262
- readonly ownership: OAuthOwnershipReadTable<O, N>;
263
- readonly credential: OAuthCredentialReadTable<C>;
264
- readonly authority: OAuthAuthorityReadTable<AC>;
265
- readonly flow: OAuthFlowTable<F>;
266
- readonly subjectId: SubjectIdCodec<N>;
267
- readonly clock: OAuthClock;
268
- readonly constraints: typeof requiredOAuthSignInConstraints;
269
- }
270
- export type OAuthOwnershipMutation<T extends Table, O extends Table, N> = {
271
- readonly mode: "integrated";
272
- readonly tuple: OAuthTupleAuthorityTable<T, N>;
273
- } | {
274
- readonly mode: "separate";
275
- readonly tuple: OAuthTupleAuthorityTable<T, N>;
276
- readonly external: OAuthOwnershipTable<O, N>;
277
- };
278
- export interface OAuthRegistrationIntentMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, T extends Table, I extends Table, N> {
279
- readonly signIn: OAuthSignInMapping<S, O, C, AC, F, N>;
280
- readonly ownership: OAuthOwnershipMutation<T, O, N>;
281
- readonly intent: OAuthRegistrationIntentTable<I>;
282
- readonly tupleConstraints: typeof requiredOAuthTupleConstraints;
283
- readonly registrationConstraints: Pick<typeof requiredOAuthRegistrationConstraints, "intentReference" | "intentFlow">;
284
- readonly eligibility: OAuthRegistrationEligibility<N>;
285
- }
286
- export interface OAuthRegistrationBase<Registration, T extends Table, O extends Table, I extends Table, R extends Table, N> {
287
- readonly ownership: OAuthOwnershipMutation<T, O, N>;
288
- readonly intent: OAuthRegistrationIntentTable<I>;
289
- readonly command: OAuthRegistrationCommandTable<R, Registration>;
290
- readonly clock: OAuthClock;
291
- readonly tupleConstraints: typeof requiredOAuthTupleConstraints;
292
- readonly constraints: typeof requiredOAuthRegistrationConstraints;
293
- readonly inspect: (input: {
294
- readonly intent: OAuthRegistrationIntent;
295
- readonly registration: Registration;
296
- }) => Effect.Effect<{
297
- readonly fingerprint: string;
298
- readonly eligible: boolean;
299
- }, PersistenceMappingError>;
300
- /** Required for an explicitly bound native/DO command: no asynchronous callback
301
- * is evaluated inside the physical owner. Standalone inspection is pre-owner. */
302
- readonly inspectSync?: (input: {
303
- readonly intent: OAuthRegistrationIntent;
304
- readonly registration: Registration;
305
- }) => {
306
- readonly fingerprint: string;
307
- readonly eligible: boolean;
308
- };
309
- /** Type projection, never the original wire transformation. */
310
- readonly snapshot: (registration: Registration) => Effect.Effect<Registration, PersistenceMappingError>;
311
- readonly snapshotSync?: (registration: Registration) => Registration;
312
- /** Canonical bounded storage of Registration.Type. These are Type codecs, not
313
- * the original wire decoder/encoder; decode(encode(value)) must encode identically.
314
- * The engine writes and roundtrip-checks this exact string (maximum 1 MiB). */
315
- readonly application: {
316
- readonly encode: (registration: Registration) => string;
317
- readonly decode: (stored: string) => Registration;
318
- };
319
- readonly eligibility: {
320
- /** Stable application authority anchors, in one configured global order.
321
- * Omit only for immutable/tuple-local policy or an equivalent explicit outer
322
- * owner lock. Each scope must match 1..64 rows, never an absent quota row.
323
- * Locks precede tuple/intent/command locks; postcondition owns changed state. */
324
- readonly guards?: ReadonlyArray<OAuthRegistrationGuardDescriptor<Registration, N>>;
325
- readonly admission: (input: {
326
- readonly intent: OAuthRegistrationIntent;
327
- readonly registration: Registration;
328
- readonly nativeSubjectId?: N;
329
- }) => SQL;
330
- /** Evaluated after subject/application writes, including appended coordinator
331
- * writes. May assert consumption of the admission invitation/quota. */
332
- readonly postcondition: (input: {
333
- readonly intent: OAuthRegistrationIntent;
334
- readonly registration: Registration;
335
- readonly nativeSubjectId?: N;
336
- }) => SQL;
337
- };
338
- readonly allocateProvisioningIdentity: Effect.Effect<string, PersistenceMappingError>;
339
- readonly retentionMillis: number;
340
- }
341
- export interface OAuthRegistrationGuardTable<T extends Table, Registration, N> {
342
- readonly table: T;
343
- readonly orderBy: Column<T>;
344
- readonly condition: (input: {
345
- readonly intent: OAuthRegistrationIntent;
346
- readonly registration: Registration;
347
- readonly nativeSubjectId?: N;
348
- }) => SQL;
349
- }
350
- export interface OAuthRegistrationGuardDescriptor<Registration, N> {
351
- readonly table: Table;
352
- readonly orderBy: string;
353
- readonly condition: OAuthRegistrationGuardTable<Table, Registration, N>["condition"];
354
- }
33
+ export type OAuthMetadataPolicy<N> = Shared.OAuthMetadataPolicy<N, SQL>;
34
+ export type OAuthCleanupTable<T extends Table, N> = Shared.OAuthCleanupTable<DrizzleTableModel<T>, N, SQL>;
35
+ export type OAuthRegistrationEligibility<N> = Shared.OAuthRegistrationEligibility<N, SQL>;
36
+ export type OAuthSignInMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, N> = Shared.OAuthSignInMapping<DrizzleTableModel<S>, DrizzleTableModel<O>, DrizzleTableModel<C>, DrizzleTableModel<AC>, DrizzleTableModel<F>, N, SQL>;
37
+ export type OAuthOwnershipMutation<T extends Table, O extends Table, N> = Shared.OAuthOwnershipMutation<DrizzleTableModel<T>, DrizzleTableModel<O>, N, SQL>;
38
+ export type OAuthRegistrationIntentMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, T extends Table, I extends Table, N> = Shared.OAuthRegistrationIntentMapping<DrizzleTableModel<S>, DrizzleTableModel<O>, DrizzleTableModel<C>, DrizzleTableModel<AC>, DrizzleTableModel<F>, DrizzleTableModel<T>, DrizzleTableModel<I>, N, SQL>;
39
+ export type OAuthRegistrationBase<Registration, T extends Table, O extends Table, I extends Table, R extends Table, N> = Shared.OAuthRegistrationBase<Registration, DrizzleTableModel<T>, DrizzleTableModel<O>, DrizzleTableModel<I>, DrizzleTableModel<R>, N, SQL, Table>;
40
+ export type OAuthRegistrationGuardTable<T extends Table, Registration, N> = Shared.OAuthRegistrationGuardTable<DrizzleTableModel<T>, Registration, N, SQL>;
41
+ export type OAuthRegistrationGuardDescriptor<Registration, N> = Shared.OAuthRegistrationGuardDescriptor<Registration, N, SQL, Table>;
355
42
  export declare const oauthRegistrationGuardTable: <T extends Table, Registration, N>(input: OAuthRegistrationGuardTable<T, Registration, N>) => OAuthRegistrationGuardDescriptor<Registration, N>;
356
- export type OAuthRegistrationMapping<Registration, S extends Table, O extends Table, C extends Table, AC extends Table, T extends Table, I extends Table, R extends Table, N> = OAuthRegistrationBase<Registration, T, O, I, R, N> & ({
357
- readonly mode: "pending";
358
- readonly allocatePendingReference: Effect.Effect<string, PersistenceMappingError>;
359
- } | {
360
- readonly mode: "atomic";
361
- readonly subjectId: SubjectIdCodec<N>;
362
- readonly subject: OAuthSubjectReadTable<S>;
363
- readonly credential: OAuthCredentialTable<C, N>;
364
- readonly authority: OAuthAuthorityTable<AC, N>;
365
- readonly allocateSubjectId: Effect.Effect<N, PersistenceMappingError>;
366
- readonly allocateCredentialId: Effect.Effect<string, PersistenceMappingError>;
367
- readonly allocateRevision: Effect.Effect<SecurityRevision, PersistenceMappingError>;
368
- readonly encodeSubjectInsert: (input: {
369
- readonly intent: OAuthRegistrationIntent;
370
- readonly registration: Registration;
371
- }, ids: {
372
- readonly subjectId: N;
373
- readonly securityRevision: SecurityRevision;
374
- }) => InferInsertModel<S>;
375
- });
43
+ export type OAuthRegistrationMapping<Registration, S extends Table, O extends Table, C extends Table, AC extends Table, T extends Table, I extends Table, R extends Table, N> = Shared.OAuthRegistrationMapping<Registration, DrizzleTableModel<S>, DrizzleTableModel<O>, DrizzleTableModel<C>, DrizzleTableModel<AC>, DrizzleTableModel<T>, DrizzleTableModel<I>, DrizzleTableModel<R>, N, SQL, Table>;
376
44
  /** Heterogeneous descriptors are made by typed factories and projected privately. */
377
- export interface OAuthEligibilityDescriptor<N> {
378
- readonly _tag: "OAuthEligibilityDescriptor";
379
- readonly scope: string;
380
- readonly table: Table;
381
- readonly subjectId: string;
382
- readonly credentialId: string;
383
- readonly revision: string;
384
- readonly condition: (subjectId: N) => SQL;
385
- readonly decode: (row: unknown) => OAuthEligibilityFact | undefined;
386
- }
45
+ export type OAuthEligibilityDescriptor<N> = Shared.OAuthEligibilityDescriptor<N, SQL, Table>;
387
46
  export declare const oauthEligibilityTable: <T extends Table, N>(input: OAuthEligibilityTable<T, N>) => OAuthEligibilityDescriptor<N>;
388
- export interface OAuthCleanupDescriptor<N> {
389
- readonly table: Table;
390
- readonly subjectId: string;
391
- readonly condition: OAuthCleanupTable<Table, N>["condition"];
392
- }
47
+ export type OAuthCleanupDescriptor<N> = Shared.OAuthCleanupDescriptor<N, SQL, Table>;
393
48
  export declare const oauthCleanupTable: <T extends Table, N>(input: OAuthCleanupTable<T, N>) => OAuthCleanupDescriptor<N>;
394
49
  /** A stable application/reference lock acquired before an ownership target.
395
50
  * Missing rows retain ownership. Conditions use detached native IDs; every
396
51
  * writer of the guarded reference follows the same order. */
397
- export interface OAuthReferenceGuardTable<T extends Table, N> {
398
- readonly table: T;
399
- readonly orderBy: Column<T>;
400
- readonly condition: (input: {
401
- readonly identity: typeof OAuthExternalIdentity.Type;
402
- readonly identityKey: string;
403
- readonly subjectId: N;
404
- }) => SQL | Effect.Effect<SQL, PlatformError.PlatformError, Crypto.Crypto>;
405
- }
406
- export interface OAuthReferenceGuardDescriptor<N> {
407
- readonly table: Table;
408
- readonly orderBy: string;
409
- readonly condition: OAuthReferenceGuardTable<Table, N>["condition"];
410
- }
52
+ export type OAuthReferenceGuardTable<T extends Table, N> = Shared.OAuthReferenceGuardTable<DrizzleTableModel<T>, N, SQL>;
53
+ export type OAuthReferenceGuardDescriptor<N> = Shared.OAuthReferenceGuardDescriptor<N, SQL, Table>;
411
54
  export declare const oauthReferenceGuardTable: <T extends Table, N>(input: OAuthReferenceGuardTable<T, N>) => OAuthReferenceGuardDescriptor<N>;
412
- export interface OAuthAccountsMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, T extends Table, U extends Table, N> {
413
- readonly subject: OAuthSubjectTable<S>;
414
- readonly ownership: OAuthOwnershipMutation<T, O, N>;
415
- readonly credential: OAuthCredentialTable<C, N>;
416
- readonly authority: OAuthAuthorityTable<AC, N>;
417
- readonly flow: OAuthFlowTable<F>;
418
- readonly command: OAuthUnlinkCommandTable<U>;
419
- readonly subjectId: SubjectIdCodec<N>;
420
- readonly clock: OAuthClock;
421
- readonly constraints: typeof requiredOAuthSignInConstraints & typeof requiredOAuthAccountsConstraints;
422
- readonly tupleConstraints: typeof requiredOAuthTupleConstraints;
423
- readonly eligibility: ReadonlyArray<OAuthEligibilityDescriptor<N>>;
424
- readonly cleanup: ReadonlyArray<OAuthCleanupDescriptor<N>>;
425
- readonly metadata: OAuthMetadataPolicy<N>;
426
- readonly sessionInvalidation: "same-authority-immediate" | "original-absolute-expiry";
427
- /** Omit only when connected access is absent. A predicate alone conservatively
428
- * retains ownership; release also needs all configured guard rows below. */
429
- readonly connectedReference?: (input: {
430
- readonly identityKey: string;
431
- readonly subjectId: N;
432
- }) => SQL;
433
- /** At most 32 descriptors, each locking 1..64 stable rows in supplied order.
434
- * Missing/empty guards retain Owned, even when the reference predicate is false. */
435
- readonly connectedReferenceGuards?: ReadonlyArray<OAuthReferenceGuardDescriptor<N>>;
436
- readonly allocateCredentialId: Effect.Effect<string, PersistenceMappingError>;
437
- readonly allocateRevision: Effect.Effect<SecurityRevision, PersistenceMappingError>;
438
- }
439
- export interface OAuthRegistrationAuthority<Registration> {
440
- readonly read: (access: import("@yielded/auth/OAuth").OAuthRegistrationAccess) => Effect.Effect<import("@yielded/auth/OAuth").OAuthRegistrationInspection | undefined, import("@yielded/auth/OAuth").OAuthUnavailable>;
441
- readonly inspect: (input: {
442
- readonly intent: OAuthRegistrationIntent;
443
- readonly registration: Registration;
444
- }) => Effect.Effect<{
445
- readonly fingerprint: import("@yielded/auth/Schema").TokenDigest;
446
- readonly eligible: boolean;
447
- }, import("@yielded/auth/OAuth").OAuthUnavailable>;
448
- readonly register: <A>(input: {
449
- readonly access: import("@yielded/auth/OAuth").OAuthRegistrationAccess;
450
- readonly intent: OAuthRegistrationIntent;
451
- readonly commandId: typeof import("@yielded/auth/OAuth").OAuthCommandId.Type;
452
- readonly registration: Registration;
453
- readonly fingerprint: import("@yielded/auth/Schema").TokenDigest;
454
- }, prepare: import("@yielded/auth/OAuth").PrepareOAuthCommit<import("@yielded/auth/OAuth").OAuthRegistrationDecision, A>) => Effect.Effect<import("@yielded/auth/Hooks").PreparedCommit<A>, import("@yielded/auth/OAuth").OAuthUnavailable>;
455
- readonly cleanup: <A>(input: import("@yielded/auth/OAuth").OAuthCleanupInput, prepare: import("@yielded/auth/OAuth").PrepareOAuthCommit<{
456
- readonly removed: number;
457
- readonly hasMore: boolean;
458
- }, A>) => Effect.Effect<import("@yielded/auth/Hooks").PreparedCommit<A>, import("@yielded/auth/OAuth").OAuthUnavailable>;
459
- }
55
+ export type OAuthAccountsMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, T extends Table, U extends Table, N> = Shared.OAuthAccountsMapping<DrizzleTableModel<S>, DrizzleTableModel<O>, DrizzleTableModel<C>, DrizzleTableModel<AC>, DrizzleTableModel<F>, DrizzleTableModel<T>, DrizzleTableModel<U>, N, SQL, Table>;
460
56
  //#endregion
57
+ export { type OAuthAction, type OAuthD1Mapping, type OAuthEligibilityFact, type OAuthFlowState, type OAuthRegistrationAuthority, type OAuthRegistrationState, type OAuthTupleState, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints };
461
58
  //# sourceMappingURL=oauth-model.d.mts.map
@@ -1,48 +1,10 @@
1
+ import * as Shared from "@yielded/auth-persistence/Adapter";
2
+ import { requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints } from "@yielded/auth-persistence/Adapter";
1
3
  //#region src/drizzle/oauth-model.ts
2
- const requiredOAuthSignInConstraints = {
3
- flow: "unique(flow.moduleId,flow.flowId)",
4
- command: "unique(flow.moduleId,flow.commandId)",
5
- stateDigest: "unique(flow.stateDigest)",
6
- ownership: "unique(ownership.identityKey)",
7
- credentialId: "unique(credential.credentialId)",
8
- credentialIdentity: "unique(credential.identityKey)",
9
- authorityCredential: "unique(authority.subjectId,authority.credentialId)"
10
- };
11
- const requiredOAuthTupleConstraints = { identityKey: "unique(tuple.identityKey)" };
12
- const requiredOAuthRegistrationConstraints = {
13
- intentReference: "unique(intent.moduleId,intent.reference)",
14
- intentFlow: "unique(intent.moduleId,intent.flowId)",
15
- command: "unique(registrationCommand.moduleId,registrationCommand.commandId)"
16
- };
17
- const requiredOAuthAccountsConstraints = { unlinkCommand: "unique(unlinkCommand.moduleId,unlinkCommand.commandId)" };
18
- const oauthRegistrationGuardTable = (input) => Object.freeze({
19
- table: input.table,
20
- orderBy: input.orderBy,
21
- condition: input.condition
22
- });
23
- const oauthEligibilityTable = (input) => {
24
- const { table, subjectId, credentialId, revision, scope, condition, decode } = input;
25
- return Object.freeze({
26
- _tag: "OAuthEligibilityDescriptor",
27
- table,
28
- subjectId,
29
- credentialId,
30
- revision,
31
- scope,
32
- condition,
33
- decode: (row) => decode(row)
34
- });
35
- };
36
- const oauthCleanupTable = (input) => Object.freeze({
37
- table: input.table,
38
- subjectId: input.subjectId,
39
- condition: input.condition
40
- });
41
- const oauthReferenceGuardTable = (input) => Object.freeze({
42
- table: input.table,
43
- orderBy: input.orderBy,
44
- condition: input.condition
45
- });
4
+ const oauthRegistrationGuardTable = (input) => Shared.oauthRegistrationGuardTable(input);
5
+ const oauthEligibilityTable = (input) => Shared.oauthEligibilityTable(input);
6
+ const oauthCleanupTable = (input) => Shared.oauthCleanupTable(input);
7
+ const oauthReferenceGuardTable = (input) => Shared.oauthReferenceGuardTable(input);
46
8
  //#endregion
47
9
  export { oauthCleanupTable, oauthEligibilityTable, oauthReferenceGuardTable, oauthRegistrationGuardTable, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints };
48
10
 
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-model.mjs","names":[],"sources":["../../src/drizzle/oauth-model.ts"],"sourcesContent":["import type {\n OAuthActionAuthorization,\n OAuthAccountRevision,\n OAuthRegistrationIntent,\n OAuthCredentialSnapshot,\n OAuthExternalIdentity,\n} from \"@yielded/auth/OAuth\";\nimport type { AuthenticationFactor } from \"@yielded/auth/Operations\";\nimport type { AuthenticationRequirement, SecurityRevision } from \"@yielded/auth/Sessions\";\nimport type { InferInsertModel, InferSelectModel, SQL, Table } from \"drizzle-orm\";\nimport type { Crypto, Effect, PlatformError } from \"effect\";\n\nimport type { PersistenceMappingError, SubjectIdCodec } from \"./model\";\n\ntype Column<T extends Table> = Extract<keyof T[\"_\"][\"columns\"], string>;\n\nexport type OAuthFlowState =\n | \"Pending\"\n | \"Claimed\"\n | \"Verified\"\n | \"RegistrationIssued\"\n | \"Linked\"\n | \"Cancelled\"\n | \"Rejected\"\n | \"Ambiguous\"\n | \"Conflict\";\n\nexport type OAuthTupleState = \"Unowned\" | \"Reserved\" | \"Owned\";\nexport type OAuthRegistrationState = \"Unbound\" | \"Registered\" | \"ProvisioningPending\" | \"Rejected\";\nexport type OAuthAction = OAuthActionAuthorization[\"challenge\"][\"action\"];\n\n/** The engine writes every critical column explicitly after applying the pure\n * consumer encoder. Native instant values must roundtrip without precision loss. */\nexport interface OAuthClock {\n readonly encodeInstant: (millis: number) => unknown;\n readonly decodeInstant: (value: unknown) => number;\n /** Actual engine wall clock sampled after locks, not transaction-start time.\n * PostgreSQL uses clock_timestamp(), never now()/CURRENT_TIMESTAMP. D1 repeats\n * its primary-engine sample bounds in final guards. Return integer milliseconds. */\n readonly engineNowMillis: SQL;\n}\n\nexport interface OAuthSubjectReadTable<S extends Table> {\n readonly table: S;\n readonly id: Column<S>;\n readonly status: Column<S>;\n readonly securityRevision: Column<S>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: SQL;\n}\n\nexport interface OAuthSubjectTable<S extends Table> extends OAuthSubjectReadTable<S> {\n readonly decodeActionRequirement: (\n row: InferSelectModel<S>,\n action: OAuthAction,\n ) => AuthenticationRequirement;\n readonly decodeAuthenticationRequirement: (row: InferSelectModel<S>) => AuthenticationRequirement;\n readonly nextSecurityRevision: (current: SecurityRevision) => SecurityRevision;\n}\n\nexport interface OAuthOwnershipReadTable<O extends Table, N> {\n readonly table: O;\n readonly identityKey: Column<O>;\n readonly provider: Column<O>;\n readonly issuer: Column<O>;\n readonly externalSubject: Column<O>;\n readonly subjectId: Column<O>;\n /** Includes Owned state when authority and ownership share a physical table. */\n readonly ownedCondition: SQL;\n readonly decodeSubjectId: (row: InferSelectModel<O>) => N;\n}\n\nexport interface OAuthOwnershipTable<O extends Table, N> extends OAuthOwnershipReadTable<O, N> {\n readonly encodeInsert: (input: {\n readonly identity: typeof OAuthExternalIdentity.Type;\n readonly identityKey: string;\n readonly subjectId: N;\n }) => InferInsertModel<O>;\n}\n\nexport interface OAuthCredentialReadTable<C extends Table> {\n readonly table: C;\n readonly moduleId: Column<C>;\n readonly credentialId: Column<C>;\n readonly subjectId: Column<C>;\n readonly identityKey: Column<C>;\n readonly credentialRevision: Column<C>;\n readonly status: Column<C>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: SQL;\n}\n\nexport interface OAuthCredentialTable<C extends Table, N> extends OAuthCredentialReadTable<C> {\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly subjectId: N;\n readonly identityKey: string;\n readonly credentialId: string;\n readonly credentialRevision: SecurityRevision;\n }) => InferInsertModel<C>;\n /** This slice removes login rows. Historical records belong in separate audit storage. */\n readonly removal: \"delete\";\n}\n\nexport interface OAuthAuthorityReadTable<C extends Table> {\n readonly table: C;\n readonly subjectId: Column<C>;\n readonly credentialId: Column<C>;\n readonly revision: Column<C>;\n readonly status: Column<C>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: SQL;\n}\n\nexport interface OAuthAuthorityTable<C extends Table, N> extends OAuthAuthorityReadTable<C> {\n readonly encodeInsert: (input: {\n readonly subjectId: N;\n readonly credentialId: string;\n readonly revision: SecurityRevision;\n }) => InferInsertModel<C>;\n}\n\n/** Both purposes may use the same physical table. Shared tables share module/flow\n * and module/command uniqueness. The snapshot has the exact purpose-specific core\n * codec; terminal writes erase it, while identity, claim and retention columns remain. */\nexport interface OAuthFlowTable<F extends Table> {\n readonly table: F;\n readonly moduleId: Column<F>;\n readonly flowId: Column<F>;\n readonly commandId: Column<F>;\n readonly purpose: Column<F>;\n readonly generation: Column<F>;\n readonly state: Column<F>;\n readonly version: Column<F>;\n readonly stateDigest: Column<F>;\n readonly binderVerifier: Column<F>;\n readonly binderExpiresAt: Column<F>;\n readonly snapshot: Column<F>;\n readonly issuedAt: Column<F>;\n readonly expiresAt: Column<F>;\n readonly claimId: Column<F>;\n readonly claimedAt: Column<F>;\n readonly claimExpiresAt: Column<F>;\n readonly retentionUntil: Column<F>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly flowId: string;\n readonly purpose: \"sign-in\" | \"link\";\n }) => InferInsertModel<F>;\n}\n\nexport interface OAuthTupleAuthorityTable<T extends Table, N> {\n readonly table: T;\n readonly identityKey: Column<T>;\n readonly provider: Column<T>;\n readonly issuer: Column<T>;\n readonly externalSubject: Column<T>;\n readonly state: Column<T>;\n readonly version: Column<T>;\n readonly subjectId: Column<T>;\n /** Exact reservation identity; no application payload or bearer. */\n readonly reservation: Column<T>;\n readonly encodeInsert: (input: {\n readonly identityKey: string;\n readonly identity: typeof OAuthExternalIdentity.Type;\n readonly subjectId?: N;\n }) => InferInsertModel<T>;\n}\n\nexport interface OAuthRegistrationIntentTable<I extends Table> {\n readonly table: I;\n readonly moduleId: Column<I>;\n readonly reference: Column<I>;\n readonly flowId: Column<I>;\n readonly claimId: Column<I>;\n readonly identityKey: Column<I>;\n readonly version: Column<I>;\n readonly state: Column<I>;\n readonly snapshot: Column<I>;\n readonly commandId: Column<I>;\n readonly fingerprint: Column<I>;\n readonly pendingReference: Column<I>;\n readonly expiresAt: Column<I>;\n readonly retentionUntil: Column<I>;\n readonly encodeInsert: (intent: OAuthRegistrationIntent) => InferInsertModel<I>;\n}\n\nexport interface OAuthRegistrationCommandTable<R extends Table, Registration> {\n readonly table: R;\n readonly moduleId: Column<R>;\n readonly commandId: Column<R>;\n readonly reference: Column<R>;\n readonly identityKey: Column<R>;\n readonly fingerprint: Column<R>;\n readonly intentSnapshot: Column<R>;\n readonly applicationSnapshot: Column<R>;\n readonly provisioningIdentity: Column<R>;\n readonly decision: Column<R>;\n readonly retentionUntil: Column<R>;\n /** Persists exact detached Type before protected pending work can start. */\n readonly encodeInsert: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly commandId: string;\n readonly fingerprint: string;\n readonly registration: Registration;\n readonly provisioningIdentity: string;\n }) => InferInsertModel<R>;\n}\n\nexport interface OAuthUnlinkCommandTable<U extends Table> {\n readonly table: U;\n readonly moduleId: Column<U>;\n readonly commandId: Column<U>;\n readonly subjectId: Column<U>;\n readonly credentialId: Column<U>;\n readonly intentSnapshot: Column<U>;\n readonly decision: Column<U>;\n readonly retentionUntil: Column<U>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly commandId: string;\n readonly credential: OAuthCredentialSnapshot;\n }) => InferInsertModel<U>;\n}\n\nexport interface OAuthEligibilityFact {\n readonly credentialId: string;\n readonly revision: SecurityRevision;\n readonly usablePrimary: boolean;\n readonly factors: ReadonlyArray<AuthenticationFactor>;\n readonly userVerified: boolean;\n readonly phishingResistant: boolean;\n}\n\n/** Each descriptor reads only its own subject-scoped method rows. The native row\n * projector and SQL condition must express the same installed method eligibility.\n * All source/identifier/policy mutations advance subject securityRevision. D1 also\n * guards exact selected IDs/versions and absence/count assumptions, never just a\n * stale boolean. An over-limit graph fails closed rather than truncating. */\nexport interface OAuthEligibilityTable<T extends Table, N> {\n readonly table: T;\n readonly subjectId: Column<T>;\n readonly credentialId: Column<T>;\n readonly revision: Column<T>;\n readonly scope: string;\n readonly condition: (subjectId: N) => SQL;\n readonly decode: (row: InferSelectModel<T>) => OAuthEligibilityFact | undefined;\n}\n\n/** Authenticated command replay uses current subject status and this additional\n * nonconsuming SQL policy. It never consumes a fresh action factor. */\nexport interface OAuthMetadataPolicy<N> {\n readonly condition: (subjectId: N) => SQL;\n}\n\nexport interface OAuthCleanupTable<T extends Table, N> {\n readonly table: T;\n readonly subjectId: Column<T>;\n /** Bound to this subject's old revision; no opaque independently committing service. */\n readonly condition: (input: {\n readonly subjectId: N;\n readonly revision: OAuthAccountRevision;\n readonly removedCredentialId?: string;\n }) => SQL;\n readonly disposition: \"delete\";\n}\n\nexport interface OAuthRegistrationEligibility<N> {\n /** Pure SQL guards for mutable app policy; evaluated again after app writes. */\n readonly condition: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly nativeSubjectId?: N;\n }) => SQL;\n}\n\nexport interface OAuthD1Mapping {\n readonly d1: { readonly primary: true };\n}\n\nexport const requiredOAuthSignInConstraints = {\n flow: \"unique(flow.moduleId,flow.flowId)\",\n command: \"unique(flow.moduleId,flow.commandId)\",\n stateDigest: \"unique(flow.stateDigest)\",\n ownership: \"unique(ownership.identityKey)\",\n credentialId: \"unique(credential.credentialId)\",\n credentialIdentity: \"unique(credential.identityKey)\",\n authorityCredential: \"unique(authority.subjectId,authority.credentialId)\",\n} as const;\n\nexport const requiredOAuthTupleConstraints = { identityKey: \"unique(tuple.identityKey)\" } as const;\n\nexport const requiredOAuthRegistrationConstraints = {\n intentReference: \"unique(intent.moduleId,intent.reference)\",\n intentFlow: \"unique(intent.moduleId,intent.flowId)\",\n command: \"unique(registrationCommand.moduleId,registrationCommand.commandId)\",\n} as const;\n\nexport const requiredOAuthAccountsConstraints = {\n unlinkCommand: \"unique(unlinkCommand.moduleId,unlinkCommand.commandId)\",\n} as const;\n\nexport interface OAuthSignInMapping<\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n F extends Table,\n N,\n> {\n readonly subject: OAuthSubjectReadTable<S>;\n readonly ownership: OAuthOwnershipReadTable<O, N>;\n readonly credential: OAuthCredentialReadTable<C>;\n readonly authority: OAuthAuthorityReadTable<AC>;\n readonly flow: OAuthFlowTable<F>;\n readonly subjectId: SubjectIdCodec<N>;\n readonly clock: OAuthClock;\n readonly constraints: typeof requiredOAuthSignInConstraints;\n}\n\nexport type OAuthOwnershipMutation<T extends Table, O extends Table, N> =\n | { readonly mode: \"integrated\"; readonly tuple: OAuthTupleAuthorityTable<T, N> }\n | {\n readonly mode: \"separate\";\n readonly tuple: OAuthTupleAuthorityTable<T, N>;\n readonly external: OAuthOwnershipTable<O, N>;\n };\n\nexport interface OAuthRegistrationIntentMapping<\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n F extends Table,\n T extends Table,\n I extends Table,\n N,\n> {\n readonly signIn: OAuthSignInMapping<S, O, C, AC, F, N>;\n readonly ownership: OAuthOwnershipMutation<T, O, N>;\n readonly intent: OAuthRegistrationIntentTable<I>;\n readonly tupleConstraints: typeof requiredOAuthTupleConstraints;\n readonly registrationConstraints: Pick<\n typeof requiredOAuthRegistrationConstraints,\n \"intentReference\" | \"intentFlow\"\n >;\n readonly eligibility: OAuthRegistrationEligibility<N>;\n}\n\nexport interface OAuthRegistrationBase<\n Registration,\n T extends Table,\n O extends Table,\n I extends Table,\n R extends Table,\n N,\n> {\n readonly ownership: OAuthOwnershipMutation<T, O, N>;\n readonly intent: OAuthRegistrationIntentTable<I>;\n readonly command: OAuthRegistrationCommandTable<R, Registration>;\n readonly clock: OAuthClock;\n readonly tupleConstraints: typeof requiredOAuthTupleConstraints;\n readonly constraints: typeof requiredOAuthRegistrationConstraints;\n readonly inspect: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n }) => Effect.Effect<\n { readonly fingerprint: string; readonly eligible: boolean },\n PersistenceMappingError\n >;\n /** Required for an explicitly bound native/DO command: no asynchronous callback\n * is evaluated inside the physical owner. Standalone inspection is pre-owner. */\n readonly inspectSync?: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n }) => { readonly fingerprint: string; readonly eligible: boolean };\n /** Type projection, never the original wire transformation. */\n readonly snapshot: (\n registration: Registration,\n ) => Effect.Effect<Registration, PersistenceMappingError>;\n readonly snapshotSync?: (registration: Registration) => Registration;\n /** Canonical bounded storage of Registration.Type. These are Type codecs, not\n * the original wire decoder/encoder; decode(encode(value)) must encode identically.\n * The engine writes and roundtrip-checks this exact string (maximum 1 MiB). */\n readonly application: {\n readonly encode: (registration: Registration) => string;\n readonly decode: (stored: string) => Registration;\n };\n readonly eligibility: {\n /** Stable application authority anchors, in one configured global order.\n * Omit only for immutable/tuple-local policy or an equivalent explicit outer\n * owner lock. Each scope must match 1..64 rows, never an absent quota row.\n * Locks precede tuple/intent/command locks; postcondition owns changed state. */\n readonly guards?: ReadonlyArray<OAuthRegistrationGuardDescriptor<Registration, N>>;\n readonly admission: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n readonly nativeSubjectId?: N;\n }) => SQL;\n /** Evaluated after subject/application writes, including appended coordinator\n * writes. May assert consumption of the admission invitation/quota. */\n readonly postcondition: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n readonly nativeSubjectId?: N;\n }) => SQL;\n };\n readonly allocateProvisioningIdentity: Effect.Effect<string, PersistenceMappingError>;\n readonly retentionMillis: number;\n}\n\nexport interface OAuthRegistrationGuardTable<T extends Table, Registration, N> {\n readonly table: T;\n readonly orderBy: Column<T>;\n readonly condition: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n readonly nativeSubjectId?: N;\n }) => SQL;\n}\n\nexport interface OAuthRegistrationGuardDescriptor<Registration, N> {\n readonly table: Table;\n readonly orderBy: string;\n readonly condition: OAuthRegistrationGuardTable<Table, Registration, N>[\"condition\"];\n}\n\nexport const oauthRegistrationGuardTable = <T extends Table, Registration, N>(\n input: OAuthRegistrationGuardTable<T, Registration, N>,\n): OAuthRegistrationGuardDescriptor<Registration, N> =>\n Object.freeze({\n table: input.table,\n orderBy: input.orderBy,\n condition: input.condition,\n });\n\nexport type OAuthRegistrationMapping<\n Registration,\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n T extends Table,\n I extends Table,\n R extends Table,\n N,\n> = OAuthRegistrationBase<Registration, T, O, I, R, N> &\n (\n | {\n readonly mode: \"pending\";\n readonly allocatePendingReference: Effect.Effect<string, PersistenceMappingError>;\n }\n | {\n readonly mode: \"atomic\";\n readonly subjectId: SubjectIdCodec<N>;\n readonly subject: OAuthSubjectReadTable<S>;\n readonly credential: OAuthCredentialTable<C, N>;\n readonly authority: OAuthAuthorityTable<AC, N>;\n readonly allocateSubjectId: Effect.Effect<N, PersistenceMappingError>;\n readonly allocateCredentialId: Effect.Effect<string, PersistenceMappingError>;\n readonly allocateRevision: Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly encodeSubjectInsert: (\n input: { readonly intent: OAuthRegistrationIntent; readonly registration: Registration },\n ids: { readonly subjectId: N; readonly securityRevision: SecurityRevision },\n ) => InferInsertModel<S>;\n }\n );\n\n/** Heterogeneous descriptors are made by typed factories and projected privately. */\nexport interface OAuthEligibilityDescriptor<N> {\n readonly _tag: \"OAuthEligibilityDescriptor\";\n readonly scope: string;\n readonly table: Table;\n readonly subjectId: string;\n readonly credentialId: string;\n readonly revision: string;\n readonly condition: (subjectId: N) => SQL;\n readonly decode: (row: unknown) => OAuthEligibilityFact | undefined;\n}\n\nexport const oauthEligibilityTable = <T extends Table, N>(\n input: OAuthEligibilityTable<T, N>,\n): OAuthEligibilityDescriptor<N> => {\n const { table, subjectId, credentialId, revision, scope, condition, decode } = input;\n\n return Object.freeze({\n _tag: \"OAuthEligibilityDescriptor\",\n table,\n subjectId,\n credentialId,\n revision,\n scope,\n condition,\n decode: (row: unknown) => decode(row as InferSelectModel<T>),\n });\n};\n\nexport interface OAuthCleanupDescriptor<N> {\n readonly table: Table;\n readonly subjectId: string;\n readonly condition: OAuthCleanupTable<Table, N>[\"condition\"];\n}\n\nexport const oauthCleanupTable = <T extends Table, N>(\n input: OAuthCleanupTable<T, N>,\n): OAuthCleanupDescriptor<N> =>\n Object.freeze({ table: input.table, subjectId: input.subjectId, condition: input.condition });\n\n/** A stable application/reference lock acquired before an ownership target.\n * Missing rows retain ownership. Conditions use detached native IDs; every\n * writer of the guarded reference follows the same order. */\nexport interface OAuthReferenceGuardTable<T extends Table, N> {\n readonly table: T;\n readonly orderBy: Column<T>;\n readonly condition: (input: {\n readonly identity: typeof OAuthExternalIdentity.Type;\n readonly identityKey: string;\n readonly subjectId: N;\n }) => SQL | Effect.Effect<SQL, PlatformError.PlatformError, Crypto.Crypto>;\n}\n\nexport interface OAuthReferenceGuardDescriptor<N> {\n readonly table: Table;\n readonly orderBy: string;\n readonly condition: OAuthReferenceGuardTable<Table, N>[\"condition\"];\n}\n\nexport const oauthReferenceGuardTable = <T extends Table, N>(\n input: OAuthReferenceGuardTable<T, N>,\n): OAuthReferenceGuardDescriptor<N> =>\n Object.freeze({\n table: input.table,\n orderBy: input.orderBy,\n condition: input.condition,\n });\n\nexport interface OAuthAccountsMapping<\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n F extends Table,\n T extends Table,\n U extends Table,\n N,\n> {\n readonly subject: OAuthSubjectTable<S>;\n readonly ownership: OAuthOwnershipMutation<T, O, N>;\n readonly credential: OAuthCredentialTable<C, N>;\n readonly authority: OAuthAuthorityTable<AC, N>;\n readonly flow: OAuthFlowTable<F>;\n readonly command: OAuthUnlinkCommandTable<U>;\n readonly subjectId: SubjectIdCodec<N>;\n readonly clock: OAuthClock;\n readonly constraints: typeof requiredOAuthSignInConstraints &\n typeof requiredOAuthAccountsConstraints;\n readonly tupleConstraints: typeof requiredOAuthTupleConstraints;\n readonly eligibility: ReadonlyArray<OAuthEligibilityDescriptor<N>>;\n readonly cleanup: ReadonlyArray<OAuthCleanupDescriptor<N>>;\n readonly metadata: OAuthMetadataPolicy<N>;\n readonly sessionInvalidation: \"same-authority-immediate\" | \"original-absolute-expiry\";\n /** Omit only when connected access is absent. A predicate alone conservatively\n * retains ownership; release also needs all configured guard rows below. */\n readonly connectedReference?: (input: {\n readonly identityKey: string;\n readonly subjectId: N;\n }) => SQL;\n /** At most 32 descriptors, each locking 1..64 stable rows in supplied order.\n * Missing/empty guards retain Owned, even when the reference predicate is false. */\n readonly connectedReferenceGuards?: ReadonlyArray<OAuthReferenceGuardDescriptor<N>>;\n readonly allocateCredentialId: Effect.Effect<string, PersistenceMappingError>;\n readonly allocateRevision: Effect.Effect<SecurityRevision, PersistenceMappingError>;\n}\n\nexport interface OAuthRegistrationAuthority<Registration> {\n readonly read: (\n access: import(\"@yielded/auth/OAuth\").OAuthRegistrationAccess,\n ) => Effect.Effect<\n import(\"@yielded/auth/OAuth\").OAuthRegistrationInspection | undefined,\n import(\"@yielded/auth/OAuth\").OAuthUnavailable\n >;\n readonly inspect: (input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n }) => Effect.Effect<\n {\n readonly fingerprint: import(\"@yielded/auth/Schema\").TokenDigest;\n readonly eligible: boolean;\n },\n import(\"@yielded/auth/OAuth\").OAuthUnavailable\n >;\n readonly register: <A>(\n input: {\n readonly access: import(\"@yielded/auth/OAuth\").OAuthRegistrationAccess;\n readonly intent: OAuthRegistrationIntent;\n readonly commandId: typeof import(\"@yielded/auth/OAuth\").OAuthCommandId.Type;\n readonly registration: Registration;\n readonly fingerprint: import(\"@yielded/auth/Schema\").TokenDigest;\n },\n prepare: import(\"@yielded/auth/OAuth\").PrepareOAuthCommit<\n import(\"@yielded/auth/OAuth\").OAuthRegistrationDecision,\n A\n >,\n ) => Effect.Effect<\n import(\"@yielded/auth/Hooks\").PreparedCommit<A>,\n import(\"@yielded/auth/OAuth\").OAuthUnavailable\n >;\n readonly cleanup: <A>(\n input: import(\"@yielded/auth/OAuth\").OAuthCleanupInput,\n prepare: import(\"@yielded/auth/OAuth\").PrepareOAuthCommit<\n { readonly removed: number; readonly hasMore: boolean },\n A\n >,\n ) => Effect.Effect<\n import(\"@yielded/auth/Hooks\").PreparedCommit<A>,\n import(\"@yielded/auth/OAuth\").OAuthUnavailable\n >;\n}\n"],"mappings":";AAuRA,MAAa,iCAAiC;CAC5C,MAAM;CACN,SAAS;CACT,aAAa;CACb,WAAW;CACX,cAAc;CACd,oBAAoB;CACpB,qBAAqB;AACvB;AAEA,MAAa,gCAAgC,EAAE,aAAa,4BAA4B;AAExF,MAAa,uCAAuC;CAClD,iBAAiB;CACjB,YAAY;CACZ,SAAS;AACX;AAEA,MAAa,mCAAmC,EAC9C,eAAe,yDACjB;AA+HA,MAAa,+BACX,UAEA,OAAO,OAAO;CACZ,OAAO,MAAM;CACb,SAAS,MAAM;CACf,WAAW,MAAM;AACnB,CAAC;AA8CH,MAAa,yBACX,UACkC;CAClC,MAAM,EAAE,OAAO,WAAW,cAAc,UAAU,OAAO,WAAW,WAAW;CAE/E,OAAO,OAAO,OAAO;EACnB,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA,SAAS,QAAiB,OAAO,GAA0B;CAC7D,CAAC;AACH;AAQA,MAAa,qBACX,UAEA,OAAO,OAAO;CAAE,OAAO,MAAM;CAAO,WAAW,MAAM;CAAW,WAAW,MAAM;AAAU,CAAC;AAqB9F,MAAa,4BACX,UAEA,OAAO,OAAO;CACZ,OAAO,MAAM;CACb,SAAS,MAAM;CACf,WAAW,MAAM;AACnB,CAAC"}
1
+ {"version":3,"file":"oauth-model.mjs","names":[],"sources":["../../src/drizzle/oauth-model.ts"],"sourcesContent":["import * as Shared from \"@yielded/auth-persistence/Adapter\";\nimport type { SQL, Table } from \"drizzle-orm\";\n\nimport type { DrizzleTableModel } from \"./table-model\";\n\nexport {\n type OAuthFlowState,\n type OAuthTupleState,\n type OAuthRegistrationState,\n type OAuthAction,\n type OAuthEligibilityFact,\n type OAuthD1Mapping,\n requiredOAuthSignInConstraints,\n requiredOAuthTupleConstraints,\n requiredOAuthRegistrationConstraints,\n requiredOAuthAccountsConstraints,\n type OAuthRegistrationAuthority,\n} from \"@yielded/auth-persistence/Adapter\";\n\n/** The engine writes every critical column explicitly after applying the pure\n * consumer encoder. Native instant values must roundtrip without precision loss. */\nexport type OAuthClock = Shared.OAuthClock<SQL>;\n\nexport type OAuthSubjectReadTable<S extends Table> = Shared.OAuthSubjectReadTable<\n DrizzleTableModel<S>,\n SQL\n>;\n\nexport type OAuthSubjectTable<S extends Table> = Shared.OAuthSubjectTable<\n DrizzleTableModel<S>,\n SQL\n>;\n\nexport type OAuthOwnershipReadTable<O extends Table, N> = Shared.OAuthOwnershipReadTable<\n DrizzleTableModel<O>,\n N,\n SQL\n>;\n\nexport type OAuthOwnershipTable<O extends Table, N> = Shared.OAuthOwnershipTable<\n DrizzleTableModel<O>,\n N,\n SQL\n>;\n\nexport type OAuthCredentialReadTable<C extends Table> = Shared.OAuthCredentialReadTable<\n DrizzleTableModel<C>,\n SQL\n>;\n\nexport type OAuthCredentialTable<C extends Table, N> = Shared.OAuthCredentialTable<\n DrizzleTableModel<C>,\n N,\n SQL\n>;\n\nexport type OAuthAuthorityReadTable<C extends Table> = Shared.OAuthAuthorityReadTable<\n DrizzleTableModel<C>,\n SQL\n>;\n\nexport type OAuthAuthorityTable<C extends Table, N> = Shared.OAuthAuthorityTable<\n DrizzleTableModel<C>,\n N,\n SQL\n>;\n\n/** Both purposes may use the same physical table. Shared tables share module/flow\n * and module/command uniqueness. The snapshot has the exact purpose-specific core\n * codec; terminal writes erase it, while identity, claim and retention columns remain. */\nexport type OAuthFlowTable<F extends Table> = Shared.OAuthFlowTable<DrizzleTableModel<F>>;\n\nexport type OAuthTupleAuthorityTable<T extends Table, N> = Shared.OAuthTupleAuthorityTable<\n DrizzleTableModel<T>,\n N\n>;\n\nexport type OAuthRegistrationIntentTable<I extends Table> = Shared.OAuthRegistrationIntentTable<\n DrizzleTableModel<I>\n>;\n\nexport type OAuthRegistrationCommandTable<\n R extends Table,\n Registration,\n> = Shared.OAuthRegistrationCommandTable<DrizzleTableModel<R>, Registration>;\n\nexport type OAuthUnlinkCommandTable<U extends Table> = Shared.OAuthUnlinkCommandTable<\n DrizzleTableModel<U>\n>;\n\n/** Each descriptor reads only its own subject-scoped method rows. The native row\n * projector and SQL condition must express the same installed method eligibility.\n * All source/identifier/policy mutations advance subject securityRevision. D1 also\n * guards exact selected IDs/versions and absence/count assumptions, never just a\n * stale boolean. An over-limit graph fails closed rather than truncating. */\nexport type OAuthEligibilityTable<T extends Table, N> = Shared.OAuthEligibilityTable<\n DrizzleTableModel<T>,\n N,\n SQL\n>;\n\n/** Authenticated command replay uses current subject status and this additional\n * nonconsuming SQL policy. It never consumes a fresh action factor. */\nexport type OAuthMetadataPolicy<N> = Shared.OAuthMetadataPolicy<N, SQL>;\n\nexport type OAuthCleanupTable<T extends Table, N> = Shared.OAuthCleanupTable<\n DrizzleTableModel<T>,\n N,\n SQL\n>;\n\nexport type OAuthRegistrationEligibility<N> = Shared.OAuthRegistrationEligibility<N, SQL>;\n\nexport type OAuthSignInMapping<\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n F extends Table,\n N,\n> = Shared.OAuthSignInMapping<\n DrizzleTableModel<S>,\n DrizzleTableModel<O>,\n DrizzleTableModel<C>,\n DrizzleTableModel<AC>,\n DrizzleTableModel<F>,\n N,\n SQL\n>;\n\nexport type OAuthOwnershipMutation<\n T extends Table,\n O extends Table,\n N,\n> = Shared.OAuthOwnershipMutation<DrizzleTableModel<T>, DrizzleTableModel<O>, N, SQL>;\n\nexport type OAuthRegistrationIntentMapping<\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n F extends Table,\n T extends Table,\n I extends Table,\n N,\n> = Shared.OAuthRegistrationIntentMapping<\n DrizzleTableModel<S>,\n DrizzleTableModel<O>,\n DrizzleTableModel<C>,\n DrizzleTableModel<AC>,\n DrizzleTableModel<F>,\n DrizzleTableModel<T>,\n DrizzleTableModel<I>,\n N,\n SQL\n>;\n\nexport type OAuthRegistrationBase<\n Registration,\n T extends Table,\n O extends Table,\n I extends Table,\n R extends Table,\n N,\n> = Shared.OAuthRegistrationBase<\n Registration,\n DrizzleTableModel<T>,\n DrizzleTableModel<O>,\n DrizzleTableModel<I>,\n DrizzleTableModel<R>,\n N,\n SQL,\n Table\n>;\n\nexport type OAuthRegistrationGuardTable<\n T extends Table,\n Registration,\n N,\n> = Shared.OAuthRegistrationGuardTable<DrizzleTableModel<T>, Registration, N, SQL>;\n\nexport type OAuthRegistrationGuardDescriptor<Registration, N> =\n Shared.OAuthRegistrationGuardDescriptor<Registration, N, SQL, Table>;\n\nexport const oauthRegistrationGuardTable = <T extends Table, Registration, N>(\n input: OAuthRegistrationGuardTable<T, Registration, N>,\n): OAuthRegistrationGuardDescriptor<Registration, N> =>\n Shared.oauthRegistrationGuardTable<DrizzleTableModel<T>, Registration, N, SQL>(input);\n\nexport type OAuthRegistrationMapping<\n Registration,\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n T extends Table,\n I extends Table,\n R extends Table,\n N,\n> = Shared.OAuthRegistrationMapping<\n Registration,\n DrizzleTableModel<S>,\n DrizzleTableModel<O>,\n DrizzleTableModel<C>,\n DrizzleTableModel<AC>,\n DrizzleTableModel<T>,\n DrizzleTableModel<I>,\n DrizzleTableModel<R>,\n N,\n SQL,\n Table\n>;\n\n/** Heterogeneous descriptors are made by typed factories and projected privately. */\nexport type OAuthEligibilityDescriptor<N> = Shared.OAuthEligibilityDescriptor<N, SQL, Table>;\n\nexport const oauthEligibilityTable = <T extends Table, N>(\n input: OAuthEligibilityTable<T, N>,\n): OAuthEligibilityDescriptor<N> =>\n Shared.oauthEligibilityTable<DrizzleTableModel<T>, N, SQL>(input);\n\nexport type OAuthCleanupDescriptor<N> = Shared.OAuthCleanupDescriptor<N, SQL, Table>;\n\nexport const oauthCleanupTable = <T extends Table, N>(\n input: OAuthCleanupTable<T, N>,\n): OAuthCleanupDescriptor<N> => Shared.oauthCleanupTable<DrizzleTableModel<T>, N, SQL>(input);\n\n/** A stable application/reference lock acquired before an ownership target.\n * Missing rows retain ownership. Conditions use detached native IDs; every\n * writer of the guarded reference follows the same order. */\nexport type OAuthReferenceGuardTable<T extends Table, N> = Shared.OAuthReferenceGuardTable<\n DrizzleTableModel<T>,\n N,\n SQL\n>;\n\nexport type OAuthReferenceGuardDescriptor<N> = Shared.OAuthReferenceGuardDescriptor<N, SQL, Table>;\n\nexport const oauthReferenceGuardTable = <T extends Table, N>(\n input: OAuthReferenceGuardTable<T, N>,\n): OAuthReferenceGuardDescriptor<N> =>\n Shared.oauthReferenceGuardTable<DrizzleTableModel<T>, N, SQL>(input);\n\nexport type OAuthAccountsMapping<\n S extends Table,\n O extends Table,\n C extends Table,\n AC extends Table,\n F extends Table,\n T extends Table,\n U extends Table,\n N,\n> = Shared.OAuthAccountsMapping<\n DrizzleTableModel<S>,\n DrizzleTableModel<O>,\n DrizzleTableModel<C>,\n DrizzleTableModel<AC>,\n DrizzleTableModel<F>,\n DrizzleTableModel<T>,\n DrizzleTableModel<U>,\n N,\n SQL,\n Table\n>;\n"],"mappings":";;;AAwLA,MAAa,+BACX,UAEA,OAAO,4BAAwE,KAAK;AA6BtF,MAAa,yBACX,UAEA,OAAO,sBAAoD,KAAK;AAIlE,MAAa,qBACX,UAC8B,OAAO,kBAAgD,KAAK;AAa5F,MAAa,4BACX,UAEA,OAAO,yBAAuD,KAAK"}