@rvoh/dream 2.5.0 → 2.5.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.
Files changed (182) hide show
  1. package/dist/types/src/types/dream.d.ts +34 -0
  2. package/dist/types/src/types/dream.ts +46 -0
  3. package/dist/types/src/types/variadic.d.ts +15 -6
  4. package/dist/types/src/types/variadic.ts +129 -31
  5. package/docs/classes/db.DreamMigrationHelpers.html +9 -9
  6. package/docs/classes/db.KyselyQueryDriver.html +32 -32
  7. package/docs/classes/db.PostgresQueryDriver.html +33 -33
  8. package/docs/classes/db.QueryDriverBase.html +31 -31
  9. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  10. package/docs/classes/errors.ColumnOverflow.html +3 -3
  11. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  12. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  13. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  14. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  15. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  16. package/docs/classes/errors.InvalidClockTime.html +2 -2
  17. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  18. package/docs/classes/errors.InvalidDateTime.html +2 -2
  19. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  20. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  21. package/docs/classes/errors.NotNullViolation.html +3 -3
  22. package/docs/classes/errors.RecordNotFound.html +3 -3
  23. package/docs/classes/errors.ValidationError.html +3 -3
  24. package/docs/classes/index.CalendarDate.html +33 -33
  25. package/docs/classes/index.ClockTime.html +32 -32
  26. package/docs/classes/index.ClockTimeTz.html +35 -35
  27. package/docs/classes/index.DateTime.html +86 -86
  28. package/docs/classes/index.Decorators.html +19 -19
  29. package/docs/classes/index.Dream.html +118 -118
  30. package/docs/classes/index.DreamApp.html +5 -5
  31. package/docs/classes/index.DreamTransaction.html +2 -2
  32. package/docs/classes/index.Env.html +2 -2
  33. package/docs/classes/index.Query.html +56 -56
  34. package/docs/classes/system.CliFileWriter.html +4 -4
  35. package/docs/classes/system.DreamBin.html +2 -2
  36. package/docs/classes/system.DreamCLI.html +6 -6
  37. package/docs/classes/system.DreamImporter.html +2 -2
  38. package/docs/classes/system.DreamLogos.html +2 -2
  39. package/docs/classes/system.DreamSerializerBuilder.html +11 -11
  40. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  41. package/docs/classes/system.PathHelpers.html +3 -3
  42. package/docs/classes/utils.Encrypt.html +2 -2
  43. package/docs/classes/utils.Range.html +2 -2
  44. package/docs/functions/db.closeAllDbConnections.html +1 -1
  45. package/docs/functions/db.dreamDbConnections.html +1 -1
  46. package/docs/functions/db.untypedDb.html +1 -1
  47. package/docs/functions/db.validateColumn.html +1 -1
  48. package/docs/functions/db.validateTable.html +1 -1
  49. package/docs/functions/errors.pgErrorType.html +1 -1
  50. package/docs/functions/index.DreamSerializer.html +1 -1
  51. package/docs/functions/index.ObjectSerializer.html +1 -1
  52. package/docs/functions/index.ReplicaSafe.html +1 -1
  53. package/docs/functions/index.STI.html +1 -1
  54. package/docs/functions/index.SoftDelete.html +1 -1
  55. package/docs/functions/utils.camelize.html +1 -1
  56. package/docs/functions/utils.capitalize.html +1 -1
  57. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  58. package/docs/functions/utils.compact.html +1 -1
  59. package/docs/functions/utils.groupBy.html +1 -1
  60. package/docs/functions/utils.hyphenize.html +1 -1
  61. package/docs/functions/utils.intersection.html +1 -1
  62. package/docs/functions/utils.isEmpty.html +1 -1
  63. package/docs/functions/utils.normalizeUnicode.html +1 -1
  64. package/docs/functions/utils.pascalize.html +1 -1
  65. package/docs/functions/utils.percent.html +1 -1
  66. package/docs/functions/utils.range.html +1 -1
  67. package/docs/functions/utils.round.html +1 -1
  68. package/docs/functions/utils.sanitizeString.html +1 -1
  69. package/docs/functions/utils.snakeify.html +1 -1
  70. package/docs/functions/utils.sort.html +1 -1
  71. package/docs/functions/utils.sortBy.html +1 -1
  72. package/docs/functions/utils.sortObjectByKey.html +1 -1
  73. package/docs/functions/utils.sortObjectByValue.html +1 -1
  74. package/docs/functions/utils.uncapitalize.html +1 -1
  75. package/docs/functions/utils.uniq.html +1 -1
  76. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  77. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  78. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  79. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  80. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  81. package/docs/interfaces/types.DecoratorContext.html +2 -2
  82. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  83. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  84. package/docs/interfaces/types.DurationObject.html +2 -2
  85. package/docs/interfaces/types.EncryptOptions.html +2 -2
  86. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  87. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  88. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  89. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  90. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  91. package/docs/types/openapi.OpenapiFormats.html +1 -1
  92. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  93. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  94. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  95. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  96. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  97. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  98. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  99. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  100. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  101. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +2 -2
  102. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +2 -2
  103. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +2 -2
  104. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  105. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  106. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  107. package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
  108. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  109. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  110. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  111. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  112. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
  113. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  114. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  115. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  116. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
  117. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
  118. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  119. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  120. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +2 -2
  121. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +2 -2
  122. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +2 -2
  123. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  124. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  125. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  126. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  127. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  128. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  129. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  130. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  131. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  132. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  133. package/docs/types/types.CalendarDateObject.html +1 -1
  134. package/docs/types/types.Camelized.html +1 -1
  135. package/docs/types/types.ClockTimeObject.html +1 -1
  136. package/docs/types/types.DbConnectionType.html +1 -1
  137. package/docs/types/types.DbTypes.html +1 -1
  138. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  139. package/docs/types/types.DreamAttributes.html +1 -1
  140. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  141. package/docs/types/types.DreamClassColumn.html +1 -1
  142. package/docs/types/types.DreamColumn.html +1 -1
  143. package/docs/types/types.DreamColumnNames.html +1 -1
  144. package/docs/types/types.DreamLogLevel.html +1 -1
  145. package/docs/types/types.DreamLogger.html +2 -2
  146. package/docs/types/types.DreamModelSerializerType.html +1 -1
  147. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  148. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  149. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  150. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  151. package/docs/types/types.DreamSerializable.html +1 -1
  152. package/docs/types/types.DreamSerializableArray.html +1 -1
  153. package/docs/types/types.DreamSerializerKey.html +1 -1
  154. package/docs/types/types.DreamSerializers.html +1 -1
  155. package/docs/types/types.DreamVirtualColumns.html +1 -1
  156. package/docs/types/types.DurationUnit.html +1 -1
  157. package/docs/types/types.EncryptAlgorithm.html +1 -1
  158. package/docs/types/types.HasManyStatement.html +1 -1
  159. package/docs/types/types.HasOneStatement.html +1 -1
  160. package/docs/types/types.Hyphenized.html +1 -1
  161. package/docs/types/types.Pascalized.html +1 -1
  162. package/docs/types/types.PrimaryKeyType.html +1 -1
  163. package/docs/types/types.RoundingPrecision.html +1 -1
  164. package/docs/types/types.SerializerCasing.html +1 -1
  165. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  166. package/docs/types/types.Snakeified.html +1 -1
  167. package/docs/types/types.StrictInterface.html +1 -1
  168. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  169. package/docs/types/types.UpdateableProperties.html +1 -1
  170. package/docs/types/types.ValidationType.html +1 -1
  171. package/docs/types/types.ViewModel.html +2 -2
  172. package/docs/types/types.ViewModelClass.html +1 -1
  173. package/docs/types/types.WeekdayName.html +1 -1
  174. package/docs/types/types.WhereStatementForDream.html +1 -1
  175. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  176. package/docs/variables/index.DreamConst.html +1 -1
  177. package/docs/variables/index.ops.html +1 -1
  178. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  179. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  180. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  181. package/docs/variables/system.primaryKeyTypes.html +1 -1
  182. package/package.json +1 -1
