@rvoh/dream 2.0.0-alpha.1 → 2.0.0-alpha.11
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 +5 -105
- package/dist/cjs/src/cli/index.js +15 -1
- package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +6 -2
- package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +0 -48
- package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +0 -50
- package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +0 -49
- package/dist/cjs/src/dream/Query.js +0 -57
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +2 -0
- package/dist/cjs/src/dream-app/helpers/globalSerializerKeyFromPath.js +1 -1
- package/dist/cjs/src/dream-app/index.js +50 -0
- package/dist/cjs/src/helpers/cli/generateDreamContent.js +5 -5
- package/dist/cjs/src/helpers/cli/generateFactoryContent.js +5 -2
- package/dist/cjs/src/helpers/cli/generateMigrationContent.js +11 -4
- package/dist/cjs/src/helpers/sanitizeString.js +25 -0
- package/dist/cjs/src/package-exports/index.js +0 -1
- package/dist/cjs/src/package-exports/system.js +8 -0
- package/dist/cjs/src/package-exports/utils.js +1 -0
- package/dist/cjs/src/serializer/builders/DreamSerializerBuilder.js +1 -1
- package/dist/esm/src/Dream.js +5 -105
- package/dist/esm/src/cli/index.js +15 -1
- package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +6 -2
- package/dist/esm/src/dream/DreamClassTransactionBuilder.js +0 -48
- package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +0 -50
- package/dist/esm/src/dream/LeftJoinLoadBuilder.js +0 -49
- package/dist/esm/src/dream/Query.js +0 -57
- package/dist/esm/src/dream/QueryDriver/Kysely.js +2 -0
- package/dist/esm/src/dream-app/helpers/globalSerializerKeyFromPath.js +1 -1
- package/dist/esm/src/dream-app/index.js +50 -0
- package/dist/esm/src/helpers/cli/generateDreamContent.js +5 -5
- package/dist/esm/src/helpers/cli/generateFactoryContent.js +5 -2
- package/dist/esm/src/helpers/cli/generateMigrationContent.js +11 -4
- package/dist/esm/src/helpers/sanitizeString.js +25 -0
- package/dist/esm/src/package-exports/index.js +0 -1
- package/dist/esm/src/package-exports/system.js +8 -0
- package/dist/esm/src/package-exports/utils.js +1 -0
- package/dist/esm/src/serializer/builders/DreamSerializerBuilder.js +1 -1
- package/dist/types/src/Dream.d.ts +1 -107
- package/dist/types/src/cli/index.d.ts +18 -0
- package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +2 -1
- package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +0 -55
- package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +0 -48
- package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +1 -48
- package/dist/types/src/dream/Query.d.ts +0 -54
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +2 -0
- package/dist/types/src/dream-app/index.d.ts +45 -0
- package/dist/types/src/helpers/sanitizeString.d.ts +1 -0
- package/dist/types/src/package-exports/index.d.ts +0 -1
- package/dist/types/src/package-exports/system.d.ts +8 -0
- package/dist/types/src/package-exports/types.d.ts +1 -0
- package/dist/types/src/package-exports/utils.d.ts +1 -0
- package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +11 -20
- package/dist/types/src/serializer/builders/ObjectSerializerBuilder.d.ts +8 -8
- package/dist/types/src/types/utils.d.ts +3 -0
- package/dist/types/src/types/utils.ts +7 -0
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/db.DreamMigrationHelpers.html +10 -9
- package/docs/classes/db.KyselyQueryDriver.html +30 -30
- package/docs/classes/db.PostgresQueryDriver.html +31 -31
- package/docs/classes/db.QueryDriverBase.html +29 -29
- 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.GlobalNameNotSet.html +3 -3
- package/docs/classes/errors.InvalidCalendarDate.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 +2 -2
- package/docs/classes/index.Decorators.html +19 -19
- package/docs/classes/index.Dream.html +189 -230
- package/docs/classes/index.DreamApp.html +16 -4
- package/docs/classes/index.DreamTransaction.html +2 -2
- package/docs/classes/index.Env.html +2 -2
- package/docs/classes/index.Query.html +66 -87
- package/docs/classes/system.CliFileWriter.html +8 -0
- package/docs/classes/system.DreamBin.html +11 -0
- package/docs/classes/{index.DreamCLI.html → system.DreamCLI.html} +11 -8
- package/docs/classes/system.DreamImporter.html +5 -0
- package/docs/classes/system.DreamLogos.html +4 -0
- package/docs/classes/system.DreamSerializerBuilder.html +76 -0
- package/docs/classes/system.ObjectSerializerBuilder.html +75 -0
- package/docs/classes/utils.Encrypt.html +2 -2
- 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-1.html +1 -1
- package/docs/functions/utils.round.html +1 -1
- package/docs/functions/utils.sanitizeString.html +1 -0
- 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/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.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/modules/db.html +1 -1
- package/docs/modules/errors.html +1 -1
- package/docs/modules/index.html +1 -2
- package/docs/modules/openapi.html +1 -1
- package/docs/modules/system.html +10 -0
- package/docs/modules/types.html +2 -1
- package/docs/modules/utils.html +2 -1
- package/docs/types/index.DateTime.html +1 -1
- 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 +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionRef.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
- package/docs/types/openapi.OpenapiSchemaNull.html +1 -1
- 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 +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
- 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 -0
- package/docs/types/types.Camelized.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 +1 -1
- 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.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.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 -0
- 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 +1 -1
- package/docs/types/types.ViewModelClass.html +1 -1
- package/docs/types/types.WhereStatementForDream.html +1 -1
- package/docs/types/types.WhereStatementForDreamClass.html +1 -1
- package/docs/variables/index.DateTime-1.html +1 -1
- package/docs/variables/index.DreamConst.html +1 -1
- package/docs/variables/index.ops.html +1 -1
- package/docs/variables/openapi.openapiPrimitiveTypes-1.html +1 -1
- package/docs/variables/openapi.openapiShorthandPrimitiveTypes-1.html +1 -1
- package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -0
- package/docs/variables/types.TRIGRAM_OPERATORS.html +1 -1
- package/docs/variables/types.primaryKeyTypes.html +1 -1
- package/package.json +5 -5
- package/dist/cjs/src/package-exports/internal.js +0 -18
- package/dist/esm/src/package-exports/internal.js +0 -18
- package/dist/types/src/package-exports/internal.d.ts +0 -18
- package/docs/classes/internal.CliFileWriter.html +0 -8
- package/docs/classes/internal.DreamBin.html +0 -11
- package/docs/classes/internal.DreamImporter.html +0 -5
- package/docs/classes/internal.DreamLogos.html +0 -4
- package/docs/classes/internal.DreamSerializerBuilder.html +0 -76
- package/docs/classes/internal.ObjectSerializerBuilder.html +0 -75
- package/docs/functions/internal.absoluteDreamPath.html +0 -1
- package/docs/functions/internal.dreamPath.html +0 -1
- package/docs/functions/internal.expandStiClasses.html +0 -1
- package/docs/functions/internal.generateDream.html +0 -1
- package/docs/functions/internal.globalClassNameFromFullyQualifiedModelName.html +0 -1
- package/docs/functions/internal.inferSerializerFromDreamOrViewModel.html +0 -1
- package/docs/functions/internal.inferSerializersFromDreamClassOrViewModelClass.html +0 -1
- package/docs/functions/internal.isDreamSerializer.html +0 -1
- package/docs/functions/internal.loadRepl.html +0 -1
- package/docs/functions/internal.lookupClassByGlobalName.html +0 -1
- package/docs/functions/internal.serializerNameFromFullyQualifiedModelName.html +0 -1
- package/docs/functions/internal.standardizeFullyQualifiedModelName.html +0 -1
- package/docs/modules/internal.html +0 -21
- package/docs/types/internal.DreamAppAllowedPackageManagersEnum.html +0 -1
- package/docs/variables/internal.DreamAppAllowedPackageManagersEnumValues.html +0 -1
package/dist/cjs/src/Dream.js
CHANGED
|
@@ -1403,56 +1403,6 @@ export default class Dream {
|
|
|
1403
1403
|
static preloadFor(serializerKey, modifierFn) {
|
|
1404
1404
|
return this.query().preloadFor(serializerKey, modifierFn);
|
|
1405
1405
|
}
|
|
1406
|
-
/**
|
|
1407
|
-
* Recursively preloads all Dream associations referenced by `rendersOne` and `rendersMany`
|
|
1408
|
-
* in a DreamSerializer using left join preloading. This traverses the entire content tree
|
|
1409
|
-
* of serializers to automatically load all necessary associations in a single query,
|
|
1410
|
-
* eliminating N+1 query problems and removing the need to manually remember which
|
|
1411
|
-
* associations to preload for serialization.
|
|
1412
|
-
*
|
|
1413
|
-
* This method decouples data loading code from data rendering code by having the serializer
|
|
1414
|
-
* (rendering code) inform the query (loading code) about which associations are needed.
|
|
1415
|
-
* As serializers evolve over time - adding new `rendersOne` and `rendersMany` calls or
|
|
1416
|
-
* modifying existing ones - the loading code automatically adapts without requiring
|
|
1417
|
-
* corresponding modifications to left join preload statements.
|
|
1418
|
-
*
|
|
1419
|
-
* This method analyzes the serializer (specified by `serializerKey` or 'default') and
|
|
1420
|
-
* automatically left join preloads all associations that will be needed during serialization.
|
|
1421
|
-
*
|
|
1422
|
-
* Note: Left join preloading loads all data in a single SQL query but has trade-offs compared
|
|
1423
|
-
* to regular preloading. See {@link Dream.leftJoinPreload} for details about limitations.
|
|
1424
|
-
*
|
|
1425
|
-
* ```ts
|
|
1426
|
-
* // Instead of manually specifying all associations:
|
|
1427
|
-
* await User.leftJoinPreload('posts', 'comments', 'replies').all()
|
|
1428
|
-
*
|
|
1429
|
-
* // Automatically left join preload everything needed for serialization:
|
|
1430
|
-
* await User.leftJoinPreloadFor('summary').all()
|
|
1431
|
-
*
|
|
1432
|
-
* // Add where conditions to specific associations during left join preloading:
|
|
1433
|
-
* await User.leftJoinPreloadFor('detailed', (associationName, dreamClass) => {
|
|
1434
|
-
* if (dreamClass.typeof(Post) && associationName === 'comments') {
|
|
1435
|
-
* return { and: { published: true } }
|
|
1436
|
-
* }
|
|
1437
|
-
* }).all()
|
|
1438
|
-
*
|
|
1439
|
-
* // Skip left join preloading specific associations to handle them manually:
|
|
1440
|
-
* await User.leftJoinPreloadFor('summary', (associationName, dreamClass) => {
|
|
1441
|
-
* if (dreamClass.typeof(User) && associationName === 'posts') {
|
|
1442
|
-
* return 'omit' // Handle posts preloading separately with custom logic
|
|
1443
|
-
* }
|
|
1444
|
-
* })
|
|
1445
|
-
* .preload('posts', { and: { featured: true } }) // Custom preloading instead
|
|
1446
|
-
* .all()
|
|
1447
|
-
* ```
|
|
1448
|
-
*
|
|
1449
|
-
* @param serializerKey - The serializer key to use for determining which associations to preload.
|
|
1450
|
-
* @param modifierFn - Optional callback function to modify or omit specific associations during preloading. Called for each association with the Dream class and association name. Return an object with `and`, `andAny`, or `andNot` properties to add where conditions, return 'omit' to skip preloading that association (useful when you want to handle it manually), or return undefined to use default preloading
|
|
1451
|
-
* @returns A Query with all serialization associations left join preloaded
|
|
1452
|
-
*/
|
|
1453
|
-
static leftJoinPreloadFor(serializerKey, modifierFn) {
|
|
1454
|
-
return this.query().leftJoinPreloadFor(serializerKey, modifierFn);
|
|
1455
|
-
}
|
|
1456
1406
|
/**
|
|
1457
1407
|
* Returns a new Query instance with the provided
|
|
1458
1408
|
* inner join statement attached
|
|
@@ -2667,7 +2617,7 @@ export default class Dream {
|
|
|
2667
2617
|
*
|
|
2668
2618
|
* ```ts
|
|
2669
2619
|
* const user = User.new({ email: 'how@yadoin' })
|
|
2670
|
-
* user.
|
|
2620
|
+
* user.getAttributes()
|
|
2671
2621
|
* // {
|
|
2672
2622
|
* // email: 'how@yadoin',
|
|
2673
2623
|
* // ...
|
|
@@ -2998,9 +2948,10 @@ export default class Dream {
|
|
|
2998
2948
|
* @returns A boolean
|
|
2999
2949
|
*/
|
|
3000
2950
|
equals(other) {
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
2951
|
+
return (!!(other instanceof Dream) &&
|
|
2952
|
+
this.isPersisted &&
|
|
2953
|
+
other.isPersisted &&
|
|
2954
|
+
this.comparisonKey === other.comparisonKey);
|
|
3004
2955
|
}
|
|
3005
2956
|
get comparisonKey() {
|
|
3006
2957
|
return `${this.constructor.globalName}:${this.primaryKeyValue()}`;
|
|
@@ -3374,57 +3325,6 @@ export default class Dream {
|
|
|
3374
3325
|
leftJoinLoad(...args) {
|
|
3375
3326
|
return new LeftJoinLoadBuilder(this).leftJoinLoad(...args);
|
|
3376
3327
|
}
|
|
3377
|
-
/**
|
|
3378
|
-
* Recursively loads all Dream associations referenced by `rendersOne` and `rendersMany`
|
|
3379
|
-
* in a DreamSerializer. This traverses the entire content tree of serializers to automatically
|
|
3380
|
-
* load all necessary associations, eliminating N+1 query problems and removing the need to
|
|
3381
|
-
* manually remember which associations to preload for serialization.
|
|
3382
|
-
*
|
|
3383
|
-
* This method decouples data loading code from data rendering code by having the serializer
|
|
3384
|
-
* (rendering code) inform the query (loading code) about which associations are needed.
|
|
3385
|
-
* As serializers evolve over time - adding new `rendersOne` and `rendersMany` calls or
|
|
3386
|
-
* modifying existing ones - the loading code automatically adapts without requiring
|
|
3387
|
-
* corresponding modifications to preload statements.
|
|
3388
|
-
*
|
|
3389
|
-
* This method analyzes the serializer (specified by `serializerKey` or 'default') and
|
|
3390
|
-
* automatically preloads all associations that will be needed during serialization.
|
|
3391
|
-
*
|
|
3392
|
-
* Note: Left join loading loads all data in a single SQL query but has trade-offs compared
|
|
3393
|
-
* to regular preloading. See {@link Dream.leftJoinPreload} for details about limitations.
|
|
3394
|
-
*
|
|
3395
|
-
* ```ts
|
|
3396
|
-
* // Instead of manually specifying all associations:
|
|
3397
|
-
* await User.preload('posts', 'comments', 'replies').all()
|
|
3398
|
-
*
|
|
3399
|
-
* // Automatically preload everything needed for serialization:
|
|
3400
|
-
* await user.leftJoinLoadFor('summary').execute()
|
|
3401
|
-
*
|
|
3402
|
-
* // Add where conditions to specific associations during preloading:
|
|
3403
|
-
* await user.leftJoinLoadFor('detailed', (associationName, dreamClass) => {
|
|
3404
|
-
* if (dreamClass.typeof(Post) && associationName === 'comments') {
|
|
3405
|
-
* return { and: { published: true } }
|
|
3406
|
-
* }
|
|
3407
|
-
* })
|
|
3408
|
-
* .execute()
|
|
3409
|
-
*
|
|
3410
|
-
* // Skip preloading specific associations to handle them manually:
|
|
3411
|
-
* await user
|
|
3412
|
-
* .loadFor('summary', (associationName, dreamClass) => {
|
|
3413
|
-
* if (dreamClass.typeof(User) && associationName === 'posts') {
|
|
3414
|
-
* return 'omit' // Handle posts preloading separately with custom logic
|
|
3415
|
-
* }
|
|
3416
|
-
* })
|
|
3417
|
-
* .load('posts', { and: { featured: true } }) // Custom preloading
|
|
3418
|
-
* .execute()
|
|
3419
|
-
* ```
|
|
3420
|
-
*
|
|
3421
|
-
* @param serializerKey - The serializer key to use for determining which associations to preload.
|
|
3422
|
-
* @param modifierFn - Optional callback function to modify or omit specific associations during preloading. Called for each association with the Dream class and association name. Return an object with `and`, `andAny`, or `andNot` properties to add where conditions, return 'omit' to skip preloading that association (useful when you want to handle it manually), or return undefined to use default preloading
|
|
3423
|
-
* @returns A Query with all serialization associations preloaded
|
|
3424
|
-
*/
|
|
3425
|
-
leftJoinLoadFor(serializerKey, modifierFn) {
|
|
3426
|
-
return new LeftJoinLoadBuilder(this)['leftJoinLoadFor'](serializerKey, modifierFn);
|
|
3427
|
-
}
|
|
3428
3328
|
/**
|
|
3429
3329
|
* Returns true if the association specified has
|
|
3430
3330
|
* been loaded on this instance
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { InvalidArgumentError } from 'commander';
|
|
2
2
|
import DreamBin from '../bin/index.js';
|
|
3
3
|
import DreamApp from '../dream-app/index.js';
|
|
4
|
+
import generateDream from '../helpers/cli/generateDream.js';
|
|
4
5
|
import EnvInternal from '../helpers/EnvInternal.js';
|
|
6
|
+
import loadRepl from '../helpers/loadRepl.js';
|
|
5
7
|
import sspawn from '../helpers/sspawn.js';
|
|
6
8
|
import DreamCliLogger from './logger/DreamCliLogger.js';
|
|
7
9
|
const INDENT = ' ';
|
|
@@ -61,6 +63,12 @@ ${INDENT}
|
|
|
61
63
|
${INDENT} include the fully qualified model name, e.g., if the Coach model is in src/app/models/Health/Coach:
|
|
62
64
|
${INDENT} Health/Coach:belongs_to`;
|
|
63
65
|
export default class DreamCLI {
|
|
66
|
+
/**
|
|
67
|
+
* Starts the Dream console
|
|
68
|
+
*/
|
|
69
|
+
static async loadRepl(context) {
|
|
70
|
+
return await loadRepl(context);
|
|
71
|
+
}
|
|
64
72
|
/**
|
|
65
73
|
* use this method for initializing a standalone dream application. If using Psychic and Dream together,
|
|
66
74
|
* a different pattern is used, which leverages the `generateDreamCli` method instead.
|
|
@@ -81,6 +89,12 @@ export default class DreamCLI {
|
|
|
81
89
|
onSync: () => { },
|
|
82
90
|
});
|
|
83
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
static async generateDream(opts) {
|
|
96
|
+
await generateDream(opts);
|
|
97
|
+
}
|
|
84
98
|
/**
|
|
85
99
|
* called under the hood when provisioning both psychic and dream applications.
|
|
86
100
|
*/
|
|
@@ -89,7 +103,7 @@ export default class DreamCLI {
|
|
|
89
103
|
.command('generate:migration')
|
|
90
104
|
.alias('g:migration')
|
|
91
105
|
.description('create a new migration')
|
|
92
|
-
.argument('<migrationName>', 'end with -to-table-name to prepopulate with an alterTable command')
|
|
106
|
+
.argument('<migrationName>', 'end with -to-table-name or -from-table-name to prepopulate with an alterTable command')
|
|
93
107
|
.option('--connection-name <connectionName>', 'the connection name you wish to use for your migration')
|
|
94
108
|
.argument('[columnsWithTypes...]', columnsWithTypesDescriptionForMigration)
|
|
95
109
|
.action(async (migrationName, columnsWithTypes, options) => {
|
|
@@ -17,7 +17,10 @@ export default class DreamMigrationHelpers {
|
|
|
17
17
|
*/
|
|
18
18
|
static async renameTable(db, from, to) {
|
|
19
19
|
await db.schema.alterTable(from).renameTo(to).execute();
|
|
20
|
-
|
|
20
|
+
const fromSequenceName = `${from}_id_seq`;
|
|
21
|
+
const toSequenceName = `${to}_id_seq`;
|
|
22
|
+
const sqlStatement = `ALTER SEQUENCE ${fromSequenceName} RENAME TO ${toSequenceName}`;
|
|
23
|
+
await sql.raw(sqlStatement).execute(db);
|
|
21
24
|
}
|
|
22
25
|
/**
|
|
23
26
|
* Unique indexes cannot be populated by the same value even within a transaction,
|
|
@@ -148,7 +151,8 @@ export default class DreamMigrationHelpers {
|
|
|
148
151
|
*/
|
|
149
152
|
static newTransaction() { }
|
|
150
153
|
/**
|
|
151
|
-
* Drop a value from an enum and replace it
|
|
154
|
+
* Drop a value from an enum and replace it with a different enum already
|
|
155
|
+
* present in the enum type (or optionally remove it from array columns).
|
|
152
156
|
*
|
|
153
157
|
* @param db - The Kysely database object passed into the migration up/down function
|
|
154
158
|
* @param __namedParameters - The options for dropping the enum value
|
|
@@ -362,54 +362,6 @@ export default class DreamClassTransactionBuilder {
|
|
|
362
362
|
leftJoinPreload(...args) {
|
|
363
363
|
return this.queryInstance().leftJoinPreload(...args);
|
|
364
364
|
}
|
|
365
|
-
/**
|
|
366
|
-
* Recursively left-join-preloads all Dream associations referenced by `rendersOne` and `rendersMany`
|
|
367
|
-
* in a DreamSerializer. This traverses the entire content tree of serializers to automatically
|
|
368
|
-
* load all necessary associations, eliminating N+1 query problems and removing the need to
|
|
369
|
-
* manually remember which associations to preload for serialization.
|
|
370
|
-
*
|
|
371
|
-
* This method decouples data loading code from data rendering code by having the serializer
|
|
372
|
-
* (rendering code) inform the query (loading code) about which associations are needed.
|
|
373
|
-
* As serializers evolve over time - adding new `rendersOne` and `rendersMany` calls or
|
|
374
|
-
* modifying existing ones - the loading code automatically adapts without requiring
|
|
375
|
-
* corresponding modifications to preload statements.
|
|
376
|
-
*
|
|
377
|
-
* This method analyzes the serializer (specified by `serializerKey` or 'default') and
|
|
378
|
-
* automatically preloads all associations that will be needed during serialization.
|
|
379
|
-
*
|
|
380
|
-
* ```ts
|
|
381
|
-
* await ApplicationModel.transaction(async txn => {
|
|
382
|
-
* // Instead of manually specifying all associations:
|
|
383
|
-
* await User.txn(txn).preload('posts', 'comments', 'replies').all()
|
|
384
|
-
*
|
|
385
|
-
* // Automatically preload everything needed for serialization:
|
|
386
|
-
* await User.txn(txn).preloadFor('summary').all()
|
|
387
|
-
*
|
|
388
|
-
* // Add where conditions to specific associations during preloading:
|
|
389
|
-
* await User.txn(txn).leftJoinPreloadFor('detailed', (associationName, dreamClass) => {
|
|
390
|
-
* if (dreamClass.typeof(Post) && associationName === 'comments') {
|
|
391
|
-
* return { and: { published: true } }
|
|
392
|
-
* }
|
|
393
|
-
* }).all()
|
|
394
|
-
*
|
|
395
|
-
* // Skip preloading specific associations to handle them manually:
|
|
396
|
-
* await User.txn(txn).leftJoinPreloadFor('summary', (associationName, dreamClass) => {
|
|
397
|
-
* if (dreamClass.typeof(User) && associationName === 'posts') {
|
|
398
|
-
* return 'omit' // Handle posts preloading separately with custom logic
|
|
399
|
-
* }
|
|
400
|
-
* })
|
|
401
|
-
* .preload('posts', { and: { featured: true } }) // Custom preloading
|
|
402
|
-
* .all()
|
|
403
|
-
* })
|
|
404
|
-
* ```
|
|
405
|
-
*
|
|
406
|
-
* @param serializerKey - The serializer key to use for determining which associations to preload.
|
|
407
|
-
* @param modifierFn - Optional callback function to modify or omit specific associations during preloading. Called for each association with the Dream class and association name. Return an object with `and`, `andAny`, or `andNot` properties to add where conditions, return 'omit' to skip preloading that association (useful when you want to handle it manually), or return undefined to use default preloading
|
|
408
|
-
* @returns A Query with all serialization associations preloaded
|
|
409
|
-
*/
|
|
410
|
-
leftJoinPreloadFor(serializerKey, modifierFn) {
|
|
411
|
-
return this.queryInstance().leftJoinPreloadFor(serializerKey, modifierFn);
|
|
412
|
-
}
|
|
413
365
|
/**
|
|
414
366
|
* Applies preload statement to a Query scoped to this model.
|
|
415
367
|
* Upon instantiating records of this model type,
|
|
@@ -143,56 +143,6 @@ export default class DreamInstanceTransactionBuilder {
|
|
|
143
143
|
leftJoinLoad(...args) {
|
|
144
144
|
return new LeftJoinLoadBuilder(this.dreamInstance, this.dreamTransaction).leftJoinLoad(...args);
|
|
145
145
|
}
|
|
146
|
-
/**
|
|
147
|
-
* Recursively loads all Dream associations referenced by `rendersOne` and `rendersMany`
|
|
148
|
-
* in a DreamSerializer. This traverses the entire content tree of serializers to automatically
|
|
149
|
-
* load all necessary associations, eliminating N+1 query problems and removing the need to
|
|
150
|
-
* manually remember which associations to preload for serialization.
|
|
151
|
-
*
|
|
152
|
-
* This method decouples data loading code from data rendering code by having the serializer
|
|
153
|
-
* (rendering code) inform the query (loading code) about which associations are needed.
|
|
154
|
-
* As serializers evolve over time - adding new `rendersOne` and `rendersMany` calls or
|
|
155
|
-
* modifying existing ones - the loading code automatically adapts without requiring
|
|
156
|
-
* corresponding modifications to preload statements.
|
|
157
|
-
*
|
|
158
|
-
* This method analyzes the serializer (specified by `serializerKey` or 'default') and
|
|
159
|
-
* automatically preloads all associations that will be needed during serialization.
|
|
160
|
-
*
|
|
161
|
-
* ```ts
|
|
162
|
-
* await ApplicationModel.transaction(async txn => {
|
|
163
|
-
* // Instead of manually specifying all associations:
|
|
164
|
-
* await User.txn(txn).preload('posts', 'comments', 'replies').all()
|
|
165
|
-
*
|
|
166
|
-
* // Automatically preload everything needed for serialization:
|
|
167
|
-
* await user.txn(txn).leftJoinLoadFor('summary').execute()
|
|
168
|
-
*
|
|
169
|
-
* // Add where conditions to specific associations during preloading:
|
|
170
|
-
* await user.txn(txn).leftJoinLoadFor('detailed', (associationName, dreamClass) => {
|
|
171
|
-
* if (dreamClass.typeof(Post) && associationName === 'comments') {
|
|
172
|
-
* return { and: { published: true } }
|
|
173
|
-
* }
|
|
174
|
-
* }).execute()
|
|
175
|
-
*
|
|
176
|
-
* // Skip preloading specific associations to handle them manually:
|
|
177
|
-
* await user
|
|
178
|
-
* .txn(txn)
|
|
179
|
-
* .leftJoinLoadFor('summary', (associationName, dreamClass) => {
|
|
180
|
-
* if (dreamClass.typeof(User) && associationName === 'posts') {
|
|
181
|
-
* return 'omit' // Handle posts preloading separately with custom logic
|
|
182
|
-
* }
|
|
183
|
-
* })
|
|
184
|
-
* .load('posts', { and: { featured: true } }) // Custom preloading
|
|
185
|
-
* .execute()
|
|
186
|
-
* })
|
|
187
|
-
* ```
|
|
188
|
-
*
|
|
189
|
-
* @param serializerKey - The serializer key to use for determining which associations to preload.
|
|
190
|
-
* @param modifierFn - Optional callback function to modify or omit specific associations during preloading. Called for each association with the Dream class and association name. Return an object with `and`, `andAny`, or `andNot` properties to add where conditions, return 'omit' to skip preloading that association (useful when you want to handle it manually), or return undefined to use default preloading
|
|
191
|
-
* @returns A Query with all serialization associations preloaded
|
|
192
|
-
*/
|
|
193
|
-
leftJoinLoadFor(serializerKey, modifierFn) {
|
|
194
|
-
return new LeftJoinLoadBuilder(this.dreamInstance, this.dreamTransaction)['leftJoinLoadFor'](serializerKey, modifierFn);
|
|
195
|
-
}
|
|
196
146
|
/**
|
|
197
147
|
* Returns a new Query instance with the provided
|
|
198
148
|
* inner join statement attached
|
|
@@ -38,55 +38,6 @@ export default class LeftJoinLoadBuilder {
|
|
|
38
38
|
this.query = this.query.leftJoinPreload(...args);
|
|
39
39
|
return this;
|
|
40
40
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Recursively loads all Dream associations referenced by `rendersOne` and `rendersMany`
|
|
43
|
-
* in a DreamSerializer. This traverses the entire content tree of serializers to automatically
|
|
44
|
-
* load all necessary associations, eliminating N+1 query problems and removing the need to
|
|
45
|
-
* manually remember which associations to preload for serialization.
|
|
46
|
-
*
|
|
47
|
-
* This method decouples data loading code from data rendering code by having the serializer
|
|
48
|
-
* (rendering code) inform the query (loading code) about which associations are needed.
|
|
49
|
-
* As serializers evolve over time - adding new `rendersOne` and `rendersMany` calls or
|
|
50
|
-
* modifying existing ones - the loading code automatically adapts without requiring
|
|
51
|
-
* corresponding modifications to preload statements.
|
|
52
|
-
*
|
|
53
|
-
* This method analyzes the serializer (specified by `serializerKey` or 'default') and
|
|
54
|
-
* automatically preloads all associations that will be needed during serialization.
|
|
55
|
-
*
|
|
56
|
-
* ```ts
|
|
57
|
-
* // Instead of manually specifying all associations:
|
|
58
|
-
* await User.preload('posts', 'comments', 'replies').all()
|
|
59
|
-
*
|
|
60
|
-
* // Automatically preload everything needed for serialization:
|
|
61
|
-
* await user.leftJoinLoadFor('summary').execute()
|
|
62
|
-
*
|
|
63
|
-
* // Add where conditions to specific associations during preloading:
|
|
64
|
-
* await user.leftJoinLoadFor('detailed', (associationName, dreamClass) => {
|
|
65
|
-
* if (dreamClass.typeof(Post) && associationName === 'comments') {
|
|
66
|
-
* return { and: { published: true } }
|
|
67
|
-
* }
|
|
68
|
-
* })
|
|
69
|
-
* .execute()
|
|
70
|
-
*
|
|
71
|
-
* // Skip preloading specific associations to handle them manually:
|
|
72
|
-
* await user
|
|
73
|
-
* .leftJoinLoadFor('summary', (associationName, dreamClass) => {
|
|
74
|
-
* if (dreamClass.typeof(User) && associationName === 'posts') {
|
|
75
|
-
* return 'omit' // Handle posts preloading separately with custom logic
|
|
76
|
-
* }
|
|
77
|
-
* })
|
|
78
|
-
* .load('posts', { and: { featured: true } }) // Custom preloading
|
|
79
|
-
* .execute()
|
|
80
|
-
* ```
|
|
81
|
-
*
|
|
82
|
-
* @param serializerKey - The serializer key to use for determining which associations to preload.
|
|
83
|
-
* @param modifierFn - Optional callback function to modify or omit specific associations during preloading. Called for each association with the Dream class and association name. Return an object with `and`, `andAny`, or `andNot` properties to add where conditions, return 'omit' to skip preloading that association (useful when you want to handle it manually), or return undefined to use default preloading
|
|
84
|
-
* @returns A Query with all serialization associations preloaded
|
|
85
|
-
*/
|
|
86
|
-
leftJoinLoadFor(serializerKey, modifierFn) {
|
|
87
|
-
this.query = this.query.leftJoinPreloadFor(serializerKey, modifierFn);
|
|
88
|
-
return this;
|
|
89
|
-
}
|
|
90
41
|
/**
|
|
91
42
|
* executes a load builder query, binding
|
|
92
43
|
* all associations to their respective model
|
|
@@ -530,63 +530,6 @@ export default class Query {
|
|
|
530
530
|
});
|
|
531
531
|
return query;
|
|
532
532
|
}
|
|
533
|
-
/**
|
|
534
|
-
* Recursively preloads all Dream associations referenced by `rendersOne` and `rendersMany`
|
|
535
|
-
* in a DreamSerializer using left join preloading. This traverses the entire content tree
|
|
536
|
-
* of serializers to automatically load all necessary associations in a single query,
|
|
537
|
-
* eliminating N+1 query problems and removing the need to manually remember which
|
|
538
|
-
* associations to preload for serialization.
|
|
539
|
-
*
|
|
540
|
-
* This method decouples data loading code from data rendering code by having the serializer
|
|
541
|
-
* (rendering code) inform the query (loading code) about which associations are needed.
|
|
542
|
-
* As serializers evolve over time - adding new `rendersOne` and `rendersMany` calls or
|
|
543
|
-
* modifying existing ones - the loading code automatically adapts without requiring
|
|
544
|
-
* corresponding modifications to left join preload statements.
|
|
545
|
-
*
|
|
546
|
-
* This method analyzes the serializer (specified by `serializerKey` or 'default') and
|
|
547
|
-
* automatically left join preloads all associations that will be needed during serialization.
|
|
548
|
-
*
|
|
549
|
-
* Note: Left join preloading loads all data in a single SQL query but has trade-offs compared
|
|
550
|
-
* to regular preloading. See {@link Dream.leftJoinPreload} for details about limitations.
|
|
551
|
-
*
|
|
552
|
-
* ```ts
|
|
553
|
-
* // Instead of manually specifying all associations:
|
|
554
|
-
* await User.leftJoinPreload('posts', 'comments', 'replies').all()
|
|
555
|
-
*
|
|
556
|
-
* // Automatically left join preload everything needed for serialization:
|
|
557
|
-
* await User.leftJoinPreloadFor('summary').all()
|
|
558
|
-
*
|
|
559
|
-
* // Add where conditions to specific associations during left join preloading:
|
|
560
|
-
* await User.leftJoinPreloadFor('detailed', (associationName, dreamClass) => {
|
|
561
|
-
* if (dreamClass.typeof(Post) && associationName === 'comments') {
|
|
562
|
-
* return { and: { published: true } }
|
|
563
|
-
* }
|
|
564
|
-
* })
|
|
565
|
-
* .all()
|
|
566
|
-
*
|
|
567
|
-
* // Skip left join preloading specific associations to handle them manually:
|
|
568
|
-
* await User.leftJoinPreloadFor('summary', (associationName, dreamClass) => {
|
|
569
|
-
* if (dreamClass.typeof(User) && associationName === 'posts') {
|
|
570
|
-
* return 'omit' // Handle posts preloading separately with custom logic
|
|
571
|
-
* }
|
|
572
|
-
* })
|
|
573
|
-
* .preload('posts', { and: { featured: true } }) // Custom preloading instead
|
|
574
|
-
* .all()
|
|
575
|
-
* ```
|
|
576
|
-
*
|
|
577
|
-
* @param serializerKey - The serializer key to use for determining which associations to preload.
|
|
578
|
-
* @param modifierFn - Optional callback function to modify or omit specific associations during preloading. Called for each association with the Dream class and association name. Return an object with `and`, `andAny`, or `andNot` properties to add where conditions, return 'omit' to skip preloading that association (useful when you want to handle it manually), or return undefined to use default preloading
|
|
579
|
-
* @returns A Query with all serialization associations left join preloaded
|
|
580
|
-
*/
|
|
581
|
-
leftJoinPreloadFor(serializerKey, modifierFn) {
|
|
582
|
-
const preloadArgs = extractNestedPaths(this.dreamClass['serializationMap'](serializerKey));
|
|
583
|
-
let query = this;
|
|
584
|
-
const counter = { count: 0 };
|
|
585
|
-
preloadArgs.forEach(dreamClassAndAssociationNameTupleArray => {
|
|
586
|
-
query = query.leftJoinPreload(...convertDreamClassAndAssociationNameTupleArrayToPreloadArgs(dreamClassAndAssociationNameTupleArray, modifierFn, counter));
|
|
587
|
-
});
|
|
588
|
-
return query;
|
|
589
|
-
}
|
|
590
533
|
/**
|
|
591
534
|
* Returns a new Query instance, with the provided
|
|
592
535
|
* joins statement attached
|
|
@@ -392,6 +392,8 @@ export default class KyselyQueryDriver extends QueryDriverBase {
|
|
|
392
392
|
return null;
|
|
393
393
|
}
|
|
394
394
|
/**
|
|
395
|
+
* @internal
|
|
396
|
+
*
|
|
395
397
|
* Retrieves an array containing all records matching the Query.
|
|
396
398
|
* Be careful using this, since it will attempt to pull every
|
|
397
399
|
* record into memory at once. When querying might return a large
|
|
@@ -9,6 +9,6 @@ export default function globalSerializerKeyFromPath(filepath, dirPath, exportKey
|
|
|
9
9
|
}
|
|
10
10
|
else {
|
|
11
11
|
const namePrefixFromPath = defaultExport.replace(/[^/]+\/?$/, '');
|
|
12
|
-
return namePrefixFromPath + exportKey.replace(new RegExp(`^${namePrefixFromPath.replace(
|
|
12
|
+
return namePrefixFromPath + exportKey.replace(new RegExp(`^${namePrefixFromPath.replace(/\//g, '')}`), '');
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -8,9 +8,18 @@ import DreamAppInitMissingMissingProjectRoot from '../errors/dream-app/DreamAppI
|
|
|
8
8
|
import CalendarDate from '../helpers/CalendarDate.js';
|
|
9
9
|
import { DateTime, Settings } from '../helpers/DateTime.js';
|
|
10
10
|
import EnvInternal from '../helpers/EnvInternal.js';
|
|
11
|
+
import globalClassNameFromFullyQualifiedModelName from '../helpers/globalClassNameFromFullyQualifiedModelName.js';
|
|
12
|
+
import absoluteDreamPath from '../helpers/path/absoluteDreamPath.js';
|
|
13
|
+
import dreamPath from '../helpers/path/dreamPath.js';
|
|
14
|
+
import standardizeFullyQualifiedModelName from '../helpers/standardizeFullyQualifiedModelName.js';
|
|
15
|
+
import expandStiClasses from '../helpers/sti/expandStiClasses.js';
|
|
16
|
+
import inferSerializerFromDreamOrViewModel, { inferSerializersFromDreamClassOrViewModelClass, } from '../serializer/helpers/inferSerializerFromDreamOrViewModel.js';
|
|
17
|
+
import isDreamSerializer from '../serializer/helpers/isDreamSerializer.js';
|
|
18
|
+
import serializerNameFromFullyQualifiedModelName from '../serializer/helpers/serializerNameFromFullyQualifiedModelName.js';
|
|
11
19
|
import { cacheDreamApp, getCachedDreamAppOrFail } from './cache.js';
|
|
12
20
|
import importModels, { getModelsOrFail } from './helpers/importers/importModels.js';
|
|
13
21
|
import importSerializers, { getSerializersOrFail, setCachedSerializers, } from './helpers/importers/importSerializers.js';
|
|
22
|
+
import lookupClassByGlobalName from './helpers/lookupClassByGlobalName.js';
|
|
14
23
|
// this needs to be done top-level to ensure proper configuration
|
|
15
24
|
Settings.defaultZone = 'UTC';
|
|
16
25
|
export default class DreamApp {
|
|
@@ -44,6 +53,47 @@ export default class DreamApp {
|
|
|
44
53
|
});
|
|
45
54
|
return dreamApp;
|
|
46
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Since javascript is inherently vulnerable to circular dependencies,
|
|
58
|
+
* this function provides a workaround by enabling you to dynamically
|
|
59
|
+
* bring in classes that, if imported directly, would result in circular
|
|
60
|
+
* dependency issues.
|
|
61
|
+
*
|
|
62
|
+
* NOTE: You should only use this as a last resort, since it can create quite
|
|
63
|
+
* a headache for you when leaning into your editor to apply renames, etc...
|
|
64
|
+
*
|
|
65
|
+
* @param name - the global name you are trying to look up, i.e. 'User', or 'UserSerializer'.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* // this pattern is safe from circular imports, since _UserSerializer
|
|
70
|
+
* // is only being used to type something else, which will not result
|
|
71
|
+
* // in the circular dependency issue.
|
|
72
|
+
*
|
|
73
|
+
* import _UserSerializer from '../serializers/UserSerializer.js'
|
|
74
|
+
* const UserSerializer = PsychicApp.lookupClassByGlobalName('UserSerializer') as _UserSerializer
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
static lookupClassByGlobalName(name) {
|
|
78
|
+
return lookupClassByGlobalName(name);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @internal
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
static get system() {
|
|
85
|
+
return {
|
|
86
|
+
globalClassNameFromFullyQualifiedModelName,
|
|
87
|
+
absoluteDreamPath,
|
|
88
|
+
dreamPath,
|
|
89
|
+
standardizeFullyQualifiedModelName,
|
|
90
|
+
expandStiClasses,
|
|
91
|
+
inferSerializerFromDreamOrViewModel,
|
|
92
|
+
inferSerializersFromDreamClassOrViewModelClass,
|
|
93
|
+
isDreamSerializer,
|
|
94
|
+
serializerNameFromFullyQualifiedModelName,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
47
97
|
/**
|
|
48
98
|
* @internal
|
|
49
99
|
*
|
|
@@ -11,9 +11,10 @@ export default function generateDreamContent({ fullyQualifiedModelName, columnsW
|
|
|
11
11
|
fullyQualifiedModelName = standardizeFullyQualifiedModelName(fullyQualifiedModelName);
|
|
12
12
|
const modelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedModelName);
|
|
13
13
|
let parentModelClassName;
|
|
14
|
-
const
|
|
14
|
+
const dreamTypeImports = ['DreamColumn'];
|
|
15
|
+
const dreamImports = ['Decorators'];
|
|
15
16
|
if (serializer)
|
|
16
|
-
|
|
17
|
+
dreamTypeImports.push('DreamSerializers');
|
|
17
18
|
const isSTI = !!fullyQualifiedParentName;
|
|
18
19
|
if (isSTI) {
|
|
19
20
|
fullyQualifiedParentName = standardizeFullyQualifiedModelName(fullyQualifiedParentName);
|
|
@@ -49,9 +50,8 @@ public ${associationForeignKey}: DreamColumn<${modelClassName}, '${associationNa
|
|
|
49
50
|
case 'has_many':
|
|
50
51
|
return '';
|
|
51
52
|
case 'encrypted':
|
|
52
|
-
dreamImports.push('Encrypted');
|
|
53
53
|
return `
|
|
54
|
-
@Encrypted()
|
|
54
|
+
@deco.Encrypted()
|
|
55
55
|
public ${camelize(attributeName)}: ${getAttributeType(attribute, modelClassName)}\
|
|
56
56
|
`;
|
|
57
57
|
default:
|
|
@@ -77,7 +77,7 @@ public ${camelize(attributeName)}: ${getAttributeType(attribute, modelClassName)
|
|
|
77
77
|
timestamps = timestamps.replace(/\n$/, '');
|
|
78
78
|
const tableName = snakeify(pluralize(fullyQualifiedModelName.replace(/\//g, '_')));
|
|
79
79
|
return `\
|
|
80
|
-
import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'${uniq(modelImportStatements).join('')}
|
|
80
|
+
${dreamImports.length ? `import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'\n` : ''}import { ${uniq(dreamTypeImports).join(', ')} } from '@rvoh/dream/types'${uniq(modelImportStatements).join('')}
|
|
81
81
|
|
|
82
82
|
const deco = new Decorators<typeof ${modelClassName}>()
|
|
83
83
|
|
|
@@ -6,7 +6,8 @@ import uniq from '../uniq.js';
|
|
|
6
6
|
import { optionalFromDescriptors } from './generateMigrationContent.js';
|
|
7
7
|
export default function generateFactoryContent({ fullyQualifiedModelName, columnsWithTypes, }) {
|
|
8
8
|
fullyQualifiedModelName = standardizeFullyQualifiedModelName(fullyQualifiedModelName);
|
|
9
|
-
const
|
|
9
|
+
const dreamTypeImports = ['UpdateableProperties'];
|
|
10
|
+
const dreamImports = [];
|
|
10
11
|
const additionalImports = [];
|
|
11
12
|
const belongsToNames = [];
|
|
12
13
|
const belongsToTypedNames = [];
|
|
@@ -23,6 +24,8 @@ export default function generateFactoryContent({ fullyQualifiedModelName, column
|
|
|
23
24
|
if (optional)
|
|
24
25
|
continue;
|
|
25
26
|
const attributeVariable = camelize(attributeName.replace(/\//g, ''));
|
|
27
|
+
if (/^type$/.test(attributeName))
|
|
28
|
+
continue;
|
|
26
29
|
if (/(_type|_id)$/.test(attributeName))
|
|
27
30
|
continue;
|
|
28
31
|
if (!attributeType)
|
|
@@ -101,7 +104,7 @@ export default function generateFactoryContent({ fullyQualifiedModelName, column
|
|
|
101
104
|
const relativePath = absoluteDreamPath('models', fullyQualifiedModelName);
|
|
102
105
|
const modelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedModelName);
|
|
103
106
|
return `\
|
|
104
|
-
import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'
|
|
107
|
+
${dreamImports.length ? `import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'\n` : ''}import { ${uniq(dreamTypeImports).join(', ')} } from '@rvoh/dream/types'
|
|
105
108
|
import ${modelClassName} from '${relativePath}'${additionalImports.length ? '\n' + uniq(additionalImports).join('\n') : ''}
|
|
106
109
|
${counterVariableIncremented ? '\nlet counter = 0\n' : ''}
|
|
107
110
|
export default async function create${modelClassName}(attrs: UpdateableProperties<${modelClassName}> = {}) {
|
|
@@ -11,7 +11,12 @@ export default function generateMigrationContent({ connectionName = 'default', t
|
|
|
11
11
|
const checkConstraints = [];
|
|
12
12
|
const { columnDefs, columnDrops, indexDefs, indexDrops } = columnsWithTypes.reduce((acc, attributeDeclaration) => {
|
|
13
13
|
const { columnDefs, columnDrops, indexDefs, indexDrops } = acc;
|
|
14
|
-
const [nonStandardAttributeName,
|
|
14
|
+
const [nonStandardAttributeName, _attributeType, ...descriptors] = attributeDeclaration.split(':');
|
|
15
|
+
/**
|
|
16
|
+
* Automatically set email columns to citext since different casings of
|
|
17
|
+
* email address are the same email address
|
|
18
|
+
*/
|
|
19
|
+
const attributeType = nonStandardAttributeName === 'email' ? 'citext' : _attributeType;
|
|
15
20
|
const userWantsThisOptional = optionalFromDescriptors(descriptors);
|
|
16
21
|
// when creating a migration for an STI child, we don't want to include notNull;
|
|
17
22
|
// instead, we'll add a check constraint that uses the STI child class name
|
|
@@ -116,9 +121,9 @@ export async function down(db: Kysely<any>): Promise<void> {
|
|
|
116
121
|
? ` await DreamMigrationHelpers.createExtension(db, 'citext')\n\n`
|
|
117
122
|
: '';
|
|
118
123
|
const kyselyImports = ['Kysely', 'sql'];
|
|
119
|
-
const
|
|
124
|
+
const dreamDbImports = [];
|
|
120
125
|
if (requireCitextExtension)
|
|
121
|
-
|
|
126
|
+
dreamDbImports.push('DreamMigrationHelpers');
|
|
122
127
|
const newlineIndent = '\n ';
|
|
123
128
|
const newlineDoubleIndent = '\n ';
|
|
124
129
|
const doubleNewlineIndent = '\n\n ';
|
|
@@ -127,7 +132,7 @@ export async function down(db: Kysely<any>): Promise<void> {
|
|
|
127
132
|
? newlineDoubleIndent + columnDrops.join(newlineDoubleIndent) + newlineDoubleIndent
|
|
128
133
|
: '';
|
|
129
134
|
return `\
|
|
130
|
-
${
|
|
135
|
+
${dreamDbImports.length ? `import { ${dreamDbImports.join(', ')} } from '@rvoh/dream/db'\n` : ''}import { ${kyselyImports.join(', ')} } from 'kysely'
|
|
131
136
|
|
|
132
137
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
133
138
|
export async function up(db: Kysely<any>): Promise<void> {
|
|
@@ -231,6 +236,8 @@ function generateColumnStr(attributeName, attributeType, descriptors, { omitInli
|
|
|
231
236
|
returnStr += ', col => col';
|
|
232
237
|
if (notNull)
|
|
233
238
|
returnStr += '.notNull()';
|
|
239
|
+
if (attributeName === 'email' || /token$/.test(attributeName))
|
|
240
|
+
returnStr += '.unique()';
|
|
234
241
|
if (providedDefault)
|
|
235
242
|
returnStr += `.defaultTo('${providedDefault}')`;
|
|
236
243
|
else if (isArray)
|