@rvoh/dream 2.13.0 → 2.14.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/Dream.js +4 -4
- package/dist/cjs/src/db/DreamDbConnection.js +9 -3
- package/dist/cjs/src/db/dbConnectionLeakDiagnostics.js +0 -14
- package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +131 -0
- package/dist/cjs/src/db/testDatabasePool.js +182 -0
- package/dist/cjs/src/dream/QueryDriver/Base.js +29 -0
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +56 -22
- package/dist/cjs/src/dream/QueryDriver/Postgres.js +76 -1
- package/dist/cjs/src/dream/QueryDriver/helpers/pg/dropDb.js +3 -1
- package/dist/cjs/src/dream-app/index.js +113 -6
- package/dist/cjs/src/helpers/areEqual.js +1 -1
- package/dist/cjs/src/helpers/loadRepl.js +4 -0
- package/dist/cjs/src/helpers/range.js +1 -1
- package/dist/esm/src/Dream.js +4 -4
- package/dist/esm/src/db/DreamDbConnection.js +9 -3
- package/dist/esm/src/db/dbConnectionLeakDiagnostics.js +0 -14
- package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +131 -0
- package/dist/esm/src/db/testDatabasePool.js +182 -0
- package/dist/esm/src/dream/QueryDriver/Base.js +29 -0
- package/dist/esm/src/dream/QueryDriver/Kysely.js +56 -22
- package/dist/esm/src/dream/QueryDriver/Postgres.js +76 -1
- package/dist/esm/src/dream/QueryDriver/helpers/pg/dropDb.js +3 -1
- package/dist/esm/src/dream-app/index.js +113 -6
- package/dist/esm/src/helpers/areEqual.js +1 -1
- package/dist/esm/src/helpers/loadRepl.js +4 -0
- package/dist/esm/src/helpers/range.js +1 -1
- package/dist/types/src/Dream.d.ts +4 -4
- package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +108 -4
- package/dist/types/src/db/testDatabasePool.d.ts +42 -0
- package/dist/types/src/dream/QueryDriver/Base.d.ts +47 -0
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +11 -0
- package/dist/types/src/dream/QueryDriver/Postgres.d.ts +19 -0
- package/dist/types/src/dream-app/index.d.ts +64 -1
- package/dist/types/src/helpers/areEqual.d.ts +1 -1
- package/dist/types/src/helpers/range.d.ts +8 -4
- package/dist/types/src/types/utils.d.ts +1 -1
- package/dist/types/src/types/utils.ts +1 -1
- package/dist/types/src/types/variadic.d.ts +1 -1
- package/dist/types/src/types/variadic.ts +1 -1
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/db.DreamMigrationHelpers.html +65 -9
- package/docs/classes/db.KyselyQueryDriver.html +47 -32
- package/docs/classes/db.PostgresQueryDriver.html +52 -33
- package/docs/classes/db.QueryDriverBase.html +46 -31
- package/docs/classes/errors.CheckConstraintViolation.html +3 -3
- package/docs/classes/errors.ColumnOverflow.html +3 -3
- package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
- package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
- package/docs/classes/errors.DecryptionError.html +2 -2
- package/docs/classes/errors.DecryptionParseError.html +2 -2
- package/docs/classes/errors.DecryptionRotationError.html +3 -3
- package/docs/classes/errors.GlobalNameNotSet.html +3 -3
- package/docs/classes/errors.InvalidCalendarDate.html +2 -2
- package/docs/classes/errors.InvalidClockTime.html +2 -2
- package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
- package/docs/classes/errors.InvalidDateTime.html +2 -2
- package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
- package/docs/classes/errors.NonLoadedAssociation.html +3 -3
- package/docs/classes/errors.NotNullViolation.html +3 -3
- package/docs/classes/errors.RecordNotFound.html +3 -3
- package/docs/classes/errors.ValidationError.html +3 -3
- package/docs/classes/index.CalendarDate.html +33 -33
- package/docs/classes/index.ClockTime.html +32 -32
- package/docs/classes/index.ClockTimeTz.html +35 -35
- package/docs/classes/index.DateTime.html +86 -86
- package/docs/classes/index.Decorators.html +19 -19
- package/docs/classes/index.Dream.html +118 -118
- package/docs/classes/index.DreamApp.html +42 -6
- package/docs/classes/index.DreamTransaction.html +2 -2
- package/docs/classes/index.Env.html +2 -2
- package/docs/classes/index.Query.html +57 -57
- package/docs/classes/system.CliFileWriter.html +4 -4
- package/docs/classes/system.DreamBin.html +2 -2
- package/docs/classes/system.DreamCLI.html +7 -7
- package/docs/classes/system.DreamImporter.html +2 -2
- package/docs/classes/system.DreamLogos.html +2 -2
- package/docs/classes/system.DreamSerializerBuilder.html +11 -11
- package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
- package/docs/classes/system.PathHelpers.html +3 -3
- package/docs/classes/utils.Encrypt.html +3 -3
- package/docs/classes/utils.Range.html +2 -2
- package/docs/functions/db.closeAllDbConnections.html +1 -1
- package/docs/functions/db.dreamDbConnections.html +1 -1
- package/docs/functions/db.untypedDb.html +1 -1
- package/docs/functions/db.validateColumn.html +1 -1
- package/docs/functions/db.validateTable.html +1 -1
- package/docs/functions/errors.pgErrorType.html +1 -1
- package/docs/functions/index.DreamSerializer.html +1 -1
- package/docs/functions/index.ObjectSerializer.html +1 -1
- package/docs/functions/index.ReplicaSafe.html +1 -1
- package/docs/functions/index.STI.html +1 -1
- package/docs/functions/index.SoftDelete.html +1 -1
- package/docs/functions/utils.camelize.html +1 -1
- package/docs/functions/utils.capitalize.html +1 -1
- package/docs/functions/utils.cloneDeepSafe.html +1 -1
- package/docs/functions/utils.compact.html +1 -1
- package/docs/functions/utils.groupBy.html +1 -1
- package/docs/functions/utils.hyphenize.html +1 -1
- package/docs/functions/utils.intersection.html +1 -1
- package/docs/functions/utils.isEmpty.html +1 -1
- package/docs/functions/utils.normalizeUnicode.html +1 -1
- package/docs/functions/utils.pascalize.html +1 -1
- package/docs/functions/utils.percent.html +1 -1
- package/docs/functions/utils.range.html +1 -1
- package/docs/functions/utils.round.html +1 -1
- package/docs/functions/utils.sanitizeString.html +1 -1
- package/docs/functions/utils.snakeify.html +1 -1
- package/docs/functions/utils.sort.html +1 -1
- package/docs/functions/utils.sortBy.html +1 -1
- package/docs/functions/utils.sortObjectByKey.html +1 -1
- package/docs/functions/utils.sortObjectByValue.html +1 -1
- package/docs/functions/utils.uncapitalize.html +1 -1
- package/docs/functions/utils.uniq.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
- package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
- package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
- package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
- package/docs/interfaces/types.BelongsToStatement.html +2 -2
- package/docs/interfaces/types.DecoratorContext.html +2 -2
- package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
- package/docs/interfaces/types.DreamAppOpts.html +2 -2
- package/docs/interfaces/types.DreamDbConfig.html +5 -5
- package/docs/interfaces/types.DurationObject.html +2 -2
- package/docs/interfaces/types.EncryptOptions.html +2 -2
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
- package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
- package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
- package/docs/types/openapi.OpenapiAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiFormats.html +1 -1
- package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +2 -2
- package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +2 -2
- package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +2 -2
- package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
- package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
- package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
- package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaString.html +1 -1
- package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiTypeField.html +1 -1
- package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
- package/docs/types/types.CalendarDateDurationUnit.html +1 -1
- package/docs/types/types.CalendarDateObject.html +1 -1
- package/docs/types/types.Camelized.html +1 -1
- package/docs/types/types.ClockTimeObject.html +1 -1
- package/docs/types/types.DbConnectionType.html +1 -1
- package/docs/types/types.DbTypes.html +1 -1
- package/docs/types/types.DreamAssociationMetadata.html +1 -1
- package/docs/types/types.DreamAttributes.html +1 -1
- package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
- package/docs/types/types.DreamClassColumn.html +1 -1
- package/docs/types/types.DreamColumn.html +1 -1
- package/docs/types/types.DreamColumnNames.html +1 -1
- package/docs/types/types.DreamLogLevel.html +1 -1
- package/docs/types/types.DreamLogger.html +2 -2
- package/docs/types/types.DreamModelSerializerType.html +1 -1
- package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
- package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
- package/docs/types/types.DreamParamSafeAttributes.html +1 -1
- package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
- package/docs/types/types.DreamSerializable.html +1 -1
- package/docs/types/types.DreamSerializableArray.html +1 -1
- package/docs/types/types.DreamSerializerKey.html +1 -1
- package/docs/types/types.DreamSerializers.html +1 -1
- package/docs/types/types.DreamVirtualColumns.html +1 -1
- package/docs/types/types.DurationUnit.html +1 -1
- package/docs/types/types.EncryptAlgorithm.html +1 -1
- package/docs/types/types.HasManyStatement.html +1 -1
- package/docs/types/types.HasOneStatement.html +1 -1
- package/docs/types/types.Hyphenized.html +1 -1
- package/docs/types/types.Pascalized.html +1 -1
- package/docs/types/types.PrimaryKeyType.html +1 -1
- package/docs/types/types.RoundingPrecision.html +1 -1
- package/docs/types/types.SerializerCasing.html +1 -1
- package/docs/types/types.SimpleObjectSerializerType.html +1 -1
- package/docs/types/types.Snakeified.html +1 -1
- package/docs/types/types.StrictInterface.html +1 -1
- package/docs/types/types.UpdateableAssociationProperties.html +1 -1
- package/docs/types/types.UpdateableProperties.html +1 -1
- package/docs/types/types.ValidationType.html +1 -1
- package/docs/types/types.ViewModel.html +2 -2
- package/docs/types/types.ViewModelClass.html +1 -1
- package/docs/types/types.WeekdayName.html +1 -1
- package/docs/types/types.WhereStatementForDream.html +1 -1
- package/docs/types/types.WhereStatementForDreamClass.html +1 -1
- package/docs/variables/index.DreamConst.html +1 -1
- package/docs/variables/index.ops.html +1 -1
- package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
- package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
- package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
- package/docs/variables/system.primaryKeyTypes.html +1 -1
- package/package.json +4 -3
|
@@ -1660,10 +1660,10 @@ export default class Dream {
|
|
|
1660
1660
|
* // as: 'ratings',
|
|
1661
1661
|
* // polymorphic: true,
|
|
1662
1662
|
* // source: 'ratings',
|
|
1663
|
-
* //
|
|
1664
|
-
* //
|
|
1665
|
-
* //
|
|
1666
|
-
* //
|
|
1663
|
+
* // and: undefined,
|
|
1664
|
+
* // andNot: undefined,
|
|
1665
|
+
* // selfAnd: undefined,
|
|
1666
|
+
* // selfAndNot: undefined,
|
|
1667
1667
|
* // primaryKeyOverride: null,
|
|
1668
1668
|
* // primaryKey: [Function: primaryKey],
|
|
1669
1669
|
* // primaryKeyValue: [Function: primaryKeyValue],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Kysely } from 'kysely';
|
|
1
|
+
import { ColumnDataType, Kysely } from 'kysely';
|
|
2
2
|
export default class DreamMigrationHelpers {
|
|
3
3
|
/**
|
|
4
4
|
* Rename a table and its associated primary key index and sequence.
|
|
@@ -141,6 +141,95 @@ export default class DreamMigrationHelpers {
|
|
|
141
141
|
* @param __namedParameters.replacements - Details about which table and column to change and which value to replace the dropped value with (or remove it if the column is an array)
|
|
142
142
|
*/
|
|
143
143
|
static dropEnumValue(db: Kysely<any>, { enumName, value, replacements }: DropValueFromEnumOpts): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Convert an existing plaintext column into the encrypted-backed form expected by
|
|
146
|
+
* the `@Encrypted` decorator.
|
|
147
|
+
*
|
|
148
|
+
* This renames `column` to `encrypted_<column>`, widens it to `text`, and rewrites
|
|
149
|
+
* every non-null value with the AES-GCM ciphertext produced by the exact same code
|
|
150
|
+
* path the decorator's setter uses (`InternalEncrypt.encryptColumn`). After it runs,
|
|
151
|
+
* the column holds real ciphertext that the decorator's getter can decrypt — which is
|
|
152
|
+
* what a bare column rename does **not** do (renaming a plaintext column to
|
|
153
|
+
* `encrypted_<column>` and decorating the property leaves plaintext in the column, so
|
|
154
|
+
* the getter throws `DecryptionError`).
|
|
155
|
+
*
|
|
156
|
+
* The encryption key and algorithm come from the application's encryption config
|
|
157
|
+
* (`DreamApp` `encryption.columns.current`); if encryption is not configured this
|
|
158
|
+
* throws `MissingColumnEncryptionOpts`. Null values are left null.
|
|
159
|
+
*
|
|
160
|
+
* Intended for text/string columns (the common case is text -> encrypted text). The
|
|
161
|
+
* column is widened to `text` before reading, so values are encrypted as their text
|
|
162
|
+
* form; the inverse `decryptColumn` can restore a non-text type via its `columnType`
|
|
163
|
+
* option.
|
|
164
|
+
*
|
|
165
|
+
* ```ts
|
|
166
|
+
* // plaintext `phone` column -> encrypted `encrypted_phone` text column
|
|
167
|
+
* await DreamMigrationHelpers.encryptColumn(db, { table: 'users', column: 'phone' })
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* **Rewrites rows one at a time** (each value needs a fresh random IV computed in Node,
|
|
171
|
+
* so the rewrite cannot be a single SQL `UPDATE`), reading them in keyset batches of
|
|
172
|
+
* `batchSize` to bound memory. It still holds the table for the migration's duration; on
|
|
173
|
+
* very large tables do not use this helper — write your own batched / online migration.
|
|
174
|
+
*
|
|
175
|
+
* **Drop any index on the column first.** Per-row updates pay index-maintenance cost on
|
|
176
|
+
* every write, and an index over ciphertext is useless anyway (encrypted values are not
|
|
177
|
+
* queryable). Remove the index before this migration and do not re-add it.
|
|
178
|
+
*
|
|
179
|
+
* @param db - The Kysely database object passed into the migration up/down function
|
|
180
|
+
* @param options - Configuration options
|
|
181
|
+
* @param options.table - The name of the table
|
|
182
|
+
* @param options.column - The current (plaintext) column name
|
|
183
|
+
* @param options.encryptedColumnName - The target encrypted column name. Defaults to `encrypted_<column>`, matching the `@Encrypted` decorator's default; pass this when the decorator was given a custom encrypted column name.
|
|
184
|
+
* @param options.primaryKey - The primary key column used to keyset-paginate and target each row's update. Defaults to `id`.
|
|
185
|
+
* @param options.batchSize - How many rows to read per batch. Defaults to `1000`.
|
|
186
|
+
*/
|
|
187
|
+
static encryptColumn(db: Kysely<any>, { table, column, encryptedColumnName, primaryKey, batchSize, }: EncryptColumnOpts): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Inverse of {@link DreamMigrationHelpers.encryptColumn}: decrypt an
|
|
190
|
+
* `encrypted_<column>` column back to plaintext and rename it to `column`.
|
|
191
|
+
*
|
|
192
|
+
* Every non-null value is decrypted with the same path the decorator's getter uses
|
|
193
|
+
* (`InternalEncrypt.decryptColumn`, which honors both the `current` and `legacy`
|
|
194
|
+
* encryption keys), then the column is renamed back. Called with the same `table` and
|
|
195
|
+
* `column`, this exactly reverses `encryptColumn`.
|
|
196
|
+
*
|
|
197
|
+
* By default the column is left as `text`, because the original column type cannot be
|
|
198
|
+
* recovered from the encrypted state. Pass `columnType` to restore a specific type
|
|
199
|
+
* (e.g. `'integer'`); the conversion runs `ALTER COLUMN ... TYPE <columnType> USING
|
|
200
|
+
* <column>::<columnType>`.
|
|
201
|
+
*
|
|
202
|
+
* ```ts
|
|
203
|
+
* await DreamMigrationHelpers.decryptColumn(db, { table: 'users', column: 'phone' })
|
|
204
|
+
*
|
|
205
|
+
* // restore the original column type as part of the inverse
|
|
206
|
+
* await DreamMigrationHelpers.decryptColumn(db, { table: 'users', column: 'age', columnType: 'integer' })
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* The same per-row, batched, table-locking caveat as `encryptColumn` applies.
|
|
210
|
+
*
|
|
211
|
+
* @param db - The Kysely database object passed into the migration up/down function
|
|
212
|
+
* @param options - Configuration options
|
|
213
|
+
* @param options.table - The name of the table
|
|
214
|
+
* @param options.column - The target (plaintext) column name to rename back to
|
|
215
|
+
* @param options.encryptedColumnName - The current encrypted column name. Defaults to `encrypted_<column>`.
|
|
216
|
+
* @param options.primaryKey - The primary key column used to keyset-paginate and target each row's update. Defaults to `id`.
|
|
217
|
+
* @param options.batchSize - How many rows to read per batch. Defaults to `1000`.
|
|
218
|
+
* @param options.columnType - When provided, the restored column is converted to this type. When omitted, the column is left as `text`.
|
|
219
|
+
*/
|
|
220
|
+
static decryptColumn(db: Kysely<any>, { table, column, encryptedColumnName, primaryKey, batchSize, columnType, }: DecryptColumnOpts): Promise<void>;
|
|
221
|
+
/**
|
|
222
|
+
* Walk every non-null value of `column` in keyset batches of `batchSize`, applying
|
|
223
|
+
* `transform` in Node and writing the result back one row at a time. Keyset pagination
|
|
224
|
+
* on `primaryKey` (`WHERE pk > last ORDER BY pk`) bounds memory to a single batch and
|
|
225
|
+
* guarantees forward progress, so a row is never read — or transformed — twice (which
|
|
226
|
+
* matters because the transform is not idempotent: re-encrypting ciphertext would
|
|
227
|
+
* double-encrypt, and re-decrypting plaintext would throw).
|
|
228
|
+
*
|
|
229
|
+
* Reads alias the selected columns to fixed keys via `sql.ref(...).as(...)` so a
|
|
230
|
+
* `CamelCasePlugin` on the connection cannot rename the result keys.
|
|
231
|
+
*/
|
|
232
|
+
private static transformColumnInBatches;
|
|
144
233
|
}
|
|
145
234
|
interface DropValueFromEnumOpts {
|
|
146
235
|
enumName: string;
|
|
@@ -154,11 +243,11 @@ interface DropValueFromEnumTablesAndColumnsForArrayBase {
|
|
|
154
243
|
array: true;
|
|
155
244
|
}
|
|
156
245
|
interface DropValueWithRemovalFromEnumTablesAndColumnsForArray extends DropValueFromEnumTablesAndColumnsForArrayBase {
|
|
157
|
-
behavior: '
|
|
158
|
-
replaceWith: string;
|
|
246
|
+
behavior: 'remove';
|
|
159
247
|
}
|
|
160
248
|
interface DropValueWithReplacementFromEnumTablesAndColumnsForArray extends DropValueFromEnumTablesAndColumnsForArrayBase {
|
|
161
|
-
behavior: '
|
|
249
|
+
behavior: 'replace';
|
|
250
|
+
replaceWith: string;
|
|
162
251
|
}
|
|
163
252
|
type DropValueFromEnumTablesAndColumnsForNonArray = {
|
|
164
253
|
table: string;
|
|
@@ -169,4 +258,19 @@ interface AddValueToEnumOpts {
|
|
|
169
258
|
enumName: string;
|
|
170
259
|
value: string;
|
|
171
260
|
}
|
|
261
|
+
interface EncryptColumnOpts {
|
|
262
|
+
table: string;
|
|
263
|
+
column: string;
|
|
264
|
+
encryptedColumnName?: string;
|
|
265
|
+
primaryKey?: string;
|
|
266
|
+
batchSize?: number;
|
|
267
|
+
}
|
|
268
|
+
interface DecryptColumnOpts {
|
|
269
|
+
table: string;
|
|
270
|
+
column: string;
|
|
271
|
+
encryptedColumnName?: string;
|
|
272
|
+
primaryKey?: string;
|
|
273
|
+
batchSize?: number;
|
|
274
|
+
columnType?: ColumnDataType;
|
|
275
|
+
}
|
|
172
276
|
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type DreamApp from '../dream-app/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The number of databases in the pre-created pool (including the unsuffixed
|
|
4
|
+
* base at index 1). Shared by the CLI pool-creation / drop loops and the claim
|
|
5
|
+
* probe so they always agree on the index range.
|
|
6
|
+
*/
|
|
7
|
+
export declare function testDatabasePoolSize(parallelTests: number | undefined): number;
|
|
8
|
+
/**
|
|
9
|
+
* The database name for a pool index given the un-suffixed base name. Index 1
|
|
10
|
+
* is the base itself (no suffix); higher indexes are `<base>_<index>`. This is
|
|
11
|
+
* the single naming rule, used by both the claim path and the CLI loops.
|
|
12
|
+
*/
|
|
13
|
+
export declare function testDatabaseNameForIndex(baseName: string, index: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* Sync read of the already-claimed pool index, or null if no claim has
|
|
16
|
+
* completed yet in this process. `DreamApp.dbName()` (synchronous, called when
|
|
17
|
+
* Kysely builds a pool) relies on the claim having been awaited earlier in the
|
|
18
|
+
* worker — `DreamApp.init()` awaits {@link claimTestDatabase} before the first
|
|
19
|
+
* connection is built, and `truncate` awaits it too — so by the time any
|
|
20
|
+
* connection resolves its database name the index is populated.
|
|
21
|
+
*/
|
|
22
|
+
export declare function claimedTestDatabaseIndexOrNull(): number | null;
|
|
23
|
+
/**
|
|
24
|
+
* Claim a free pool database for this worker (idempotent). On first call it
|
|
25
|
+
* opens the default driver's dedicated lock session, probes
|
|
26
|
+
* {@link TestDatabaseLockSession.tryAcquire} across the pool indexes until one
|
|
27
|
+
* succeeds, and caches the claimed index for the rest of the process.
|
|
28
|
+
* Subsequent calls (and concurrent callers) return the same index.
|
|
29
|
+
*
|
|
30
|
+
* Throws a loud, actionable error if the pool is genuinely exhausted after the
|
|
31
|
+
* wait-for-free window — telling the reader to recreate the pool with
|
|
32
|
+
* `<packageManager> psy db:reset`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function claimTestDatabase(dreamApp: DreamApp): Promise<number>;
|
|
35
|
+
/**
|
|
36
|
+
* Test-only escape hatch for dream's own spec suite: release the claim and
|
|
37
|
+
* close the lock session so a test can exercise the claim machinery in
|
|
38
|
+
* isolation. Not part of the public API.
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export declare function __resetTestDatabaseClaimForSpec(): Promise<void>;
|
|
@@ -121,6 +121,30 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
|
|
|
121
121
|
*/
|
|
122
122
|
static setDatabaseTypeParsers(connectionName: string): Promise<void>;
|
|
123
123
|
static duplicateDatabase(connectionName: string): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* @internal
|
|
126
|
+
*
|
|
127
|
+
* Whether this driver implements the per-worker test-database claim seam
|
|
128
|
+
* ({@link openTestDatabaseLockSession}). Adapters that can hold a
|
|
129
|
+
* process-lifetime, auto-releasing lock to reserve one database from the
|
|
130
|
+
* test pool override this to `true`. It defaults to `false` so that a new
|
|
131
|
+
* adapter fails loud under vitest rather than silently sharing a single
|
|
132
|
+
* database across overlapping workers — see `src/db/testDatabasePool.ts`.
|
|
133
|
+
*/
|
|
134
|
+
static supportsParallelTestDatabases: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* @internal
|
|
137
|
+
*
|
|
138
|
+
* Open a dedicated, process-lifetime lock session used to claim one database
|
|
139
|
+
* from the per-worker test pool. Only ever called when
|
|
140
|
+
* {@link supportsParallelTestDatabases} is `true`; the base default throws.
|
|
141
|
+
*
|
|
142
|
+
* The returned session wraps a single dedicated connection: the orchestrator
|
|
143
|
+
* (`src/db/testDatabasePool.ts`) probes many pool indexes on the one session
|
|
144
|
+
* via `tryAcquire` and keeps whichever it acquires, holding it for the
|
|
145
|
+
* worker's lifetime.
|
|
146
|
+
*/
|
|
147
|
+
static openTestDatabaseLockSession(connectionName: string): Promise<TestDatabaseLockSession>;
|
|
124
148
|
static getColumnData(connectionName: string, tableName: string, allTableAssociationData: {
|
|
125
149
|
[key: string]: SchemaBuilderAssociationData;
|
|
126
150
|
}): Promise<{
|
|
@@ -327,3 +351,26 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
|
|
|
327
351
|
hydratePreload(this: QueryDriverBase<DreamInstance>, dream: Dream): Promise<void>;
|
|
328
352
|
}
|
|
329
353
|
export type GenericDbType = 'datetime' | 'date';
|
|
354
|
+
/**
|
|
355
|
+
* One dedicated lock session backing the per-worker test-database claim. The
|
|
356
|
+
* orchestrator (`src/db/testDatabasePool.ts`) opens one session per worker,
|
|
357
|
+
* probes pool indexes with {@link tryAcquire}, and keeps the first index it
|
|
358
|
+
* wins for the worker's lifetime.
|
|
359
|
+
*
|
|
360
|
+
* The session intentionally carries no adapter-specific lock-key type:
|
|
361
|
+
* `tryAcquire` takes a semantic `(namespace, index)` pair and each driver maps
|
|
362
|
+
* it to its own primitive (Postgres `pg_try_advisory_lock(int4, int4)`, MySQL
|
|
363
|
+
* `GET_LOCK`), so no Postgres int-pair leaks into the shared contract.
|
|
364
|
+
*/
|
|
365
|
+
export interface TestDatabaseLockSession {
|
|
366
|
+
/**
|
|
367
|
+
* Try to acquire the lock for `(namespace, index)` without blocking. Returns
|
|
368
|
+
* `true` if this session now holds it, `false` if another live session does.
|
|
369
|
+
* Must not wait — the orchestrator drives its own probe / wait-for-free loop.
|
|
370
|
+
*/
|
|
371
|
+
tryAcquire(namespace: string, index: number): Promise<boolean>;
|
|
372
|
+
/**
|
|
373
|
+
* Close the underlying connection, releasing any lock it holds.
|
|
374
|
+
*/
|
|
375
|
+
release(): Promise<void>;
|
|
376
|
+
}
|
|
@@ -362,6 +362,17 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
|
|
|
362
362
|
* @returns A string
|
|
363
363
|
*/
|
|
364
364
|
private namespaceColumn;
|
|
365
|
+
/**
|
|
366
|
+
* @internal
|
|
367
|
+
*
|
|
368
|
+
* Builds the table expression passed to Kysely's `innerJoin`/`leftJoin` for an
|
|
369
|
+
* association. When the alias already snakeifies to the table name, Kysely's
|
|
370
|
+
* CamelCasePlugin emits the correct identifier from the alias alone, so no
|
|
371
|
+
* explicit `as` clause is needed; otherwise we join the table aliased as `alias`.
|
|
372
|
+
*
|
|
373
|
+
* @returns A table expression string, e.g. `"beautiful_balloons as balloon"`
|
|
374
|
+
*/
|
|
375
|
+
private aliasedJoinTableExpression;
|
|
365
376
|
private checkForQueryViolations;
|
|
366
377
|
private similarityStatementBuilder;
|
|
367
378
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Dream from '../../Dream.js';
|
|
2
2
|
import { SchemaBuilderAssociationData, SchemaBuilderColumnData } from '../../helpers/cli/ASTBuilder.js';
|
|
3
3
|
import KyselyQueryDriver from './Kysely.js';
|
|
4
|
+
import type { TestDatabaseLockSession } from './Base.js';
|
|
4
5
|
export default class PostgresQueryDriver<DreamInstance extends Dream> extends KyselyQueryDriver<DreamInstance> {
|
|
5
6
|
/**
|
|
6
7
|
* create the database. Must respond to the NODE_ENV value.
|
|
@@ -33,4 +34,22 @@ export default class PostgresQueryDriver<DreamInstance extends Dream> extends Ky
|
|
|
33
34
|
[key: string]: SchemaBuilderColumnData;
|
|
34
35
|
}>;
|
|
35
36
|
static duplicateDatabase(connectionName: string): Promise<void>;
|
|
37
|
+
static supportsParallelTestDatabases: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*
|
|
41
|
+
* Postgres implementation of the per-worker test-database claim seam (see
|
|
42
|
+
* {@link TestDatabaseLockSession} and `src/db/testDatabasePool.ts`).
|
|
43
|
+
*
|
|
44
|
+
* Postgres advisory locks are global to the cluster (not scoped to a single
|
|
45
|
+
* database), so one dedicated connection — to the `postgres` maintenance
|
|
46
|
+
* database — can reserve a pool index for the whole cluster. We use the
|
|
47
|
+
* two-`int4` form `pg_try_advisory_lock(key1, key2)`, whose lock space is
|
|
48
|
+
* distinct from the single-`bigint` form `pg_advisory_lock(bigint)` that
|
|
49
|
+
* application code typically uses, so a claim can never clash with an
|
|
50
|
+
* app-level advisory lock. `key1` folds a hash of the lock namespace (the
|
|
51
|
+
* base database name) into a fixed dream-pool constant; `key2` is the pool
|
|
52
|
+
* index. The lock auto-releases when the connection drops on process exit.
|
|
53
|
+
*/
|
|
54
|
+
static openTestDatabaseLockSession(connectionName: string): Promise<TestDatabaseLockSession>;
|
|
36
55
|
}
|
|
@@ -148,12 +148,75 @@ export default class DreamApp {
|
|
|
148
148
|
constructor(opts?: Partial<DreamAppOpts>);
|
|
149
149
|
get models(): Record<string, typeof Dream>;
|
|
150
150
|
get serializers(): Record<string, DreamModelSerializerType | SimpleObjectSerializerType>;
|
|
151
|
+
/**
|
|
152
|
+
* The database name to connect to for a given connection. In dev/prod this is
|
|
153
|
+
* simply the configured name. Under vitest (test env) it is the per-worker
|
|
154
|
+
* database claimed from the pool — see {@link testDatabaseClaimEnabled} and
|
|
155
|
+
* `src/db/testDatabasePool.ts`.
|
|
156
|
+
*
|
|
157
|
+
* This is synchronous because Kysely builds its `pg.Pool` synchronously. It
|
|
158
|
+
* reads the already-claimed pool index; the claim is awaited earlier in the
|
|
159
|
+
* worker — `DreamApp.init()` calls {@link claimTestDatabase} before the first
|
|
160
|
+
* connection is built, and `dream-spec-helpers`' `truncate` awaits
|
|
161
|
+
* {@link testDatabaseName} — so the index is always populated by the time any
|
|
162
|
+
* connection resolves its name.
|
|
163
|
+
*/
|
|
151
164
|
dbName(connectionName: string, connection: DbConnectionType): string;
|
|
165
|
+
/**
|
|
166
|
+
* Single source of truth for the claimed test-database name, used both by
|
|
167
|
+
* dream's connection resolution and by `dream-spec-helpers`' `truncate`
|
|
168
|
+
* (which opens its own `pg.Client` and so must read — not recompute — the
|
|
169
|
+
* claim). Awaits the pool claim if it has not happened yet in this worker.
|
|
170
|
+
*/
|
|
171
|
+
testDatabaseName(connectionName: string, connection: DbConnectionType): Promise<string>;
|
|
172
|
+
/**
|
|
173
|
+
* Claim this worker's pool database if it hasn't been claimed yet. Idempotent
|
|
174
|
+
* and a no-op outside the test-under-vitest path. Called by `DreamApp.init()`
|
|
175
|
+
* before any connection is built so the synchronous {@link dbName} always
|
|
176
|
+
* sees a populated index.
|
|
177
|
+
*/
|
|
178
|
+
ensureTestDatabaseClaimed(): Promise<void>;
|
|
152
179
|
dbConnectionConfig(connectionName: string, connection: DbConnectionType): DreamDbConfig;
|
|
153
180
|
dbConnectionQueryDriverClass<T extends Dream = Dream>(connectionName: string): typeof QueryDriverBase<T>;
|
|
154
181
|
dbConnectionKeys(): string[];
|
|
155
182
|
hasReplicaConfig(connectionName: string): boolean;
|
|
156
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Whether the runtime *requires* a per-worker test-database claim. Gated on
|
|
185
|
+
* test env *under vitest* (not on `parallelTests > 1`): the slot-reuse
|
|
186
|
+
* collision reproduces even serially, because vitest respawns a process per
|
|
187
|
+
* file and the lingering process overlaps the new one on the same database.
|
|
188
|
+
* CLI db tasks (`db:migrate`, `db:reset`, …) do not run under vitest, so they
|
|
189
|
+
* keep the unsuffixed name and operate on the whole pool explicitly.
|
|
190
|
+
*
|
|
191
|
+
* This is independent of whether the default driver can actually claim — when
|
|
192
|
+
* the need is present but the capability is absent, the claim path fails loud
|
|
193
|
+
* (see {@link requireTestDatabaseClaimSupport}) rather than silently sharing
|
|
194
|
+
* one database.
|
|
195
|
+
*/
|
|
196
|
+
get runtimeNeedsTestDatabaseClaim(): boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Whether the default connection's query driver implements the per-worker
|
|
199
|
+
* test-database claim seam (`openTestDatabaseLockSession`). The claim is keyed
|
|
200
|
+
* off the **default** connection's capability so a Postgres-default app with a
|
|
201
|
+
* MySQL secondary keeps working (the secondary borrows the Postgres-claimed
|
|
202
|
+
* index for its database name).
|
|
203
|
+
*/
|
|
204
|
+
private get defaultConnectionSupportsParallelTestDatabases();
|
|
205
|
+
/**
|
|
206
|
+
* Whether the per-worker test-database pool claim is active: needed by the
|
|
207
|
+
* runtime *and* supported by the default connection's driver. Consumers that
|
|
208
|
+
* key behavior off the claimed index (connection-cache suffixing) use this;
|
|
209
|
+
* the claim entry points additionally fail loud when the need is present but
|
|
210
|
+
* support is absent.
|
|
211
|
+
*/
|
|
212
|
+
get testDatabaseClaimEnabled(): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Throw an actionable error when the runtime needs a per-worker test-database
|
|
215
|
+
* claim but the default connection's driver cannot provide one — rather than
|
|
216
|
+
* silently sharing a single database across overlapping vitest workers (which
|
|
217
|
+
* reintroduces the flake this whole mechanism exists to fix).
|
|
218
|
+
*/
|
|
219
|
+
private requireTestDatabaseClaimSupport;
|
|
157
220
|
load<RT extends 'models' | 'serializers'>(resourceType: RT, resourcePath: string, importCb: (path: string) => Promise<any>): Promise<void>;
|
|
158
221
|
plugin(cb: (app: DreamApp) => void | Promise<void>): void;
|
|
159
222
|
set<ApplyOpt extends DreamAppSetOption>(applyOption: ApplyOpt, options: ApplyOpt extends 'bypassDeprecationChecks' ? boolean : ApplyOpt extends 'db' ? DreamDbCredentialOptions | string : ApplyOpt extends 'encryption' ? DreamAppEncryptionOptions : ApplyOpt extends 'primaryKeyType' ? LegacyCompatiblePrimaryKeyType : ApplyOpt extends 'importExtension' ? GeneratorImportStyle : ApplyOpt extends 'logger' ? DreamLogger : ApplyOpt extends 'projectRoot' ? string : ApplyOpt extends 'inflections' ? () => void | Promise<void> : ApplyOpt extends 'packageManager' ? DreamAppAllowedPackageManagersEnum : ApplyOpt extends 'paths' ? DreamDirectoryPaths : ApplyOpt extends 'parallelTests' ? number : ApplyOpt extends 'unicodeNormalization' ? UnicodeNormalizationForm : ApplyOpt extends 'paginationPageSize' ? number : never, secondaryOptions?: ApplyOpt extends 'db' ? DreamDbCredentialOptions : never): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Performs a deep equality check between two values, supporting primitives, arrays,
|
|
3
|
-
* Dream instances, CalendarDate, DateTime, and objects.
|
|
3
|
+
* Dream instances, CalendarDate, DateTime, ClockTime, ClockTimeTz, and objects.
|
|
4
4
|
*
|
|
5
5
|
* Examples:
|
|
6
6
|
* areEqual(undefined, undefined) // true
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import CalendarDate from '../utils/datetime/CalendarDate.js';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type CalendarDate from '../utils/datetime/CalendarDate.js';
|
|
2
|
+
import type ClockTime from '../utils/datetime/ClockTime.js';
|
|
3
|
+
import type ClockTimeTz from '../utils/datetime/ClockTimeTz.js';
|
|
4
|
+
import type { DateTime } from '../utils/datetime/DateTime.js';
|
|
5
|
+
type RangeEndType<T> = T extends null ? any : T extends DateTime | CalendarDate ? DateTime | CalendarDate : T extends ClockTime ? ClockTime : T extends ClockTimeTz ? ClockTimeTz : T;
|
|
6
|
+
export default function range<T, U extends RangeEndType<T>>(begin: T, end?: U | null, excludeEnd?: boolean): Range<T, U>;
|
|
7
|
+
export declare class Range<T, U extends RangeEndType<T> = RangeEndType<T>> {
|
|
5
8
|
readonly begin: T | null;
|
|
6
9
|
readonly end: U | null;
|
|
7
10
|
readonly excludeEnd: boolean;
|
|
8
11
|
constructor(begin: T | null, end?: U | null, excludeEnd?: boolean);
|
|
9
12
|
}
|
|
13
|
+
export {};
|
|
@@ -23,7 +23,7 @@ export type VariadicJoinsArgs<I extends Dream, DB, Schema, ConcreteTableName ext
|
|
|
23
23
|
type VariadicCheckThenRecurse<I extends Dream, DB, Schema, ConcreteTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, ConcreteArgs extends readonly unknown[], RecursionType extends RecursionTypes, UsedNamespaces, Depth extends number, PreviousConcreteTableName, ConcreteAssociationName, AssociationNamesOrOnClause, LastDream extends Dream = I, SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]], AllowedNamesForArrayArg = PreviousConcreteTableName extends keyof Schema ? AssociationNamesForAssociation<Schema, PreviousConcreteTableName, ConcreteAssociationName> : keyof SchemaAssociations & string, NthArgument extends VALID | INVALID = ConcreteArgs['length'] extends 0 ? VALID : ConcreteArgs[0] extends keyof SchemaAssociations & string ? VALID : ConcreteArgs[0] extends AliasedSchemaAssociation<Schema, ConcreteTableName> ? VALID : ConcreteArgs[0] extends JoinAndStatements<LastDream, DB, Schema, ConcreteTableName, RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>> ? VALID : ConcreteArgs[0] extends readonly AllowedNamesForArrayArg[] ? VALID : ConcreteArgs[0] extends JoinAndStatements<LastDream, DB, Schema, ConcreteTableName, RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>> ? VALID : ConcreteArgs[0] extends AllowedNamesForArrayArg ? VALID : INVALID> = NthArgument extends INVALID ? `invalid where clause in argument ${Inc<Depth>}` : ConcreteArgs['length'] extends 0 ? AssociationNamesOrOnClause : VariadicRecurse<I, DB, Schema, ConcreteTableName, ConcreteArgs, RecursionType, UsedNamespaces, Depth, PreviousConcreteTableName, ConcreteAssociationName, LastDream>;
|
|
24
24
|
export type AliasedSchemaAssociation<Schema, ConcreteTableName extends keyof Schema, SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]]> = `${keyof SchemaAssociations & string} as ${string}`;
|
|
25
25
|
type VariadicRecurse<I extends Dream, DB, Schema, ConcreteTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, ConcreteArgs extends readonly unknown[], RecursionType extends RecursionTypes, UsedNamespaces, Depth extends number, PreviousConcreteTableName, ConcreteAssociationName, LastDream extends Dream, SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]], PolymorphicTableNamesUnion = PreviousConcreteTableName extends keyof Schema ? AssociationTableNamesForAssociation<Schema, PreviousConcreteTableName, ConcreteAssociationName> : ConcreteTableName, CrossPolymorphicTableForCurrentArg = ConcreteArgs[0] extends string ? TableContainingAssociationInUnion<Schema, PolymorphicTableNamesUnion, ConcreteArgs[0]> : never, EffectiveConcreteTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB = ConcreteArgs[0] extends keyof SchemaAssociations & string ? ConcreteTableName : [CrossPolymorphicTableForCurrentArg] extends [never] ? ConcreteTableName : CrossPolymorphicTableForCurrentArg extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB ? CrossPolymorphicTableForCurrentArg : ConcreteTableName, EffectiveSchemaAssociations = Schema[EffectiveConcreteTableName]['associations' & keyof Schema[EffectiveConcreteTableName]], ConcreteNthArg extends (keyof SchemaAssociations & string) | (keyof EffectiveSchemaAssociations & string) | AliasedSchemaAssociation<Schema, ConcreteTableName> | null = ConcreteArgs[0] extends undefined ? null : ConcreteArgs[0] extends null ? null : ConcreteArgs[0] extends keyof SchemaAssociations & string ? ConcreteArgs[0] & keyof SchemaAssociations & string : ConcreteArgs[0] extends AliasedSchemaAssociation<Schema, ConcreteTableName> ? ConcreteArgs[0] & AliasedSchemaAssociation<Schema, ConcreteTableName> : ConcreteArgs[0] extends keyof EffectiveSchemaAssociations & string ? ConcreteArgs[0] & keyof EffectiveSchemaAssociations & string : null, NextUsedNamespaces = ConcreteArgs[0] extends undefined ? never : ConcreteArgs[0] extends null ? never : ConcreteNthArg extends null ? UsedNamespaces : UsedNamespaces | ConcreteNthArg, CurrentArgumentType extends IS_ASSOCIATION_NAME | IS_ASSOCIATION_ALIAS | IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME | IS_NOT_ASSOCIATION_NAME = ConcreteNthArg extends null ? IS_NOT_ASSOCIATION_NAME : ConcreteNthArg extends keyof SchemaAssociations & string ? IS_ASSOCIATION_NAME : ConcreteNthArg extends AliasedSchemaAssociation<Schema, ConcreteTableName> ? IS_ASSOCIATION_ALIAS : ConcreteNthArg extends keyof EffectiveSchemaAssociations & string ? IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME : IS_NOT_ASSOCIATION_NAME, NextPreviousConcreteTableName = CurrentArgumentType extends IS_ASSOCIATION_NAME ? ConcreteTableName : CurrentArgumentType extends IS_ASSOCIATION_ALIAS ? ConcreteTableName : CurrentArgumentType extends IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME ? EffectiveConcreteTableName : PreviousConcreteTableName, NextUnaliasedAssociationName = CurrentArgumentType extends IS_ASSOCIATION_NAME ? ConcreteNthArg : CurrentArgumentType extends IS_ASSOCIATION_ALIAS ? ConcreteNthArg extends `${infer AssocName extends string} as ${string}` ? AssocName & keyof SchemaAssociations & string : never : CurrentArgumentType extends IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME ? ConcreteNthArg : never, NextAliasedAssociationName = CurrentArgumentType extends IS_ASSOCIATION_NAME ? ConcreteNthArg : CurrentArgumentType extends IS_ASSOCIATION_ALIAS ? ConcreteNthArg extends `${string} as ${infer AssocAlias extends string}` ? AssocAlias & string : ConcreteAssociationName : CurrentArgumentType extends IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME ? ConcreteNthArg : ConcreteAssociationName, IsAssociationNameOrAlias extends boolean = CurrentArgumentType extends IS_ASSOCIATION_NAME | IS_ASSOCIATION_ALIAS | IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME ? true : false, NextTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB = IsAssociationNameOrAlias extends true ? AssociationTableName<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName> : ConcreteTableName & AssociationTableNames<DB, Schema> & keyof DB, AllowedAssociationNames = IsAssociationNameOrAlias extends true ? AssociationNamesForAssociation<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName> : PreviousConcreteTableName extends keyof Schema ? AssociationNamesForAssociation<Schema, PreviousConcreteTableName, ConcreteAssociationName> : AssociationNamesForTable<Schema, ConcreteTableName>, // fall back to association names for table for root only
|
|
26
|
-
AssociationTableOrConcreteTable extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB = IsAssociationNameOrAlias extends true ? AssociationTableName<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName> : ConcreteTableName, CurrentRequiredOnClauseKeys = IsAssociationNameOrAlias extends true ? RequiredOnClauseKeys<Schema, EffectiveConcreteTableName,
|
|
26
|
+
AssociationTableOrConcreteTable extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB = IsAssociationNameOrAlias extends true ? AssociationTableName<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName> : ConcreteTableName, CurrentRequiredOnClauseKeys = IsAssociationNameOrAlias extends true ? RequiredOnClauseKeys<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName> : RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>, AllowedNextArgValues = RecursionType extends 'load' ? AllowedNextArgValuesForLoad<DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>, DB, Schema, AllowedAssociationNames, AssociationTableOrConcreteTable, CurrentRequiredOnClauseKeys> : RecursionType extends 'leftJoinLoad' ? AllowedNextArgValuesForLeftJoinLoad<DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>, DB, Schema, AllowedAssociationNames, AssociationTableOrConcreteTable, CurrentRequiredOnClauseKeys, NextUsedNamespaces> : RecursionType extends 'join' ? AllowedNextArgValuesForJoin<DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>, DB, Schema, AllowedAssociationNames, AssociationTableOrConcreteTable, CurrentRequiredOnClauseKeys, NextUsedNamespaces> : never> = Depth extends MAX_VARIADIC_DEPTH ? never : VariadicCheckThenRecurse<I, DB, Schema, NextTableName, ReadonlyTail<ConcreteArgs>, RecursionType, NextUsedNamespaces, Inc<Depth>, NextPreviousConcreteTableName, NextAliasedAssociationName, AllowedNextArgValues, DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream> extends Dream ? DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream> : LastDream>;
|
|
27
27
|
type AllowedNextArgValuesForLoad<I extends Dream, DB, Schema, AllowedNames, TableForJoin extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation> = AllowedNames | AllowedNames[] | JoinAndStatements<I, DB, Schema, TableForJoin, RequiredOnClauseKeysForThisAssociation>;
|
|
28
28
|
type AllowedNextArgValuesForLeftJoinLoad<I extends Dream, DB, Schema, AllowedNames, TableForJoin extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation, UsedNamespaces> = Exclude<AllowedNames, UsedNamespaces> | Exclude<AllowedNames, UsedNamespaces>[] | JoinAndStatements<I, DB, Schema, TableForJoin, RequiredOnClauseKeysForThisAssociation>;
|
|
29
29
|
type AllowedNextArgValuesForJoin<I extends Dream, DB, Schema, AllowedNames, TableForJoin extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation, UsedNamespaces> = Exclude<AllowedNames, UsedNamespaces> | JoinAndStatements<I, DB, Schema, TableForJoin, RequiredOnClauseKeysForThisAssociation>;
|
|
@@ -341,7 +341,7 @@ type VariadicRecurse<
|
|
|
341
341
|
: ConcreteTableName,
|
|
342
342
|
//
|
|
343
343
|
CurrentRequiredOnClauseKeys = IsAssociationNameOrAlias extends true
|
|
344
|
-
? RequiredOnClauseKeys<Schema, EffectiveConcreteTableName,
|
|
344
|
+
? RequiredOnClauseKeys<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName>
|
|
345
345
|
: RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>,
|
|
346
346
|
//
|
|
347
347
|
AllowedNextArgValues = RecursionType extends 'load'
|
package/docs/assets/hierarchy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
window.hierarchyData = "
|
|
1
|
+
window.hierarchyData = "eJyVksFOAyEQht9lzlgLtmTL0TYmxlg1MXpoeqC7U5eUhQbYmk3TdzfYC9bq0hOEzM/3McwenLXBg1hQzimhlC4JOFxrLIOyxoPYA6U0LkY2CAJeWnTdzKkdulvpEQhslKlAUFYQaJ0GAaWW3qO/rlaDk+pBHRoN5FgBAoKvrmL86nhAoKyVrhwaEAvG2fJAgHGW0B86j7pLbu3h/6q/xICOhjQqxDVxeLY+fDj0+RZnEj0ekcrZOKFOayw3U2t8cFKZ8KaslvGL/kOjc9b5wV/RHIfRTepgdduYpx26tbafOeQfgRweTzs9k0Hem9I2WxnUSuO7CnU8W0mPdwp1laHQe8dFE8HZmMSmEMqLIaF8UnwPCC+GJ9qv3RaPr4+7R+UbGco60/d8OKd9kyLxmNswb7W+ZFROI33Mw+ELlqZu/Q=="
|