@@ -80,6 +80,40 @@ type AssociationMetadataForTable<Schema, TableName extends keyof Schema> = Schem
80
80
  export type AssociationNamesForTable<Schema, TableName extends keyof Schema> = keyof AssociationMetadataForTable<Schema, TableName> | AliasedSchemaAssociation<Schema, TableName>;
81
81
  type MetadataForAssociation<Schema, TableName extends keyof Schema, AssociationName, AssociationMetadata = AssociationMetadataForTable<Schema, TableName>> = AssociationMetadata[AssociationName & keyof AssociationMetadata];
82
82
  export type AssociationTableName<Schema, TableName extends keyof Schema, AssociationName, AssociationData = MetadataForAssociation<Schema, TableName, AssociationName>> = (AssociationData['tables' & keyof AssociationData] & any[])[0] & keyof Schema;
83
+ /**
84
+ * @internal
85
+ *
86
+ * Union of all table names for an association, accounting
87
+ * for polymorphic associations, which contain more than one
88
+ * table.
89
+ *
90
+ * ```ts
91
+ * AssociationTableNamesForAssociation<Schema, 'ratings', 'rateable'>
92
+ * // 'compositions' | 'posts'
93
+ * ```
94
+ */
95
+ export type AssociationTableNamesForAssociation<Schema, TableName extends keyof Schema, AssociationName, AssociationData = MetadataForAssociation<Schema, TableName, AssociationName>> = (AssociationData['tables' & keyof AssociationData] & readonly (keyof Schema)[])[number];
96
+ /**
97
+ * @internal
98
+ *
99
+ * Union of all association names for an association, accounting
100
+ * for polymorphic associations. In a polymorphic scenario, an association
101
+ * like `Rating#rateable` will point to multiple models, in this case
102
+ * either Composition or Post. Both of these models have some shared associations
103
+ * (i.e. `user`), but also some differing associations. This type helper
104
+ * will union all of these possibilities together, enabling us to preload
105
+ * inner associations safely at the type layer, since it is already
106
+ * supported at the implementation layer.
107
+ *
108
+ * In the example below, `compositionAssets` will come from the Composition model,
109
+ * while `comments` will come from the Post model.
110
+ *
111
+ * ```ts
112
+ * AssociationNamesForAssociation<Schema, 'ratings', 'rateable'>
113
+ * // 'compositionAssets' | 'comments' ...
114
+ * ```
115
+ */
116
+ export type AssociationNamesForAssociation<Schema, TableName extends keyof Schema, AssociationName, TableNamesUnion = AssociationTableNamesForAssociation<Schema, TableName, AssociationName>> = TableNamesUnion extends keyof Schema ? AssociationNamesForTable<Schema, TableNamesUnion> : never;
83
117
  export type DreamClassAssociationAndStatement<DreamClass extends typeof Dream, AssociationName, DreamInstance extends InstanceType<DreamClass> = InstanceType<DreamClass>, DB extends DreamInstance['DB'] = DreamInstance['DB'], Schema extends DreamInstance['schema'] = DreamInstance['schema'], TableName extends DreamInstance['table'] = DreamInstance['table'], AssocTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB = AssociationTableName<Schema, TableName, AssociationName>, RequiredOnClauseKeysForThisAssociation extends RequiredOnClauseKeys<Schema, TableName, AssociationName> = RequiredOnClauseKeys<Schema, TableName, AssociationName>, Statements extends JoinAndStatements<DreamInstance, DB, Schema, AssocTableName, RequiredOnClauseKeysForThisAssociation> = JoinAndStatements<DreamInstance, DB, Schema, AssocTableName, RequiredOnClauseKeysForThisAssociation>> = Statements;
