@rvoh/dream 2.21.1 → 2.23.0
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 +71 -23
- package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +3 -0
- package/dist/cjs/src/dream/Query.js +242 -12
- package/dist/cjs/src/dream/QueryDriver/Base.js +26 -0
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +46 -4
- package/dist/cjs/src/dream/QueryDriver/Postgres.js +21 -0
- package/dist/cjs/src/dream/internal/buildSerializerPreloadPaths.js +93 -20
- package/dist/cjs/src/dream/internal/convertDreamClassAndAssociationNameTupleArrayToPreloadArgs.js +18 -10
- package/dist/cjs/src/dream/internal/destroyAssociatedRecords.js +76 -4
- package/dist/cjs/src/dream/internal/destroyDream.js +6 -7
- package/dist/cjs/src/dream/internal/mergeSerializerAssociationEdges.js +75 -0
- package/dist/cjs/src/dream/internal/printSerializerHierarchyLevel.js +50 -8
- package/dist/cjs/src/dream/internal/resolveSerializerAssociationEdges.js +79 -14
- package/dist/cjs/src/errors/InvalidBatchSize.js +19 -0
- package/dist/cjs/src/errors/RowLockIncompatibleWithDistinct.js +14 -0
- package/dist/cjs/src/errors/RowLockIncompatibleWithJoinLoad.js +14 -0
- package/dist/cjs/src/errors/ops/ArrayEqualityRequiresArrayColumn.js +23 -0
- package/dist/cjs/src/errors/serializers/NoSerializersResolvedForKey.js +30 -0
- package/dist/cjs/src/ops/index.js +19 -0
- package/dist/cjs/src/serializer/helpers/inferSerializerFromDreamOrViewModel.js +22 -0
- package/dist/cjs/src/serializer/helpers/serializerForAssociatedClass.js +13 -0
- package/dist/esm/src/Dream.js +71 -23
- package/dist/esm/src/dream/DreamClassTransactionBuilder.js +3 -0
- package/dist/esm/src/dream/Query.js +242 -12
- package/dist/esm/src/dream/QueryDriver/Base.js +26 -0
- package/dist/esm/src/dream/QueryDriver/Kysely.js +46 -4
- package/dist/esm/src/dream/QueryDriver/Postgres.js +21 -0
- package/dist/esm/src/dream/internal/buildSerializerPreloadPaths.js +93 -20
- package/dist/esm/src/dream/internal/convertDreamClassAndAssociationNameTupleArrayToPreloadArgs.js +18 -10
- package/dist/esm/src/dream/internal/destroyAssociatedRecords.js +76 -4
- package/dist/esm/src/dream/internal/destroyDream.js +6 -7
- package/dist/esm/src/dream/internal/mergeSerializerAssociationEdges.js +75 -0
- package/dist/esm/src/dream/internal/printSerializerHierarchyLevel.js +50 -8
- package/dist/esm/src/dream/internal/resolveSerializerAssociationEdges.js +79 -14
- package/dist/esm/src/errors/InvalidBatchSize.js +19 -0
- package/dist/esm/src/errors/RowLockIncompatibleWithDistinct.js +14 -0
- package/dist/esm/src/errors/RowLockIncompatibleWithJoinLoad.js +14 -0
- package/dist/esm/src/errors/ops/ArrayEqualityRequiresArrayColumn.js +23 -0
- package/dist/esm/src/errors/serializers/NoSerializersResolvedForKey.js +30 -0
- package/dist/esm/src/ops/index.js +19 -0
- package/dist/esm/src/serializer/helpers/inferSerializerFromDreamOrViewModel.js +22 -0
- package/dist/esm/src/serializer/helpers/serializerForAssociatedClass.js +13 -0
- package/dist/types/src/Dream.d.ts +12 -0
- package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +3 -0
- package/dist/types/src/dream/Query.d.ts +150 -3
- package/dist/types/src/dream/QueryDriver/Base.d.ts +21 -0
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +1 -0
- package/dist/types/src/dream/QueryDriver/Postgres.d.ts +20 -0
- package/dist/types/src/dream/internal/destroyAssociatedRecords.d.ts +22 -3
- package/dist/types/src/dream/internal/mergeSerializerAssociationEdges.d.ts +69 -0
- package/dist/types/src/dream/internal/printSerializerHierarchyLevel.d.ts +23 -5
- package/dist/types/src/dream/internal/resolveSerializerAssociationEdges.d.ts +27 -1
- package/dist/types/src/errors/InvalidBatchSize.d.ts +5 -0
- package/dist/types/src/errors/RowLockIncompatibleWithDistinct.d.ts +3 -0
- package/dist/types/src/errors/RowLockIncompatibleWithJoinLoad.d.ts +3 -0
- package/dist/types/src/errors/ops/ArrayEqualityRequiresArrayColumn.d.ts +8 -0
- package/dist/types/src/errors/serializers/NoSerializersResolvedForKey.d.ts +18 -0
- package/dist/types/src/ops/index.d.ts +19 -0
- package/dist/types/src/serializer/helpers/inferSerializerFromDreamOrViewModel.d.ts +16 -0
- package/dist/types/src/types/associations/shared.d.ts +2 -2
- package/dist/types/src/types/dream.d.ts +8 -0
- package/dist/types/src/types/types/associations/shared.ts +84 -55
- package/dist/types/src/types/types/dream.ts +30 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/db.DreamMigrationHelpers.html +11 -11
- package/docs/classes/db.KyselyQueryDriver.html +55 -41
- package/docs/classes/db.PostgresQueryDriver.html +55 -42
- package/docs/classes/db.QueryDriverBase.html +54 -40
- 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 +127 -125
- package/docs/classes/index.DreamApp.html +10 -10
- package/docs/classes/index.DreamTransaction.html +2 -2
- package/docs/classes/index.Env.html +2 -2
- package/docs/classes/index.Query.html +161 -71
- 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 +38 -23
- 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 +1 -1
|
@@ -7,8 +7,27 @@ import { ReallyDestroyOptions } from './destroyDream.js';
|
|
|
7
7
|
* Destroys all HasOne/HasMany associations on this
|
|
8
8
|
* dream that are marked as `dependent: 'destroy'`.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The whole dependent-destroy tree is loaded ONCE, at the root of the destroy
|
|
11
|
+
* operation, by `loadDependentDestroyTree`. Descendants reached by recursing
|
|
12
|
+
* through this function consume those already-hydrated associations rather
|
|
13
|
+
* than re-querying their own subtrees.
|
|
14
|
+
*
|
|
15
|
+
* A load still happens here when an association is not hydrated. That covers
|
|
16
|
+
* two cases:
|
|
17
|
+
*
|
|
18
|
+
* 1. the root of the operation, whose associations have not been loaded yet
|
|
19
|
+
* 2. a node past `RECURSIVE_DESTROY_PRELOAD_MAX_REPEATS` levels of
|
|
20
|
+
* self-reference, which the root's preload could not reach
|
|
21
|
+
*
|
|
22
|
+
* The second case is why the check is per-association-hydration rather than a
|
|
23
|
+
* "descendants are already loaded" flag: such a flag would truncate cascades
|
|
24
|
+
* deeper than the preload horizon.
|
|
25
|
+
*
|
|
26
|
+
* NOTE: reusing a hydrated subtree is only sound because the same `options`
|
|
27
|
+
* are forwarded unchanged all the way down the cascade (see the recursive
|
|
28
|
+
* `destroy`/`reallyDestroy` calls below), so every node's associations were
|
|
29
|
+
* loaded under the scopes this node would have used. Nothing in the types
|
|
30
|
+
* enforces that; if `options` ever start varying by depth, this reuse has to
|
|
31
|
+
* be revisited.
|
|
13
32
|
*/
|
|
14
33
|
export default function destroyAssociatedRecords<I extends Dream>(dream: I, txn: DreamTransaction<I>, options: ReallyDestroyOptions<I>): Promise<void>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Dream from '../../Dream.js';
|
|
2
|
+
import { SerializerType } from '../../types/serializer.js';
|
|
3
|
+
import { ResolvedSerializerAssociationEdge } from './resolveSerializerAssociationEdges.js';
|
|
4
|
+
/**
|
|
5
|
+
* One contributing serializer's view of a merged target: the serializer that renders the target
|
|
6
|
+
* through this association, together with how it renders it. The edge type and the serializer-side
|
|
7
|
+
* association name belong here rather than on the target because they vary per contributing
|
|
8
|
+
* serializer — two children of an STI base can reach the same target class through the same
|
|
9
|
+
* association under different names or different edge types.
|
|
10
|
+
*/
|
|
11
|
+
export interface MergedSerializerAssociationTargetSerializer {
|
|
12
|
+
serializer: SerializerType;
|
|
13
|
+
type: ResolvedSerializerAssociationEdge['type'];
|
|
14
|
+
serializerAssociationName: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MergedSerializerAssociationTarget {
|
|
17
|
+
dreamClass: typeof Dream;
|
|
18
|
+
/**
|
|
19
|
+
* Every serializer that renders this target through this association, deduped by serializer
|
|
20
|
+
* identity. More than one when the target is itself an STI base (one serializer per child).
|
|
21
|
+
*/
|
|
22
|
+
serializers: MergedSerializerAssociationTargetSerializer[];
|
|
23
|
+
}
|
|
24
|
+
export interface MergedSerializerAssociationEdge {
|
|
25
|
+
associationAs: string;
|
|
26
|
+
/**
|
|
27
|
+
* true when at least one contributing serializer terminates this association — a
|
|
28
|
+
* delegatedAttribute (which always carries `targets: []`), or a rendersOne/rendersMany resolving
|
|
29
|
+
* to no serializer.
|
|
30
|
+
*
|
|
31
|
+
* Independent of `targets`: an association one child terminates and another descends into (as
|
|
32
|
+
* Balloon's `stiUnion` key does with `balloonLine`) is both terminating and targeted. The preload
|
|
33
|
+
* walk emits a leaf path for the terminating side; the display walk ignores it, since a
|
|
34
|
+
* terminated association prints nothing of its own.
|
|
35
|
+
*/
|
|
36
|
+
terminates: boolean;
|
|
37
|
+
targets: MergedSerializerAssociationTarget[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* @internal
|
|
41
|
+
*
|
|
42
|
+
* Resolves the association edges of *every* serializer that can render `dreamClass` at this point
|
|
43
|
+
* in a serialization walk and merges them into one set, so that a walk rooted at an STI base sees
|
|
44
|
+
* the union across its children's serializers rather than one child's view of the class.
|
|
45
|
+
*
|
|
46
|
+
* The merge is keyed on (association, target class), so:
|
|
47
|
+
*
|
|
48
|
+
* - an association several children render identically (all three `stiUnion` serializers render
|
|
49
|
+
* `sandbags`) collapses to a single edge with a single target, rather than repeating per child;
|
|
50
|
+
* - a polymorphic association keeps one target per target class
|
|
51
|
+
* (`Polymorphic/Task#taskable` → `Chore` and `Workout`), which is a real distinction, not a
|
|
52
|
+
* duplicate;
|
|
53
|
+
* - an association only some children render (`heartRatings`, rendered only by Latex's `stiUnion`
|
|
54
|
+
* serializer) is present exactly once.
|
|
55
|
+
*
|
|
56
|
+
* Grouping the serializers *under* the target rather than emitting one target per serializer is
|
|
57
|
+
* what lets a caller recurse once per target class with the full set, so nested trees from
|
|
58
|
+
* different children of the same target merge instead of clobbering one another.
|
|
59
|
+
*
|
|
60
|
+
* Insertion-ordered throughout, so edges come back in the order the serializers declare them.
|
|
61
|
+
*
|
|
62
|
+
* This is the single union both serializer walks run on: `buildSerializerPreloadPaths` turns these
|
|
63
|
+
* edges into preload paths (taking `terminates` and the target classes, ignoring the per-serializer
|
|
64
|
+
* edge type and serializer-side name), and `Dream.recursiveSerializationMap` prints them (taking the
|
|
65
|
+
* per-serializer edge type and name, ignoring `terminates`). Keeping the two walks on one merge is the point: the bug
|
|
66
|
+
* this exists to prevent is `psy i:serialization` and `preloadFor` disagreeing about which
|
|
67
|
+
* associations a serializer key reaches, which a second hand-maintained merge invites back.
|
|
68
|
+
*/
|
|
69
|
+
export default function mergeSerializerAssociationEdges(dreamClass: typeof Dream, serializers: SerializerType[]): MergedSerializerAssociationEdge[];
|
|
@@ -1,7 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { MergedSerializerAssociationTargetSerializer } from './mergeSerializerAssociationEdges.js';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*
|
|
5
|
+
* Prints one level of `psy i:serialization`'s tree: the heading for an association, then the name
|
|
6
|
+
* of every serializer that renders the target of that association at this point in the walk. That
|
|
7
|
+
* is more than one serializer when the target is an STI base, since each child may register a
|
|
8
|
+
* different serializer under the same key.
|
|
9
|
+
*
|
|
10
|
+
* Those serializers are printed under a *single* heading rather than one heading each, because the
|
|
11
|
+
* caller prints the union of their association trees below, indented one level in from the
|
|
12
|
+
* heading. Repeating the heading per serializer would leave that union sitting directly beneath
|
|
13
|
+
* whichever child's serializer happened to print last, reading as though every sibling's
|
|
14
|
+
* associations belonged to that one child. Grouped, the shape matches what `displaySerialization`
|
|
15
|
+
* prints at the root of the tree — one name, then every serializer that can render it, then one
|
|
16
|
+
* merged tree.
|
|
17
|
+
*
|
|
18
|
+
* A target reached under more than one edge type or serializer-side name (two children of an STI
|
|
19
|
+
* base rendering the same class through `rendersOne` and `rendersMany`, say) gets one heading per
|
|
20
|
+
* distinct (type, name), since those are genuinely different lines rather than repetitions of one.
|
|
21
|
+
*/
|
|
22
|
+
export default function printSerializerHierarchyLevel({ targetSerializers, forDisplayDepth, }: {
|
|
23
|
+
targetSerializers: MergedSerializerAssociationTargetSerializer[];
|
|
6
24
|
forDisplayDepth: number;
|
|
7
25
|
}): void;
|
|
@@ -2,7 +2,6 @@ import Dream from '../../Dream.js';
|
|
|
2
2
|
import { DreamModelSerializerType, SimpleObjectSerializerType } from '../../types/serializer.js';
|
|
3
3
|
export interface ResolvedSerializerAssociationEdge {
|
|
4
4
|
associationAs: string;
|
|
5
|
-
sourceDreamClass: typeof Dream;
|
|
6
5
|
type: 'rendersOne' | 'rendersMany' | 'delegatedAttribute';
|
|
7
6
|
serializerAssociationName: string;
|
|
8
7
|
targets: {
|
|
@@ -10,4 +9,31 @@ export interface ResolvedSerializerAssociationEdge {
|
|
|
10
9
|
serializer: DreamModelSerializerType | SimpleObjectSerializerType;
|
|
11
10
|
}[];
|
|
12
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*
|
|
15
|
+
* Drops every memoized edge set. Only needed when a class object that stays in the process has its
|
|
16
|
+
* `serializers` getter replaced, which the memo cannot detect — specs that install or remove one
|
|
17
|
+
* around an example. Replacing the model classes themselves needs no call, since the memo keys on
|
|
18
|
+
* the class and serializer objects and entries resolved against the previous ones become
|
|
19
|
+
* unreachable.
|
|
20
|
+
*/
|
|
21
|
+
export declare function clearResolvedSerializerAssociationEdgesCache(): void;
|
|
22
|
+
/**
|
|
23
|
+
* @internal
|
|
24
|
+
*
|
|
25
|
+
* Resolves the rendersOne/rendersMany/delegatedAttribute attributes of `serializer` to the
|
|
26
|
+
* associations of `dreamClass` they preload, along with the classes and serializers each one
|
|
27
|
+
* targets.
|
|
28
|
+
*
|
|
29
|
+
* Memoized on its two arguments, because every call rebuilds a throwaway serializer builder and
|
|
30
|
+
* re-infers the serializers of every association target, and the traversal in
|
|
31
|
+
* buildSerializerPreloadPaths revisits the same (class, serializer) pair many times.
|
|
32
|
+
*
|
|
33
|
+
* The two arguments are not the function's only inputs, though: resolving a target's serializers
|
|
34
|
+
* also reads that target's `serializers` getter, the STI children registered on it, and the
|
|
35
|
+
* DreamApp serializer registry. Loading a fresh set of classes replaces the keys along with that
|
|
36
|
+
* state, so the memo follows it. Mutating a `serializers` getter in place does not, and needs
|
|
37
|
+
* `clearResolvedSerializerAssociationEdgesCache` — see there.
|
|
38
|
+
*/
|
|
13
39
|
export default function resolveSerializerAssociationEdges(dreamClass: typeof Dream, serializer: DreamModelSerializerType | SimpleObjectSerializerType): ResolvedSerializerAssociationEdge[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Dream from '../../Dream.js';
|
|
2
|
+
export default class ArrayEqualityRequiresArrayColumn extends Error {
|
|
3
|
+
dreamClass: typeof Dream;
|
|
4
|
+
column: string;
|
|
5
|
+
operator: string;
|
|
6
|
+
constructor(dreamClass: typeof Dream, column: string, operator: string);
|
|
7
|
+
get message(): string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Dream from '../../Dream.js';
|
|
2
|
+
import { ViewModelClass } from '../../types/dream.js';
|
|
3
|
+
/**
|
|
4
|
+
* Raised when resolving a serializer key against a class yields an empty set of serializers.
|
|
5
|
+
*
|
|
6
|
+
* This is an internal-invariant failure, not a misconfiguration: an unresolvable serializer key
|
|
7
|
+
* raises `MissingSerializersDefinitionForKey` (and a class with no `serializers` getter at all
|
|
8
|
+
* raises `MissingSerializersDefinition`) while it is being resolved, and STI expansion always
|
|
9
|
+
* yields at least one class, so there is no supported application shape that reaches this. It is
|
|
10
|
+
* typed rather than a bare `Error` so that it can be asserted on, and so that the two callers that
|
|
11
|
+
* guard the invariant raise the same thing.
|
|
12
|
+
*/
|
|
13
|
+
export default class NoSerializersResolvedForKey extends Error {
|
|
14
|
+
private classDef;
|
|
15
|
+
private serializerKey;
|
|
16
|
+
constructor(classDef: typeof Dream | ViewModelClass | null | undefined, serializerKey: string);
|
|
17
|
+
get message(): string;
|
|
18
|
+
}
|
|
@@ -112,11 +112,27 @@ declare const ops: {
|
|
|
112
112
|
/**
|
|
113
113
|
* Creates an `OpsStatement` using the `=` operator for strict equality.
|
|
114
114
|
*
|
|
115
|
+
* **Array columns:** passing an array means literal array equality — the
|
|
116
|
+
* whole array is bound as a single parameter, so the column must match
|
|
117
|
+
* element-for-element, in order. This is the opt-in counterpart to a bare
|
|
118
|
+
* array in a where clause (`Post.where({ tags: ['a', 'b'] })`), which means
|
|
119
|
+
* `IN`, and to `ops.any`, which tests for containment of a single element.
|
|
120
|
+
* Element types are constrained by the column, so an enum array column
|
|
121
|
+
* rejects a string that is not a member of its enum.
|
|
122
|
+
*
|
|
123
|
+
* Note that PostgreSQL defines no equality operator for `json` (as opposed
|
|
124
|
+
* to `jsonb`), so `ops.equal` against a `json[]` column raises at the
|
|
125
|
+
* database.
|
|
126
|
+
*
|
|
115
127
|
* @param equal - The value the column must equal.
|
|
116
128
|
* @returns An `OpsStatement` using the `=` operator.
|
|
117
129
|
*
|
|
118
130
|
* @example
|
|
119
131
|
* User.where({ role: ops.equal('admin') })
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* // matches only rows whose tags column is exactly ['a', 'b'], in that order
|
|
135
|
+
* Post.where({ tags: ops.equal(['a', 'b']) })
|
|
120
136
|
*/
|
|
121
137
|
equal: <const T>(equal: T) => OpsStatement<"=", T, undefined>;
|
|
122
138
|
/**
|
|
@@ -269,6 +285,9 @@ declare const ops: {
|
|
|
269
285
|
/**
|
|
270
286
|
* Creates an `OpsStatement` using the `!=` operator for inequality.
|
|
271
287
|
*
|
|
288
|
+
* **Array columns:** as with `ops.equal`, passing an array compares against
|
|
289
|
+
* the whole array rather than against its elements.
|
|
290
|
+
*
|
|
272
291
|
* @param equal - The value the column must not equal.
|
|
273
292
|
* @returns An `OpsStatement` using the `!=` operator.
|
|
274
293
|
*
|
|
@@ -4,3 +4,19 @@ import { DreamModelSerializerType, SerializerType, SimpleObjectSerializerType }
|
|
|
4
4
|
export declare const DEFAULT_SERIALIZER_KEY = "default";
|
|
5
5
|
export default function inferSerializerFromDreamOrViewModel<T extends Dream | ViewModel | null | undefined, ReturnType extends T extends null | undefined ? null : T extends Dream | ViewModel ? SerializerType : never>(obj: T, serializerKey?: string | undefined): ReturnType;
|
|
6
6
|
export declare function inferSerializersFromDreamClassOrViewModelClass(classDef: typeof Dream | ViewModelClass | null | undefined, serializerKey?: string | undefined): (DreamModelSerializerType | SimpleObjectSerializerType)[];
|
|
7
|
+
/**
|
|
8
|
+
* As `inferSerializersFromDreamClassOrViewModelClass`, but guarantees a non-empty result.
|
|
9
|
+
*
|
|
10
|
+
* The guard is unreachable today, and deliberately not phrased as "no serializer found for key": a
|
|
11
|
+
* serializer key that a class does not register throws `MissingSerializersDefinitionForKey` (and a
|
|
12
|
+
* class with no `serializers` getter at all throws `MissingSerializersDefinition`) from inside the
|
|
13
|
+
* inference above, and `expandStiClasses` always yields at least one class. It exists only so that
|
|
14
|
+
* a future change to any of those cannot turn an unresolvable serializer key into a silently empty
|
|
15
|
+
* serializer set — which, for the callers below, means a silently empty preload set and a
|
|
16
|
+
* `NonLoadedAssociation` at render rather than an error naming the real problem.
|
|
17
|
+
*
|
|
18
|
+
* Used by everything that walks a serializer graph rooted on a class rather than an instance —
|
|
19
|
+
* preload-path building and serialization display — so that they raise one typed error between
|
|
20
|
+
* them.
|
|
21
|
+
*/
|
|
22
|
+
export declare function inferSerializersFromDreamClassOrViewModelClassOrFail(classDef: typeof Dream | ViewModelClass | null | undefined, serializerKey: string): (DreamModelSerializerType | SimpleObjectSerializerType)[];
|
|
@@ -8,7 +8,7 @@ import { ClockTime, ClockTimeTz } from '../../package-exports/index.js';
|
|
|
8
8
|
import CalendarDate from '../../utils/datetime/CalendarDate.js';
|
|
9
9
|
import { DateTime } from '../../utils/datetime/DateTime.js';
|
|
10
10
|
import { AssociationTableNames } from '../db.js';
|
|
11
|
-
import { DefaultScopeName, DefaultScopeNameForTable, DreamBelongsToAssociationMetadata, DreamColumnNames, GlobalModelNameTableMap, ModelColumnType, OrderDir, TableColumnEnumTypeArray, TableColumnNames, TableColumnType, TableNameForGlobalModelName, TrigramOperator } from '../dream.js';
|
|
11
|
+
import { DefaultScopeName, DefaultScopeNameForTable, DreamBelongsToAssociationMetadata, DreamColumnNames, GlobalModelNameTableMap, ModelColumnType, OrderDir, TableColumnEnumTypeArray, TableColumnIsArray, TableColumnNames, TableColumnType, TableNameForGlobalModelName, TrigramOperator } from '../dream.js';
|
|
12
12
|
import { Inc, MergeUnionOfRecordTypes, ReadonlyTail, UnionToIntersection } from '../utils.js';
|
|
13
13
|
import { JoinedAssociation } from '../variadic.js';
|
|
14
14
|
import { BelongsToStatement } from './belongsTo.js';
|
|
@@ -25,7 +25,7 @@ export type PassthroughOnClause<PassthroughColumns extends string[]> = Partial<R
|
|
|
25
25
|
type DreamSelectable<DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<{
|
|
26
26
|
[ColumnName in keyof DB[TableName]]: NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, ColumnName>;
|
|
27
27
|
}>;
|
|
28
|
-
type NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, Column, ModelPropertyType = ModelColumnType<Schema, TableName, Column>, ColumnType = TableColumnType<Schema, TableName, Column>, EnumTypeArray extends string[] | null = TableColumnEnumTypeArray<Schema, TableName, Column>, PermanentOpsValTypes = null | readonly [], OpsValType = EnumTypeArray extends null ? ColumnType extends 'bigint' ? TypesAllowedForBigintAgainstTheDb | PermanentOpsValTypes : ModelPropertyType extends DateTime | CalendarDate ? DateTime | CalendarDate | null : ModelPropertyType extends ClockTime ? ClockTime | null : ModelPropertyType extends ClockTimeTz ? ClockTimeTz | null : ModelPropertyType extends number | string ? ModelPropertyType | PermanentOpsValTypes : never : EnumTypeArray extends string[] ? EnumTypeArray[number] | PermanentOpsValTypes : never, ResolvedOpsValType = OpsValType | RawBuilder<unknown>, PartialTypes = EnumTypeArray extends null ? ModelPropertyType extends DateTime ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTime ? Range<ClockTime> | Range<null, ClockTime> | (() => Range<ClockTime>) | (() => Range<null, ClockTime>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTimeTz ? Range<ClockTimeTz> | Range<null, ClockTimeTz> | (() => Range<ClockTimeTz>) | (() => Range<null, ClockTimeTz>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends CalendarDate ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType> : ColumnType extends 'bigint' ? Range<TypesAllowedForBigintAgainstTheDb> | Range<null, TypesAllowedForBigintAgainstTheDb> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends number ? Range<ModelPropertyType> | Range<null, ModelPropertyType> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends string ? Range<string> | Range<null, string> | OpsStatement<KyselyComparisonOperatorExpression, string, any> | OpsStatement<TrigramOperator, ResolvedOpsValType, ExtraSimilarityArgs> : never : EnumTypeArray extends string[] ? EnumTypeArray | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : never> = PartialTypes extends never ? OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any> : PartialTypes | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any>;
|
|
28
|
+
type NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, Column, ModelPropertyType = ModelColumnType<Schema, TableName, Column>, ColumnType = TableColumnType<Schema, TableName, Column>, EnumTypeArray extends string[] | null = TableColumnEnumTypeArray<Schema, TableName, Column>, IsArrayColumn = TableColumnIsArray<Schema, TableName, Column>, PermanentOpsValTypes = null | readonly [], ArrayElementType = ModelPropertyType extends readonly (infer ElementType)[] ? ElementType : never, ArrayOpsValType = readonly ArrayElementType[] | PermanentOpsValTypes | RawBuilder<unknown>, OpsValType = IsArrayColumn extends true ? ArrayElementType | PermanentOpsValTypes : EnumTypeArray extends null ? ColumnType extends 'bigint' ? TypesAllowedForBigintAgainstTheDb | PermanentOpsValTypes : ModelPropertyType extends DateTime | CalendarDate ? DateTime | CalendarDate | null : ModelPropertyType extends ClockTime ? ClockTime | null : ModelPropertyType extends ClockTimeTz ? ClockTimeTz | null : ModelPropertyType extends number | string ? ModelPropertyType | PermanentOpsValTypes : never : EnumTypeArray extends string[] ? EnumTypeArray[number] | PermanentOpsValTypes : never, ResolvedOpsValType = OpsValType | RawBuilder<unknown>, PartialTypes = IsArrayColumn extends true ? (EnumTypeArray extends string[] ? EnumTypeArray : never) | OpsStatement<'=' | '!=' | '<>', ArrayOpsValType, any> | OpsStatement<KyselyComparisonOperatorExpression, PermanentOpsValTypes | RawBuilder<unknown>, any> : EnumTypeArray extends null ? ModelPropertyType extends DateTime ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTime ? Range<ClockTime> | Range<null, ClockTime> | (() => Range<ClockTime>) | (() => Range<null, ClockTime>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTimeTz ? Range<ClockTimeTz> | Range<null, ClockTimeTz> | (() => Range<ClockTimeTz>) | (() => Range<null, ClockTimeTz>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends CalendarDate ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType> : ColumnType extends 'bigint' ? Range<TypesAllowedForBigintAgainstTheDb> | Range<null, TypesAllowedForBigintAgainstTheDb> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends number ? Range<ModelPropertyType> | Range<null, ModelPropertyType> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends string ? Range<string> | Range<null, string> | OpsStatement<KyselyComparisonOperatorExpression, string, any> | OpsStatement<TrigramOperator, ResolvedOpsValType, ExtraSimilarityArgs> : never : EnumTypeArray extends string[] ? EnumTypeArray | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : never> = PartialTypes extends never ? OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any> : PartialTypes | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any>;
|
|
29
29
|
export type WhereStatementForDreamClass<DreamClass extends typeof Dream> = WhereStatement<InstanceType<DreamClass>>;
|
|
30
30
|
export type WhereStatementForDream<DreamInstance extends Dream> = WhereStatement<DreamInstance>;
|
|
31
31
|
type AssociationNameToDotReferencedColumns<DB, TableName extends keyof DB, AssociationName> = `${AssociationName & string}.${TableColumnNames<DB, TableName>}`;
|
|
@@ -103,6 +103,14 @@ export type DreamTableSchema<DreamInstance extends Dream> = Updateable<DreamInst
|
|
|
103
103
|
export type ModelColumnType<Schema, TableName, Column, TableSchema extends Schema[TableName & keyof Schema] = Schema[TableName & keyof Schema], TableColumns extends TableSchema['columns' & keyof TableSchema] = TableSchema['columns' & keyof TableSchema], TableColumnMetadata extends TableColumns[Column & keyof TableColumns] = TableColumns[Column & keyof TableColumns], ColumnType extends TableColumnMetadata['coercedType' & keyof TableColumnMetadata] = TableColumnMetadata['coercedType' & keyof TableColumnMetadata]> = ColumnType;
|
|
104
104
|
export type TableColumnType<Schema, TableName, Column, TableSchema extends Schema[TableName & keyof Schema] = Schema[TableName & keyof Schema], TableColumns extends TableSchema['columns' & keyof TableSchema] = TableSchema['columns' & keyof TableSchema], TableColumnMetadata extends TableColumns[Column & keyof TableColumns] = TableColumns[Column & keyof TableColumns], ColumnType extends TableColumnMetadata['dbType' & keyof TableColumnMetadata] = TableColumnMetadata['dbType' & keyof TableColumnMetadata]> = ColumnType;
|
|
105
105
|
export type TableColumnEnumTypeArray<Schema, TableName, Column, TableSchema extends Schema[TableName & keyof Schema] = Schema[TableName & keyof Schema], TableColumns extends TableSchema['columns' & keyof TableSchema] = TableSchema['columns' & keyof TableSchema], TableColumnMetadata extends TableColumns[Column & keyof TableColumns] = TableColumns[Column & keyof TableColumns], EnumTypeCandidate = TableColumnMetadata['enumArrayType' & keyof TableColumnMetadata], EnumTypeArray extends string[] | null = EnumTypeCandidate extends null ? null : EnumTypeCandidate extends undefined ? null : EnumTypeCandidate extends string[] ? EnumTypeCandidate : never> = EnumTypeArray;
|
|
106
|
+
/**
|
|
107
|
+
* Resolves to `true` when the schema marks the column as a database array
|
|
108
|
+
* column (e.g. `text[]`, `integer[]`, `balloon_colors_enum[]`), otherwise
|
|
109
|
+
* `false`. Enum array columns carry both `enumArrayType` and `isArray: true`,
|
|
110
|
+
* so any branch keyed off array-ness must be checked before branching on
|
|
111
|
+
* `TableColumnEnumTypeArray`, which is also set for scalar enum columns.
|
|
112
|
+
*/
|
|
113
|
+
export type TableColumnIsArray<Schema, TableName, Column, TableSchema extends Schema[TableName & keyof Schema] = Schema[TableName & keyof Schema], TableColumns extends TableSchema['columns' & keyof TableSchema] = TableSchema['columns' & keyof TableSchema], TableColumnMetadata extends TableColumns[Column & keyof TableColumns] = TableColumns[Column & keyof TableColumns], IsArrayCandidate = TableColumnMetadata['isArray' & keyof TableColumnMetadata]> = [IsArrayCandidate] extends [never] ? false : IsArrayCandidate extends true ? true : false;
|
|
106
114
|
type AssociationMetadataForTable<Schema, TableName extends keyof Schema> = Schema[TableName]['associations' & keyof Schema[TableName]];
|
|
107
115
|
export type AssociationNamesForTable<Schema, TableName extends keyof Schema> = keyof AssociationMetadataForTable<Schema, TableName> | AliasedSchemaAssociation<Schema, TableName>;
|
|
108
116
|
type MetadataForAssociation<Schema, TableName extends keyof Schema, AssociationName, AssociationMetadata = AssociationMetadataForTable<Schema, TableName>> = AssociationMetadata[AssociationName & keyof AssociationMetadata];
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
ModelColumnType,
|
|
23
23
|
OrderDir,
|
|
24
24
|
TableColumnEnumTypeArray,
|
|
25
|
+
TableColumnIsArray,
|
|
25
26
|
TableColumnNames,
|
|
26
27
|
TableColumnType,
|
|
27
28
|
TableNameForGlobalModelName,
|
|
@@ -88,75 +89,103 @@ type NonKyselySupportedSupplementalWhereClauseValues<
|
|
|
88
89
|
ModelPropertyType = ModelColumnType<Schema, TableName, Column>,
|
|
89
90
|
ColumnType = TableColumnType<Schema, TableName, Column>,
|
|
90
91
|
EnumTypeArray extends string[] | null = TableColumnEnumTypeArray<Schema, TableName, Column>,
|
|
92
|
+
IsArrayColumn = TableColumnIsArray<Schema, TableName, Column>,
|
|
91
93
|
//
|
|
92
94
|
PermanentOpsValTypes = null | readonly [],
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
95
|
+
// The element type of an array column, e.g. `string` for `text[]` and
|
|
96
|
+
// `BalloonColorsEnum` for `balloon_colors_enum[]`.
|
|
97
|
+
ArrayElementType = ModelPropertyType extends readonly (infer ElementType)[] ? ElementType : never,
|
|
98
|
+
// The whole-array value accepted by equality operators against an array
|
|
99
|
+
// column, e.g. `ops.equal(['a', 'b'])` against a `text[]` column. Readonly,
|
|
100
|
+
// because `ops.equal`'s `const` type parameter infers array literals as
|
|
101
|
+
// readonly tuples.
|
|
102
|
+
ArrayOpsValType = readonly ArrayElementType[] | PermanentOpsValTypes | RawBuilder<unknown>,
|
|
103
|
+
//
|
|
104
|
+
// NOTE: the array-ness branch MUST come before the enum branches: the schema
|
|
105
|
+
// sets `enumArrayType` for scalar enum columns AND for enum array columns, so
|
|
106
|
+
// an enum array column would otherwise take the scalar enum path.
|
|
107
|
+
OpsValType = IsArrayColumn extends true
|
|
108
|
+
? ArrayElementType | PermanentOpsValTypes
|
|
109
|
+
: EnumTypeArray extends null
|
|
110
|
+
? ColumnType extends 'bigint'
|
|
111
|
+
? TypesAllowedForBigintAgainstTheDb | PermanentOpsValTypes
|
|
112
|
+
: ModelPropertyType extends DateTime | CalendarDate
|
|
113
|
+
? DateTime | CalendarDate | null
|
|
114
|
+
: ModelPropertyType extends ClockTime
|
|
115
|
+
? ClockTime | null
|
|
116
|
+
: ModelPropertyType extends ClockTimeTz
|
|
117
|
+
? ClockTimeTz | null
|
|
118
|
+
: ModelPropertyType extends number | string
|
|
119
|
+
? ModelPropertyType | PermanentOpsValTypes
|
|
120
|
+
: never
|
|
121
|
+
: EnumTypeArray extends string[]
|
|
122
|
+
? EnumTypeArray[number] | PermanentOpsValTypes
|
|
123
|
+
: never,
|
|
108
124
|
//
|
|
109
125
|
ResolvedOpsValType = OpsValType | RawBuilder<unknown>,
|
|
110
126
|
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
// NOTE: as with `OpsValType` above, the array-ness branch MUST come first.
|
|
128
|
+
//
|
|
129
|
+
// A whole-array value is only accepted under the equality operators, which
|
|
130
|
+
// are the only ones the driver binds as a single array parameter
|
|
131
|
+
// (EQUALITY_OPERATORS_TAKING_A_WHOLE_ARRAY_VALUE in QueryDriver/Kysely.ts).
|
|
132
|
+
// Under any other operator an array value is rendered as a SQL value list,
|
|
133
|
+
// which PostgreSQL rejects, so it stays a compile error rather than becoming
|
|
134
|
+
// a database error.
|
|
135
|
+
PartialTypes = IsArrayColumn extends true
|
|
136
|
+
?
|
|
137
|
+
| (EnumTypeArray extends string[] ? EnumTypeArray : never)
|
|
138
|
+
| OpsStatement<'=' | '!=' | '<>', ArrayOpsValType, any>
|
|
139
|
+
| OpsStatement<KyselyComparisonOperatorExpression, PermanentOpsValTypes | RawBuilder<unknown>, any>
|
|
140
|
+
: EnumTypeArray extends null
|
|
141
|
+
? ModelPropertyType extends DateTime
|
|
120
142
|
?
|
|
121
|
-
| Range<
|
|
122
|
-
| Range<null,
|
|
123
|
-
| (() => Range<
|
|
124
|
-
| (() => Range<null,
|
|
143
|
+
| Range<DateTime | CalendarDate>
|
|
144
|
+
| Range<null, DateTime | CalendarDate>
|
|
145
|
+
| (() => Range<DateTime | CalendarDate>)
|
|
146
|
+
| (() => Range<null, DateTime | CalendarDate>)
|
|
125
147
|
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
126
|
-
: ModelPropertyType extends
|
|
148
|
+
: ModelPropertyType extends ClockTime
|
|
127
149
|
?
|
|
128
|
-
| Range<
|
|
129
|
-
| Range<null,
|
|
130
|
-
| (() => Range<
|
|
131
|
-
| (() => Range<null,
|
|
150
|
+
| Range<ClockTime>
|
|
151
|
+
| Range<null, ClockTime>
|
|
152
|
+
| (() => Range<ClockTime>)
|
|
153
|
+
| (() => Range<null, ClockTime>)
|
|
132
154
|
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
133
|
-
: ModelPropertyType extends
|
|
155
|
+
: ModelPropertyType extends ClockTimeTz
|
|
134
156
|
?
|
|
135
|
-
| Range<
|
|
136
|
-
| Range<null,
|
|
137
|
-
| (() => Range<
|
|
138
|
-
| (() => Range<null,
|
|
139
|
-
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType>
|
|
140
|
-
:
|
|
157
|
+
| Range<ClockTimeTz>
|
|
158
|
+
| Range<null, ClockTimeTz>
|
|
159
|
+
| (() => Range<ClockTimeTz>)
|
|
160
|
+
| (() => Range<null, ClockTimeTz>)
|
|
161
|
+
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
162
|
+
: ModelPropertyType extends CalendarDate
|
|
141
163
|
?
|
|
142
|
-
| Range<
|
|
143
|
-
| Range<null,
|
|
144
|
-
|
|
|
145
|
-
|
|
164
|
+
| Range<DateTime | CalendarDate>
|
|
165
|
+
| Range<null, DateTime | CalendarDate>
|
|
166
|
+
| (() => Range<DateTime | CalendarDate>)
|
|
167
|
+
| (() => Range<null, DateTime | CalendarDate>)
|
|
168
|
+
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType>
|
|
169
|
+
: ColumnType extends 'bigint'
|
|
146
170
|
?
|
|
147
|
-
| Range<
|
|
148
|
-
| Range<null,
|
|
171
|
+
| Range<TypesAllowedForBigintAgainstTheDb>
|
|
172
|
+
| Range<null, TypesAllowedForBigintAgainstTheDb>
|
|
149
173
|
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
150
|
-
: ModelPropertyType extends
|
|
174
|
+
: ModelPropertyType extends number
|
|
151
175
|
?
|
|
152
|
-
| Range<
|
|
153
|
-
| Range<null,
|
|
154
|
-
| OpsStatement<KyselyComparisonOperatorExpression,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
176
|
+
| Range<ModelPropertyType>
|
|
177
|
+
| Range<null, ModelPropertyType>
|
|
178
|
+
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
179
|
+
: ModelPropertyType extends string
|
|
180
|
+
?
|
|
181
|
+
| Range<string>
|
|
182
|
+
| Range<null, string>
|
|
183
|
+
| OpsStatement<KyselyComparisonOperatorExpression, string, any>
|
|
184
|
+
| OpsStatement<TrigramOperator, ResolvedOpsValType, ExtraSimilarityArgs>
|
|
185
|
+
: never
|
|
186
|
+
: EnumTypeArray extends string[]
|
|
187
|
+
? EnumTypeArray | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
188
|
+
: never,
|
|
160
189
|
> = PartialTypes extends never
|
|
161
190
|
?
|
|
162
191
|
| OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any>
|
|
@@ -441,6 +441,36 @@ export type TableColumnEnumTypeArray<
|
|
|
441
441
|
: never,
|
|
442
442
|
> = EnumTypeArray
|
|
443
443
|
|
|
444
|
+
/**
|
|
445
|
+
* Resolves to `true` when the schema marks the column as a database array
|
|
446
|
+
* column (e.g. `text[]`, `integer[]`, `balloon_colors_enum[]`), otherwise
|
|
447
|
+
* `false`. Enum array columns carry both `enumArrayType` and `isArray: true`,
|
|
448
|
+
* so any branch keyed off array-ness must be checked before branching on
|
|
449
|
+
* `TableColumnEnumTypeArray`, which is also set for scalar enum columns.
|
|
450
|
+
*/
|
|
451
|
+
export type TableColumnIsArray<
|
|
452
|
+
Schema,
|
|
453
|
+
TableName,
|
|
454
|
+
Column,
|
|
455
|
+
TableSchema extends Schema[TableName & keyof Schema] = Schema[TableName & keyof Schema],
|
|
456
|
+
TableColumns extends TableSchema['columns' & keyof TableSchema] = TableSchema['columns' &
|
|
457
|
+
keyof TableSchema],
|
|
458
|
+
TableColumnMetadata extends TableColumns[Column & keyof TableColumns] = TableColumns[Column &
|
|
459
|
+
keyof TableColumns],
|
|
460
|
+
IsArrayCandidate = TableColumnMetadata['isArray' & keyof TableColumnMetadata],
|
|
461
|
+
// NOTE: the leading `never` arm is load-bearing. A schema entry that omits
|
|
462
|
+
// `isArray` makes `IsArrayCandidate` resolve to `never`, and a bare
|
|
463
|
+
// `IsArrayCandidate extends true` distributes over that naked type parameter
|
|
464
|
+
// and yields `never` rather than the documented `false` — which then
|
|
465
|
+
// propagates into the array-ness branches of `OpsValType`/`PartialTypes`
|
|
466
|
+
// (also keyed off naked type parameters) and erases every `ops` and `Range`
|
|
467
|
+
// form from the column in `where()`. The tuple wrappers defuse distribution
|
|
468
|
+
// for that one check only: the second arm stays deliberately distributive so
|
|
469
|
+
// that an `any` schema still resolves to `boolean` and reaches both the
|
|
470
|
+
// array and the scalar branch, as internal callers with an untyped schema
|
|
471
|
+
// rely on.
|
|
472
|
+
> = [IsArrayCandidate] extends [never] ? false : IsArrayCandidate extends true ? true : false
|
|
473
|
+
|
|
444
474
|
///////////////////////////
|
|
445
475
|
// Association type helpers
|
|
446
476
|
///////////////////////////
|
package/docs/assets/hierarchy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
window.hierarchyData = "
|
|
1
|
+
window.hierarchyData = "eJyVksFuwjAMht/F58CaokRVjgNNmqaxTZq2A+IQWrNGpAlKUqYK8e5TxqUwRsPJkeXf/xfbe3DWBg9iQVnBCaV0ScDhWmMZlDUexB4opTEY2SAIeGvRdTOndujupUcgsFGmAkHzgkDrNAgotfQe/V21Gp9Vj+vQaCDHChAQfDWK8tExQaCsla4cGhCLvODLA4G84D33p86j7npdB/z/1N9CQCdZHhFi7DG8Wh++HPp0iguKAY7oyljWc53WWG6m1vjgpDLhQ1kt44quWaNz1vnxf9IUBl70GaxuG/OyQ7fW9jvF+USQ4ney7ZkM8tGUttnKoFYaP1WoY24lPT4o1FUCwmCPmy6CsYzEoRDKM0Yozye/B8Izdob93m3x+Pv4ela+kaGsE3kvixPGx/NJj2Nuw7zV+pZTOZcMeR4OP9YLbv0="
|