@yielded/auth-persistence 0.1.0-beta.10
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/README.md +27 -0
- package/dist/Adapter.d.mts +30 -0
- package/dist/Adapter.mjs +25 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +7 -0
- package/dist/internal/PasswordPreparedPostconditions.d.mts +22 -0
- package/dist/internal/PasswordPreparedPostconditions.mjs +12 -0
- package/dist/internal/PasswordPreparedPostconditions.mjs.map +1 -0
- package/dist/internal/configuration.d.mts +174 -0
- package/dist/internal/configuration.mjs +7 -0
- package/dist/internal/configuration.mjs.map +1 -0
- package/dist/internal/email-kernel.d.mts +275 -0
- package/dist/internal/email-kernel.mjs +487 -0
- package/dist/internal/email-kernel.mjs.map +1 -0
- package/dist/internal/mapping-error.d.mts +10 -0
- package/dist/internal/mapping-error.mjs +30 -0
- package/dist/internal/mapping-error.mjs.map +1 -0
- package/dist/internal/models/common.d.mts +12 -0
- package/dist/internal/models/email-model.d.mts +353 -0
- package/dist/internal/models/email-model.mjs +21 -0
- package/dist/internal/models/email-model.mjs.map +1 -0
- package/dist/internal/models/passkey-model.d.mts +266 -0
- package/dist/internal/models/passkey-model.mjs +34 -0
- package/dist/internal/models/passkey-model.mjs.map +1 -0
- package/dist/internal/models/passkey-registration-ceremony-model.d.mts +49 -0
- package/dist/internal/models/passkey-registration-ceremony-model.mjs +18 -0
- package/dist/internal/models/passkey-registration-ceremony-model.mjs.map +1 -0
- package/dist/internal/models/passkey-write-model.d.mts +189 -0
- package/dist/internal/models/passkey-write-model.mjs +13 -0
- package/dist/internal/models/passkey-write-model.mjs.map +1 -0
- package/dist/internal/models/password-model.d.mts +328 -0
- package/dist/internal/models/password-model.mjs +23 -0
- package/dist/internal/models/password-model.mjs.map +1 -0
- package/dist/internal/models/proof-model.d.mts +285 -0
- package/dist/internal/models/proof-model.mjs +17 -0
- package/dist/internal/models/proof-model.mjs.map +1 -0
- package/dist/internal/models/session-model.d.mts +199 -0
- package/dist/internal/models/session-model.mjs +20 -0
- package/dist/internal/models/session-model.mjs.map +1 -0
- package/dist/internal/models/step-up-model.d.mts +66 -0
- package/dist/internal/models/step-up-model.mjs +9 -0
- package/dist/internal/models/step-up-model.mjs.map +1 -0
- package/dist/internal/oauth-app.d.mts +11 -0
- package/dist/internal/oauth-app.mjs +57 -0
- package/dist/internal/oauth-app.mjs.map +1 -0
- package/dist/internal/oauth-server.d.mts +10 -0
- package/dist/internal/oauth-server.mjs +66 -0
- package/dist/internal/oauth-server.mjs.map +1 -0
- package/dist/internal/passkey/admission.d.mts +6 -0
- package/dist/internal/passkey/admission.mjs +216 -0
- package/dist/internal/passkey/admission.mjs.map +1 -0
- package/dist/internal/passkey/credentials.d.mts +14 -0
- package/dist/internal/passkey/credentials.mjs +249 -0
- package/dist/internal/passkey/credentials.mjs.map +1 -0
- package/dist/internal/passkey/enrollment.mjs +138 -0
- package/dist/internal/passkey/enrollment.mjs.map +1 -0
- package/dist/internal/passkey/flow.d.mts +21 -0
- package/dist/internal/passkey/flow.mjs +452 -0
- package/dist/internal/passkey/flow.mjs.map +1 -0
- package/dist/internal/passkey/management.mjs +231 -0
- package/dist/internal/passkey/management.mjs.map +1 -0
- package/dist/internal/passkey/registration-ceremony.d.mts +9 -0
- package/dist/internal/passkey/registration-ceremony.mjs +129 -0
- package/dist/internal/passkey/registration-ceremony.mjs.map +1 -0
- package/dist/internal/passkey/registration-custody.d.mts +2 -0
- package/dist/internal/passkey/registration-custody.mjs +52 -0
- package/dist/internal/passkey/registration-custody.mjs.map +1 -0
- package/dist/internal/passkey/registration-write.mjs +211 -0
- package/dist/internal/passkey/registration-write.mjs.map +1 -0
- package/dist/internal/passkey/state.d.mts +10 -0
- package/dist/internal/passkey/state.mjs +234 -0
- package/dist/internal/passkey/state.mjs.map +1 -0
- package/dist/internal/passkey/target.d.mts +19 -0
- package/dist/internal/passkey/target.mjs +190 -0
- package/dist/internal/passkey/target.mjs.map +1 -0
- package/dist/internal/passkey/write-state.d.mts +17 -0
- package/dist/internal/passkey/write-state.mjs +345 -0
- package/dist/internal/passkey/write-state.mjs.map +1 -0
- package/dist/internal/passkey/write-target.mjs +192 -0
- package/dist/internal/passkey/write-target.mjs.map +1 -0
- package/dist/internal/passkey-kernel.d.mts +5592 -0
- package/dist/internal/passkey-kernel.mjs +49 -0
- package/dist/internal/passkey-kernel.mjs.map +1 -0
- package/dist/internal/passkeys.d.mts +7 -0
- package/dist/internal/passkeys.mjs +368 -0
- package/dist/internal/passkeys.mjs.map +1 -0
- package/dist/internal/password-kernel.d.mts +290 -0
- package/dist/internal/password-kernel.mjs +704 -0
- package/dist/internal/password-kernel.mjs.map +1 -0
- package/dist/internal/persistence.d.mts +25 -0
- package/dist/internal/persistence.mjs +291 -0
- package/dist/internal/persistence.mjs.map +1 -0
- package/dist/internal/phone-kernel.d.mts +162 -0
- package/dist/internal/phone-kernel.mjs +434 -0
- package/dist/internal/phone-kernel.mjs.map +1 -0
- package/dist/internal/proof-kernel.d.mts +93 -0
- package/dist/internal/proof-kernel.mjs +619 -0
- package/dist/internal/proof-kernel.mjs.map +1 -0
- package/dist/internal/query-operations.d.mts +61 -0
- package/dist/internal/registration-contract.d.mts +16 -0
- package/dist/internal/registration.mjs +66 -0
- package/dist/internal/registration.mjs.map +1 -0
- package/dist/internal/session-kernel.d.mts +48 -0
- package/dist/internal/session-kernel.mjs +737 -0
- package/dist/internal/session-kernel.mjs.map +1 -0
- package/dist/internal/sql-persistence.d.mts +10 -0
- package/dist/internal/sql-persistence.mjs +37 -0
- package/dist/internal/sql-persistence.mjs.map +1 -0
- package/dist/internal/sql-query.mjs +207 -0
- package/dist/internal/sql-query.mjs.map +1 -0
- package/dist/internal/sql-table.d.mts +36 -0
- package/dist/internal/sql-table.mjs +81 -0
- package/dist/internal/sql-table.mjs.map +1 -0
- package/dist/internal/standalone.d.mts +9 -0
- package/dist/internal/standalone.mjs +13 -0
- package/dist/internal/standalone.mjs.map +1 -0
- package/dist/internal/step-up-state.d.mts +49 -0
- package/dist/internal/step-up-state.mjs +32 -0
- package/dist/internal/step-up-state.mjs.map +1 -0
- package/dist/internal/storage-mapping.mjs +686 -0
- package/dist/internal/storage-mapping.mjs.map +1 -0
- package/dist/internal/storage-tables.d.mts +913 -0
- package/dist/internal/storage-tables.mjs +387 -0
- package/dist/internal/storage-tables.mjs.map +1 -0
- package/dist/internal/storage-validation.mjs +58 -0
- package/dist/internal/storage-validation.mjs.map +1 -0
- package/dist/internal/transaction-execution-kernel.d.mts +38 -0
- package/dist/internal/transaction-execution-kernel.mjs +116 -0
- package/dist/internal/transaction-execution-kernel.mjs.map +1 -0
- package/dist/internal/transaction-kernel.d.mts +77 -0
- package/dist/internal/transaction-kernel.mjs +260 -0
- package/dist/internal/transaction-kernel.mjs.map +1 -0
- package/package.json +1 -0
- package/src/Adapter.ts +291 -0
- package/src/index.ts +6 -0
- package/src/internal/PasswordPreparedPostconditions.ts +30 -0
- package/src/internal/configuration.ts +282 -0
- package/src/internal/email-kernel.ts +1535 -0
- package/src/internal/mapping-error.ts +36 -0
- package/src/internal/models/common.ts +11 -0
- package/src/internal/models/email-model.ts +559 -0
- package/src/internal/models/passkey-model.ts +390 -0
- package/src/internal/models/passkey-registration-ceremony-model.ts +72 -0
- package/src/internal/models/passkey-write-model.ts +297 -0
- package/src/internal/models/password-model.ts +513 -0
- package/src/internal/models/proof-model.ts +424 -0
- package/src/internal/models/session-model.ts +375 -0
- package/src/internal/models/step-up-model.ts +135 -0
- package/src/internal/oauth-app.ts +82 -0
- package/src/internal/oauth-server.ts +89 -0
- package/src/internal/passkey/admission.ts +361 -0
- package/src/internal/passkey/credentials.ts +511 -0
- package/src/internal/passkey/enrollment.ts +326 -0
- package/src/internal/passkey/flow.ts +1062 -0
- package/src/internal/passkey/management.ts +421 -0
- package/src/internal/passkey/registration-ceremony.ts +283 -0
- package/src/internal/passkey/registration-custody.ts +91 -0
- package/src/internal/passkey/registration-write.ts +426 -0
- package/src/internal/passkey/state.ts +353 -0
- package/src/internal/passkey/target.ts +586 -0
- package/src/internal/passkey/write-state.ts +681 -0
- package/src/internal/passkey/write-target.ts +452 -0
- package/src/internal/passkey-kernel.ts +104 -0
- package/src/internal/passkeys.ts +606 -0
- package/src/internal/password-kernel.ts +2124 -0
- package/src/internal/persistence.ts +588 -0
- package/src/internal/phone-kernel.ts +846 -0
- package/src/internal/proof-kernel.ts +1954 -0
- package/src/internal/query-operations.ts +81 -0
- package/src/internal/registration-contract.ts +22 -0
- package/src/internal/registration.ts +161 -0
- package/src/internal/session-kernel.ts +2217 -0
- package/src/internal/sql-persistence.ts +45 -0
- package/src/internal/sql-query.ts +298 -0
- package/src/internal/sql-table.ts +104 -0
- package/src/internal/standalone.ts +30 -0
- package/src/internal/step-up-state.ts +139 -0
- package/src/internal/storage-mapping.ts +708 -0
- package/src/internal/storage-tables.ts +408 -0
- package/src/internal/storage-validation.ts +117 -0
- package/src/internal/transaction-execution-kernel.ts +313 -0
- package/src/internal/transaction-kernel.ts +593 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { AnyTableModel, SqlExpression, TableModel } from "../query-operations.mjs";
|
|
2
|
+
import { PersistenceMappingError } from "../mapping-error.mjs";
|
|
3
|
+
import { SubjectIdCodec } from "./common.mjs";
|
|
4
|
+
import { Effect } from "effect";
|
|
5
|
+
import { TokenDigest } from "@yielded/auth/Schema";
|
|
6
|
+
import { ProofBinding, ProofContinuationId, ProofId, ProofPolicy, ProofPurpose, ProofRecord, ProofRequestReceipt, ProofVersion } from "@yielded/auth/Proofs";
|
|
7
|
+
//#region src/internal/models/proof-model.d.ts
|
|
8
|
+
type ColumnKey<T extends TableModel> = T["column"];
|
|
9
|
+
export type ProofAction = "issue" | "attempt";
|
|
10
|
+
export type ProofScopeKind = "action" | "identifier" | "subject";
|
|
11
|
+
export type ProofGenerationState = "active" | "consumed" | "cancelled" | "superseded";
|
|
12
|
+
export type ProofDeliveryState = "new" | "claimed" | "accepted" | "failed" | "ambiguous";
|
|
13
|
+
export type ProofCommandKind = "attempt" | "complete";
|
|
14
|
+
export type ProofCommandDecision = "accepted" | "rejected" | "completed";
|
|
15
|
+
export interface ProofScopeKeys {
|
|
16
|
+
/** Stable across flow/context/request changes and bounded by the consumer codec. */
|
|
17
|
+
readonly series: string;
|
|
18
|
+
readonly identifier: string;
|
|
19
|
+
/** A tagged non-null value; use a stable sentinel when the binding has no subject. */
|
|
20
|
+
readonly subject: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ProofAuthorityInput<NativeSubjectId> {
|
|
23
|
+
readonly moduleId: string;
|
|
24
|
+
readonly purpose: ProofPurpose;
|
|
25
|
+
readonly binding: ProofBinding;
|
|
26
|
+
/** Resolved by Effect preplanning before an interactive check or D1 predicate compile. */
|
|
27
|
+
readonly nativeSubjectId?: NativeSubjectId;
|
|
28
|
+
}
|
|
29
|
+
export interface ProofAuthorityTables<Subject extends TableModel, Identifier extends TableModel, Credential extends TableModel, NativeSubjectId, Expression extends SqlExpression = SqlExpression> {
|
|
30
|
+
readonly identifier: {
|
|
31
|
+
readonly table: Identifier["table"];
|
|
32
|
+
readonly namespace: ColumnKey<Identifier>;
|
|
33
|
+
readonly value: ColumnKey<Identifier>;
|
|
34
|
+
/** Evaluate the consumer's explicit current-ownership/availability semantics. */
|
|
35
|
+
readonly isCurrent: (input: ProofAuthorityInput<NativeSubjectId>, rows: ReadonlyArray<Identifier["select"]>) => boolean;
|
|
36
|
+
/** Optional outside D1. Never infer this semantic predicate from eligibility. */
|
|
37
|
+
readonly d1CurrentCondition?: (input: ProofAuthorityInput<NativeSubjectId>) => Expression;
|
|
38
|
+
};
|
|
39
|
+
readonly subject?: {
|
|
40
|
+
readonly table: Subject["table"];
|
|
41
|
+
readonly id: ColumnKey<Subject>;
|
|
42
|
+
readonly status: ColumnKey<Subject>;
|
|
43
|
+
readonly securityRevision: ColumnKey<Subject>;
|
|
44
|
+
readonly isActiveStatus: (value: unknown) => boolean;
|
|
45
|
+
readonly d1ActiveStatusValue: unknown;
|
|
46
|
+
};
|
|
47
|
+
readonly credential?: {
|
|
48
|
+
readonly table: Credential["table"];
|
|
49
|
+
readonly subjectId: ColumnKey<Credential>;
|
|
50
|
+
readonly credentialId: ColumnKey<Credential>;
|
|
51
|
+
readonly revision: ColumnKey<Credential>;
|
|
52
|
+
readonly status?: ColumnKey<Credential>;
|
|
53
|
+
readonly isActiveStatus?: (value: unknown) => boolean;
|
|
54
|
+
readonly d1ActiveStatusValue?: unknown;
|
|
55
|
+
};
|
|
56
|
+
readonly subjectId?: SubjectIdCodec<NativeSubjectId>;
|
|
57
|
+
}
|
|
58
|
+
export interface ProofRequestTable<Request extends TableModel> {
|
|
59
|
+
readonly table: Request["table"];
|
|
60
|
+
readonly moduleId: ColumnKey<Request>;
|
|
61
|
+
readonly requestId: ColumnKey<Request>;
|
|
62
|
+
readonly fingerprint: ColumnKey<Request>;
|
|
63
|
+
readonly proofId: ColumnKey<Request>;
|
|
64
|
+
readonly purpose: ColumnKey<Request>;
|
|
65
|
+
readonly keyId: ColumnKey<Request>;
|
|
66
|
+
readonly createdAt: ColumnKey<Request>;
|
|
67
|
+
readonly retentionUntil: ColumnKey<Request>;
|
|
68
|
+
readonly encodeInsert: (input: {
|
|
69
|
+
readonly record: ProofRecord;
|
|
70
|
+
readonly createdAtMillis: number;
|
|
71
|
+
readonly retentionUntilMillis: number;
|
|
72
|
+
}) => Request["insert"];
|
|
73
|
+
readonly decodeReceipt: (row: Request["select"]) => Effect.Effect<ProofRequestReceipt, PersistenceMappingError>;
|
|
74
|
+
}
|
|
75
|
+
export interface ProofSeriesTable<Series extends TableModel> {
|
|
76
|
+
readonly table: Series["table"];
|
|
77
|
+
readonly moduleId: ColumnKey<Series>;
|
|
78
|
+
readonly purpose: ColumnKey<Series>;
|
|
79
|
+
readonly scopeKey: ColumnKey<Series>;
|
|
80
|
+
readonly activeProofId: ColumnKey<Series>;
|
|
81
|
+
readonly lastIssueAt: ColumnKey<Series>;
|
|
82
|
+
readonly version: ColumnKey<Series>;
|
|
83
|
+
readonly encodeInsert: (input: {
|
|
84
|
+
readonly moduleId: string;
|
|
85
|
+
readonly purpose: ProofPurpose;
|
|
86
|
+
readonly scopeKey: string;
|
|
87
|
+
readonly version: ProofVersion;
|
|
88
|
+
}) => Series["insert"];
|
|
89
|
+
}
|
|
90
|
+
export interface ProofGenerationTable<Generation extends TableModel> {
|
|
91
|
+
readonly table: Generation["table"];
|
|
92
|
+
readonly moduleId: ColumnKey<Generation>;
|
|
93
|
+
readonly purpose: ColumnKey<Generation>;
|
|
94
|
+
readonly proofId: ColumnKey<Generation>;
|
|
95
|
+
readonly requestId: ColumnKey<Generation>;
|
|
96
|
+
readonly seriesKey: ColumnKey<Generation>;
|
|
97
|
+
readonly deliveryId: ColumnKey<Generation>;
|
|
98
|
+
readonly binding: ColumnKey<Generation>;
|
|
99
|
+
readonly verifierKeyId: ColumnKey<Generation>;
|
|
100
|
+
readonly verifierDigest: ColumnKey<Generation>;
|
|
101
|
+
readonly issuedAt: ColumnKey<Generation>;
|
|
102
|
+
readonly expiresAt: ColumnKey<Generation>;
|
|
103
|
+
readonly version: ColumnKey<Generation>;
|
|
104
|
+
readonly state: ColumnKey<Generation>;
|
|
105
|
+
readonly sendCount: ColumnKey<Generation>;
|
|
106
|
+
readonly deliveryState: ColumnKey<Generation>;
|
|
107
|
+
readonly claimVersion: ColumnKey<Generation>;
|
|
108
|
+
readonly claimDeadline: ColumnKey<Generation>;
|
|
109
|
+
readonly retryAt: ColumnKey<Generation>;
|
|
110
|
+
readonly deliveryRetryMillis: ColumnKey<Generation>;
|
|
111
|
+
readonly retentionUntil: ColumnKey<Generation>;
|
|
112
|
+
readonly encodeInsert: (input: {
|
|
113
|
+
readonly record: ProofRecord;
|
|
114
|
+
readonly seriesKey: string;
|
|
115
|
+
readonly retentionUntilMillis: number;
|
|
116
|
+
readonly state: ProofGenerationState;
|
|
117
|
+
readonly deliveryState: ProofDeliveryState;
|
|
118
|
+
readonly policy: ProofPolicy;
|
|
119
|
+
}) => Generation["insert"];
|
|
120
|
+
readonly decodeRecord: (row: Generation["select"]) => Effect.Effect<ProofRecord, PersistenceMappingError>;
|
|
121
|
+
readonly decodeBinding: (row: Generation["select"]) => Effect.Effect<ProofBinding, PersistenceMappingError>;
|
|
122
|
+
}
|
|
123
|
+
export interface ProofContinuationRecord {
|
|
124
|
+
readonly moduleId: string;
|
|
125
|
+
readonly purpose: ProofPurpose;
|
|
126
|
+
readonly continuationId: ProofContinuationId;
|
|
127
|
+
readonly digest: TokenDigest;
|
|
128
|
+
readonly proofId: ProofId;
|
|
129
|
+
readonly seriesKey: string;
|
|
130
|
+
readonly binding: ProofBinding;
|
|
131
|
+
readonly expiresAtMillis: number;
|
|
132
|
+
readonly version: ProofVersion;
|
|
133
|
+
}
|
|
134
|
+
export interface ProofContinuationTable<Continuation extends TableModel> {
|
|
135
|
+
readonly table: Continuation["table"];
|
|
136
|
+
readonly moduleId: ColumnKey<Continuation>;
|
|
137
|
+
readonly purpose: ColumnKey<Continuation>;
|
|
138
|
+
readonly continuationId: ColumnKey<Continuation>;
|
|
139
|
+
readonly digest: ColumnKey<Continuation>;
|
|
140
|
+
readonly proofId: ColumnKey<Continuation>;
|
|
141
|
+
readonly seriesKey: ColumnKey<Continuation>;
|
|
142
|
+
readonly binding: ColumnKey<Continuation>;
|
|
143
|
+
readonly expiresAt: ColumnKey<Continuation>;
|
|
144
|
+
readonly consumed: ColumnKey<Continuation>;
|
|
145
|
+
readonly version: ColumnKey<Continuation>;
|
|
146
|
+
readonly retentionUntil: ColumnKey<Continuation>;
|
|
147
|
+
readonly encodeInsert: (record: ProofContinuationRecord & {
|
|
148
|
+
readonly retentionUntilMillis: number;
|
|
149
|
+
}) => Continuation["insert"];
|
|
150
|
+
readonly decode: (row: Continuation["select"]) => Effect.Effect<ProofContinuationRecord, PersistenceMappingError>;
|
|
151
|
+
}
|
|
152
|
+
export interface ProofRateScopeTable<RateScope extends TableModel> {
|
|
153
|
+
readonly table: RateScope["table"];
|
|
154
|
+
readonly moduleId: ColumnKey<RateScope>;
|
|
155
|
+
readonly purpose: ColumnKey<RateScope>;
|
|
156
|
+
readonly action: ColumnKey<RateScope>;
|
|
157
|
+
readonly scopeKind: ColumnKey<RateScope>;
|
|
158
|
+
readonly scopeKey: ColumnKey<RateScope>;
|
|
159
|
+
readonly encodeInsert: (input: {
|
|
160
|
+
readonly moduleId: string;
|
|
161
|
+
readonly purpose: ProofPurpose;
|
|
162
|
+
readonly action: ProofAction;
|
|
163
|
+
readonly scopeKind: ProofScopeKind;
|
|
164
|
+
readonly scopeKey: string;
|
|
165
|
+
}) => RateScope["insert"];
|
|
166
|
+
}
|
|
167
|
+
export interface ProofAbuseEventTable<AbuseEvent extends TableModel> {
|
|
168
|
+
readonly table: AbuseEvent["table"];
|
|
169
|
+
readonly moduleId: ColumnKey<AbuseEvent>;
|
|
170
|
+
readonly purpose: ColumnKey<AbuseEvent>;
|
|
171
|
+
readonly action: ColumnKey<AbuseEvent>;
|
|
172
|
+
readonly scopeKind: ColumnKey<AbuseEvent>;
|
|
173
|
+
readonly scopeKey: ColumnKey<AbuseEvent>;
|
|
174
|
+
readonly commandId: ColumnKey<AbuseEvent>;
|
|
175
|
+
readonly occurredAt: ColumnKey<AbuseEvent>;
|
|
176
|
+
readonly retentionUntil: ColumnKey<AbuseEvent>;
|
|
177
|
+
readonly encodeInsert: (input: {
|
|
178
|
+
readonly moduleId: string;
|
|
179
|
+
readonly purpose: ProofPurpose;
|
|
180
|
+
readonly action: ProofAction;
|
|
181
|
+
readonly scopeKind: ProofScopeKind;
|
|
182
|
+
readonly scopeKey: string;
|
|
183
|
+
readonly commandId: string;
|
|
184
|
+
readonly occurredAtMillis: number;
|
|
185
|
+
readonly retentionUntilMillis: number;
|
|
186
|
+
}) => AbuseEvent["insert"];
|
|
187
|
+
}
|
|
188
|
+
export interface ProofFailureEventTable<FailureEvent extends TableModel> {
|
|
189
|
+
readonly table: FailureEvent["table"];
|
|
190
|
+
readonly moduleId: ColumnKey<FailureEvent>;
|
|
191
|
+
readonly purpose: ColumnKey<FailureEvent>;
|
|
192
|
+
readonly seriesKey: ColumnKey<FailureEvent>;
|
|
193
|
+
readonly commandId: ColumnKey<FailureEvent>;
|
|
194
|
+
readonly occurredAt: ColumnKey<FailureEvent>;
|
|
195
|
+
readonly retentionUntil: ColumnKey<FailureEvent>;
|
|
196
|
+
readonly encodeInsert: (input: {
|
|
197
|
+
readonly moduleId: string;
|
|
198
|
+
readonly purpose: ProofPurpose;
|
|
199
|
+
readonly seriesKey: string;
|
|
200
|
+
readonly commandId: string;
|
|
201
|
+
readonly occurredAtMillis: number;
|
|
202
|
+
readonly retentionUntilMillis: number;
|
|
203
|
+
}) => FailureEvent["insert"];
|
|
204
|
+
}
|
|
205
|
+
export interface ProofCommandTable<Command extends TableModel> {
|
|
206
|
+
readonly table: Command["table"];
|
|
207
|
+
readonly moduleId: ColumnKey<Command>;
|
|
208
|
+
readonly commandId: ColumnKey<Command>;
|
|
209
|
+
readonly kind: ColumnKey<Command>;
|
|
210
|
+
readonly decision: ColumnKey<Command>;
|
|
211
|
+
readonly retentionUntil: ColumnKey<Command>;
|
|
212
|
+
readonly encodeInsert: (input: {
|
|
213
|
+
readonly moduleId: string;
|
|
214
|
+
readonly commandId: string;
|
|
215
|
+
readonly kind: ProofCommandKind;
|
|
216
|
+
readonly decision: ProofCommandDecision;
|
|
217
|
+
readonly retentionUntilMillis: number;
|
|
218
|
+
}) => Command["insert"];
|
|
219
|
+
}
|
|
220
|
+
export interface RequiredProofConstraints {
|
|
221
|
+
readonly request: "unique(request.moduleId,request.requestId)";
|
|
222
|
+
readonly series: "unique(series.moduleId,series.purpose,series.scopeKey)";
|
|
223
|
+
readonly proof: "unique(generation.moduleId,generation.proofId)";
|
|
224
|
+
readonly delivery: "unique(generation.moduleId,generation.deliveryId)";
|
|
225
|
+
readonly continuationId: "unique(continuation.moduleId,continuation.continuationId)";
|
|
226
|
+
readonly continuationDigest: "unique(continuation.moduleId,continuation.digest)";
|
|
227
|
+
readonly rateScope: "unique(rateScope.moduleId,rateScope.purpose,rateScope.action,rateScope.scopeKind,rateScope.scopeKey)";
|
|
228
|
+
readonly abuseEvent: "unique(abuseEvent.moduleId,abuseEvent.action,abuseEvent.scopeKind,abuseEvent.scopeKey,abuseEvent.commandId)";
|
|
229
|
+
readonly failureEvent: "unique(failureEvent.moduleId,failureEvent.seriesKey,failureEvent.commandId)";
|
|
230
|
+
readonly command: "unique(command.moduleId,command.commandId)";
|
|
231
|
+
}
|
|
232
|
+
export declare const requiredProofConstraints: RequiredProofConstraints;
|
|
233
|
+
export interface ProofConstraintClassifier {
|
|
234
|
+
/** Match only the declared request uniqueness constraint, including wrapped driver errors. */
|
|
235
|
+
readonly isRequestConflict: (cause: unknown) => boolean;
|
|
236
|
+
/** Match only the declared series uniqueness constraint, including wrapped driver errors. */
|
|
237
|
+
readonly isSeriesConflict: (cause: unknown) => boolean;
|
|
238
|
+
/** Match only the declared command uniqueness constraint, including wrapped driver errors. */
|
|
239
|
+
readonly isCommandConflict: (cause: unknown) => boolean;
|
|
240
|
+
}
|
|
241
|
+
export interface ProofD1Clock<Expression extends SqlExpression = SqlExpression> {
|
|
242
|
+
/** Native instant expression evaluated by SQLite inside the submitted batch. */
|
|
243
|
+
readonly engineNow: Expression;
|
|
244
|
+
/** Integer Unix milliseconds expression evaluated inside the submitted batch. */
|
|
245
|
+
readonly engineNowMillis: Expression;
|
|
246
|
+
/** Native instant expression for an engine-time rolling-window cutoff. */
|
|
247
|
+
readonly engineInstantMinus: (millis: number) => Expression;
|
|
248
|
+
/** Native instant expression for a retention/lease deadline from engine time. */
|
|
249
|
+
readonly engineInstantPlus: (millis: number) => Expression;
|
|
250
|
+
}
|
|
251
|
+
export interface ProofPersistenceMapping<Request extends TableModel, Series extends TableModel, Generation extends TableModel, Continuation extends TableModel, RateScope extends TableModel, AbuseEvent extends TableModel, FailureEvent extends TableModel, Command extends TableModel, Subject extends TableModel, Identifier extends TableModel, Credential extends TableModel, NativeSubjectId, Expression extends SqlExpression = SqlExpression> extends ProofConstraintClassifier {
|
|
252
|
+
readonly request: ProofRequestTable<Request>;
|
|
253
|
+
readonly series: ProofSeriesTable<Series>;
|
|
254
|
+
readonly generation: ProofGenerationTable<Generation>;
|
|
255
|
+
readonly continuation: ProofContinuationTable<Continuation>;
|
|
256
|
+
readonly rateScope: ProofRateScopeTable<RateScope>;
|
|
257
|
+
readonly abuseEvent: ProofAbuseEventTable<AbuseEvent>;
|
|
258
|
+
readonly failureEvent: ProofFailureEventTable<FailureEvent>;
|
|
259
|
+
readonly command: ProofCommandTable<Command>;
|
|
260
|
+
readonly authority: ProofAuthorityTables<Subject, Identifier, Credential, NativeSubjectId, Expression>;
|
|
261
|
+
readonly constraints: RequiredProofConstraints;
|
|
262
|
+
readonly scopeKeys: (input: {
|
|
263
|
+
readonly moduleId: string;
|
|
264
|
+
readonly purpose: ProofPurpose;
|
|
265
|
+
readonly binding: ProofBinding;
|
|
266
|
+
}) => ProofScopeKeys;
|
|
267
|
+
readonly encodeInstant: (epochMillis: number) => unknown;
|
|
268
|
+
readonly decodeInstant: (native: unknown) => Effect.Effect<number, PersistenceMappingError>;
|
|
269
|
+
readonly allocateVersion?: Effect.Effect<ProofVersion, PersistenceMappingError>;
|
|
270
|
+
readonly allocateVersionSync?: () => ProofVersion;
|
|
271
|
+
/** Required by D1 mappings and ignored by interactive targets. */
|
|
272
|
+
readonly d1?: ProofD1Clock<Expression>;
|
|
273
|
+
}
|
|
274
|
+
export type D1ProofPersistenceMapping<Request extends TableModel, Series extends TableModel, Generation extends TableModel, Continuation extends TableModel, RateScope extends TableModel, AbuseEvent extends TableModel, FailureEvent extends TableModel, Command extends TableModel, Subject extends TableModel, Identifier extends TableModel, Credential extends TableModel, NativeSubjectId, Expression extends SqlExpression = SqlExpression> = ProofPersistenceMapping<Request, Series, Generation, Continuation, RateScope, AbuseEvent, FailureEvent, Command, Subject, Identifier, Credential, NativeSubjectId, Expression> & {
|
|
275
|
+
readonly d1: ProofD1Clock<Expression>;
|
|
276
|
+
readonly authority: ProofAuthorityTables<Subject, Identifier, Credential, NativeSubjectId, Expression> & {
|
|
277
|
+
readonly identifier: ProofAuthorityTables<Subject, Identifier, Credential, NativeSubjectId, Expression>["identifier"] & {
|
|
278
|
+
/** Synchronous SQL compiler; Effect-based ID conversion has already completed. */
|
|
279
|
+
readonly d1CurrentCondition: (input: ProofAuthorityInput<NativeSubjectId>) => Expression;
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
export type AnyProofPersistenceMapping<Expression extends SqlExpression = SqlExpression> = ProofPersistenceMapping<AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, AnyTableModel, unknown, Expression>;
|
|
284
|
+
//#endregion
|
|
285
|
+
//# sourceMappingURL=proof-model.d.mts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/internal/models/proof-model.ts
|
|
2
|
+
const requiredProofConstraints = {
|
|
3
|
+
request: "unique(request.moduleId,request.requestId)",
|
|
4
|
+
series: "unique(series.moduleId,series.purpose,series.scopeKey)",
|
|
5
|
+
proof: "unique(generation.moduleId,generation.proofId)",
|
|
6
|
+
delivery: "unique(generation.moduleId,generation.deliveryId)",
|
|
7
|
+
continuationId: "unique(continuation.moduleId,continuation.continuationId)",
|
|
8
|
+
continuationDigest: "unique(continuation.moduleId,continuation.digest)",
|
|
9
|
+
rateScope: "unique(rateScope.moduleId,rateScope.purpose,rateScope.action,rateScope.scopeKind,rateScope.scopeKey)",
|
|
10
|
+
abuseEvent: "unique(abuseEvent.moduleId,abuseEvent.action,abuseEvent.scopeKind,abuseEvent.scopeKey,abuseEvent.commandId)",
|
|
11
|
+
failureEvent: "unique(failureEvent.moduleId,failureEvent.seriesKey,failureEvent.commandId)",
|
|
12
|
+
command: "unique(command.moduleId,command.commandId)"
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { requiredProofConstraints };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=proof-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof-model.mjs","names":[],"sources":["../../../src/internal/models/proof-model.ts"],"sourcesContent":["import type {\n ProofBinding,\n ProofContinuationId,\n ProofId,\n ProofPurpose,\n ProofRequestReceipt,\n ProofVersion,\n ProofPolicy,\n ProofRecord,\n} from \"@yielded/auth/Proofs\";\nimport type { TokenDigest } from \"@yielded/auth/Schema\";\nimport type { Effect } from \"effect\";\n\nimport type { AnyTableModel, TableModel as Table, SqlExpression } from \"../query-operations\";\nimport type { PersistenceMappingError, SubjectIdCodec } from \"./common\";\n\ntype ColumnKey<T extends Table> = T[\"column\"];\n\nexport type ProofAction = \"issue\" | \"attempt\";\n\nexport type ProofScopeKind = \"action\" | \"identifier\" | \"subject\";\n\nexport type ProofGenerationState = \"active\" | \"consumed\" | \"cancelled\" | \"superseded\";\n\nexport type ProofDeliveryState = \"new\" | \"claimed\" | \"accepted\" | \"failed\" | \"ambiguous\";\n\nexport type ProofCommandKind = \"attempt\" | \"complete\";\n\nexport type ProofCommandDecision = \"accepted\" | \"rejected\" | \"completed\";\n\nexport interface ProofScopeKeys {\n /** Stable across flow/context/request changes and bounded by the consumer codec. */\n readonly series: string;\n readonly identifier: string;\n /** A tagged non-null value; use a stable sentinel when the binding has no subject. */\n readonly subject: string;\n}\n\nexport interface ProofAuthorityInput<NativeSubjectId> {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly binding: ProofBinding;\n /** Resolved by Effect preplanning before an interactive check or D1 predicate compile. */\n readonly nativeSubjectId?: NativeSubjectId;\n}\n\nexport interface ProofAuthorityTables<\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly identifier: {\n readonly table: Identifier[\"table\"];\n readonly namespace: ColumnKey<Identifier>;\n readonly value: ColumnKey<Identifier>;\n /** Evaluate the consumer's explicit current-ownership/availability semantics. */\n readonly isCurrent: (\n input: ProofAuthorityInput<NativeSubjectId>,\n rows: ReadonlyArray<Identifier[\"select\"]>,\n ) => boolean;\n /** Optional outside D1. Never infer this semantic predicate from eligibility. */\n readonly d1CurrentCondition?: (input: ProofAuthorityInput<NativeSubjectId>) => Expression;\n };\n readonly subject?: {\n readonly table: Subject[\"table\"];\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly securityRevision: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly d1ActiveStatusValue: unknown;\n };\n readonly credential?: {\n readonly table: Credential[\"table\"];\n readonly subjectId: ColumnKey<Credential>;\n readonly credentialId: ColumnKey<Credential>;\n readonly revision: ColumnKey<Credential>;\n readonly status?: ColumnKey<Credential>;\n readonly isActiveStatus?: (value: unknown) => boolean;\n readonly d1ActiveStatusValue?: unknown;\n };\n readonly subjectId?: SubjectIdCodec<NativeSubjectId>;\n}\n\nexport interface ProofRequestTable<Request extends Table> {\n readonly table: Request[\"table\"];\n readonly moduleId: ColumnKey<Request>;\n readonly requestId: ColumnKey<Request>;\n readonly fingerprint: ColumnKey<Request>;\n readonly proofId: ColumnKey<Request>;\n readonly purpose: ColumnKey<Request>;\n readonly keyId: ColumnKey<Request>;\n readonly createdAt: ColumnKey<Request>;\n readonly retentionUntil: ColumnKey<Request>;\n readonly encodeInsert: (input: {\n readonly record: ProofRecord;\n readonly createdAtMillis: number;\n readonly retentionUntilMillis: number;\n }) => Request[\"insert\"];\n readonly decodeReceipt: (\n row: Request[\"select\"],\n ) => Effect.Effect<ProofRequestReceipt, PersistenceMappingError>;\n}\n\nexport interface ProofSeriesTable<Series extends Table> {\n readonly table: Series[\"table\"];\n readonly moduleId: ColumnKey<Series>;\n readonly purpose: ColumnKey<Series>;\n readonly scopeKey: ColumnKey<Series>;\n readonly activeProofId: ColumnKey<Series>;\n readonly lastIssueAt: ColumnKey<Series>;\n readonly version: ColumnKey<Series>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly scopeKey: string;\n readonly version: ProofVersion;\n }) => Series[\"insert\"];\n}\n\nexport interface ProofGenerationTable<Generation extends Table> {\n readonly table: Generation[\"table\"];\n readonly moduleId: ColumnKey<Generation>;\n readonly purpose: ColumnKey<Generation>;\n readonly proofId: ColumnKey<Generation>;\n readonly requestId: ColumnKey<Generation>;\n readonly seriesKey: ColumnKey<Generation>;\n readonly deliveryId: ColumnKey<Generation>;\n readonly binding: ColumnKey<Generation>;\n readonly verifierKeyId: ColumnKey<Generation>;\n readonly verifierDigest: ColumnKey<Generation>;\n readonly issuedAt: ColumnKey<Generation>;\n readonly expiresAt: ColumnKey<Generation>;\n readonly version: ColumnKey<Generation>;\n readonly state: ColumnKey<Generation>;\n readonly sendCount: ColumnKey<Generation>;\n readonly deliveryState: ColumnKey<Generation>;\n readonly claimVersion: ColumnKey<Generation>;\n readonly claimDeadline: ColumnKey<Generation>;\n readonly retryAt: ColumnKey<Generation>;\n readonly deliveryRetryMillis: ColumnKey<Generation>;\n readonly retentionUntil: ColumnKey<Generation>;\n readonly encodeInsert: (input: {\n readonly record: ProofRecord;\n readonly seriesKey: string;\n readonly retentionUntilMillis: number;\n readonly state: ProofGenerationState;\n readonly deliveryState: ProofDeliveryState;\n readonly policy: ProofPolicy;\n }) => Generation[\"insert\"];\n readonly decodeRecord: (\n row: Generation[\"select\"],\n ) => Effect.Effect<ProofRecord, PersistenceMappingError>;\n readonly decodeBinding: (\n row: Generation[\"select\"],\n ) => Effect.Effect<ProofBinding, PersistenceMappingError>;\n}\n\nexport interface ProofContinuationRecord {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly continuationId: ProofContinuationId;\n readonly digest: TokenDigest;\n readonly proofId: ProofId;\n readonly seriesKey: string;\n readonly binding: ProofBinding;\n readonly expiresAtMillis: number;\n readonly version: ProofVersion;\n}\n\nexport interface ProofContinuationTable<Continuation extends Table> {\n readonly table: Continuation[\"table\"];\n readonly moduleId: ColumnKey<Continuation>;\n readonly purpose: ColumnKey<Continuation>;\n readonly continuationId: ColumnKey<Continuation>;\n readonly digest: ColumnKey<Continuation>;\n readonly proofId: ColumnKey<Continuation>;\n readonly seriesKey: ColumnKey<Continuation>;\n readonly binding: ColumnKey<Continuation>;\n readonly expiresAt: ColumnKey<Continuation>;\n readonly consumed: ColumnKey<Continuation>;\n readonly version: ColumnKey<Continuation>;\n readonly retentionUntil: ColumnKey<Continuation>;\n readonly encodeInsert: (\n record: ProofContinuationRecord & {\n readonly retentionUntilMillis: number;\n },\n ) => Continuation[\"insert\"];\n readonly decode: (\n row: Continuation[\"select\"],\n ) => Effect.Effect<ProofContinuationRecord, PersistenceMappingError>;\n}\n\nexport interface ProofRateScopeTable<RateScope extends Table> {\n readonly table: RateScope[\"table\"];\n readonly moduleId: ColumnKey<RateScope>;\n readonly purpose: ColumnKey<RateScope>;\n readonly action: ColumnKey<RateScope>;\n readonly scopeKind: ColumnKey<RateScope>;\n readonly scopeKey: ColumnKey<RateScope>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly action: ProofAction;\n readonly scopeKind: ProofScopeKind;\n readonly scopeKey: string;\n }) => RateScope[\"insert\"];\n}\n\nexport interface ProofAbuseEventTable<AbuseEvent extends Table> {\n readonly table: AbuseEvent[\"table\"];\n readonly moduleId: ColumnKey<AbuseEvent>;\n readonly purpose: ColumnKey<AbuseEvent>;\n readonly action: ColumnKey<AbuseEvent>;\n readonly scopeKind: ColumnKey<AbuseEvent>;\n readonly scopeKey: ColumnKey<AbuseEvent>;\n readonly commandId: ColumnKey<AbuseEvent>;\n readonly occurredAt: ColumnKey<AbuseEvent>;\n readonly retentionUntil: ColumnKey<AbuseEvent>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly action: ProofAction;\n readonly scopeKind: ProofScopeKind;\n readonly scopeKey: string;\n readonly commandId: string;\n readonly occurredAtMillis: number;\n readonly retentionUntilMillis: number;\n }) => AbuseEvent[\"insert\"];\n}\n\nexport interface ProofFailureEventTable<FailureEvent extends Table> {\n readonly table: FailureEvent[\"table\"];\n readonly moduleId: ColumnKey<FailureEvent>;\n readonly purpose: ColumnKey<FailureEvent>;\n readonly seriesKey: ColumnKey<FailureEvent>;\n readonly commandId: ColumnKey<FailureEvent>;\n readonly occurredAt: ColumnKey<FailureEvent>;\n readonly retentionUntil: ColumnKey<FailureEvent>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly seriesKey: string;\n readonly commandId: string;\n readonly occurredAtMillis: number;\n readonly retentionUntilMillis: number;\n }) => FailureEvent[\"insert\"];\n}\n\nexport interface ProofCommandTable<Command extends Table> {\n readonly table: Command[\"table\"];\n readonly moduleId: ColumnKey<Command>;\n readonly commandId: ColumnKey<Command>;\n readonly kind: ColumnKey<Command>;\n readonly decision: ColumnKey<Command>;\n readonly retentionUntil: ColumnKey<Command>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly commandId: string;\n readonly kind: ProofCommandKind;\n readonly decision: ProofCommandDecision;\n readonly retentionUntilMillis: number;\n }) => Command[\"insert\"];\n}\n\nexport interface RequiredProofConstraints {\n readonly request: \"unique(request.moduleId,request.requestId)\";\n readonly series: \"unique(series.moduleId,series.purpose,series.scopeKey)\";\n readonly proof: \"unique(generation.moduleId,generation.proofId)\";\n readonly delivery: \"unique(generation.moduleId,generation.deliveryId)\";\n readonly continuationId: \"unique(continuation.moduleId,continuation.continuationId)\";\n readonly continuationDigest: \"unique(continuation.moduleId,continuation.digest)\";\n readonly rateScope: \"unique(rateScope.moduleId,rateScope.purpose,rateScope.action,rateScope.scopeKind,rateScope.scopeKey)\";\n readonly abuseEvent: \"unique(abuseEvent.moduleId,abuseEvent.action,abuseEvent.scopeKind,abuseEvent.scopeKey,abuseEvent.commandId)\";\n readonly failureEvent: \"unique(failureEvent.moduleId,failureEvent.seriesKey,failureEvent.commandId)\";\n readonly command: \"unique(command.moduleId,command.commandId)\";\n}\n\nexport const requiredProofConstraints: RequiredProofConstraints = {\n request: \"unique(request.moduleId,request.requestId)\",\n series: \"unique(series.moduleId,series.purpose,series.scopeKey)\",\n proof: \"unique(generation.moduleId,generation.proofId)\",\n delivery: \"unique(generation.moduleId,generation.deliveryId)\",\n continuationId: \"unique(continuation.moduleId,continuation.continuationId)\",\n continuationDigest: \"unique(continuation.moduleId,continuation.digest)\",\n rateScope:\n \"unique(rateScope.moduleId,rateScope.purpose,rateScope.action,rateScope.scopeKind,rateScope.scopeKey)\",\n abuseEvent:\n \"unique(abuseEvent.moduleId,abuseEvent.action,abuseEvent.scopeKind,abuseEvent.scopeKey,abuseEvent.commandId)\",\n failureEvent: \"unique(failureEvent.moduleId,failureEvent.seriesKey,failureEvent.commandId)\",\n command: \"unique(command.moduleId,command.commandId)\",\n};\n\nexport interface ProofConstraintClassifier {\n /** Match only the declared request uniqueness constraint, including wrapped driver errors. */\n readonly isRequestConflict: (cause: unknown) => boolean;\n /** Match only the declared series uniqueness constraint, including wrapped driver errors. */\n readonly isSeriesConflict: (cause: unknown) => boolean;\n /** Match only the declared command uniqueness constraint, including wrapped driver errors. */\n readonly isCommandConflict: (cause: unknown) => boolean;\n}\n\nexport interface ProofD1Clock<Expression extends SqlExpression = SqlExpression> {\n /** Native instant expression evaluated by SQLite inside the submitted batch. */\n readonly engineNow: Expression;\n /** Integer Unix milliseconds expression evaluated inside the submitted batch. */\n readonly engineNowMillis: Expression;\n /** Native instant expression for an engine-time rolling-window cutoff. */\n readonly engineInstantMinus: (millis: number) => Expression;\n /** Native instant expression for a retention/lease deadline from engine time. */\n readonly engineInstantPlus: (millis: number) => Expression;\n}\n\nexport interface ProofPersistenceMapping<\n Request extends Table,\n Series extends Table,\n Generation extends Table,\n Continuation extends Table,\n RateScope extends Table,\n AbuseEvent extends Table,\n FailureEvent extends Table,\n Command extends Table,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> extends ProofConstraintClassifier {\n readonly request: ProofRequestTable<Request>;\n readonly series: ProofSeriesTable<Series>;\n readonly generation: ProofGenerationTable<Generation>;\n readonly continuation: ProofContinuationTable<Continuation>;\n readonly rateScope: ProofRateScopeTable<RateScope>;\n readonly abuseEvent: ProofAbuseEventTable<AbuseEvent>;\n readonly failureEvent: ProofFailureEventTable<FailureEvent>;\n readonly command: ProofCommandTable<Command>;\n readonly authority: ProofAuthorityTables<\n Subject,\n Identifier,\n Credential,\n NativeSubjectId,\n Expression\n >;\n readonly constraints: RequiredProofConstraints;\n readonly scopeKeys: (input: {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly binding: ProofBinding;\n }) => ProofScopeKeys;\n readonly encodeInstant: (epochMillis: number) => unknown;\n readonly decodeInstant: (native: unknown) => Effect.Effect<number, PersistenceMappingError>;\n readonly allocateVersion?: Effect.Effect<ProofVersion, PersistenceMappingError>;\n readonly allocateVersionSync?: () => ProofVersion;\n /** Required by D1 mappings and ignored by interactive targets. */\n readonly d1?: ProofD1Clock<Expression>;\n}\n\nexport type D1ProofPersistenceMapping<\n Request extends Table,\n Series extends Table,\n Generation extends Table,\n Continuation extends Table,\n RateScope extends Table,\n AbuseEvent extends Table,\n FailureEvent extends Table,\n Command extends Table,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> = ProofPersistenceMapping<\n Request,\n Series,\n Generation,\n Continuation,\n RateScope,\n AbuseEvent,\n FailureEvent,\n Command,\n Subject,\n Identifier,\n Credential,\n NativeSubjectId,\n Expression\n> & {\n readonly d1: ProofD1Clock<Expression>;\n readonly authority: ProofAuthorityTables<\n Subject,\n Identifier,\n Credential,\n NativeSubjectId,\n Expression\n > & {\n readonly identifier: ProofAuthorityTables<\n Subject,\n Identifier,\n Credential,\n NativeSubjectId,\n Expression\n >[\"identifier\"] & {\n /** Synchronous SQL compiler; Effect-based ID conversion has already completed. */\n readonly d1CurrentCondition: (input: ProofAuthorityInput<NativeSubjectId>) => Expression;\n };\n };\n};\n\nexport type AnyProofPersistenceMapping<Expression extends SqlExpression = SqlExpression> =\n ProofPersistenceMapping<\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n unknown,\n Expression\n >;\n"],"mappings":";AAuRA,MAAa,2BAAqD;CAChE,SAAS;CACT,QAAQ;CACR,OAAO;CACP,UAAU;CACV,gBAAgB;CAChB,oBAAoB;CACpB,WACE;CACF,YACE;CACF,cAAc;CACd,SAAS;AACX"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { SqlExpression, TableModel } from "../query-operations.mjs";
|
|
2
|
+
import { PersistenceMappingError } from "../mapping-error.mjs";
|
|
3
|
+
import { SubjectIdCodec } from "./common.mjs";
|
|
4
|
+
import { DateTime, Effect } from "effect";
|
|
5
|
+
import { TokenDigest } from "@yielded/auth/Schema";
|
|
6
|
+
import { AuthenticationEvidence, AuthenticationRequirement, PendingAuthenticationRecord, PendingAuthenticationState, SecurityRevision, SessionId, StatefulSessionRecord } from "@yielded/auth/Sessions";
|
|
7
|
+
//#region src/internal/models/session-model.d.ts
|
|
8
|
+
type ColumnKey<T extends TableModel> = T["column"];
|
|
9
|
+
export interface SessionIdCodec<NativeId> {
|
|
10
|
+
readonly toNative: (id: SessionId) => Effect.Effect<NativeId, PersistenceMappingError>;
|
|
11
|
+
readonly toSession: (id: NativeId) => Effect.Effect<SessionId, PersistenceMappingError>;
|
|
12
|
+
readonly equals: (left: NativeId, right: NativeId) => boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface SessionSubjectTables<Subject extends TableModel, NativeId> {
|
|
15
|
+
readonly subject: {
|
|
16
|
+
readonly table: Subject["table"];
|
|
17
|
+
readonly id: ColumnKey<Subject>;
|
|
18
|
+
readonly status: ColumnKey<Subject>;
|
|
19
|
+
readonly securityRevision: ColumnKey<Subject>;
|
|
20
|
+
readonly isActiveStatus: (value: unknown) => boolean;
|
|
21
|
+
readonly decodeRequirement: (row: Subject["select"]) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;
|
|
22
|
+
readonly nextSecurityRevision?: (current: SecurityRevision) => Effect.Effect<SecurityRevision, PersistenceMappingError>;
|
|
23
|
+
readonly nextSecurityRevisionSync?: (current: SecurityRevision) => SecurityRevision;
|
|
24
|
+
};
|
|
25
|
+
readonly subjectId: SubjectIdCodec<NativeId>;
|
|
26
|
+
}
|
|
27
|
+
export interface SessionAuthorityTables<Subject extends TableModel, Credential extends TableModel, NativeId> extends SessionSubjectTables<Subject, NativeId> {
|
|
28
|
+
readonly credential: {
|
|
29
|
+
readonly table: Credential["table"];
|
|
30
|
+
readonly subjectId: ColumnKey<Credential>;
|
|
31
|
+
readonly credentialId: ColumnKey<Credential>;
|
|
32
|
+
readonly revision: ColumnKey<Credential>;
|
|
33
|
+
/** Optional consumer status predicate; omitted means every stored credential row is active. */
|
|
34
|
+
readonly status?: ColumnKey<Credential>;
|
|
35
|
+
readonly isActiveStatus?: (value: unknown) => boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export interface SessionFlowTables<Flow extends TableModel, NativeSubjectId> {
|
|
39
|
+
readonly flow: {
|
|
40
|
+
readonly table: Flow["table"];
|
|
41
|
+
readonly flowId: ColumnKey<Flow>;
|
|
42
|
+
readonly subjectId: ColumnKey<Flow>;
|
|
43
|
+
readonly state: ColumnKey<Flow>;
|
|
44
|
+
readonly pendingDigest: ColumnKey<Flow>;
|
|
45
|
+
readonly dedupUntil: ColumnKey<Flow>;
|
|
46
|
+
readonly pendingStateValue: unknown;
|
|
47
|
+
readonly establishedStateValue: unknown;
|
|
48
|
+
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
49
|
+
readonly decodeInstant: (native: unknown) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;
|
|
50
|
+
readonly encodePendingInsert: (input: {
|
|
51
|
+
readonly evidence: AuthenticationEvidence;
|
|
52
|
+
readonly subjectId: NativeSubjectId;
|
|
53
|
+
readonly pendingDigest: TokenDigest;
|
|
54
|
+
readonly dedupUntil: DateTime.Utc;
|
|
55
|
+
}) => Flow["insert"];
|
|
56
|
+
readonly encodeEstablishedInsert: (input: {
|
|
57
|
+
readonly evidence: AuthenticationEvidence;
|
|
58
|
+
readonly subjectId: NativeSubjectId;
|
|
59
|
+
readonly dedupUntil: DateTime.Utc;
|
|
60
|
+
}) => Flow["insert"];
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export interface StatefulSessionTables<Claims, Session extends TableModel, Flow extends TableModel, NativeSubjectId, NativeSessionId> extends SessionFlowTables<Flow, NativeSubjectId> {
|
|
64
|
+
readonly session: {
|
|
65
|
+
readonly table: Session["table"];
|
|
66
|
+
readonly sessionId: ColumnKey<Session>;
|
|
67
|
+
readonly subjectId: ColumnKey<Session>;
|
|
68
|
+
readonly digest: ColumnKey<Session>;
|
|
69
|
+
readonly version: ColumnKey<Session>;
|
|
70
|
+
readonly securityRevision: ColumnKey<Session>;
|
|
71
|
+
readonly issuedAt: ColumnKey<Session>;
|
|
72
|
+
readonly expiresAt: ColumnKey<Session>;
|
|
73
|
+
readonly absoluteExpiresAt: ColumnKey<Session>;
|
|
74
|
+
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
75
|
+
readonly encodeInsert: (record: StatefulSessionRecord<Claims>, ids: {
|
|
76
|
+
readonly subjectId: NativeSubjectId;
|
|
77
|
+
readonly sessionId: NativeSessionId;
|
|
78
|
+
}) => Session["insert"];
|
|
79
|
+
/** Persist the prepared credentialVersion and retain exact private provenance. */
|
|
80
|
+
readonly encodeRotation: (record: StatefulSessionRecord<Claims>) => Partial<Session["insert"]>;
|
|
81
|
+
readonly decode: (row: Session["select"]) => Effect.Effect<StatefulSessionRecord<Claims>, PersistenceMappingError>;
|
|
82
|
+
readonly allocateId?: Effect.Effect<NativeSessionId, PersistenceMappingError>;
|
|
83
|
+
readonly allocateIdSync?: () => NativeSessionId;
|
|
84
|
+
readonly allocateVersion?: Effect.Effect<SecurityRevision, PersistenceMappingError>;
|
|
85
|
+
readonly allocateVersionSync?: () => SecurityRevision;
|
|
86
|
+
};
|
|
87
|
+
readonly sessionId: SessionIdCodec<NativeSessionId>;
|
|
88
|
+
}
|
|
89
|
+
export interface PendingAuthenticationTables<Claims, Pending extends TableModel, Flow extends TableModel, NativeSubjectId> extends SessionFlowTables<Flow, NativeSubjectId> {
|
|
90
|
+
readonly pending: {
|
|
91
|
+
readonly table: Pending["table"];
|
|
92
|
+
readonly digest: ColumnKey<Pending>;
|
|
93
|
+
readonly version: ColumnKey<Pending>;
|
|
94
|
+
readonly flowId: ColumnKey<Pending>;
|
|
95
|
+
readonly subjectId: ColumnKey<Pending>;
|
|
96
|
+
readonly bindingDigest: ColumnKey<Pending>;
|
|
97
|
+
readonly expiresAt: ColumnKey<Pending>;
|
|
98
|
+
readonly attemptLimit: ColumnKey<Pending>;
|
|
99
|
+
readonly failedAttempts: ColumnKey<Pending>;
|
|
100
|
+
readonly consumed: ColumnKey<Pending>;
|
|
101
|
+
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
102
|
+
readonly encodeInsert: (record: PendingAuthenticationRecord<Claims>, input: {
|
|
103
|
+
readonly subjectId: NativeSubjectId;
|
|
104
|
+
readonly failedAttempts: 0;
|
|
105
|
+
readonly consumed: false;
|
|
106
|
+
}) => Pending["insert"];
|
|
107
|
+
readonly decode: (row: Pending["select"]) => Effect.Effect<PendingAuthenticationRecord<Claims>, PersistenceMappingError>;
|
|
108
|
+
/** Decodes original evidence and storage guards only. The internal pending
|
|
109
|
+
* context lookup must not execute unrelated consumer Claims transforms. */
|
|
110
|
+
readonly decodeContext: (row: Pending["select"]) => Effect.Effect<PendingAuthenticationState, PersistenceMappingError>;
|
|
111
|
+
readonly allocateVersion?: Effect.Effect<SecurityRevision, PersistenceMappingError>;
|
|
112
|
+
readonly allocateVersionSync?: () => SecurityRevision;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export interface SignedSessionValidityTables<Tombstone extends TableModel, NativeSubjectId, NativeSessionId> {
|
|
116
|
+
readonly tombstone: {
|
|
117
|
+
readonly table: Tombstone["table"];
|
|
118
|
+
readonly subjectId: ColumnKey<Tombstone>;
|
|
119
|
+
readonly sessionId: ColumnKey<Tombstone>;
|
|
120
|
+
readonly absoluteExpiresAt: ColumnKey<Tombstone>;
|
|
121
|
+
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
122
|
+
readonly decodeInstant: (native: unknown) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;
|
|
123
|
+
readonly encodeInsert: (input: {
|
|
124
|
+
readonly subjectId: NativeSubjectId;
|
|
125
|
+
readonly sessionId: NativeSessionId;
|
|
126
|
+
readonly absoluteExpiresAt: DateTime.Utc;
|
|
127
|
+
}) => Tombstone["insert"];
|
|
128
|
+
};
|
|
129
|
+
readonly sessionId: SessionIdCodec<NativeSessionId>;
|
|
130
|
+
}
|
|
131
|
+
export interface RequiredSessionConstraints {
|
|
132
|
+
readonly sessionDigest: "unique(session.digest)";
|
|
133
|
+
readonly flowId: "unique(flow.flowId)";
|
|
134
|
+
}
|
|
135
|
+
export interface RequiredPendingAuthenticationConstraints {
|
|
136
|
+
readonly pendingDigest: "unique(pending.digest)";
|
|
137
|
+
readonly pendingFlow: "unique(pending.flowId)";
|
|
138
|
+
readonly flowId: "unique(flow.flowId)";
|
|
139
|
+
}
|
|
140
|
+
export interface RequiredStatefulPendingConstraints extends RequiredSessionConstraints, RequiredPendingAuthenticationConstraints {}
|
|
141
|
+
export interface RequiredSignedValidityConstraints {
|
|
142
|
+
readonly tombstoneOwner: "unique(tombstone.subjectId,tombstone.sessionId)";
|
|
143
|
+
}
|
|
144
|
+
export declare const requiredSessionConstraints: RequiredSessionConstraints;
|
|
145
|
+
export declare const requiredPendingAuthenticationConstraints: RequiredPendingAuthenticationConstraints;
|
|
146
|
+
export declare const requiredStatefulPendingConstraints: RequiredStatefulPendingConstraints;
|
|
147
|
+
export declare const requiredSignedValidityConstraints: RequiredSignedValidityConstraints;
|
|
148
|
+
export interface SessionConstraintClassifier {
|
|
149
|
+
/**
|
|
150
|
+
* Match only the named unique constraints declared by this mapping. Broad
|
|
151
|
+
* SQL/constraint classifiers can relabel application or NOT NULL failures as
|
|
152
|
+
* a domain conflict.
|
|
153
|
+
*/
|
|
154
|
+
readonly isConstraintConflict: (cause: unknown) => boolean;
|
|
155
|
+
}
|
|
156
|
+
export type AuthenticationAuthorityMapping<Claims, Subject extends TableModel, Credential extends TableModel, Flow extends TableModel, Pending extends TableModel, NativeSubjectId> = SessionAuthorityTables<Subject, Credential, NativeSubjectId> & SessionConstraintClassifier & ({
|
|
157
|
+
/** Omit for single-factor authority installations. Pending input then fails closed. */
|
|
158
|
+
readonly pending?: undefined;
|
|
159
|
+
} | {
|
|
160
|
+
readonly pending: PendingAuthenticationTables<Claims, Pending, Flow, NativeSubjectId>;
|
|
161
|
+
readonly constraints: RequiredPendingAuthenticationConstraints;
|
|
162
|
+
});
|
|
163
|
+
export type StatefulSessionMapping<Claims, Subject extends TableModel, Credential extends TableModel, Session extends TableModel, Flow extends TableModel, Pending extends TableModel, NativeSubjectId, NativeSessionId> = SessionAuthorityTables<Subject, Credential, NativeSubjectId> & StatefulSessionTables<Claims, Session, Flow, NativeSubjectId, NativeSessionId> & SessionConstraintClassifier & ({
|
|
164
|
+
/** Omit when this session module does not support pending MFA completion. */
|
|
165
|
+
readonly pending?: undefined;
|
|
166
|
+
readonly constraints: RequiredSessionConstraints;
|
|
167
|
+
} | {
|
|
168
|
+
readonly pending: PendingAuthenticationTables<Claims, Pending, Flow, NativeSubjectId>["pending"];
|
|
169
|
+
readonly constraints: RequiredStatefulPendingConstraints;
|
|
170
|
+
});
|
|
171
|
+
export type PendingAuthenticationMapping<Claims, Subject extends TableModel, Credential extends TableModel, Pending extends TableModel, Flow extends TableModel, NativeSubjectId> = SessionAuthorityTables<Subject, Credential, NativeSubjectId> & PendingAuthenticationTables<Claims, Pending, Flow, NativeSubjectId> & SessionConstraintClassifier & {
|
|
172
|
+
readonly constraints: RequiredPendingAuthenticationConstraints;
|
|
173
|
+
};
|
|
174
|
+
export type SignedSessionValidityMapping<Subject extends TableModel, Tombstone extends TableModel, NativeSubjectId, NativeSessionId> = SessionSubjectTables<Subject, NativeSubjectId> & SignedSessionValidityTables<Tombstone, NativeSubjectId, NativeSessionId> & SessionConstraintClassifier & {
|
|
175
|
+
readonly constraints: RequiredSignedValidityConstraints;
|
|
176
|
+
};
|
|
177
|
+
/** D1 evaluates these expressions inside the atomic batch, after queueing delay.
|
|
178
|
+
* `engineNow` must use the exact native representation of every mapped instant
|
|
179
|
+
* column. `engineNowMillis` is Unix epoch milliseconds for proof freshness.
|
|
180
|
+
* Changes to the consumer's factor policy MUST bump subject.securityRevision.
|
|
181
|
+
* Supply the authoritative primary D1 database, never a replica-affined
|
|
182
|
+
* `withSession` handle, because verification and security revision reads must
|
|
183
|
+
* observe completed revocation writes across clients.
|
|
184
|
+
*/
|
|
185
|
+
export interface D1SessionClockMapping<Expression extends SqlExpression = SqlExpression> {
|
|
186
|
+
readonly d1: {
|
|
187
|
+
readonly engineNow: Expression;
|
|
188
|
+
readonly engineNowMillis: Expression;
|
|
189
|
+
readonly activeSubjectStatusValue: unknown;
|
|
190
|
+
/** Required when `credential.status` is mapped. */
|
|
191
|
+
readonly activeCredentialStatusValue?: unknown;
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
export type D1AuthenticationAuthorityMapping<Claims, Subject extends TableModel, Credential extends TableModel, Flow extends TableModel, Pending extends TableModel, NativeSubjectId, Expression extends SqlExpression = SqlExpression> = AuthenticationAuthorityMapping<Claims, Subject, Credential, Flow, Pending, NativeSubjectId> & D1SessionClockMapping<Expression>;
|
|
195
|
+
export type D1PendingAuthenticationMapping<Claims, Subject extends TableModel, Credential extends TableModel, Pending extends TableModel, Flow extends TableModel, NativeSubjectId, Expression extends SqlExpression = SqlExpression> = PendingAuthenticationMapping<Claims, Subject, Credential, Pending, Flow, NativeSubjectId> & D1SessionClockMapping<Expression>;
|
|
196
|
+
export type D1StatefulSessionMapping<Claims, Subject extends TableModel, Credential extends TableModel, Session extends TableModel, Flow extends TableModel, Pending extends TableModel, NativeSubjectId, NativeSessionId, Expression extends SqlExpression = SqlExpression> = StatefulSessionMapping<Claims, Subject, Credential, Session, Flow, Pending, NativeSubjectId, NativeSessionId> & D1SessionClockMapping<Expression>;
|
|
197
|
+
export type D1SignedSessionValidityMapping<Subject extends TableModel, Tombstone extends TableModel, NativeSubjectId, NativeSessionId, Expression extends SqlExpression = SqlExpression> = SignedSessionValidityMapping<Subject, Tombstone, NativeSubjectId, NativeSessionId> & D1SessionClockMapping<Expression>;
|
|
198
|
+
//#endregion
|
|
199
|
+
//# sourceMappingURL=session-model.d.mts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import "@yielded/auth/Sessions";
|
|
2
|
+
//#region src/internal/models/session-model.ts
|
|
3
|
+
const requiredSessionConstraints = {
|
|
4
|
+
sessionDigest: "unique(session.digest)",
|
|
5
|
+
flowId: "unique(flow.flowId)"
|
|
6
|
+
};
|
|
7
|
+
const requiredPendingAuthenticationConstraints = {
|
|
8
|
+
pendingDigest: "unique(pending.digest)",
|
|
9
|
+
pendingFlow: "unique(pending.flowId)",
|
|
10
|
+
flowId: "unique(flow.flowId)"
|
|
11
|
+
};
|
|
12
|
+
const requiredStatefulPendingConstraints = {
|
|
13
|
+
...requiredSessionConstraints,
|
|
14
|
+
...requiredPendingAuthenticationConstraints
|
|
15
|
+
};
|
|
16
|
+
const requiredSignedValidityConstraints = { tombstoneOwner: "unique(tombstone.subjectId,tombstone.sessionId)" };
|
|
17
|
+
//#endregion
|
|
18
|
+
export { requiredPendingAuthenticationConstraints, requiredSessionConstraints, requiredSignedValidityConstraints, requiredStatefulPendingConstraints };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=session-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-model.mjs","names":[],"sources":["../../../src/internal/models/session-model.ts"],"sourcesContent":["import type { TokenDigest } from \"@yielded/auth/Schema\";\nimport {\n type AuthenticationRequirement,\n type AuthenticationEvidence,\n type SecurityRevision,\n type SessionId,\n type PendingAuthenticationRecord,\n type PendingAuthenticationState,\n type StatefulSessionRecord,\n} from \"@yielded/auth/Sessions\";\nimport type { DateTime, Effect } from \"effect\";\n\nimport type { TableModel as Table, SqlExpression } from \"../query-operations\";\nimport type { PersistenceMappingError, SubjectIdCodec } from \"./common\";\n\ntype ColumnKey<T extends Table> = T[\"column\"];\n\nexport interface SessionIdCodec<NativeId> {\n readonly toNative: (id: SessionId) => Effect.Effect<NativeId, PersistenceMappingError>;\n readonly toSession: (id: NativeId) => Effect.Effect<SessionId, PersistenceMappingError>;\n readonly equals: (left: NativeId, right: NativeId) => boolean;\n}\n\nexport interface SessionSubjectTables<Subject extends Table, NativeId> {\n readonly subject: {\n readonly table: Subject[\"table\"];\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly securityRevision: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly decodeRequirement: (\n row: Subject[\"select\"],\n ) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;\n readonly nextSecurityRevision?: (\n current: SecurityRevision,\n ) => Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly nextSecurityRevisionSync?: (current: SecurityRevision) => SecurityRevision;\n };\n readonly subjectId: SubjectIdCodec<NativeId>;\n}\n\nexport interface SessionAuthorityTables<\n Subject extends Table,\n Credential extends Table,\n NativeId,\n> extends SessionSubjectTables<Subject, NativeId> {\n readonly credential: {\n readonly table: Credential[\"table\"];\n readonly subjectId: ColumnKey<Credential>;\n readonly credentialId: ColumnKey<Credential>;\n readonly revision: ColumnKey<Credential>;\n /** Optional consumer status predicate; omitted means every stored credential row is active. */\n readonly status?: ColumnKey<Credential>;\n readonly isActiveStatus?: (value: unknown) => boolean;\n };\n}\n\nexport interface SessionFlowTables<Flow extends Table, NativeSubjectId> {\n readonly flow: {\n readonly table: Flow[\"table\"];\n readonly flowId: ColumnKey<Flow>;\n readonly subjectId: ColumnKey<Flow>;\n readonly state: ColumnKey<Flow>;\n readonly pendingDigest: ColumnKey<Flow>;\n readonly dedupUntil: ColumnKey<Flow>;\n readonly pendingStateValue: unknown;\n readonly establishedStateValue: unknown;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly decodeInstant: (\n native: unknown,\n ) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;\n readonly encodePendingInsert: (input: {\n readonly evidence: AuthenticationEvidence;\n readonly subjectId: NativeSubjectId;\n readonly pendingDigest: TokenDigest;\n readonly dedupUntil: DateTime.Utc;\n }) => Flow[\"insert\"];\n readonly encodeEstablishedInsert: (input: {\n readonly evidence: AuthenticationEvidence;\n readonly subjectId: NativeSubjectId;\n readonly dedupUntil: DateTime.Utc;\n }) => Flow[\"insert\"];\n };\n}\n\nexport interface StatefulSessionTables<\n Claims,\n Session extends Table,\n Flow extends Table,\n NativeSubjectId,\n NativeSessionId,\n> extends SessionFlowTables<Flow, NativeSubjectId> {\n readonly session: {\n readonly table: Session[\"table\"];\n readonly sessionId: ColumnKey<Session>;\n readonly subjectId: ColumnKey<Session>;\n readonly digest: ColumnKey<Session>;\n readonly version: ColumnKey<Session>;\n readonly securityRevision: ColumnKey<Session>;\n readonly issuedAt: ColumnKey<Session>;\n readonly expiresAt: ColumnKey<Session>;\n readonly absoluteExpiresAt: ColumnKey<Session>;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly encodeInsert: (\n record: StatefulSessionRecord<Claims>,\n ids: {\n readonly subjectId: NativeSubjectId;\n readonly sessionId: NativeSessionId;\n },\n ) => Session[\"insert\"];\n /** Persist the prepared credentialVersion and retain exact private provenance. */\n readonly encodeRotation: (record: StatefulSessionRecord<Claims>) => Partial<Session[\"insert\"]>;\n readonly decode: (\n row: Session[\"select\"],\n ) => Effect.Effect<StatefulSessionRecord<Claims>, PersistenceMappingError>;\n readonly allocateId?: Effect.Effect<NativeSessionId, PersistenceMappingError>;\n readonly allocateIdSync?: () => NativeSessionId;\n readonly allocateVersion?: Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly allocateVersionSync?: () => SecurityRevision;\n };\n readonly sessionId: SessionIdCodec<NativeSessionId>;\n}\n\nexport interface PendingAuthenticationTables<\n Claims,\n Pending extends Table,\n Flow extends Table,\n NativeSubjectId,\n> extends SessionFlowTables<Flow, NativeSubjectId> {\n readonly pending: {\n readonly table: Pending[\"table\"];\n readonly digest: ColumnKey<Pending>;\n readonly version: ColumnKey<Pending>;\n readonly flowId: ColumnKey<Pending>;\n readonly subjectId: ColumnKey<Pending>;\n readonly bindingDigest: ColumnKey<Pending>;\n readonly expiresAt: ColumnKey<Pending>;\n readonly attemptLimit: ColumnKey<Pending>;\n readonly failedAttempts: ColumnKey<Pending>;\n readonly consumed: ColumnKey<Pending>;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly encodeInsert: (\n record: PendingAuthenticationRecord<Claims>,\n input: {\n readonly subjectId: NativeSubjectId;\n readonly failedAttempts: 0;\n readonly consumed: false;\n },\n ) => Pending[\"insert\"];\n readonly decode: (\n row: Pending[\"select\"],\n ) => Effect.Effect<PendingAuthenticationRecord<Claims>, PersistenceMappingError>;\n /** Decodes original evidence and storage guards only. The internal pending\n * context lookup must not execute unrelated consumer Claims transforms. */\n readonly decodeContext: (\n row: Pending[\"select\"],\n ) => Effect.Effect<PendingAuthenticationState, PersistenceMappingError>;\n readonly allocateVersion?: Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly allocateVersionSync?: () => SecurityRevision;\n };\n}\n\nexport interface SignedSessionValidityTables<\n Tombstone extends Table,\n NativeSubjectId,\n NativeSessionId,\n> {\n readonly tombstone: {\n readonly table: Tombstone[\"table\"];\n readonly subjectId: ColumnKey<Tombstone>;\n readonly sessionId: ColumnKey<Tombstone>;\n readonly absoluteExpiresAt: ColumnKey<Tombstone>;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly decodeInstant: (\n native: unknown,\n ) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;\n readonly encodeInsert: (input: {\n readonly subjectId: NativeSubjectId;\n readonly sessionId: NativeSessionId;\n readonly absoluteExpiresAt: DateTime.Utc;\n }) => Tombstone[\"insert\"];\n };\n readonly sessionId: SessionIdCodec<NativeSessionId>;\n}\n\nexport interface RequiredSessionConstraints {\n readonly sessionDigest: \"unique(session.digest)\";\n readonly flowId: \"unique(flow.flowId)\";\n}\n\nexport interface RequiredPendingAuthenticationConstraints {\n readonly pendingDigest: \"unique(pending.digest)\";\n readonly pendingFlow: \"unique(pending.flowId)\";\n readonly flowId: \"unique(flow.flowId)\";\n}\n\nexport interface RequiredStatefulPendingConstraints\n extends RequiredSessionConstraints, RequiredPendingAuthenticationConstraints {}\n\nexport interface RequiredSignedValidityConstraints {\n readonly tombstoneOwner: \"unique(tombstone.subjectId,tombstone.sessionId)\";\n}\n\nexport const requiredSessionConstraints: RequiredSessionConstraints = {\n sessionDigest: \"unique(session.digest)\",\n flowId: \"unique(flow.flowId)\",\n};\n\nexport const requiredPendingAuthenticationConstraints: RequiredPendingAuthenticationConstraints = {\n pendingDigest: \"unique(pending.digest)\",\n pendingFlow: \"unique(pending.flowId)\",\n flowId: \"unique(flow.flowId)\",\n};\n\nexport const requiredStatefulPendingConstraints: RequiredStatefulPendingConstraints = {\n ...requiredSessionConstraints,\n ...requiredPendingAuthenticationConstraints,\n};\n\nexport const requiredSignedValidityConstraints: RequiredSignedValidityConstraints = {\n tombstoneOwner: \"unique(tombstone.subjectId,tombstone.sessionId)\",\n};\n\nexport interface SessionConstraintClassifier {\n /**\n * Match only the named unique constraints declared by this mapping. Broad\n * SQL/constraint classifiers can relabel application or NOT NULL failures as\n * a domain conflict.\n */\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\nexport type AuthenticationAuthorityMapping<\n Claims,\n Subject extends Table,\n Credential extends Table,\n Flow extends Table,\n Pending extends Table,\n NativeSubjectId,\n> = SessionAuthorityTables<Subject, Credential, NativeSubjectId> &\n SessionConstraintClassifier &\n (\n | {\n /** Omit for single-factor authority installations. Pending input then fails closed. */\n readonly pending?: undefined;\n }\n | {\n readonly pending: PendingAuthenticationTables<Claims, Pending, Flow, NativeSubjectId>;\n readonly constraints: RequiredPendingAuthenticationConstraints;\n }\n );\n\nexport type StatefulSessionMapping<\n Claims,\n Subject extends Table,\n Credential extends Table,\n Session extends Table,\n Flow extends Table,\n Pending extends Table,\n NativeSubjectId,\n NativeSessionId,\n> = SessionAuthorityTables<Subject, Credential, NativeSubjectId> &\n StatefulSessionTables<Claims, Session, Flow, NativeSubjectId, NativeSessionId> &\n SessionConstraintClassifier &\n (\n | {\n /** Omit when this session module does not support pending MFA completion. */\n readonly pending?: undefined;\n readonly constraints: RequiredSessionConstraints;\n }\n | {\n readonly pending: PendingAuthenticationTables<\n Claims,\n Pending,\n Flow,\n NativeSubjectId\n >[\"pending\"];\n readonly constraints: RequiredStatefulPendingConstraints;\n }\n );\n\nexport type PendingAuthenticationMapping<\n Claims,\n Subject extends Table,\n Credential extends Table,\n Pending extends Table,\n Flow extends Table,\n NativeSubjectId,\n> = SessionAuthorityTables<Subject, Credential, NativeSubjectId> &\n PendingAuthenticationTables<Claims, Pending, Flow, NativeSubjectId> &\n SessionConstraintClassifier & {\n readonly constraints: RequiredPendingAuthenticationConstraints;\n };\n\nexport type SignedSessionValidityMapping<\n Subject extends Table,\n Tombstone extends Table,\n NativeSubjectId,\n NativeSessionId,\n> = SessionSubjectTables<Subject, NativeSubjectId> &\n SignedSessionValidityTables<Tombstone, NativeSubjectId, NativeSessionId> &\n SessionConstraintClassifier & {\n readonly constraints: RequiredSignedValidityConstraints;\n };\n\n/** D1 evaluates these expressions inside the atomic batch, after queueing delay.\n * `engineNow` must use the exact native representation of every mapped instant\n * column. `engineNowMillis` is Unix epoch milliseconds for proof freshness.\n * Changes to the consumer's factor policy MUST bump subject.securityRevision.\n * Supply the authoritative primary D1 database, never a replica-affined\n * `withSession` handle, because verification and security revision reads must\n * observe completed revocation writes across clients.\n */\nexport interface D1SessionClockMapping<Expression extends SqlExpression = SqlExpression> {\n readonly d1: {\n readonly engineNow: Expression;\n readonly engineNowMillis: Expression;\n readonly activeSubjectStatusValue: unknown;\n /** Required when `credential.status` is mapped. */\n readonly activeCredentialStatusValue?: unknown;\n };\n}\n\nexport type D1AuthenticationAuthorityMapping<\n Claims,\n Subject extends Table,\n Credential extends Table,\n Flow extends Table,\n Pending extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> = AuthenticationAuthorityMapping<Claims, Subject, Credential, Flow, Pending, NativeSubjectId> &\n D1SessionClockMapping<Expression>;\n\nexport type D1PendingAuthenticationMapping<\n Claims,\n Subject extends Table,\n Credential extends Table,\n Pending extends Table,\n Flow extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> = PendingAuthenticationMapping<Claims, Subject, Credential, Pending, Flow, NativeSubjectId> &\n D1SessionClockMapping<Expression>;\n\nexport type D1StatefulSessionMapping<\n Claims,\n Subject extends Table,\n Credential extends Table,\n Session extends Table,\n Flow extends Table,\n Pending extends Table,\n NativeSubjectId,\n NativeSessionId,\n Expression extends SqlExpression = SqlExpression,\n> = StatefulSessionMapping<\n Claims,\n Subject,\n Credential,\n Session,\n Flow,\n Pending,\n NativeSubjectId,\n NativeSessionId\n> &\n D1SessionClockMapping<Expression>;\n\nexport type D1SignedSessionValidityMapping<\n Subject extends Table,\n Tombstone extends Table,\n NativeSubjectId,\n NativeSessionId,\n Expression extends SqlExpression = SqlExpression,\n> = SignedSessionValidityMapping<Subject, Tombstone, NativeSubjectId, NativeSessionId> &\n D1SessionClockMapping<Expression>;\n"],"mappings":";;AA2MA,MAAa,6BAAyD;CACpE,eAAe;CACf,QAAQ;AACV;AAEA,MAAa,2CAAqF;CAChG,eAAe;CACf,aAAa;CACb,QAAQ;AACV;AAEA,MAAa,qCAAyE;CACpF,GAAG;CACH,GAAG;AACL;AAEA,MAAa,oCAAuE,EAClF,gBAAgB,kDAClB"}
|