84
118
  export type JoinAndStatements<I extends Dream, DB, Schema, TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation> = RequiredOnClauseKeysForThisAssociation extends null ? {
85
119
  and?: InternalWhereStatement<I, DB, Schema, TableName>;
@@ -375,6 +375,52 @@ export type AssociationTableName<
375
375
  AssociationData = MetadataForAssociation<Schema, TableName, AssociationName>,
376
376
  > = (AssociationData['tables' & keyof AssociationData] & any[])[0] & keyof Schema
377
377
 
378
+ /**
379
+ * @internal
380
+ *
381
+ * Union of all table names for an association, accounting
382
+ * for polymorphic associations, which contain more than one
383
+ * table.
384
+ *
385
+ * ```ts
386
+ * AssociationTableNamesForAssociation<Schema, 'ratings', 'rateable'>
387
+ * // 'compositions' | 'posts'
388
+ * ```
389
+ */
390
+ export type AssociationTableNamesForAssociation<
391
+ Schema,
392
+ TableName extends keyof Schema,
393
+ AssociationName,
394
+ AssociationData = MetadataForAssociation<Schema, TableName, AssociationName>,
395
+ > = (AssociationData['tables' & keyof AssociationData] & readonly (keyof Schema)[])[number]
396
+
397
+ /**
398
+ * @internal
399
+ *
400
+ * Union of all association names for an association, accounting
401
+ * for polymorphic associations. In a polymorphic scenario, an association
402
+ * like `Rating#rateable` will point to multiple models, in this case
403
+ * either Composition or Post. Both of these models have some shared associations
404
+ * (i.e. `user`), but also some differing associations. This type helper
405
+ * will union all of these possibilities together, enabling us to preload
406
+ * inner associations safely at the type layer, since it is already
407
+ * supported at the implementation layer.
408
+ *
409
+ * In the example below, `compositionAssets` will come from the Composition model,
410
+ * while `comments` will come from the Post model.
411
+ *
412
+ * ```ts
413
+ * AssociationNamesForAssociation<Schema, 'ratings', 'rateable'>
414
+ * // 'compositionAssets' | 'comments' ...
415
+ * ```
416
+ */
417
+ export type AssociationNamesForAssociation<
418
+ Schema,
419
+ TableName extends keyof Schema,
420
+ AssociationName,
421
+ TableNamesUnion = AssociationTableNamesForAssociation<Schema, TableName, AssociationName>,
422
+ > = TableNamesUnion extends keyof Schema ? AssociationNamesForTable<Schema, TableNamesUnion> : never
423
+
378
424
  export type DreamClassAssociationAndStatement<
379
425
  DreamClass extends typeof Dream,
380
426
  AssociationName,
@@ -1,23 +1,32 @@
1
1
  import Dream from '../Dream.js';
2
2
  import { Camelized } from '../helpers/stringCasing.js';
3
3
  import { AssociationTableNames } from './db.js';
4
- import { AssociationNamesForTable, AssociationTableName, DreamAssociationNameToAssociatedModel, JoinAndStatements, MAX_VARIADIC_DEPTH, RequiredOnClauseKeys } from './dream.js';
4
+ import { AssociationNamesForAssociation, AssociationNamesForTable, AssociationTableName, AssociationTableNamesForAssociation, DreamAssociationNameToAssociatedModel, JoinAndStatements, MAX_VARIADIC_DEPTH, RequiredOnClauseKeys } from './dream.js';
5
5
  import { Inc, ReadonlyTail } from './utils.js';
6
6
  type VALID = 'valid';
7
7
  type INVALID = 'invalid';
8
8
  type IS_ASSOCIATION_ALIAS = 'association_alias';
9
9
  type IS_ASSOCIATION_NAME = 'association_name';
10
10
  type IS_NOT_ASSOCIATION_NAME = 'not_association_name';
11
+ type IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME = 'cross_polymorphic_association_name';
11
12
  type RecursionTypes = 'load' | 'leftJoinLoad' | 'join';
13
+ /**
14
+ * Given a union of table names and an association name, returns the
15
+ * specific table(s) from the union that have that association defined.
16
+ * Used when traversing through a polymorphic association to a descendant
17
+ * that only exists on one of the polymorphic targets.
18
+ */
19
+ type TableContainingAssociationInUnion<Schema, TableNamesUnion, AssociationName> = TableNamesUnion extends keyof Schema ? AssociationName extends keyof Schema[TableNamesUnion]['associations' & keyof Schema[TableNamesUnion]] ? TableNamesUnion : never : never;
12
20
  export type VariadicLoadArgs<I extends Dream, DB, Schema, ConcreteTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, ConcreteArgs extends readonly unknown[], SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]], AllowedNextArgValues = (keyof SchemaAssociations & string) | AliasedSchemaAssociation<Schema, ConcreteTableName>> = VariadicCheckThenRecurse<I, DB, Schema, ConcreteTableName, ConcreteArgs, 'load', ConcreteTableName, 0, null, never, AllowedNextArgValues | Readonly<AllowedNextArgValues[]>>;
