@yielded/auth-persistence 0.1.0-beta.23 → 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.
- package/README.md +11 -0
- package/dist/Adapter.d.mts +12 -6
- package/dist/Adapter.mjs +8 -3
- package/dist/OAuthPersistence.d.mts +87 -0
- package/dist/OAuthPersistence.mjs +125 -0
- package/dist/OAuthPersistence.mjs.map +1 -0
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +3 -1
- package/dist/internal/configuration.d.mts +1 -1
- package/dist/internal/configuration.mjs.map +1 -1
- package/dist/internal/models/oauth-connected-model.d.mts +294 -0
- package/dist/internal/models/oauth-connected-model.mjs +22 -0
- package/dist/internal/models/oauth-connected-model.mjs.map +1 -0
- package/dist/internal/models/oauth-model.d.mts +467 -0
- package/dist/internal/models/oauth-model.mjs +49 -0
- package/dist/internal/models/oauth-model.mjs.map +1 -0
- package/dist/internal/models/password-model.d.mts +4 -47
- package/dist/internal/models/password-model.mjs +0 -1
- package/dist/internal/models/password-model.mjs.map +1 -1
- package/dist/internal/native-sql-table.d.mts +4 -0
- package/dist/internal/native-sql-table.mjs +7 -0
- package/dist/internal/native-sql-table.mjs.map +1 -1
- package/dist/internal/oauth/accounts.d.mts +8 -0
- package/dist/internal/oauth/accounts.mjs +379 -0
- package/dist/internal/oauth/accounts.mjs.map +1 -0
- package/dist/internal/oauth/connected-access.d.mts +9 -0
- package/dist/internal/oauth/connected-access.mjs +229 -0
- package/dist/internal/oauth/connected-access.mjs.map +1 -0
- package/dist/internal/oauth/connected-collection.d.mts +7 -0
- package/dist/internal/oauth/connected-collection.mjs +214 -0
- package/dist/internal/oauth/connected-collection.mjs.map +1 -0
- package/dist/internal/oauth/connected-custody.d.mts +6 -0
- package/dist/internal/oauth/connected-custody.mjs +165 -0
- package/dist/internal/oauth/connected-custody.mjs.map +1 -0
- package/dist/internal/oauth/connected-flow.d.mts +7 -0
- package/dist/internal/oauth/connected-flow.mjs +324 -0
- package/dist/internal/oauth/connected-flow.mjs.map +1 -0
- package/dist/internal/oauth/connected-input.mjs +122 -0
- package/dist/internal/oauth/connected-input.mjs.map +1 -0
- package/dist/internal/oauth/connected-keys.d.mts +2 -0
- package/dist/internal/oauth/connected-keys.mjs +22 -0
- package/dist/internal/oauth/connected-keys.mjs.map +1 -0
- package/dist/internal/oauth/connected-maintenance.d.mts +9 -0
- package/dist/internal/oauth/connected-maintenance.mjs +226 -0
- package/dist/internal/oauth/connected-maintenance.mjs.map +1 -0
- package/dist/internal/oauth/connected-management.d.mts +9 -0
- package/dist/internal/oauth/connected-management.mjs +243 -0
- package/dist/internal/oauth/connected-management.mjs.map +1 -0
- package/dist/internal/oauth/connected-reference.mjs +63 -0
- package/dist/internal/oauth/connected-reference.mjs.map +1 -0
- package/dist/internal/oauth/connected-settlement.d.mts +8 -0
- package/dist/internal/oauth/connected-settlement.mjs +141 -0
- package/dist/internal/oauth/connected-settlement.mjs.map +1 -0
- package/dist/internal/oauth/connected-sign-in.d.mts +10 -0
- package/dist/internal/oauth/connected-sign-in.mjs +281 -0
- package/dist/internal/oauth/connected-sign-in.mjs.map +1 -0
- package/dist/internal/oauth/connected-state.d.mts +14 -0
- package/dist/internal/oauth/connected-state.mjs +469 -0
- package/dist/internal/oauth/connected-state.mjs.map +1 -0
- package/dist/internal/oauth/connected-target.d.mts +21 -0
- package/dist/internal/oauth/connected-target.mjs +117 -0
- package/dist/internal/oauth/connected-target.mjs.map +1 -0
- package/dist/internal/oauth/flow.d.mts +5 -0
- package/dist/internal/oauth/flow.mjs +279 -0
- package/dist/internal/oauth/flow.mjs.map +1 -0
- package/dist/internal/oauth/input.mjs +127 -0
- package/dist/internal/oauth/input.mjs.map +1 -0
- package/dist/internal/oauth/owner.d.mts +10 -0
- package/dist/internal/oauth/owner.mjs +10 -0
- package/dist/internal/oauth/owner.mjs.map +1 -0
- package/dist/internal/oauth/query-compiler.d.mts +7 -0
- package/dist/internal/oauth/query-compiler.mjs +9 -0
- package/dist/internal/oauth/query-compiler.mjs.map +1 -0
- package/dist/internal/oauth/registration.d.mts +7 -0
- package/dist/internal/oauth/registration.mjs +393 -0
- package/dist/internal/oauth/registration.mjs.map +1 -0
- package/dist/internal/oauth/state.mjs +107 -0
- package/dist/internal/oauth/state.mjs.map +1 -0
- package/dist/internal/oauth/target.d.mts +31 -0
- package/dist/internal/oauth/target.mjs +273 -0
- package/dist/internal/oauth/target.mjs.map +1 -0
- package/dist/internal/oauth-kernel.d.mts +1423 -0
- package/dist/internal/oauth-kernel.mjs +187 -0
- package/dist/internal/oauth-kernel.mjs.map +1 -0
- package/dist/internal/oauth-proxy.d.mts +31 -0
- package/dist/internal/oauth-proxy.mjs +129 -0
- package/dist/internal/oauth-proxy.mjs.map +1 -0
- package/dist/internal/passkey-kernel.d.mts +5 -5
- package/dist/internal/{password-attempts.d.mts → password-credentials.d.mts} +3 -4
- package/dist/internal/password-credentials.mjs +121 -0
- package/dist/internal/password-credentials.mjs.map +1 -0
- package/dist/internal/password-kernel.d.mts +8 -24
- package/dist/internal/password-kernel.mjs +4 -42
- package/dist/internal/password-kernel.mjs.map +1 -1
- package/dist/internal/persistence.d.mts +1 -1
- package/dist/internal/persistence.mjs +2 -2
- package/dist/internal/persistence.mjs.map +1 -1
- package/dist/internal/query-operations.d.mts +2 -0
- package/dist/internal/session-kernel.d.mts +2 -2
- package/dist/internal/session-kernel.mjs +74 -18
- package/dist/internal/session-kernel.mjs.map +1 -1
- package/dist/internal/sql-oauth-connected-model.d.mts +29 -0
- package/dist/internal/sql-oauth-connected-model.mjs +7 -0
- package/dist/internal/sql-oauth-connected-model.mjs.map +1 -0
- package/dist/internal/sql-oauth-model.d.mts +60 -0
- package/dist/internal/sql-oauth-model.mjs +10 -0
- package/dist/internal/sql-oauth-model.mjs.map +1 -0
- package/dist/internal/sql-query.d.mts +12 -0
- package/dist/internal/sql-query.mjs +15 -18
- package/dist/internal/sql-query.mjs.map +1 -1
- package/dist/internal/sql-storage-validation.mjs +54 -0
- package/dist/internal/sql-storage-validation.mjs.map +1 -0
- package/dist/internal/storage-mapping.mjs +1 -37
- package/dist/internal/storage-mapping.mjs.map +1 -1
- package/dist/internal/storage-plans.d.mts +7 -0
- package/dist/internal/storage-plans.mjs +189 -0
- package/dist/internal/storage-plans.mjs.map +1 -0
- package/dist/internal/storage-tables.d.mts +0 -56
- package/dist/internal/storage-tables.mjs +0 -17
- package/dist/internal/storage-tables.mjs.map +1 -1
- package/dist/internal/storage-validation.d.mts +6 -1
- package/dist/internal/storage-validation.mjs +42 -1
- package/dist/internal/storage-validation.mjs.map +1 -1
- package/dist/internal/transaction-kernel.mjs +3 -2
- package/dist/internal/transaction-kernel.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Adapter.ts +89 -5
- package/src/OAuthPersistence.ts +427 -0
- package/src/index.ts +3 -0
- package/src/internal/configuration.ts +1 -3
- package/src/internal/models/oauth-connected-model.ts +396 -0
- package/src/internal/models/oauth-model.ts +708 -0
- package/src/internal/models/password-model.ts +0 -56
- package/src/internal/native-sql-table.ts +14 -0
- package/src/internal/oauth/accounts.ts +838 -0
- package/src/internal/oauth/connected-access.ts +388 -0
- package/src/internal/oauth/connected-collection.ts +345 -0
- package/src/internal/oauth/connected-custody.ts +308 -0
- package/src/internal/oauth/connected-flow.ts +562 -0
- package/src/internal/oauth/connected-input.ts +147 -0
- package/src/internal/oauth/connected-keys.ts +31 -0
- package/src/internal/oauth/connected-maintenance.ts +379 -0
- package/src/internal/oauth/connected-management.ts +391 -0
- package/src/internal/oauth/connected-reference.ts +135 -0
- package/src/internal/oauth/connected-settlement.ts +278 -0
- package/src/internal/oauth/connected-sign-in.ts +472 -0
- package/src/internal/oauth/connected-state.ts +924 -0
- package/src/internal/oauth/connected-target.ts +307 -0
- package/src/internal/oauth/flow.ts +505 -0
- package/src/internal/oauth/input.ts +201 -0
- package/src/internal/oauth/owner.ts +22 -0
- package/src/internal/oauth/query-compiler.ts +15 -0
- package/src/internal/oauth/registration.ts +676 -0
- package/src/internal/oauth/state.ts +218 -0
- package/src/internal/oauth/target.ts +803 -0
- package/src/internal/oauth-kernel.ts +294 -0
- package/src/internal/oauth-proxy.ts +176 -0
- package/src/internal/password-credentials.ts +245 -0
- package/src/internal/password-kernel.ts +5 -98
- package/src/internal/persistence.ts +1 -1
- package/src/internal/query-operations.ts +2 -0
- package/src/internal/session-kernel.ts +143 -55
- package/src/internal/sql-oauth-connected-model.ts +145 -0
- package/src/internal/sql-oauth-model.ts +263 -0
- package/src/internal/sql-query.ts +16 -13
- package/src/internal/sql-storage-validation.ts +64 -0
- package/src/internal/storage-mapping.ts +0 -37
- package/src/internal/storage-plans.ts +218 -0
- package/src/internal/storage-tables.ts +0 -20
- package/src/internal/storage-validation.ts +58 -0
- package/src/internal/transaction-kernel.ts +6 -2
- package/dist/internal/password-attempts.mjs +0 -197
- package/dist/internal/password-attempts.mjs.map +0 -1
- package/src/internal/password-attempts.ts +0 -466
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { OAuthConnectedAction, OAuthConnectedAdmissionTable as OAuthConnectedAdmissionTable$1, OAuthConnectedAuthorityMapping as OAuthConnectedAuthorityMapping$1, OAuthConnectedClientRegistrationTable as OAuthConnectedClientRegistrationTable$1, OAuthConnectedCohortTable as OAuthConnectedCohortTable$1, OAuthConnectedCommandTable as OAuthConnectedCommandTable$1, OAuthConnectedFlowTable as OAuthConnectedFlowTable$1, OAuthConnectedGrantTable as OAuthConnectedGrantTable$1, OAuthConnectedMapping as OAuthConnectedMapping$1, OAuthConnectedOrderCodec, OAuthConnectedOwnershipRead as OAuthConnectedOwnershipRead$1, OAuthConnectedPolicyGuard as OAuthConnectedPolicyGuard$1, OAuthConnectedPolicyGuardTable as OAuthConnectedPolicyGuardTable$1, OAuthConnectedPolicyInput, OAuthConnectedRevocationJobTable as OAuthConnectedRevocationJobTable$1, OAuthConnectedRevocationMapping as OAuthConnectedRevocationMapping$1, OAuthConnectedSqlPolicy as OAuthConnectedSqlPolicy$1, OAuthConnectedSubjectTable as OAuthConnectedSubjectTable$1, oauth_connected_model_d_exports, requiredOAuthConnectedConstraints, requiredOAuthConnectedRevocationConstraints } from "./models/oauth-connected-model.mjs";
|
|
2
|
+
import { Fragment, Table } from "./sql-table.mjs";
|
|
3
|
+
import { SqlTableModel } from "./sql-oauth-model.mjs";
|
|
4
|
+
//#region src/internal/sql-oauth-connected-model.d.ts
|
|
5
|
+
export type OAuthConnectedSubjectTable<S extends Table> = OAuthConnectedSubjectTable$1<SqlTableModel<S>, Fragment>;
|
|
6
|
+
export type OAuthConnectedFlowTable<F extends Table, N> = OAuthConnectedFlowTable$1<SqlTableModel<F>, N>;
|
|
7
|
+
export type OAuthConnectedGrantTable<G extends Table, N> = OAuthConnectedGrantTable$1<SqlTableModel<G>, N>;
|
|
8
|
+
/** Also stores a permanent provider/issuer scope anchor. clientKey must fit 52
|
|
9
|
+
* ASCII characters. Empty clientRegistrationId is reserved for that anchor;
|
|
10
|
+
* actual profile registrations are nonempty. Scope counter stays zero. */
|
|
11
|
+
export type OAuthConnectedClientRegistrationTable<C extends Table> = OAuthConnectedClientRegistrationTable$1<SqlTableModel<C>>;
|
|
12
|
+
/** Remote authority: no local-subject column or subject-scoped key. Retain this
|
|
13
|
+
* anchor/cutoff when a legitimately released tuple gains a different local owner. */
|
|
14
|
+
export type OAuthConnectedCohortTable<C extends Table> = OAuthConnectedCohortTable$1<SqlTableModel<C>>;
|
|
15
|
+
export type OAuthConnectedAdmissionTable<A extends Table, N> = OAuthConnectedAdmissionTable$1<SqlTableModel<A>, N>;
|
|
16
|
+
export type OAuthConnectedCommandTable<C extends Table, N> = OAuthConnectedCommandTable$1<SqlTableModel<C>, N>;
|
|
17
|
+
export type OAuthConnectedRevocationJobTable<J extends Table, N> = OAuthConnectedRevocationJobTable$1<SqlTableModel<J>, N>;
|
|
18
|
+
export type OAuthConnectedPolicyGuardTable<T extends Table, N> = OAuthConnectedPolicyGuardTable$1<SqlTableModel<T>, N, Fragment>;
|
|
19
|
+
export type OAuthConnectedPolicyGuard<N> = OAuthConnectedPolicyGuard$1<N, Fragment, Table>;
|
|
20
|
+
export declare const oauthConnectedPolicyGuard: <T extends Table, N>(input: OAuthConnectedPolicyGuardTable<T, N>) => OAuthConnectedPolicyGuard<N>;
|
|
21
|
+
export type OAuthConnectedSqlPolicy<N> = OAuthConnectedSqlPolicy$1<N, Fragment, Table>;
|
|
22
|
+
/** Existing ownership only; workers never allocate or acquire a tuple. */
|
|
23
|
+
export type OAuthConnectedOwnershipRead<T extends Table, O extends Table, N> = OAuthConnectedOwnershipRead$1<SqlTableModel<T>, SqlTableModel<O>, N, Fragment>;
|
|
24
|
+
export type OAuthConnectedAuthorityMapping<T extends Table, O extends Table, F extends Table, G extends Table, C extends Table, H extends Table, N> = OAuthConnectedAuthorityMapping$1<SqlTableModel<T>, SqlTableModel<O>, SqlTableModel<F>, SqlTableModel<G>, SqlTableModel<C>, SqlTableModel<H>, N, Fragment>;
|
|
25
|
+
export type OAuthConnectedMapping<S extends Table, AC extends Table, T extends Table, O extends Table, F extends Table, G extends Table, C extends Table, H extends Table, A extends Table, D extends Table, N, J extends Table = never> = OAuthConnectedMapping$1<SqlTableModel<S>, SqlTableModel<AC>, SqlTableModel<T>, SqlTableModel<O>, SqlTableModel<F>, SqlTableModel<G>, SqlTableModel<C>, SqlTableModel<H>, SqlTableModel<A>, SqlTableModel<D>, N, SqlTableModel<J>, Fragment, Table, SqlTableModel<Table>>;
|
|
26
|
+
export type OAuthConnectedRevocationMapping<T extends Table, O extends Table, F extends Table, G extends Table, C extends Table, H extends Table, J extends Table, N> = OAuthConnectedRevocationMapping$1<SqlTableModel<T>, SqlTableModel<O>, SqlTableModel<F>, SqlTableModel<G>, SqlTableModel<C>, SqlTableModel<H>, SqlTableModel<J>, N, Fragment>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { type OAuthConnectedAction, type OAuthConnectedOrderCodec, type OAuthConnectedPolicyInput, requiredOAuthConnectedConstraints, requiredOAuthConnectedRevocationConstraints };
|
|
29
|
+
//# sourceMappingURL=sql-oauth-connected-model.d.mts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { oauthConnectedPolicyGuard as oauthConnectedPolicyGuard$1, requiredOAuthConnectedConstraints, requiredOAuthConnectedRevocationConstraints } from "./models/oauth-connected-model.mjs";
|
|
2
|
+
//#region src/internal/sql-oauth-connected-model.ts
|
|
3
|
+
const oauthConnectedPolicyGuard = (input) => oauthConnectedPolicyGuard$1(input);
|
|
4
|
+
//#endregion
|
|
5
|
+
export { oauthConnectedPolicyGuard, requiredOAuthConnectedConstraints, requiredOAuthConnectedRevocationConstraints };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=sql-oauth-connected-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-oauth-connected-model.mjs","names":["Shared.oauthConnectedPolicyGuard"],"sources":["../../src/internal/sql-oauth-connected-model.ts"],"sourcesContent":["import * as Shared from \"./models/oauth-connected-model\";\nimport type { SqlTableModel } from \"./sql-oauth-model\";\nimport type { Fragment as SQL, Table } from \"./sql-table\";\n\nexport {\n type OAuthConnectedAction,\n type OAuthConnectedOrderCodec,\n type OAuthConnectedPolicyInput,\n requiredOAuthConnectedConstraints,\n requiredOAuthConnectedRevocationConstraints,\n} from \"./models/oauth-connected-model\";\n\nexport type OAuthConnectedSubjectTable<S extends Table> = Shared.OAuthConnectedSubjectTable<\n SqlTableModel<S>,\n SQL\n>;\n\nexport type OAuthConnectedFlowTable<F extends Table, N> = Shared.OAuthConnectedFlowTable<\n SqlTableModel<F>,\n N\n>;\n\nexport type OAuthConnectedGrantTable<G extends Table, N> = Shared.OAuthConnectedGrantTable<\n SqlTableModel<G>,\n N\n>;\n\n/** Also stores a permanent provider/issuer scope anchor. clientKey must fit 52\n * ASCII characters. Empty clientRegistrationId is reserved for that anchor;\n * actual profile registrations are nonempty. Scope counter stays zero. */\nexport type OAuthConnectedClientRegistrationTable<C extends Table> =\n Shared.OAuthConnectedClientRegistrationTable<SqlTableModel<C>>;\n\n/** Remote authority: no local-subject column or subject-scoped key. Retain this\n * anchor/cutoff when a legitimately released tuple gains a different local owner. */\nexport type OAuthConnectedCohortTable<C extends Table> = Shared.OAuthConnectedCohortTable<\n SqlTableModel<C>\n>;\n\nexport type OAuthConnectedAdmissionTable<A extends Table, N> = Shared.OAuthConnectedAdmissionTable<\n SqlTableModel<A>,\n N\n>;\n\nexport type OAuthConnectedCommandTable<C extends Table, N> = Shared.OAuthConnectedCommandTable<\n SqlTableModel<C>,\n N\n>;\n\nexport type OAuthConnectedRevocationJobTable<\n J extends Table,\n N,\n> = Shared.OAuthConnectedRevocationJobTable<SqlTableModel<J>, N>;\n\nexport type OAuthConnectedPolicyGuardTable<\n T extends Table,\n N,\n> = Shared.OAuthConnectedPolicyGuardTable<SqlTableModel<T>, N, SQL>;\n\nexport type OAuthConnectedPolicyGuard<N> = Shared.OAuthConnectedPolicyGuard<N, SQL, Table>;\n\nexport const oauthConnectedPolicyGuard = <T extends Table, N>(\n input: OAuthConnectedPolicyGuardTable<T, N>,\n): OAuthConnectedPolicyGuard<N> =>\n Shared.oauthConnectedPolicyGuard<SqlTableModel<T>, N, SQL>(input);\n\nexport type OAuthConnectedSqlPolicy<N> = Shared.OAuthConnectedSqlPolicy<N, SQL, Table>;\n\n/** Existing ownership only; workers never allocate or acquire a tuple. */\nexport type OAuthConnectedOwnershipRead<\n T extends Table,\n O extends Table,\n N,\n> = Shared.OAuthConnectedOwnershipRead<SqlTableModel<T>, SqlTableModel<O>, N, SQL>;\n\nexport type OAuthConnectedAuthorityMapping<\n T extends Table,\n O extends Table,\n F extends Table,\n G extends Table,\n C extends Table,\n H extends Table,\n N,\n> = Shared.OAuthConnectedAuthorityMapping<\n SqlTableModel<T>,\n SqlTableModel<O>,\n SqlTableModel<F>,\n SqlTableModel<G>,\n SqlTableModel<C>,\n SqlTableModel<H>,\n N,\n SQL\n>;\n\nexport type OAuthConnectedMapping<\n S extends Table,\n AC extends Table,\n T extends Table,\n O extends Table,\n F extends Table,\n G extends Table,\n C extends Table,\n H extends Table,\n A extends Table,\n D extends Table,\n N,\n J extends Table = never,\n> = Shared.OAuthConnectedMapping<\n SqlTableModel<S>,\n SqlTableModel<AC>,\n SqlTableModel<T>,\n SqlTableModel<O>,\n SqlTableModel<F>,\n SqlTableModel<G>,\n SqlTableModel<C>,\n SqlTableModel<H>,\n SqlTableModel<A>,\n SqlTableModel<D>,\n N,\n SqlTableModel<J>,\n SQL,\n Table,\n SqlTableModel<Table>\n>;\n\nexport type OAuthConnectedRevocationMapping<\n T extends Table,\n O extends Table,\n F extends Table,\n G extends Table,\n C extends Table,\n H extends Table,\n J extends Table,\n N,\n> = Shared.OAuthConnectedRevocationMapping<\n SqlTableModel<T>,\n SqlTableModel<O>,\n SqlTableModel<F>,\n SqlTableModel<G>,\n SqlTableModel<C>,\n SqlTableModel<H>,\n SqlTableModel<J>,\n N,\n SQL\n>;\n"],"mappings":";;AA6DA,MAAa,6BACX,UAEAA,4BAA2D,KAAK"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { TableModel } from "./query-operations.mjs";
|
|
2
|
+
import { OAuthAccountsMapping as OAuthAccountsMapping$1, OAuthAction, OAuthAuthorityReadTable as OAuthAuthorityReadTable$1, OAuthAuthorityTable as OAuthAuthorityTable$1, OAuthCleanupDescriptor as OAuthCleanupDescriptor$1, OAuthCleanupTable as OAuthCleanupTable$1, OAuthClock as OAuthClock$1, OAuthCredentialReadTable as OAuthCredentialReadTable$1, OAuthCredentialTable as OAuthCredentialTable$1, OAuthD1Mapping, OAuthEligibilityDescriptor as OAuthEligibilityDescriptor$1, OAuthEligibilityFact, OAuthEligibilityTable as OAuthEligibilityTable$1, OAuthFlowState, OAuthFlowTable as OAuthFlowTable$1, OAuthMetadataPolicy as OAuthMetadataPolicy$1, OAuthOwnershipMutation as OAuthOwnershipMutation$1, OAuthOwnershipReadTable as OAuthOwnershipReadTable$1, OAuthOwnershipTable as OAuthOwnershipTable$1, OAuthReferenceGuardDescriptor as OAuthReferenceGuardDescriptor$1, OAuthReferenceGuardTable as OAuthReferenceGuardTable$1, OAuthRegistrationAuthority, OAuthRegistrationBase as OAuthRegistrationBase$1, OAuthRegistrationCommandTable as OAuthRegistrationCommandTable$1, OAuthRegistrationEligibility as OAuthRegistrationEligibility$1, OAuthRegistrationGuardDescriptor as OAuthRegistrationGuardDescriptor$1, OAuthRegistrationGuardTable as OAuthRegistrationGuardTable$1, OAuthRegistrationIntentMapping as OAuthRegistrationIntentMapping$1, OAuthRegistrationIntentTable as OAuthRegistrationIntentTable$1, OAuthRegistrationMapping as OAuthRegistrationMapping$1, OAuthRegistrationState, OAuthSignInMapping as OAuthSignInMapping$1, OAuthSubjectReadTable as OAuthSubjectReadTable$1, OAuthSubjectTable as OAuthSubjectTable$1, OAuthTupleAuthorityTable as OAuthTupleAuthorityTable$1, OAuthTupleState, OAuthUnlinkCommandTable as OAuthUnlinkCommandTable$1, oauth_model_d_exports, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints } from "./models/oauth-model.mjs";
|
|
3
|
+
import { Fragment, Table } from "./sql-table.mjs";
|
|
4
|
+
//#region src/internal/sql-oauth-model.d.ts
|
|
5
|
+
export interface SqlTableModel<T extends Table = Table> extends TableModel {
|
|
6
|
+
readonly table: T;
|
|
7
|
+
}
|
|
8
|
+
/** The engine writes every critical column explicitly after applying the pure
|
|
9
|
+
* consumer encoder. Native instant values must roundtrip without precision loss. */
|
|
10
|
+
export type OAuthClock = OAuthClock$1<Fragment>;
|
|
11
|
+
export type OAuthSubjectReadTable<S extends Table> = OAuthSubjectReadTable$1<SqlTableModel<S>, Fragment>;
|
|
12
|
+
export type OAuthSubjectTable<S extends Table> = OAuthSubjectTable$1<SqlTableModel<S>, Fragment>;
|
|
13
|
+
export type OAuthOwnershipReadTable<O extends Table, N> = OAuthOwnershipReadTable$1<SqlTableModel<O>, N, Fragment>;
|
|
14
|
+
export type OAuthOwnershipTable<O extends Table, N> = OAuthOwnershipTable$1<SqlTableModel<O>, N, Fragment>;
|
|
15
|
+
export type OAuthCredentialReadTable<C extends Table> = OAuthCredentialReadTable$1<SqlTableModel<C>, Fragment>;
|
|
16
|
+
export type OAuthCredentialTable<C extends Table, N> = OAuthCredentialTable$1<SqlTableModel<C>, N, Fragment>;
|
|
17
|
+
export type OAuthAuthorityReadTable<C extends Table> = OAuthAuthorityReadTable$1<SqlTableModel<C>, Fragment>;
|
|
18
|
+
export type OAuthAuthorityTable<C extends Table, N> = OAuthAuthorityTable$1<SqlTableModel<C>, N, Fragment>;
|
|
19
|
+
/** Both purposes may use the same physical table. Shared tables share module/flow
|
|
20
|
+
* and module/command uniqueness. The snapshot has the exact purpose-specific core
|
|
21
|
+
* codec; terminal writes erase it, while identity, claim and retention columns remain. */
|
|
22
|
+
export type OAuthFlowTable<F extends Table> = OAuthFlowTable$1<SqlTableModel<F>>;
|
|
23
|
+
export type OAuthTupleAuthorityTable<T extends Table, N> = OAuthTupleAuthorityTable$1<SqlTableModel<T>, N>;
|
|
24
|
+
export type OAuthRegistrationIntentTable<I extends Table> = OAuthRegistrationIntentTable$1<SqlTableModel<I>>;
|
|
25
|
+
export type OAuthRegistrationCommandTable<R extends Table, Registration> = OAuthRegistrationCommandTable$1<SqlTableModel<R>, Registration>;
|
|
26
|
+
export type OAuthUnlinkCommandTable<U extends Table> = OAuthUnlinkCommandTable$1<SqlTableModel<U>>;
|
|
27
|
+
/** Each descriptor reads only its own subject-scoped method rows. The native row
|
|
28
|
+
* projector and SQL condition must express the same installed method eligibility.
|
|
29
|
+
* All source/identifier/policy mutations advance subject securityRevision. D1 also
|
|
30
|
+
* guards exact selected IDs/versions and absence/count assumptions, never just a
|
|
31
|
+
* stale boolean. An over-limit graph fails closed rather than truncating. */
|
|
32
|
+
export type OAuthEligibilityTable<T extends Table, N> = OAuthEligibilityTable$1<SqlTableModel<T>, N, Fragment>;
|
|
33
|
+
/** Authenticated command replay uses current subject status and this additional
|
|
34
|
+
* nonconsuming SQL policy. It never consumes a fresh action factor. */
|
|
35
|
+
export type OAuthMetadataPolicy<N> = OAuthMetadataPolicy$1<N, Fragment>;
|
|
36
|
+
export type OAuthCleanupTable<T extends Table, N> = OAuthCleanupTable$1<SqlTableModel<T>, N, Fragment>;
|
|
37
|
+
export type OAuthRegistrationEligibility<N> = OAuthRegistrationEligibility$1<N, Fragment>;
|
|
38
|
+
export type OAuthSignInMapping<S extends Table, O extends Table, C extends Table, AC extends Table, F extends Table, N> = OAuthSignInMapping$1<SqlTableModel<S>, SqlTableModel<O>, SqlTableModel<C>, SqlTableModel<AC>, SqlTableModel<F>, N, Fragment>;
|
|
39
|
+
export type OAuthOwnershipMutation<T extends Table, O extends Table, N> = OAuthOwnershipMutation$1<SqlTableModel<T>, SqlTableModel<O>, N, Fragment>;
|
|
40
|
+
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> = OAuthRegistrationIntentMapping$1<SqlTableModel<S>, SqlTableModel<O>, SqlTableModel<C>, SqlTableModel<AC>, SqlTableModel<F>, SqlTableModel<T>, SqlTableModel<I>, N, Fragment>;
|
|
41
|
+
export type OAuthRegistrationBase<Registration, T extends Table, O extends Table, I extends Table, R extends Table, N> = OAuthRegistrationBase$1<Registration, SqlTableModel<T>, SqlTableModel<O>, SqlTableModel<I>, SqlTableModel<R>, N, Fragment, Table>;
|
|
42
|
+
export type OAuthRegistrationGuardTable<T extends Table, Registration, N> = OAuthRegistrationGuardTable$1<SqlTableModel<T>, Registration, N, Fragment>;
|
|
43
|
+
export type OAuthRegistrationGuardDescriptor<Registration, N> = OAuthRegistrationGuardDescriptor$1<Registration, N, Fragment, Table>;
|
|
44
|
+
export declare const oauthRegistrationGuardTable: <T extends Table, Registration, N>(input: OAuthRegistrationGuardTable<T, Registration, N>) => OAuthRegistrationGuardDescriptor<Registration, N>;
|
|
45
|
+
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> = OAuthRegistrationMapping$1<Registration, SqlTableModel<S>, SqlTableModel<O>, SqlTableModel<C>, SqlTableModel<AC>, SqlTableModel<T>, SqlTableModel<I>, SqlTableModel<R>, N, Fragment, Table>;
|
|
46
|
+
/** Heterogeneous descriptors are made by typed factories and projected privately. */
|
|
47
|
+
export type OAuthEligibilityDescriptor<N> = OAuthEligibilityDescriptor$1<N, Fragment, Table>;
|
|
48
|
+
export declare const oauthEligibilityTable: <T extends Table, N>(input: OAuthEligibilityTable<T, N>) => OAuthEligibilityDescriptor<N>;
|
|
49
|
+
export type OAuthCleanupDescriptor<N> = OAuthCleanupDescriptor$1<N, Fragment, Table>;
|
|
50
|
+
export declare const oauthCleanupTable: <T extends Table, N>(input: OAuthCleanupTable<T, N>) => OAuthCleanupDescriptor<N>;
|
|
51
|
+
/** A stable application/reference lock acquired before an ownership target.
|
|
52
|
+
* Missing rows retain ownership. Conditions use detached native IDs; every
|
|
53
|
+
* writer of the guarded reference follows the same order. */
|
|
54
|
+
export type OAuthReferenceGuardTable<T extends Table, N> = OAuthReferenceGuardTable$1<SqlTableModel<T>, N, Fragment>;
|
|
55
|
+
export type OAuthReferenceGuardDescriptor<N> = OAuthReferenceGuardDescriptor$1<N, Fragment, Table>;
|
|
56
|
+
export declare const oauthReferenceGuardTable: <T extends Table, N>(input: OAuthReferenceGuardTable<T, N>) => OAuthReferenceGuardDescriptor<N>;
|
|
57
|
+
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> = OAuthAccountsMapping$1<SqlTableModel<S>, SqlTableModel<O>, SqlTableModel<C>, SqlTableModel<AC>, SqlTableModel<F>, SqlTableModel<T>, SqlTableModel<U>, N, Fragment, Table>;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { type OAuthAction, type OAuthD1Mapping, type OAuthEligibilityFact, type OAuthFlowState, type OAuthRegistrationAuthority, type OAuthRegistrationState, type OAuthTupleState, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints };
|
|
60
|
+
//# sourceMappingURL=sql-oauth-model.d.mts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { oauthCleanupTable as oauthCleanupTable$1, oauthEligibilityTable as oauthEligibilityTable$1, oauthReferenceGuardTable as oauthReferenceGuardTable$1, oauthRegistrationGuardTable as oauthRegistrationGuardTable$1, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints } from "./models/oauth-model.mjs";
|
|
2
|
+
//#region src/internal/sql-oauth-model.ts
|
|
3
|
+
const oauthRegistrationGuardTable = (input) => oauthRegistrationGuardTable$1(input);
|
|
4
|
+
const oauthEligibilityTable = (input) => oauthEligibilityTable$1(input);
|
|
5
|
+
const oauthCleanupTable = (input) => oauthCleanupTable$1(input);
|
|
6
|
+
const oauthReferenceGuardTable = (input) => oauthReferenceGuardTable$1(input);
|
|
7
|
+
//#endregion
|
|
8
|
+
export { oauthCleanupTable, oauthEligibilityTable, oauthReferenceGuardTable, oauthRegistrationGuardTable, requiredOAuthAccountsConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, requiredOAuthTupleConstraints };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=sql-oauth-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-oauth-model.mjs","names":["Shared.oauthRegistrationGuardTable","Shared.oauthEligibilityTable","Shared.oauthCleanupTable","Shared.oauthReferenceGuardTable"],"sources":["../../src/internal/sql-oauth-model.ts"],"sourcesContent":["import * as Shared from \"./models/oauth-model\";\nimport type { TableModel } from \"./query-operations\";\nimport type { Fragment as SQL, Table } from \"./sql-table\";\n\nexport interface SqlTableModel<T extends Table = Table> extends TableModel {\n readonly table: T;\n}\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 \"./models/oauth-model\";\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 SqlTableModel<S>,\n SQL\n>;\n\nexport type OAuthSubjectTable<S extends Table> = Shared.OAuthSubjectTable<SqlTableModel<S>, SQL>;\n\nexport type OAuthOwnershipReadTable<O extends Table, N> = Shared.OAuthOwnershipReadTable<\n SqlTableModel<O>,\n N,\n SQL\n>;\n\nexport type OAuthOwnershipTable<O extends Table, N> = Shared.OAuthOwnershipTable<\n SqlTableModel<O>,\n N,\n SQL\n>;\n\nexport type OAuthCredentialReadTable<C extends Table> = Shared.OAuthCredentialReadTable<\n SqlTableModel<C>,\n SQL\n>;\n\nexport type OAuthCredentialTable<C extends Table, N> = Shared.OAuthCredentialTable<\n SqlTableModel<C>,\n N,\n SQL\n>;\n\nexport type OAuthAuthorityReadTable<C extends Table> = Shared.OAuthAuthorityReadTable<\n SqlTableModel<C>,\n SQL\n>;\n\nexport type OAuthAuthorityTable<C extends Table, N> = Shared.OAuthAuthorityTable<\n SqlTableModel<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<SqlTableModel<F>>;\n\nexport type OAuthTupleAuthorityTable<T extends Table, N> = Shared.OAuthTupleAuthorityTable<\n SqlTableModel<T>,\n N\n>;\n\nexport type OAuthRegistrationIntentTable<I extends Table> = Shared.OAuthRegistrationIntentTable<\n SqlTableModel<I>\n>;\n\nexport type OAuthRegistrationCommandTable<\n R extends Table,\n Registration,\n> = Shared.OAuthRegistrationCommandTable<SqlTableModel<R>, Registration>;\n\nexport type OAuthUnlinkCommandTable<U extends Table> = Shared.OAuthUnlinkCommandTable<\n SqlTableModel<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 SqlTableModel<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 SqlTableModel<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 SqlTableModel<S>,\n SqlTableModel<O>,\n SqlTableModel<C>,\n SqlTableModel<AC>,\n SqlTableModel<F>,\n N,\n SQL\n>;\n\nexport type OAuthOwnershipMutation<\n T extends Table,\n O extends Table,\n N,\n> = Shared.OAuthOwnershipMutation<SqlTableModel<T>, SqlTableModel<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 SqlTableModel<S>,\n SqlTableModel<O>,\n SqlTableModel<C>,\n SqlTableModel<AC>,\n SqlTableModel<F>,\n SqlTableModel<T>,\n SqlTableModel<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 SqlTableModel<T>,\n SqlTableModel<O>,\n SqlTableModel<I>,\n SqlTableModel<R>,\n N,\n SQL,\n Table\n>;\n\nexport type OAuthRegistrationGuardTable<\n T extends Table,\n Registration,\n N,\n> = Shared.OAuthRegistrationGuardTable<SqlTableModel<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<SqlTableModel<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 SqlTableModel<S>,\n SqlTableModel<O>,\n SqlTableModel<C>,\n SqlTableModel<AC>,\n SqlTableModel<T>,\n SqlTableModel<I>,\n SqlTableModel<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> => Shared.oauthEligibilityTable<SqlTableModel<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<SqlTableModel<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 SqlTableModel<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<SqlTableModel<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 SqlTableModel<S>,\n SqlTableModel<O>,\n SqlTableModel<C>,\n SqlTableModel<AC>,\n SqlTableModel<F>,\n SqlTableModel<T>,\n SqlTableModel<U>,\n N,\n SQL,\n Table\n>;\n"],"mappings":";;AAwLA,MAAa,+BACX,UAEAA,8BAA2E,KAAK;AA6BlF,MAAa,yBACX,UACkCC,wBAAuD,KAAK;AAIhG,MAAa,qBACX,UAC8BC,oBAAmD,KAAK;AAaxF,MAAa,4BACX,UAEAC,2BAA0D,KAAK"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "./query-operations.mjs";
|
|
2
|
+
import { Fragment } from "./sql-table.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { SqlClient } from "effect/sql/SqlClient";
|
|
5
|
+
import { SqlError } from "effect/sql/SqlError";
|
|
6
|
+
//#region src/internal/sql-query.d.ts
|
|
7
|
+
declare const template: (parts: TemplateStringsArray, ...values: unknown[]) => Fragment;
|
|
8
|
+
export declare const and: (...values: ReadonlyArray<Fragment | undefined>) => Fragment | undefined;
|
|
9
|
+
export declare const sql: typeof template;
|
|
10
|
+
export declare const eq: (left: unknown, right: unknown) => Fragment;
|
|
11
|
+
//#endregion
|
|
12
|
+
//# sourceMappingURL=sql-query.d.mts.map
|
|
@@ -16,14 +16,16 @@ const combine = (separator, values) => {
|
|
|
16
16
|
};
|
|
17
17
|
const and = (...values) => combine(" AND ", values);
|
|
18
18
|
const or = (...values) => combine(" OR ", values);
|
|
19
|
-
const
|
|
19
|
+
const operations = {
|
|
20
20
|
and,
|
|
21
21
|
or,
|
|
22
22
|
asc: (value) => template`${value} ASC`,
|
|
23
23
|
eq: (left, right) => template`${left} = ${right}`,
|
|
24
|
+
ne: (left, right) => template`${left} <> ${right}`,
|
|
24
25
|
gt: (left, right) => template`${left} > ${right}`,
|
|
25
26
|
gte: (left, right) => template`${left} >= ${right}`,
|
|
26
27
|
lte: (left, right) => template`${left} <= ${right}`,
|
|
28
|
+
isNotNull: (value) => template`${value} IS NOT NULL`,
|
|
27
29
|
isNull: (value) => template`${value} IS NULL`,
|
|
28
30
|
notExists: (value) => template`NOT EXISTS (${value})`,
|
|
29
31
|
inArray: (column, values) => values.length === 0 ? template`false` : new Fragment((compiler) => `${render(column, compiler)} IN (${values.map((value) => render(value, compiler)).join(", ")})`),
|
|
@@ -44,27 +46,20 @@ const sqlQueryOperations = {
|
|
|
44
46
|
balancedD1And: and,
|
|
45
47
|
compactD1GeneratedStatement: (_client, statement) => statement
|
|
46
48
|
};
|
|
49
|
+
const sqlQueryOperations = operations;
|
|
47
50
|
const selectionFor = (state) => state.selection ?? (state.table instanceof Table ? state.table.columns : {});
|
|
48
51
|
const selectionFields = (selection) => {
|
|
49
|
-
const used = new Set(Object.keys(selection));
|
|
50
52
|
let index = 0;
|
|
51
|
-
return Object.entries(selection).flatMap(([key, value]) => value instanceof Table ? Object.entries(value.columns).map(([name, column]) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
key,
|
|
59
|
-
name,
|
|
60
|
-
column,
|
|
61
|
-
alias
|
|
62
|
-
};
|
|
63
|
-
}) : [{
|
|
53
|
+
return Object.entries(selection).flatMap(([key, value]) => value instanceof Table ? Object.entries(value.columns).map(([name, column]) => ({
|
|
54
|
+
key,
|
|
55
|
+
name,
|
|
56
|
+
column,
|
|
57
|
+
alias: `auth_column_${index++}`
|
|
58
|
+
})) : [{
|
|
64
59
|
key,
|
|
65
60
|
name: void 0,
|
|
66
61
|
column: value,
|
|
67
|
-
alias:
|
|
62
|
+
alias: `auth_column_${index++}`
|
|
68
63
|
}]);
|
|
69
64
|
};
|
|
70
65
|
const projection = (selection, compiler) => selectionFields(selection).map(({ column, alias }) => `${column.render(compiler)} AS ${identifier(alias)}`).join(", ");
|
|
@@ -113,7 +108,7 @@ const compile = (state, compiler) => {
|
|
|
113
108
|
};
|
|
114
109
|
/** Captures one Effect SQL client. Its transaction service remains the physical owner. */
|
|
115
110
|
const makeSqlDatabase = Effect.fnUntraced(function* (dialect) {
|
|
116
|
-
const client = yield* SqlClient;
|
|
111
|
+
const client = (yield* SqlClient).withoutTransforms();
|
|
117
112
|
const query = (state) => {
|
|
118
113
|
const execute = Effect.suspend(() => {
|
|
119
114
|
const compiler = {
|
|
@@ -203,7 +198,9 @@ const makeSqlDatabase = Effect.fnUntraced(function* (dialect) {
|
|
|
203
198
|
};
|
|
204
199
|
return database;
|
|
205
200
|
});
|
|
201
|
+
const sql = template;
|
|
202
|
+
const { eq } = operations;
|
|
206
203
|
//#endregion
|
|
207
|
-
export { makeSqlDatabase, sqlQueryOperations };
|
|
204
|
+
export { and, eq, makeSqlDatabase, sql, sqlQueryOperations };
|
|
208
205
|
|
|
209
206
|
//# sourceMappingURL=sql-query.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-query.mjs","names":[],"sources":["../../src/internal/sql-query.ts"],"sourcesContent":["import { Effect, Predicate } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { QueryOperations } from \"./query-operations\";\nimport {\n type Column,\n Fragment,\n Table,\n identifier,\n type Compiler,\n type Dialect,\n type Row,\n} from \"./sql-table\";\n\nconst render = (value: unknown, compiler: Compiler): string => {\n if (value instanceof Fragment) return value.render(compiler);\n if (Predicate.hasProperty(value, \"getSQL\") && typeof value.getSQL === \"function\") {\n return render(value.getSQL(), compiler);\n }\n\n compiler.parameters.push(\n compiler.dialect === \"sqlite\" && typeof value === \"boolean\" ? Number(value) : value,\n );\n\n return compiler.dialect === \"pg\" ? `$${compiler.parameters.length}` : \"?\";\n};\n\nconst template = (parts: TemplateStringsArray, ...values: unknown[]): Fragment =>\n new Fragment((compiler) =>\n parts.reduce(\n (sql, part, i) => sql + (i === 0 ? \"\" : render(values[i - 1], compiler)) + part,\n \"\",\n ),\n );\n\nconst combine = (separator: string, values: ReadonlyArray<Fragment | undefined>) => {\n const fragments = values.filter((value) => value !== undefined);\n\n return fragments.length === 0\n ? undefined\n : new Fragment(\n (compiler) =>\n \"(\" + fragments.map((fragment) => fragment.render(compiler)).join(separator) + \")\",\n );\n};\n\nconst and = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" AND \", values);\nconst or = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" OR \", values);\n\nconst operations = {\n and,\n or,\n asc: (value: unknown) => template`${value} ASC`,\n eq: (left: unknown, right: unknown) => template`${left} = ${right}`,\n gt: (left: unknown, right: unknown) => template`${left} > ${right}`,\n gte: (left: unknown, right: unknown) => template`${left} >= ${right}`,\n lte: (left: unknown, right: unknown) => template`${left} <= ${right}`,\n isNull: (value: unknown) => template`${value} IS NULL`,\n notExists: (value: unknown) => template`NOT EXISTS (${value})`,\n inArray: (column: unknown, values: ReadonlyArray<unknown>) =>\n values.length === 0\n ? template`false`\n : new Fragment(\n (compiler) =>\n `${render(column, compiler)} IN (${values.map((value) => render(value, compiler)).join(\", \")})`,\n ),\n sql: Object.assign(template, {\n param: (value: unknown, column: Column) => column.mapToDriverValue(value),\n join: (values: ReadonlyArray<unknown>, separator: Fragment = template``) =>\n new Fragment((compiler) =>\n values\n .map(\n (value, index) =>\n (index === 0 ? \"\" : separator.render(compiler)) + render(value, compiler),\n )\n .join(\"\"),\n ),\n }),\n getTableColumns: (table: Table) => table.columns,\n column: (table: Table, key: string) => {\n const column = table.columns[key];\n\n if (column === undefined)\n throw PersistenceMappingError.make({ operation: \"column\", cause: key });\n\n return column;\n },\n updateValues: (entries: ReadonlyArray<readonly [string, unknown]>) => Object.fromEntries(entries),\n balancedD1And: and,\n // Raw clients use interactive transactions, so no D1 batch compaction is needed.\n compactD1GeneratedStatement: <S>(_client: unknown, statement: S) => statement,\n};\n\n// The existing kernels erase query-builder shapes at this boundary. The raw compiler\n// implements precisely those operations; no row decoding or Effect requirements are cast.\nexport const sqlQueryOperations = operations as unknown as QueryOperations;\n\ntype Selection = Readonly<Record<string, Fragment>>;\n\ninterface QueryState {\n readonly operation: \"select\" | \"insert\" | \"update\" | \"delete\";\n readonly table?: Table | Fragment;\n readonly joins?: ReadonlyArray<{\n readonly table: Table | Fragment;\n readonly on: Fragment;\n }>;\n readonly selection?: Selection;\n readonly where?: Fragment | undefined;\n readonly values?: Row;\n readonly returning?: Selection | true;\n readonly order?: ReadonlyArray<Fragment>;\n readonly limit?: number;\n readonly lock?: boolean;\n readonly conflict?: boolean;\n}\n\nconst selectionFor = (state: QueryState): Selection =>\n state.selection ?? (state.table instanceof Table ? state.table.columns : {});\n\nconst selectionFields = (selection: Selection) => {\n const used = new Set(Object.keys(selection));\n let index = 0;\n\n return Object.entries(selection).flatMap<{\n readonly key: string;\n readonly name: string | undefined;\n readonly column: Fragment;\n readonly alias: string;\n }>(([key, value]) =>\n value instanceof Table\n ? Object.entries(value.columns).map(([name, column]) => {\n let alias: string;\n\n do alias = `auth_column_${index++}`;\n while (used.has(alias));\n used.add(alias);\n\n return { key, name, column, alias };\n })\n : [{ key, name: undefined, column: value, alias: key }],\n );\n};\n\nconst projection = (selection: Selection, compiler: Compiler) =>\n selectionFields(selection)\n .map(({ column, alias }) => `${column.render(compiler)} AS ${identifier(alias)}`)\n .join(\", \");\n\n// Joined table selections retain their own column codecs and nested row names.\nconst decodeRow = (selection: Selection, row: Row): Row => {\n const entries: Array<readonly [string, unknown]> = [];\n const groups = new Map<string, Array<readonly [string, unknown]>>();\n\n for (const field of selectionFields(selection)) {\n const value = field.column.decode(row[field.alias]);\n\n if (field.name === undefined) entries.push([field.key, value]);\n else {\n const group = groups.get(field.key) ?? [];\n\n group.push([field.name, value]);\n groups.set(field.key, group);\n }\n }\n\n return Object.fromEntries([\n ...entries,\n ...Array.from(groups, ([key, values]) => [key, Object.fromEntries(values)]),\n ]);\n};\n\nconst compile = (state: QueryState, compiler: Compiler): string => {\n const table = state.table;\n\n if (table === undefined)\n throw PersistenceMappingError.make({ operation: \"query\", cause: \"Missing table\" });\n let query: string;\n\n if (state.operation === \"select\") {\n query = `SELECT ${projection(selectionFor(state), compiler)} FROM ${table.render(compiler)}`;\n for (const join of state.joins ?? [])\n query += ` INNER JOIN ${join.table.render(compiler)} ON ${join.on.render(compiler)}`;\n } else {\n if (!(table instanceof Table))\n throw PersistenceMappingError.make({\n operation: \"query\",\n cause: \"Mutation requires a table\",\n });\n const target = table.render(compiler);\n\n const fields = Object.entries(state.values ?? {}).filter(\n ([key, value]) => table.columns[key] !== undefined && value !== undefined,\n );\n\n if (state.operation === \"insert\") {\n query = `INSERT INTO ${target} (${fields.map(([key]) => identifier(table.columns[key].options.name)).join(\", \")}) VALUES (${fields.map(([, value]) => render(value, compiler)).join(\", \")})`;\n } else if (state.operation === \"update\") {\n query = `UPDATE ${target} SET ${fields.map(([key, value]) => `${identifier(table.columns[key].options.name)} = ${render(value, compiler)}`).join(\", \")}`;\n } else query = `DELETE FROM ${target}`;\n }\n if (state.where !== undefined) query += ` WHERE ${state.where.render(compiler)}`;\n if (state.order?.length)\n query += ` ORDER BY ${state.order.map((field) => field.render(compiler)).join(\", \")}`;\n if (state.limit !== undefined) query += ` LIMIT ${render(state.limit, compiler)}`;\n if (state.conflict) query += \" ON CONFLICT DO NOTHING\";\n if (state.returning)\n query += ` RETURNING ${projection(state.returning === true && table instanceof Table ? table.columns : state.returning === true ? {} : state.returning, compiler)}`;\n if (state.lock && compiler.dialect === \"pg\") query += \" FOR UPDATE\";\n\n return query;\n};\n\n/** Captures one Effect SQL client. Its transaction service remains the physical owner. */\nexport const makeSqlDatabase = Effect.fnUntraced(function* (dialect: Dialect) {\n const client = yield* SqlClient;\n\n const query = (state: QueryState): Query => {\n const execute = Effect.suspend(() => {\n const compiler: Compiler = { dialect, parameters: [] };\n const text = compile(state, compiler);\n\n const selected: Selection =\n state.operation === \"select\"\n ? selectionFor(state)\n : state.returning === true\n ? state.table instanceof Table\n ? state.table.columns\n : {}\n : state.returning || {};\n\n return client\n .unsafe<Row>(text, compiler.parameters)\n .pipe(Effect.map((rows) => rows.map((row) => decodeRow(selected, row))));\n });\n\n return Object.assign(execute, {\n toSQL: () => {\n const compiler: Compiler = { dialect, parameters: [] };\n\n return { sql: compile(state, compiler), params: compiler.parameters };\n },\n getSQL: () => new Fragment((compiler) => compile(state, compiler)),\n from: (table: Table | Fragment) => query({ ...state, table }),\n innerJoin: (table: Table | Fragment, on: Fragment) =>\n query({ ...state, joins: [...(state.joins ?? []), { table, on }] }),\n where: (where: Fragment | undefined) => query({ ...state, where }),\n limit: (limit: number) => query({ ...state, limit }),\n orderBy: (...order: Fragment[]) => query({ ...state, order }),\n for: (_lock: \"update\") => query({ ...state, lock: true }),\n values: (values: Row) => query({ ...state, values }),\n set: (values: Row) => query({ ...state, values }),\n returning: (returning: Selection | true = true) => query({ ...state, returning }),\n onConflictDoNothing: () => query({ ...state, conflict: true }),\n });\n };\n\n const database: SqlDatabase = {\n $client: client,\n select: (selection?: Selection) =>\n query({ operation: \"select\", ...(selection === undefined ? {} : { selection }) }),\n insert: (table: Table) => query({ operation: \"insert\", table }),\n update: (table: Table) => query({ operation: \"update\", table }),\n delete: (table: Table) => query({ operation: \"delete\", table }),\n transaction: <A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R> =>\n client.withTransaction(Effect.suspend(() => body(database))),\n };\n\n return database;\n});\n\ninterface Query extends Effect.Effect<Row[], SqlError> {\n toSQL(): { readonly sql: string; readonly params: ReadonlyArray<unknown> };\n getSQL(): Fragment;\n from(table: Table | Fragment): Query;\n innerJoin(table: Table | Fragment, on: Fragment): Query;\n where(where: Fragment | undefined): Query;\n limit(limit: number): Query;\n orderBy(...order: Fragment[]): Query;\n for(lock: \"update\"): Query;\n values(values: Row): Query;\n set(values: Row): Query;\n returning(returning?: Selection | true): Query;\n onConflictDoNothing(): Query;\n}\n\nexport interface SqlDatabase {\n readonly $client: SqlClient;\n select(selection?: Selection): Query;\n insert(table: Table): Query;\n update(table: Table): Query;\n delete(table: Table): Query;\n transaction<A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport const sql = template;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sql-query.mjs","names":[],"sources":["../../src/internal/sql-query.ts"],"sourcesContent":["import { Effect, Predicate } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { QueryOperations } from \"./query-operations\";\nimport {\n type Column,\n Fragment,\n Table,\n identifier,\n type Compiler,\n type Dialect,\n type Row,\n} from \"./sql-table\";\n\nconst render = (value: unknown, compiler: Compiler): string => {\n if (value instanceof Fragment) return value.render(compiler);\n if (Predicate.hasProperty(value, \"getSQL\") && typeof value.getSQL === \"function\") {\n return render(value.getSQL(), compiler);\n }\n\n compiler.parameters.push(\n compiler.dialect === \"sqlite\" && typeof value === \"boolean\" ? Number(value) : value,\n );\n\n return compiler.dialect === \"pg\" ? `$${compiler.parameters.length}` : \"?\";\n};\n\nconst template = (parts: TemplateStringsArray, ...values: unknown[]): Fragment =>\n new Fragment((compiler) =>\n parts.reduce(\n (sql, part, i) => sql + (i === 0 ? \"\" : render(values[i - 1], compiler)) + part,\n \"\",\n ),\n );\n\nconst combine = (separator: string, values: ReadonlyArray<Fragment | undefined>) => {\n const fragments = values.filter((value) => value !== undefined);\n\n return fragments.length === 0\n ? undefined\n : new Fragment(\n (compiler) =>\n \"(\" + fragments.map((fragment) => fragment.render(compiler)).join(separator) + \")\",\n );\n};\n\nexport const and = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" AND \", values);\nconst or = (...values: ReadonlyArray<Fragment | undefined>) => combine(\" OR \", values);\n\nconst operations = {\n and,\n or,\n asc: (value: unknown) => template`${value} ASC`,\n eq: (left: unknown, right: unknown) => template`${left} = ${right}`,\n ne: (left: unknown, right: unknown) => template`${left} <> ${right}`,\n gt: (left: unknown, right: unknown) => template`${left} > ${right}`,\n gte: (left: unknown, right: unknown) => template`${left} >= ${right}`,\n lte: (left: unknown, right: unknown) => template`${left} <= ${right}`,\n isNotNull: (value: unknown) => template`${value} IS NOT NULL`,\n isNull: (value: unknown) => template`${value} IS NULL`,\n notExists: (value: unknown) => template`NOT EXISTS (${value})`,\n inArray: (column: unknown, values: ReadonlyArray<unknown>) =>\n values.length === 0\n ? template`false`\n : new Fragment(\n (compiler) =>\n `${render(column, compiler)} IN (${values.map((value) => render(value, compiler)).join(\", \")})`,\n ),\n sql: Object.assign(template, {\n param: (value: unknown, column: Column) => column.mapToDriverValue(value),\n join: (values: ReadonlyArray<unknown>, separator: Fragment = template``) =>\n new Fragment((compiler) =>\n values\n .map(\n (value, index) =>\n (index === 0 ? \"\" : separator.render(compiler)) + render(value, compiler),\n )\n .join(\"\"),\n ),\n }),\n getTableColumns: (table: Table) => table.columns,\n column: (table: Table, key: string) => {\n const column = table.columns[key];\n\n if (column === undefined)\n throw PersistenceMappingError.make({ operation: \"column\", cause: key });\n\n return column;\n },\n updateValues: (entries: ReadonlyArray<readonly [string, unknown]>) => Object.fromEntries(entries),\n balancedD1And: and,\n // Raw clients use interactive transactions, so no D1 batch compaction is needed.\n compactD1GeneratedStatement: <S>(_client: unknown, statement: S) => statement,\n};\n\n// The existing kernels erase query-builder shapes at this boundary. The raw compiler\n// implements precisely those operations; no row decoding or Effect requirements are cast.\nexport const sqlQueryOperations = operations as unknown as QueryOperations;\n\ntype Selection = Readonly<Record<string, Fragment>>;\n\ninterface QueryState {\n readonly operation: \"select\" | \"insert\" | \"update\" | \"delete\";\n readonly table?: Table | Fragment;\n readonly joins?: ReadonlyArray<{\n readonly table: Table | Fragment;\n readonly on: Fragment;\n }>;\n readonly selection?: Selection;\n readonly where?: Fragment | undefined;\n readonly values?: Row;\n readonly returning?: Selection | true;\n readonly order?: ReadonlyArray<Fragment>;\n readonly limit?: number;\n readonly lock?: boolean;\n readonly conflict?: boolean;\n}\n\nconst selectionFor = (state: QueryState): Selection =>\n state.selection ?? (state.table instanceof Table ? state.table.columns : {});\n\n// Logical keys may exceed SQL identifier limits; only short internal aliases reach the driver.\nconst selectionFields = (selection: Selection) => {\n let index = 0;\n\n return Object.entries(selection).flatMap<{\n readonly key: string;\n readonly name: string | undefined;\n readonly column: Fragment;\n readonly alias: string;\n }>(([key, value]) =>\n value instanceof Table\n ? Object.entries(value.columns).map(([name, column]) => ({\n key,\n name,\n column,\n alias: `auth_column_${index++}`,\n }))\n : [{ key, name: undefined, column: value, alias: `auth_column_${index++}` }],\n );\n};\n\nconst projection = (selection: Selection, compiler: Compiler) =>\n selectionFields(selection)\n .map(({ column, alias }) => `${column.render(compiler)} AS ${identifier(alias)}`)\n .join(\", \");\n\n// Joined table selections retain their own column codecs and nested row names.\nconst decodeRow = (selection: Selection, row: Row): Row => {\n const entries: Array<readonly [string, unknown]> = [];\n const groups = new Map<string, Array<readonly [string, unknown]>>();\n\n for (const field of selectionFields(selection)) {\n const value = field.column.decode(row[field.alias]);\n\n if (field.name === undefined) entries.push([field.key, value]);\n else {\n const group = groups.get(field.key) ?? [];\n\n group.push([field.name, value]);\n groups.set(field.key, group);\n }\n }\n\n return Object.fromEntries([\n ...entries,\n ...Array.from(groups, ([key, values]) => [key, Object.fromEntries(values)]),\n ]);\n};\n\nconst compile = (state: QueryState, compiler: Compiler): string => {\n const table = state.table;\n\n if (table === undefined)\n throw PersistenceMappingError.make({ operation: \"query\", cause: \"Missing table\" });\n let query: string;\n\n if (state.operation === \"select\") {\n query = `SELECT ${projection(selectionFor(state), compiler)} FROM ${table.render(compiler)}`;\n for (const join of state.joins ?? [])\n query += ` INNER JOIN ${join.table.render(compiler)} ON ${join.on.render(compiler)}`;\n } else {\n if (!(table instanceof Table))\n throw PersistenceMappingError.make({\n operation: \"query\",\n cause: \"Mutation requires a table\",\n });\n const target = table.render(compiler);\n\n const fields = Object.entries(state.values ?? {}).filter(\n ([key, value]) => table.columns[key] !== undefined && value !== undefined,\n );\n\n if (state.operation === \"insert\") {\n query = `INSERT INTO ${target} (${fields.map(([key]) => identifier(table.columns[key].options.name)).join(\", \")}) VALUES (${fields.map(([, value]) => render(value, compiler)).join(\", \")})`;\n } else if (state.operation === \"update\") {\n query = `UPDATE ${target} SET ${fields.map(([key, value]) => `${identifier(table.columns[key].options.name)} = ${render(value, compiler)}`).join(\", \")}`;\n } else query = `DELETE FROM ${target}`;\n }\n if (state.where !== undefined) query += ` WHERE ${state.where.render(compiler)}`;\n if (state.order?.length)\n query += ` ORDER BY ${state.order.map((field) => field.render(compiler)).join(\", \")}`;\n if (state.limit !== undefined) query += ` LIMIT ${render(state.limit, compiler)}`;\n if (state.conflict) query += \" ON CONFLICT DO NOTHING\";\n if (state.returning)\n query += ` RETURNING ${projection(state.returning === true && table instanceof Table ? table.columns : state.returning === true ? {} : state.returning, compiler)}`;\n if (state.lock && compiler.dialect === \"pg\") query += \" FOR UPDATE\";\n\n return query;\n};\n\n/** Captures one Effect SQL client. Its transaction service remains the physical owner. */\nexport const makeSqlDatabase = Effect.fnUntraced(function* (dialect: Dialect) {\n // Mappings and projection aliases own their names. Retain the client's\n // connection and transaction identity while bypassing naming transforms.\n const client = (yield* SqlClient).withoutTransforms();\n\n const query = (state: QueryState): Query => {\n const execute = Effect.suspend(() => {\n const compiler: Compiler = { dialect, parameters: [] };\n const text = compile(state, compiler);\n\n const selected: Selection =\n state.operation === \"select\"\n ? selectionFor(state)\n : state.returning === true\n ? state.table instanceof Table\n ? state.table.columns\n : {}\n : state.returning || {};\n\n return client\n .unsafe<Row>(text, compiler.parameters)\n .pipe(Effect.map((rows) => rows.map((row) => decodeRow(selected, row))));\n });\n\n return Object.assign(execute, {\n toSQL: () => {\n const compiler: Compiler = { dialect, parameters: [] };\n\n return { sql: compile(state, compiler), params: compiler.parameters };\n },\n getSQL: () => new Fragment((compiler) => compile(state, compiler)),\n from: (table: Table | Fragment) => query({ ...state, table }),\n innerJoin: (table: Table | Fragment, on: Fragment) =>\n query({ ...state, joins: [...(state.joins ?? []), { table, on }] }),\n where: (where: Fragment | undefined) => query({ ...state, where }),\n limit: (limit: number) => query({ ...state, limit }),\n orderBy: (...order: Fragment[]) => query({ ...state, order }),\n for: (_lock: \"update\") => query({ ...state, lock: true }),\n values: (values: Row) => query({ ...state, values }),\n set: (values: Row) => query({ ...state, values }),\n returning: (returning: Selection | true = true) => query({ ...state, returning }),\n onConflictDoNothing: () => query({ ...state, conflict: true }),\n });\n };\n\n const database: SqlDatabase = {\n $client: client,\n select: (selection?: Selection) =>\n query({ operation: \"select\", ...(selection === undefined ? {} : { selection }) }),\n insert: (table: Table) => query({ operation: \"insert\", table }),\n update: (table: Table) => query({ operation: \"update\", table }),\n delete: (table: Table) => query({ operation: \"delete\", table }),\n transaction: <A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R> =>\n client.withTransaction(Effect.suspend(() => body(database))),\n };\n\n return database;\n});\n\ninterface Query extends Effect.Effect<Row[], SqlError> {\n toSQL(): { readonly sql: string; readonly params: ReadonlyArray<unknown> };\n getSQL(): Fragment;\n from(table: Table | Fragment): Query;\n innerJoin(table: Table | Fragment, on: Fragment): Query;\n where(where: Fragment | undefined): Query;\n limit(limit: number): Query;\n orderBy(...order: Fragment[]): Query;\n for(lock: \"update\"): Query;\n values(values: Row): Query;\n set(values: Row): Query;\n returning(returning?: Selection | true): Query;\n onConflictDoNothing(): Query;\n}\n\nexport interface SqlDatabase {\n readonly $client: SqlClient;\n select(selection?: Selection): Query;\n insert(table: Table): Query;\n update(table: Table): Query;\n delete(table: Table): Query;\n transaction<A, E, R>(\n body: (database: SqlDatabase) => Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R>;\n}\n\nexport const sql = template;\n\nexport const { eq } = operations;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { PersistenceMappingError } from "./mapping-error.mjs";
|
|
2
|
+
import { Table } from "./sql-table.mjs";
|
|
3
|
+
import { NativeDatabase } from "./transaction-kernel.mjs";
|
|
4
|
+
import { validateStorageBatch } from "./storage-validation.mjs";
|
|
5
|
+
import { storageKeyPlans } from "./storage-plans.mjs";
|
|
6
|
+
import { Effect } from "effect";
|
|
7
|
+
import { SqlClient } from "effect/sql";
|
|
8
|
+
//#region src/internal/sql-storage-validation.ts
|
|
9
|
+
/** Check declared mappings against physical keys before acquiring OAuth services. */
|
|
10
|
+
const validateSqlStorage = Effect.fnUntraced(function* (mapping) {
|
|
11
|
+
const plans = yield* Effect.try({
|
|
12
|
+
try: () => storageKeyPlans(mapping, (table) => {
|
|
13
|
+
if (!(table instanceof Table)) throw new Error("Expected a SQL table");
|
|
14
|
+
return table.columns;
|
|
15
|
+
}),
|
|
16
|
+
catch: () => PersistenceMappingError.make({
|
|
17
|
+
operation: "mapping",
|
|
18
|
+
cause: "Invalid storage key mapping"
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
const { $client: client } = yield* NativeDatabase;
|
|
22
|
+
const dialect = client.onDialectOrElse({
|
|
23
|
+
pg: () => "pg",
|
|
24
|
+
sqlite: () => "sqlite",
|
|
25
|
+
orElse: () => void 0
|
|
26
|
+
});
|
|
27
|
+
if (dialect === void 0) return yield* PersistenceMappingError.make({
|
|
28
|
+
operation: "mapping",
|
|
29
|
+
cause: "OAuth persistence requires PostgreSQL or SQLite"
|
|
30
|
+
});
|
|
31
|
+
const validations = [];
|
|
32
|
+
for (const plan of plans) {
|
|
33
|
+
if (!(plan.table instanceof Table)) return yield* PersistenceMappingError.make({
|
|
34
|
+
operation: "mapping",
|
|
35
|
+
cause: "Expected a SQL table"
|
|
36
|
+
});
|
|
37
|
+
validations.push({
|
|
38
|
+
table: {
|
|
39
|
+
name: plan.table.name,
|
|
40
|
+
...plan.table.schema === void 0 ? {} : { schema: plan.table.schema },
|
|
41
|
+
columns: Object.fromEntries(Object.entries(plan.table.columns).map(([key, column]) => [key, column.options]))
|
|
42
|
+
},
|
|
43
|
+
required: [plan.keys]
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
yield* validateStorageBatch(dialect, validations).pipe(Effect.provideService(SqlClient.SqlClient, client), Effect.mapError(() => PersistenceMappingError.make({
|
|
47
|
+
operation: "mapping",
|
|
48
|
+
cause: "Required SQL storage key is unavailable"
|
|
49
|
+
})));
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
export { validateSqlStorage };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=sql-storage-validation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-storage-validation.mjs","names":[],"sources":["../../src/internal/sql-storage-validation.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport { Table } from \"./sql-table\";\nimport { storageKeyPlans } from \"./storage-plans\";\nimport { validateStorageBatch, type StorageValidation } from \"./storage-validation\";\nimport { NativeDatabase } from \"./transaction-kernel\";\n\n/** Check declared mappings against physical keys before acquiring OAuth services. */\nexport const validateSqlStorage = Effect.fnUntraced(function* (mapping: unknown) {\n const plans = yield* Effect.try({\n try: () =>\n storageKeyPlans(mapping, (table) => {\n if (!(table instanceof Table)) throw new Error(\"Expected a SQL table\");\n\n return table.columns;\n }),\n catch: () =>\n PersistenceMappingError.make({ operation: \"mapping\", cause: \"Invalid storage key mapping\" }),\n });\n\n const { $client: client } = yield* NativeDatabase;\n\n const dialect = client.onDialectOrElse({\n pg: () => \"pg\" as const,\n sqlite: () => \"sqlite\" as const,\n orElse: () => undefined,\n });\n\n if (dialect === undefined)\n return yield* PersistenceMappingError.make({\n operation: \"mapping\",\n cause: \"OAuth persistence requires PostgreSQL or SQLite\",\n });\n const validations: StorageValidation[] = [];\n\n for (const plan of plans) {\n if (!(plan.table instanceof Table))\n return yield* PersistenceMappingError.make({\n operation: \"mapping\",\n cause: \"Expected a SQL table\",\n });\n validations.push({\n table: {\n name: plan.table.name,\n ...(plan.table.schema === undefined ? {} : { schema: plan.table.schema }),\n columns: Object.fromEntries(\n Object.entries(plan.table.columns).map(([key, column]) => [key, column.options]),\n ),\n },\n required: [plan.keys],\n });\n }\n yield* validateStorageBatch(dialect, validations).pipe(\n Effect.provideService(SqlClient.SqlClient, client),\n Effect.mapError(() =>\n PersistenceMappingError.make({\n operation: \"mapping\",\n cause: \"Required SQL storage key is unavailable\",\n }),\n ),\n );\n});\n"],"mappings":";;;;;;;;;AAUA,MAAa,qBAAqB,OAAO,WAAW,WAAW,SAAkB;CAC/E,MAAM,QAAQ,OAAO,OAAO,IAAI;EAC9B,WACE,gBAAgB,UAAU,UAAU;GAClC,IAAI,EAAE,iBAAiB,QAAQ,MAAM,IAAI,MAAM,sBAAsB;GAErE,OAAO,MAAM;EACf,CAAC;EACH,aACE,wBAAwB,KAAK;GAAE,WAAW;GAAW,OAAO;EAA8B,CAAC;CAC/F,CAAC;CAED,MAAM,EAAE,SAAS,WAAW,OAAO;CAEnC,MAAM,UAAU,OAAO,gBAAgB;EACrC,UAAU;EACV,cAAc;EACd,cAAc,KAAA;CAChB,CAAC;CAED,IAAI,YAAY,KAAA,GACd,OAAO,OAAO,wBAAwB,KAAK;EACzC,WAAW;EACX,OAAO;CACT,CAAC;CACH,MAAM,cAAmC,CAAC;CAE1C,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,EAAE,KAAK,iBAAiB,QAC1B,OAAO,OAAO,wBAAwB,KAAK;GACzC,WAAW;GACX,OAAO;EACT,CAAC;EACH,YAAY,KAAK;GACf,OAAO;IACL,MAAM,KAAK,MAAM;IACjB,GAAI,KAAK,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,OAAO;IACvE,SAAS,OAAO,YACd,OAAO,QAAQ,KAAK,MAAM,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,KAAK,OAAO,OAAO,CAAC,CACjF;GACF;GACA,UAAU,CAAC,KAAK,IAAI;EACtB,CAAC;CACH;CACA,OAAO,qBAAqB,SAAS,WAAW,CAAC,CAAC,KAChD,OAAO,eAAe,UAAU,WAAW,MAAM,GACjD,OAAO,eACL,wBAAwB,KAAK;EAC3B,WAAW;EACX,OAAO;CACT,CAAC,CACH,CACF;AACF,CAAC"}
|
|
@@ -9,7 +9,7 @@ import { TokenDigest } from "@yielded/auth/Schema";
|
|
|
9
9
|
import { SecurityRevision, SessionAuthenticationProvenance, SessionCredentialVersion, SessionId, SessionMetadata } from "@yielded/auth/Sessions";
|
|
10
10
|
import { ProofBinding, ProofContinuationId, ProofDeliveryId, ProofId, ProofPurpose, ProofRequestId, ProofRequestReceipt, ProofVersion } from "@yielded/auth/Proofs";
|
|
11
11
|
import { EmailCredentialSnapshot } from "@yielded/auth/Email";
|
|
12
|
-
import { EncodedPasswordHash,
|
|
12
|
+
import { EncodedPasswordHash, PasswordCredentialSnapshot } from "@yielded/auth/Password";
|
|
13
13
|
import { LoginIdentifier } from "@yielded/auth/Identity";
|
|
14
14
|
//#region src/internal/storage-mapping.ts
|
|
15
15
|
const failure = (cause) => PersistenceMappingError.make({
|
|
@@ -329,7 +329,6 @@ const makeMappings = Effect.fnUntraced(function* (input) {
|
|
|
329
329
|
isCommandConflict: () => false,
|
|
330
330
|
encodeInstant: instant,
|
|
331
331
|
decodeInstant: readInstant,
|
|
332
|
-
allocateAttemptId: allocate.pipe(Effect.map(PasswordAttemptId.make)),
|
|
333
332
|
allocateCredentialId: allocate,
|
|
334
333
|
allocateRevision: allocate.pipe(Effect.map(SecurityRevision.make)),
|
|
335
334
|
commandRetentionMillis: 864e5,
|
|
@@ -398,41 +397,6 @@ const makeMappings = Effect.fnUntraced(function* (input) {
|
|
|
398
397
|
});
|
|
399
398
|
})
|
|
400
399
|
},
|
|
401
|
-
attempt: {
|
|
402
|
-
...mapped("passwordAttempts"),
|
|
403
|
-
moduleId: "moduleId",
|
|
404
|
-
action: "action",
|
|
405
|
-
attemptId: "attemptId",
|
|
406
|
-
identifierNamespace: "identifierNamespace",
|
|
407
|
-
identifierValue: "identifierValue",
|
|
408
|
-
subjectId: "subjectId",
|
|
409
|
-
credentialId: "credentialId",
|
|
410
|
-
securityRevision: "securityRevision",
|
|
411
|
-
credentialRevision: "credentialRevision",
|
|
412
|
-
verifierVersion: "verifierVersion",
|
|
413
|
-
identifierBindingRevision: "identifierBindingRevision",
|
|
414
|
-
admittedAt: "admittedAt",
|
|
415
|
-
deadline: "deadline",
|
|
416
|
-
retentionUntil: "retentionUntil",
|
|
417
|
-
state: "state",
|
|
418
|
-
encodeInsert: (row, { nativeSubjectId, state }) => ({
|
|
419
|
-
moduleId: row.moduleId,
|
|
420
|
-
action: row.action,
|
|
421
|
-
attemptId: row.attemptId,
|
|
422
|
-
identifierNamespace: row.identifier.namespace,
|
|
423
|
-
identifierValue: row.identifier.value,
|
|
424
|
-
subjectId: nativeSubjectId ?? null,
|
|
425
|
-
credentialId: row.credentialId ?? null,
|
|
426
|
-
securityRevision: row.securityRevision ?? null,
|
|
427
|
-
credentialRevision: row.credentialRevision ?? null,
|
|
428
|
-
verifierVersion: row.verifierVersion ?? null,
|
|
429
|
-
identifierBindingRevision: row.identifierBindingRevision ?? null,
|
|
430
|
-
admittedAt: instant(row.admittedAtMillis),
|
|
431
|
-
deadline: instant(row.deadlineMillis),
|
|
432
|
-
retentionUntil: instant(row.retentionUntilMillis),
|
|
433
|
-
state
|
|
434
|
-
})
|
|
435
|
-
},
|
|
436
400
|
command: {
|
|
437
401
|
...mapped("passwordCommands"),
|
|
438
402
|
moduleId: "moduleId",
|