13
21
  export type VariadicLeftJoinLoadArgs<I extends Dream, DB, Schema, ConcreteTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, ConcreteArgs extends readonly unknown[], SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]], AllowedNextArgValues = (keyof SchemaAssociations & string) | AliasedSchemaAssociation<Schema, ConcreteTableName>> = VariadicCheckThenRecurse<I, DB, Schema, ConcreteTableName, ConcreteArgs, 'leftJoinLoad', Camelized<ConcreteTableName>, 0, null, never, AllowedNextArgValues | Readonly<AllowedNextArgValues[]>>;
14
22
  export type VariadicJoinsArgs<I extends Dream, DB, Schema, ConcreteTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, ConcreteArgs extends readonly unknown[], SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]], AllowedNextArgValues = (keyof SchemaAssociations & string) | AliasedSchemaAssociation<Schema, ConcreteTableName>> = VariadicCheckThenRecurse<I, DB, Schema, ConcreteTableName, ConcreteArgs, 'join', Camelized<ConcreteTableName>, 0, null, never, AllowedNextArgValues>;
15
- 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]], 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 : 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>;
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>;
16
24
  export type AliasedSchemaAssociation<Schema, ConcreteTableName extends keyof Schema, SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]]> = `${keyof SchemaAssociations & string} as ${string}`;
17
- 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]], ConcreteNthArg extends (keyof SchemaAssociations & 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> : null, NextUsedNamespaces = ConcreteArgs[0] extends undefined ? never : ConcreteArgs[0] extends null ? never : ConcreteArgs[0] extends keyof SchemaAssociations & string ? UsedNamespaces | ConcreteNthArg : UsedNamespaces, CurrentArgumentType extends IS_ASSOCIATION_NAME | IS_ASSOCIATION_ALIAS | 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 : IS_NOT_ASSOCIATION_NAME, NextPreviousConcreteTableName = CurrentArgumentType extends IS_ASSOCIATION_NAME ? ConcreteTableName : CurrentArgumentType extends IS_ASSOCIATION_ALIAS ? ConcreteTableName : 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 : never, NextAliasedAssociationName = CurrentArgumentType extends IS_ASSOCIATION_NAME ? ConcreteNthArg : CurrentArgumentType extends IS_ASSOCIATION_ALIAS ? ConcreteNthArg extends `${string} as ${infer AssocAlias extends string}` ? AssocAlias & string : ConcreteAssociationName : ConcreteAssociationName, NextTableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB = CurrentArgumentType extends IS_ASSOCIATION_NAME ? AssociationTableName<Schema, ConcreteTableName, NextUnaliasedAssociationName> : CurrentArgumentType extends IS_ASSOCIATION_ALIAS ? AssociationTableName<Schema, ConcreteTableName, NextUnaliasedAssociationName> : ConcreteTableName & AssociationTableNames<DB, Schema> & keyof DB, AllowedNextArgValues = RecursionType extends 'load' ? AllowedNextArgValuesForLoad<DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>, DB, Schema, NextTableName, RequiredOnClauseKeys<Schema, ConcreteTableName, NextAliasedAssociationName>> : RecursionType extends 'leftJoinLoad' ? AllowedNextArgValuesForLeftJoinLoad<DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>, DB, Schema, NextTableName, RequiredOnClauseKeys<Schema, ConcreteTableName, NextAliasedAssociationName>, NextUsedNamespaces> : RecursionType extends 'join' ? AllowedNextArgValuesForJoin<DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>, DB, Schema, NextTableName, RequiredOnClauseKeys<Schema, ConcreteTableName, NextAliasedAssociationName>, 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>;
18
- type AllowedNextArgValuesForLoad<I extends Dream, DB, Schema, TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation> = AssociationNamesForTable<Schema, TableName> | AssociationNamesForTable<Schema, TableName>[] | JoinAndStatements<I, DB, Schema, TableName, RequiredOnClauseKeysForThisAssociation>;
19
- type AllowedNextArgValuesForLeftJoinLoad<I extends Dream, DB, Schema, TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation, UsedNamespaces> = Exclude<AssociationNamesForTable<Schema, TableName>, UsedNamespaces> | Exclude<AssociationNamesForTable<Schema, TableName>, UsedNamespaces>[] | JoinAndStatements<I, DB, Schema, TableName, RequiredOnClauseKeysForThisAssociation>;
20
- type AllowedNextArgValuesForJoin<I extends Dream, DB, Schema, TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation, UsedNamespaces> = Exclude<AssociationNamesForTable<Schema, TableName>, UsedNamespaces> | JoinAndStatements<I, DB, Schema, TableName, RequiredOnClauseKeysForThisAssociation>;
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, NextAliasedAssociationName> : 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
+ 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
+ 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
+ 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>;
21
30
  export interface JoinedAssociation {
22
31
  table: string;
23
32
  alias: string;
@@ -2,8 +2,10 @@ import Dream from '../Dream.js'
2
2
  import { Camelized } from '../helpers/stringCasing.js'
3
3
  import { AssociationTableNames } from './db.js'
4
4
  import {
5
+ AssociationNamesForAssociation,
5
6
  AssociationNamesForTable,
6
7
  AssociationTableName,
8
+ AssociationTableNamesForAssociation,
7
9
  DreamAssociationNameToAssociatedModel,
8
10
  JoinAndStatements,
9
11
  MAX_VARIADIC_DEPTH,
@@ -16,7 +18,21 @@ type INVALID = 'invalid'
16
18
  type IS_ASSOCIATION_ALIAS = 'association_alias'
17
19
  type IS_ASSOCIATION_NAME = 'association_name'
18
20
  type IS_NOT_ASSOCIATION_NAME = 'not_association_name'
21
+ type IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME = 'cross_polymorphic_association_name'
19
22
  type RecursionTypes = 'load' | 'leftJoinLoad' | 'join'
23
+
24
+ /**
25
+ * Given a union of table names and an association name, returns the
26
+ * specific table(s) from the union that have that association defined.
27
+ * Used when traversing through a polymorphic association to a descendant
28
+ * that only exists on one of the polymorphic targets.
29
+ */
30
+ type TableContainingAssociationInUnion<Schema, TableNamesUnion, AssociationName> =
31
+ TableNamesUnion extends keyof Schema
32
+ ? AssociationName extends keyof Schema[TableNamesUnion]['associations' & keyof Schema[TableNamesUnion]]
33
+ ? TableNamesUnion
34
+ : never
35
+ : never
20
36
  ///////////////////////////////
21
37
  // VARIADIC LOAD
22
38
  ///////////////////////////////
@@ -137,6 +153,9 @@ type VariadicCheckThenRecurse<
137
153
  LastDream extends Dream = I,
138
154
  //
139
155
  SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]],
156
+ AllowedNamesForArrayArg = PreviousConcreteTableName extends keyof Schema
157
+ ? AssociationNamesForAssociation<Schema, PreviousConcreteTableName, ConcreteAssociationName>
158
+ : keyof SchemaAssociations & string,
140
159
  NthArgument extends VALID | INVALID = ConcreteArgs['length'] extends 0
141
160
  ? VALID
142
161
  : ConcreteArgs[0] extends keyof SchemaAssociations & string
@@ -151,7 +170,19 @@ type VariadicCheckThenRecurse<
151
170
  RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>
152
171
  >
153
172
  ? VALID
154
- : INVALID,
173
+ : ConcreteArgs[0] extends readonly AllowedNamesForArrayArg[]
174
+ ? VALID
175
+ : ConcreteArgs[0] extends JoinAndStatements<
176
+ LastDream,
177
+ DB,
178
+ Schema,
179
+ ConcreteTableName,
180
+ RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>
181
+ >
182
+ ? VALID
183
+ : ConcreteArgs[0] extends AllowedNamesForArrayArg
184
+ ? VALID
185
+ : INVALID,
155
186
  > = NthArgument extends INVALID
156
187
  ? `invalid where clause in argument ${Inc<Depth>}`
157
188
  : ConcreteArgs['length'] extends 0
@@ -191,8 +222,37 @@ type VariadicRecurse<
191
222
  LastDream extends Dream,
192
223
  //
193
224
  SchemaAssociations = Schema[ConcreteTableName]['associations' & keyof Schema[ConcreteTableName]],
225
+ // Union of all table names reachable via the previous polymorphic association.
226
+ // When PreviousConcreteTableName is not a schema key (e.g. at depth 0), fall back to ConcreteTableName.
227
+ PolymorphicTableNamesUnion = PreviousConcreteTableName extends keyof Schema
228
+ ? AssociationTableNamesForAssociation<Schema, PreviousConcreteTableName, ConcreteAssociationName>
229
+ : ConcreteTableName,
230
+ // The specific table from the polymorphic union that owns the current arg as an association.
231
+ // Used when the arg is not directly on ConcreteTableName (i.e. cross-polymorphic traversal).
232
+ CrossPolymorphicTableForCurrentArg = ConcreteArgs[0] extends string
233
+ ? TableContainingAssociationInUnion<Schema, PolymorphicTableNamesUnion, ConcreteArgs[0]>
234
+ : never,
235
+ // The effective table for looking up the current arg's association:
236
+ // - ConcreteTableName when the arg is directly on it (normal case)
237
+ // - CrossPolymorphicTableForCurrentArg when the arg is on a different table in the polymorphic union
238
+ // Note: we use [T] extends [never] (non-distributive) to guard against CrossPolymorphicTableForCurrentArg
239
+ // being `never`, because `never extends X` is vacuously true and would cause EffectiveConcreteTableName
240
+ // to become `never` if we used a plain conditional.
241
+ EffectiveConcreteTableName extends keyof Schema &
242
+ AssociationTableNames<DB, Schema> &
243
+ keyof DB = ConcreteArgs[0] extends keyof SchemaAssociations & string
244
+ ? ConcreteTableName
245
+ : [CrossPolymorphicTableForCurrentArg] extends [never]
246
+ ? ConcreteTableName
247
+ : CrossPolymorphicTableForCurrentArg extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB
248
+ ? CrossPolymorphicTableForCurrentArg
249
+ : ConcreteTableName,
250
+ // Schema associations on the effective table (may differ from SchemaAssociations when cross-polymorphic).
251
+ EffectiveSchemaAssociations = Schema[EffectiveConcreteTableName]['associations' &
252
+ keyof Schema[EffectiveConcreteTableName]],
194
253
  ConcreteNthArg extends
195
254
  | (keyof SchemaAssociations & string)
255
+ | (keyof EffectiveSchemaAssociations & string)
196
256
  | AliasedSchemaAssociation<Schema, ConcreteTableName>
197
257
  | null = ConcreteArgs[0] extends undefined
198
258
  ? null
@@ -202,31 +262,38 @@ type VariadicRecurse<
202
262
  ? ConcreteArgs[0] & keyof SchemaAssociations & string
203
263
  : ConcreteArgs[0] extends AliasedSchemaAssociation<Schema, ConcreteTableName>
204
264
  ? ConcreteArgs[0] & AliasedSchemaAssociation<Schema, ConcreteTableName>
205
- : null,
265
+ : ConcreteArgs[0] extends keyof EffectiveSchemaAssociations & string
266
+ ? ConcreteArgs[0] & keyof EffectiveSchemaAssociations & string
267
+ : null,
206
268
  NextUsedNamespaces = ConcreteArgs[0] extends undefined
207
269
  ? never
208
270
  : ConcreteArgs[0] extends null
209
271
  ? never
210
- : ConcreteArgs[0] extends keyof SchemaAssociations & string
211
- ? UsedNamespaces | ConcreteNthArg
212
- : UsedNamespaces,
272
+ : ConcreteNthArg extends null
273
+ ? UsedNamespaces
274
+ : UsedNamespaces | ConcreteNthArg,
213
275
  //
214
276
  CurrentArgumentType extends
215
277
  | IS_ASSOCIATION_NAME
216
278
  | IS_ASSOCIATION_ALIAS
279
+ | IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME
217
280
  | IS_NOT_ASSOCIATION_NAME = ConcreteNthArg extends null
218
281
  ? IS_NOT_ASSOCIATION_NAME
219
282
  : ConcreteNthArg extends keyof SchemaAssociations & string
220
283
  ? IS_ASSOCIATION_NAME
221
284
  : ConcreteNthArg extends AliasedSchemaAssociation<Schema, ConcreteTableName>
222
285
  ? IS_ASSOCIATION_ALIAS
223
- : IS_NOT_ASSOCIATION_NAME,
286
+ : ConcreteNthArg extends keyof EffectiveSchemaAssociations & string
287
+ ? IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME
288
+ : IS_NOT_ASSOCIATION_NAME,
224
289
  //
225
290
  NextPreviousConcreteTableName = CurrentArgumentType extends IS_ASSOCIATION_NAME
226
291
  ? ConcreteTableName
227
292
  : CurrentArgumentType extends IS_ASSOCIATION_ALIAS
228
293
  ? ConcreteTableName
229
- : PreviousConcreteTableName,
294
+ : CurrentArgumentType extends IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME
295
+ ? EffectiveConcreteTableName
296
+ : PreviousConcreteTableName,
230
297
  //
231
298
  NextUnaliasedAssociationName = CurrentArgumentType extends IS_ASSOCIATION_NAME
232
299
  ? ConcreteNthArg
@@ -234,7 +301,9 @@ type VariadicRecurse<
234
301
  ? ConcreteNthArg extends `${infer AssocName extends string} as ${string}`
235
302
  ? AssocName & keyof SchemaAssociations & string
236
303
  : never
237
- : never,
304
+ : CurrentArgumentType extends IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME
305
+ ? ConcreteNthArg
306
+ : never,
238
307
  //
239
308
  NextAliasedAssociationName = CurrentArgumentType extends IS_ASSOCIATION_NAME
240
309
  ? ConcreteNthArg
@@ -242,31 +311,56 @@ type VariadicRecurse<
242
311
  ? ConcreteNthArg extends `${string} as ${infer AssocAlias extends string}`
243
312
  ? AssocAlias & string
244
313
  : ConcreteAssociationName
245
- : ConcreteAssociationName,
314
+ : CurrentArgumentType extends IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME
315
+ ? ConcreteNthArg
316
+ : ConcreteAssociationName,
317
+ //
318
+ IsAssociationNameOrAlias extends boolean = CurrentArgumentType extends
319
+ | IS_ASSOCIATION_NAME
320
+ | IS_ASSOCIATION_ALIAS
321
+ | IS_CROSS_POLYMORPHIC_ASSOCIATION_NAME
322
+ ? true
323
+ : false,
246
324
  //
247
325
  NextTableName extends keyof Schema &
248
326
  AssociationTableNames<DB, Schema> &
249
- keyof DB = CurrentArgumentType extends IS_ASSOCIATION_NAME
250
- ? AssociationTableName<Schema, ConcreteTableName, NextUnaliasedAssociationName>
251
- : CurrentArgumentType extends IS_ASSOCIATION_ALIAS
252
- ? AssociationTableName<Schema, ConcreteTableName, NextUnaliasedAssociationName>
253
- : ConcreteTableName & AssociationTableNames<DB, Schema> & keyof DB,
327
+ keyof DB = IsAssociationNameOrAlias extends true
328
+ ? AssociationTableName<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName>
329
+ : ConcreteTableName & AssociationTableNames<DB, Schema> & keyof DB,
330
+ //
331
+ AllowedAssociationNames = IsAssociationNameOrAlias extends true
332
+ ? AssociationNamesForAssociation<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName>
333
+ : PreviousConcreteTableName extends keyof Schema
334
+ ? AssociationNamesForAssociation<Schema, PreviousConcreteTableName, ConcreteAssociationName>
335
+ : AssociationNamesForTable<Schema, ConcreteTableName>, // fall back to association names for table for root only
336
+ //
337
+ AssociationTableOrConcreteTable extends keyof Schema &
338
+ AssociationTableNames<DB, Schema> &
339
+ keyof DB = IsAssociationNameOrAlias extends true
340
+ ? AssociationTableName<Schema, EffectiveConcreteTableName, NextUnaliasedAssociationName>
341
+ : ConcreteTableName,
342
+ //
343
+ CurrentRequiredOnClauseKeys = IsAssociationNameOrAlias extends true
344
+ ? RequiredOnClauseKeys<Schema, EffectiveConcreteTableName, NextAliasedAssociationName>
345
+ : RequiredOnClauseKeys<Schema, PreviousConcreteTableName, ConcreteAssociationName>,
254
346
  //
255
347
  AllowedNextArgValues = RecursionType extends 'load'
256
348
  ? AllowedNextArgValuesForLoad<
257
349
  DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>,
258
350
  DB,
259
351
  Schema,
260
- NextTableName,
261
- RequiredOnClauseKeys<Schema, ConcreteTableName, NextAliasedAssociationName>
352
+ AllowedAssociationNames,
353
+ AssociationTableOrConcreteTable,
354
+ CurrentRequiredOnClauseKeys
262
355
  >
263
356
  : RecursionType extends 'leftJoinLoad'
264
357
  ? AllowedNextArgValuesForLeftJoinLoad<
265
358
  DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>,
266
359
  DB,
267
360
  Schema,
268
- NextTableName,
269
- RequiredOnClauseKeys<Schema, ConcreteTableName, NextAliasedAssociationName>,
361
+ AllowedAssociationNames,
362
+ AssociationTableOrConcreteTable,
363
+ CurrentRequiredOnClauseKeys,
270
364
  NextUsedNamespaces
271
365
  >
272
366
  : RecursionType extends 'join'
@@ -274,8 +368,9 @@ type VariadicRecurse<
274
368
  DreamAssociationNameToAssociatedModel<LastDream, ConcreteArgs[0] & keyof LastDream>,
275
369
  DB,
276
370
  Schema,
277
- NextTableName,
278
- RequiredOnClauseKeys<Schema, ConcreteTableName, NextAliasedAssociationName>,
371
+ AllowedAssociationNames,
372
+ AssociationTableOrConcreteTable,
373
+ CurrentRequiredOnClauseKeys,
279
374
  NextUsedNamespaces
280
375
  >
281
376
  : never,
@@ -302,35 +397,38 @@ type AllowedNextArgValuesForLoad<
302
397
  I extends Dream,
303
398
  DB,
304
399
  Schema,
305
- TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB,
400
+ AllowedNames,
401
+ TableForJoin extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB,
306
402
  RequiredOnClauseKeysForThisAssociation,
307
403
  > =
308
- | AssociationNamesForTable<Schema, TableName>
309
- | AssociationNamesForTable<Schema, TableName>[]
310
- | JoinAndStatements<I, DB, Schema, TableName, RequiredOnClauseKeysForThisAssociation>
404
+ | AllowedNames
405
+ | AllowedNames[]
406
+ | JoinAndStatements<I, DB, Schema, TableForJoin, RequiredOnClauseKeysForThisAssociation>
311
407
 
312
408
  type AllowedNextArgValuesForLeftJoinLoad<
313
409
  I extends Dream,
314
410
  DB,
315
411
  Schema,
316
- TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB,
412
+ AllowedNames,
413
+ TableForJoin extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB,
317
414
  RequiredOnClauseKeysForThisAssociation,
318
415
  UsedNamespaces,
319
416
  > =
320
- | Exclude<AssociationNamesForTable<Schema, TableName>, UsedNamespaces>
321
- | Exclude<AssociationNamesForTable<Schema, TableName>, UsedNamespaces>[]
322
- | JoinAndStatements<I, DB, Schema, TableName, RequiredOnClauseKeysForThisAssociation>
417
+ | Exclude<AllowedNames, UsedNamespaces>
418
+ | Exclude<AllowedNames, UsedNamespaces>[]
419
+ | JoinAndStatements<I, DB, Schema, TableForJoin, RequiredOnClauseKeysForThisAssociation>
323
420
 
324
421
  type AllowedNextArgValuesForJoin<
325
422
  I extends Dream,
326
423
  DB,
327
424
  Schema,
328
- TableName extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB,
425
+ AllowedNames,
426
+ TableForJoin extends keyof Schema & AssociationTableNames<DB, Schema> & keyof DB,
329
427
  RequiredOnClauseKeysForThisAssociation,
330
428
  UsedNamespaces,
331
429
  > =
332
- | Exclude<AssociationNamesForTable<Schema, TableName>, UsedNamespaces>
333
- | JoinAndStatements<I, DB, Schema, TableName, RequiredOnClauseKeysForThisAssociation>
430
+ | Exclude<AllowedNames, UsedNamespaces>
431
+ | JoinAndStatements<I, DB, Schema, TableForJoin, RequiredOnClauseKeysForThisAssociation>
334
432
 
335
433
  export interface JoinedAssociation {
336
434
  table: string