@rvoh/dream 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +382 -0
- package/boilerplate/app/models/ApplicationModel.ts +14 -0
- package/boilerplate/app/serializers/.gitkeep +0 -0
- package/boilerplate/bin/esm.js +19 -0
- package/boilerplate/cli/helpers/initializeDreamApplication.ts +6 -0
- package/boilerplate/cli/index.ts +22 -0
- package/boilerplate/conf/inflections.ts +5 -0
- package/boilerplate/conf/loadEnv.ts +4 -0
- package/boilerplate/conf/repl.ts +11 -0
- package/boilerplate/eslint.config.js +21 -0
- package/boilerplate/package.json +42 -0
- package/boilerplate/tsconfig.build.json +41 -0
- package/boilerplate/tsconfig.json +12 -0
- package/boilerplate/types/db.ts +5 -0
- package/boilerplate/types/dream.ts +3 -0
- package/dist/cjs/boilerplate/package.json +42 -0
- package/dist/cjs/src/Dream.js +2984 -0
- package/dist/cjs/src/bin/helpers/sync.js +109 -0
- package/dist/cjs/src/bin/index.js +107 -0
- package/dist/cjs/src/cli/index.js +155 -0
- package/dist/cjs/src/db/ConnectedToDB.js +43 -0
- package/dist/cjs/src/db/ConnectionConfRetriever.js +22 -0
- package/dist/cjs/src/db/DreamDbConnection.js +77 -0
- package/dist/cjs/src/db/dataTypes.js +58 -0
- package/dist/cjs/src/db/errors.js +17 -0
- package/dist/cjs/src/db/index.js +12 -0
- package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +193 -0
- package/dist/cjs/src/db/reflections.js +2 -0
- package/dist/cjs/src/db/types.js +2 -0
- package/dist/cjs/src/db/validators/validateColumn.js +11 -0
- package/dist/cjs/src/db/validators/validateTable.js +9 -0
- package/dist/cjs/src/db/validators/validateTableAlias.js +55 -0
- package/dist/cjs/src/decorators/DecoratorContextType.js +2 -0
- package/dist/cjs/src/decorators/Decorators.js +326 -0
- package/dist/cjs/src/decorators/Encrypted.js +83 -0
- package/dist/cjs/src/decorators/ReplicaSafe.js +12 -0
- package/dist/cjs/src/decorators/STI.js +35 -0
- package/dist/cjs/src/decorators/Scope.js +31 -0
- package/dist/cjs/src/decorators/SoftDelete.js +54 -0
- package/dist/cjs/src/decorators/Virtual.js +28 -0
- package/dist/cjs/src/decorators/associations/BelongsTo.js +77 -0
- package/dist/cjs/src/decorators/associations/HasMany.js +100 -0
- package/dist/cjs/src/decorators/associations/HasOne.js +96 -0
- package/dist/cjs/src/decorators/associations/associationToGetterSetterProp.js +6 -0
- package/dist/cjs/src/decorators/associations/shared.js +132 -0
- package/dist/cjs/src/decorators/helpers/freezeBaseClassArrayMap.js +10 -0
- package/dist/cjs/src/decorators/hooks/AfterCreate.js +26 -0
- package/dist/cjs/src/decorators/hooks/AfterCreateCommit.js +43 -0
- package/dist/cjs/src/decorators/hooks/AfterDestroy.js +25 -0
- package/dist/cjs/src/decorators/hooks/AfterDestroyCommit.js +40 -0
- package/dist/cjs/src/decorators/hooks/AfterSave.js +26 -0
- package/dist/cjs/src/decorators/hooks/AfterSaveCommit.js +43 -0
- package/dist/cjs/src/decorators/hooks/AfterUpdate.js +26 -0
- package/dist/cjs/src/decorators/hooks/AfterUpdateCommit.js +43 -0
- package/dist/cjs/src/decorators/hooks/BeforeCreate.js +26 -0
- package/dist/cjs/src/decorators/hooks/BeforeDestroy.js +25 -0
- package/dist/cjs/src/decorators/hooks/BeforeSave.js +26 -0
- package/dist/cjs/src/decorators/hooks/BeforeUpdate.js +26 -0
- package/dist/cjs/src/decorators/hooks/shared.js +23 -0
- package/dist/cjs/src/decorators/sortable/Sortable.js +160 -0
- package/dist/cjs/src/decorators/sortable/helpers/applySortableScopeToQuery.js +17 -0
- package/dist/cjs/src/decorators/sortable/helpers/clearCachedSortableValues.js +11 -0
- package/dist/cjs/src/decorators/sortable/helpers/decrementScopedRecordsGreaterThanPosition.js +26 -0
- package/dist/cjs/src/decorators/sortable/helpers/getColumnForSortableScope.js +18 -0
- package/dist/cjs/src/decorators/sortable/helpers/isSortedCorrectly.js +7 -0
- package/dist/cjs/src/decorators/sortable/helpers/positionIsInvalid.js +11 -0
- package/dist/cjs/src/decorators/sortable/helpers/resortAllRecords.js +38 -0
- package/dist/cjs/src/decorators/sortable/helpers/scopeArray.js +10 -0
- package/dist/cjs/src/decorators/sortable/helpers/setPosition.js +158 -0
- package/dist/cjs/src/decorators/sortable/helpers/sortableCacheKeyName.js +7 -0
- package/dist/cjs/src/decorators/sortable/helpers/sortableCacheValuesName.js +7 -0
- package/dist/cjs/src/decorators/sortable/helpers/sortableQueryExcludingDream.js +10 -0
- package/dist/cjs/src/decorators/sortable/hooks/afterSortableCreate.js +18 -0
- package/dist/cjs/src/decorators/sortable/hooks/afterSortableDestroy.js +14 -0
- package/dist/cjs/src/decorators/sortable/hooks/afterSortableUpdate.js +31 -0
- package/dist/cjs/src/decorators/sortable/hooks/beforeSortableSave.js +65 -0
- package/dist/cjs/src/decorators/validations/Validate.js +22 -0
- package/dist/cjs/src/decorators/validations/Validates.js +70 -0
- package/dist/cjs/src/decorators/validations/shared.js +2 -0
- package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +592 -0
- package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +480 -0
- package/dist/cjs/src/dream/DreamTransaction.js +26 -0
- package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +77 -0
- package/dist/cjs/src/dream/LoadBuilder.js +68 -0
- package/dist/cjs/src/dream/Query.js +2618 -0
- package/dist/cjs/src/dream/internal/applyScopeBypassingSettingsToQuery.js +11 -0
- package/dist/cjs/src/dream/internal/associations/associationQuery.js +23 -0
- package/dist/cjs/src/dream/internal/associations/associationUpdateQuery.js +36 -0
- package/dist/cjs/src/dream/internal/associations/createAssociation.js +55 -0
- package/dist/cjs/src/dream/internal/associations/destroyAssociation.js +17 -0
- package/dist/cjs/src/dream/internal/associations/undestroyAssociation.js +12 -0
- package/dist/cjs/src/dream/internal/checkSingleValidation.js +52 -0
- package/dist/cjs/src/dream/internal/destroyAssociatedRecords.js +21 -0
- package/dist/cjs/src/dream/internal/destroyDream.js +72 -0
- package/dist/cjs/src/dream/internal/destroyOptions.js +32 -0
- package/dist/cjs/src/dream/internal/ensureSTITypeFieldIsSet.js +10 -0
- package/dist/cjs/src/dream/internal/executeDatabaseQuery.js +24 -0
- package/dist/cjs/src/dream/internal/extractAssociationMetadataFromAssociationName.js +8 -0
- package/dist/cjs/src/dream/internal/orderByDirection.js +15 -0
- package/dist/cjs/src/dream/internal/reload.js +21 -0
- package/dist/cjs/src/dream/internal/runHooksFor.js +99 -0
- package/dist/cjs/src/dream/internal/runValidations.js +16 -0
- package/dist/cjs/src/dream/internal/safelyRunCommitHooks.js +15 -0
- package/dist/cjs/src/dream/internal/saveDream.js +67 -0
- package/dist/cjs/src/dream/internal/scopeHelpers.js +13 -0
- package/dist/cjs/src/dream/internal/shouldBypassDefaultScope.js +12 -0
- package/dist/cjs/src/dream/internal/similarity/SimilarityBuilder.js +331 -0
- package/dist/cjs/src/dream/internal/similarity/similaritySelectSql.js +21 -0
- package/dist/cjs/src/dream/internal/similarity/similarityWhereSql.js +21 -0
- package/dist/cjs/src/dream/internal/softDeleteDream.js +22 -0
- package/dist/cjs/src/dream/internal/sqlResultToDreamInstance.js +38 -0
- package/dist/cjs/src/dream/internal/undestroyDream.js +90 -0
- package/dist/cjs/src/dream/types.js +98 -0
- package/dist/cjs/src/dream-application/cache.js +13 -0
- package/dist/cjs/src/dream-application/helpers/DreamImporter.js +52 -0
- package/dist/cjs/src/dream-application/helpers/globalModelKeyFromPath.js +10 -0
- package/dist/cjs/src/dream-application/helpers/globalSerializerKeyFromPath.js +17 -0
- package/dist/cjs/src/dream-application/helpers/globalServiceKeyFromPath.js +11 -0
- package/dist/cjs/src/dream-application/helpers/importers/importModels.js +81 -0
- package/dist/cjs/src/dream-application/helpers/importers/importSerializers.js +63 -0
- package/dist/cjs/src/dream-application/helpers/importers/importServices.js +43 -0
- package/dist/cjs/src/dream-application/helpers/lookupClassByGlobalName.js +17 -0
- package/dist/cjs/src/dream-application/helpers/lookupModelByGlobalName.js +13 -0
- package/dist/cjs/src/dream-application/helpers/lookupModelByGlobalNameOrNames.js +10 -0
- package/dist/cjs/src/dream-application/index.js +284 -0
- package/dist/cjs/src/encrypt/InternalEncrypt.js +32 -0
- package/dist/cjs/src/encrypt/algorithms/aes-gcm/decryptAESGCM.js +26 -0
- package/dist/cjs/src/encrypt/algorithms/aes-gcm/encryptAESGCM.js +12 -0
- package/dist/cjs/src/encrypt/algorithms/aes-gcm/generateKeyAESGCM.js +7 -0
- package/dist/cjs/src/encrypt/algorithms/aes-gcm/validateKeyAESGCM.js +11 -0
- package/dist/cjs/src/encrypt/index.js +95 -0
- package/dist/cjs/src/errors/AttemptingToMarshalInvalidArrayType.js +20 -0
- package/dist/cjs/src/errors/CannotCallUndestroyOnANonSoftDeleteModel.js +21 -0
- package/dist/cjs/src/errors/CannotDefineAssociationWithBothDependentAndPassthrough.js +19 -0
- package/dist/cjs/src/errors/CannotDefineAssociationWithBothDependentAndRequiredOnClause.js +19 -0
- package/dist/cjs/src/errors/CannotNegateSimilarityClause.js +22 -0
- package/dist/cjs/src/errors/CannotPassAdditionalFieldsToPluckEachAfterCallback.js +22 -0
- package/dist/cjs/src/errors/CannotPassUndefinedAsAValueToAWhereClause.js +20 -0
- package/dist/cjs/src/errors/CannotReloadUnsavedDream.js +16 -0
- package/dist/cjs/src/errors/ConstructorOnlyForInternalUse.js +9 -0
- package/dist/cjs/src/errors/CreateOrFindByFailedToCreateAndFind.js +18 -0
- package/dist/cjs/src/errors/DoNotSetEncryptedFieldsDirectly.js +23 -0
- package/dist/cjs/src/errors/InvalidColumnName.js +19 -0
- package/dist/cjs/src/errors/InvalidDecimalFieldPassedToGenerator.js +19 -0
- package/dist/cjs/src/errors/InvalidTableAlias.js +30 -0
- package/dist/cjs/src/errors/InvalidTableName.js +23 -0
- package/dist/cjs/src/errors/LeftJoinPreloadIncompatibleWithFindEach.js +12 -0
- package/dist/cjs/src/errors/MissingDB.js +10 -0
- package/dist/cjs/src/errors/MissingDeletedAtFieldForSoftDelete.js +24 -0
- package/dist/cjs/src/errors/MissingRequiredCallbackFunctionToPluckEach.js +22 -0
- package/dist/cjs/src/errors/MissingSerializersDefinition.js +26 -0
- package/dist/cjs/src/errors/MissingTable.js +27 -0
- package/dist/cjs/src/errors/NoUpdateAllOnJoins.js +13 -0
- package/dist/cjs/src/errors/NoUpdateOnAssociationQuery.js +10 -0
- package/dist/cjs/src/errors/NonBelongsToAssociationProvidedAsSortableDecoratorScope.js +23 -0
- package/dist/cjs/src/errors/NonExistentScopeProvidedToResort.js +23 -0
- package/dist/cjs/src/errors/PrototypePollutingAssignment.js +13 -0
- package/dist/cjs/src/errors/RecordNotFound.js +15 -0
- package/dist/cjs/src/errors/SortableDecoratorRequiresColumnOrBelongsToAssociation.js +26 -0
- package/dist/cjs/src/errors/ValidationError.js +19 -0
- package/dist/cjs/src/errors/associations/CanOnlyPassBelongsToModelParam.js +20 -0
- package/dist/cjs/src/errors/associations/CannotAssociateThroughPolymorphic.js +19 -0
- package/dist/cjs/src/errors/associations/CannotCreateAssociationWithThroughContext.js +19 -0
- package/dist/cjs/src/errors/associations/CannotJoinPolymorphicBelongsToError.js +27 -0
- package/dist/cjs/src/errors/associations/CannotPassNullOrUndefinedToRequiredBelongsTo.js +19 -0
- package/dist/cjs/src/errors/associations/InvalidComputedForeignKey.js +64 -0
- package/dist/cjs/src/errors/associations/JoinAttemptedOnMissingAssociation.js +27 -0
- package/dist/cjs/src/errors/associations/MissingRequiredAssociationOnClause.js +19 -0
- package/dist/cjs/src/errors/associations/MissingRequiredPassthroughForAssociationOnClause.js +16 -0
- package/dist/cjs/src/errors/associations/MissingThroughAssociation.js +27 -0
- package/dist/cjs/src/errors/associations/MissingThroughAssociationSource.js +42 -0
- package/dist/cjs/src/errors/associations/NonLoadedAssociation.js +18 -0
- package/dist/cjs/src/errors/dream-application/DreamApplicationInitMissingCallToLoadModels.js +18 -0
- package/dist/cjs/src/errors/dream-application/DreamApplicationInitMissingMissingProjectRoot.js +19 -0
- package/dist/cjs/src/errors/dream-application/GlobalNameNotSet.js +14 -0
- package/dist/cjs/src/errors/dream-application/SerializerNameConflict.js +15 -0
- package/dist/cjs/src/errors/encrypt/MissingColumnEncryptionOpts.js +27 -0
- package/dist/cjs/src/errors/encrypt/MissingEncryptionKey.js +12 -0
- package/dist/cjs/src/errors/environment/MissingRequiredEnvironmentVariable.js +13 -0
- package/dist/cjs/src/errors/ops/AnyRequiresArrayColumn.js +18 -0
- package/dist/cjs/src/errors/ops/ScoreMustBeANormalNumber.js +17 -0
- package/dist/cjs/src/errors/schema-builder/FailedToIdentifyAssociation.js +80 -0
- package/dist/cjs/src/errors/serializers/FailedToRenderThroughAssociationForSerializer.js +17 -0
- package/dist/cjs/src/errors/sortable/CannotCallSortableOnSTIChild.js +18 -0
- package/dist/cjs/src/errors/sti/STIChildMissing.js +23 -0
- package/dist/cjs/src/errors/sti/StiChildCannotDefineNewAssociations.js +20 -0
- package/dist/cjs/src/errors/sti/StiChildIncompatibleWithReplicaSafeDecorator.js +17 -0
- package/dist/cjs/src/errors/sti/StiChildIncompatibleWithSoftDeleteDecorator.js +17 -0
- package/dist/cjs/src/global-cli/dream.js +46 -0
- package/dist/cjs/src/global-cli/file-builders/DreamtsBuilder.js +69 -0
- package/dist/cjs/src/global-cli/file-builders/EnvBuilder.js +27 -0
- package/dist/cjs/src/global-cli/file-builders/EslintConfBuilder.js +29 -0
- package/dist/cjs/src/global-cli/file-builders/PackagejsonBuilder.js +9 -0
- package/dist/cjs/src/global-cli/helpers/argAndValue.js +15 -0
- package/dist/cjs/src/global-cli/helpers/autogeneratedFileMessage.js +71 -0
- package/dist/cjs/src/global-cli/helpers/buildNewDreamApp.js +63 -0
- package/dist/cjs/src/global-cli/helpers/copyRecursive.js +20 -0
- package/dist/cjs/src/global-cli/helpers/filterObjectByKey.js +23 -0
- package/dist/cjs/src/global-cli/helpers/generateEncryptionKey.js +26 -0
- package/dist/cjs/src/global-cli/helpers/globalCliSnakeify.js +1 -0
- package/dist/cjs/src/global-cli/helpers/initDreamAppIntoExistingProject.js +85 -0
- package/dist/cjs/src/global-cli/helpers/log.js +28 -0
- package/dist/cjs/src/global-cli/helpers/logo.js +81 -0
- package/dist/cjs/src/global-cli/helpers/primaryKeyTypes.js +13 -0
- package/dist/cjs/src/global-cli/helpers/prompt.js +33 -0
- package/dist/cjs/src/global-cli/helpers/select.js +113 -0
- package/dist/cjs/src/global-cli/helpers/sleep.js +10 -0
- package/dist/cjs/src/global-cli/helpers/sspawn.js +21 -0
- package/dist/cjs/src/global-cli/helpers/welcomeMessage.js +41 -0
- package/dist/cjs/src/global-cli/init.js +56 -0
- package/dist/cjs/src/global-cli/new.js +10 -0
- package/dist/cjs/src/helpers/CalendarDate.js +172 -0
- package/dist/cjs/src/helpers/Env.js +78 -0
- package/dist/cjs/src/helpers/EnvInternal.js +5 -0
- package/dist/cjs/src/helpers/allNestedObjectKeys.js +12 -0
- package/dist/cjs/src/helpers/benchmark.js +18 -0
- package/dist/cjs/src/helpers/camelize.js +15 -0
- package/dist/cjs/src/helpers/capitalize.js +6 -0
- package/dist/cjs/src/helpers/cli/SchemaBuilder.js +378 -0
- package/dist/cjs/src/helpers/cli/generateDream.js +48 -0
- package/dist/cjs/src/helpers/cli/generateDreamContent.js +107 -0
- package/dist/cjs/src/helpers/cli/generateFactory.js +26 -0
- package/dist/cjs/src/helpers/cli/generateFactoryContent.js +58 -0
- package/dist/cjs/src/helpers/cli/generateMigration.js +56 -0
- package/dist/cjs/src/helpers/cli/generateMigrationContent.js +196 -0
- package/dist/cjs/src/helpers/cli/generateSerializer.js +26 -0
- package/dist/cjs/src/helpers/cli/generateSerializerContent.js +130 -0
- package/dist/cjs/src/helpers/cli/generateStiMigrationContent.js +7 -0
- package/dist/cjs/src/helpers/cli/generateUnitSpec.js +26 -0
- package/dist/cjs/src/helpers/cli/generateUnitSpecContent.js +10 -0
- package/dist/cjs/src/helpers/cloneDeepSafe.js +69 -0
- package/dist/cjs/src/helpers/compact.js +14 -0
- package/dist/cjs/src/helpers/customPgParsers.js +39 -0
- package/dist/cjs/src/helpers/db/cachedTypeForAttribute.js +6 -0
- package/dist/cjs/src/helpers/db/createDb.js +20 -0
- package/dist/cjs/src/helpers/db/dropDb.js +36 -0
- package/dist/cjs/src/helpers/db/foreignKeyTypeFromPrimaryKey.js +11 -0
- package/dist/cjs/src/helpers/db/loadPgClient.js +20 -0
- package/dist/cjs/src/helpers/db/primaryKeyType.js +23 -0
- package/dist/cjs/src/helpers/db/runMigration.js +97 -0
- package/dist/cjs/src/helpers/db/truncateDb.js +27 -0
- package/dist/cjs/src/helpers/db/types/isDatabaseArrayColumn.js +6 -0
- package/dist/cjs/src/helpers/db/types/isDateColumn.js +6 -0
- package/dist/cjs/src/helpers/db/types/isDateTimeColumn.js +6 -0
- package/dist/cjs/src/helpers/db/types/isJsonColumn.js +6 -0
- package/dist/cjs/src/helpers/debug.js +11 -0
- package/dist/cjs/src/helpers/dreamOrPsychicCoreDevelopment.js +10 -0
- package/dist/cjs/src/helpers/filterObjectByKey.js +14 -0
- package/dist/cjs/src/helpers/getFiles.js +20 -0
- package/dist/cjs/src/helpers/globalClassNameFromFullyQualifiedModelName.js +7 -0
- package/dist/cjs/src/helpers/hyphenize.js +11 -0
- package/dist/cjs/src/helpers/inferSerializerFromDreamOrViewModel.js +16 -0
- package/dist/cjs/src/helpers/isEmpty.js +8 -0
- package/dist/cjs/src/helpers/loadEnv.js +37 -0
- package/dist/cjs/src/helpers/loadRepl.js +25 -0
- package/dist/cjs/src/helpers/migrationVersion.js +6 -0
- package/dist/cjs/src/helpers/namespaceColumn.js +8 -0
- package/dist/cjs/src/helpers/objectPathsToArrays.js +19 -0
- package/dist/cjs/src/helpers/pascalize.js +12 -0
- package/dist/cjs/src/helpers/pascalizePath.js +10 -0
- package/dist/cjs/src/helpers/path/dreamFileAndDirPaths.js +16 -0
- package/dist/cjs/src/helpers/path/dreamPath.js +25 -0
- package/dist/cjs/src/helpers/path/relativeDreamPath.js +50 -0
- package/dist/cjs/src/helpers/path/sharedPathPrefix.js +14 -0
- package/dist/cjs/src/helpers/propertyNameFromFullyQualifiedModelName.js +8 -0
- package/dist/cjs/src/helpers/protectAgainstPollutingAssignment.js +14 -0
- package/dist/cjs/src/helpers/range.js +20 -0
- package/dist/cjs/src/helpers/round.js +7 -0
- package/dist/cjs/src/helpers/serializerNameFromFullyQualifiedModelName.js +13 -0
- package/dist/cjs/src/helpers/snakeify.js +14 -0
- package/dist/cjs/src/helpers/sortBy.js +31 -0
- package/dist/cjs/src/helpers/sqlAttributes.js +28 -0
- package/dist/cjs/src/helpers/sspawn.js +21 -0
- package/dist/cjs/src/helpers/standardizeFullyQualifiedModelName.js +10 -0
- package/dist/cjs/src/helpers/stringCasing.js +34 -0
- package/dist/cjs/src/helpers/typechecks.js +16 -0
- package/dist/cjs/src/helpers/typeutils.js +2 -0
- package/dist/cjs/src/helpers/uncapitalize.js +6 -0
- package/dist/cjs/src/helpers/uniq.js +21 -0
- package/dist/cjs/src/index.js +154 -0
- package/dist/cjs/src/openapi/types.js +26 -0
- package/dist/cjs/src/ops/curried-ops-statement.js +12 -0
- package/dist/cjs/src/ops/index.js +42 -0
- package/dist/cjs/src/ops/ops-statement.js +38 -0
- package/dist/cjs/src/serializer/decorators/associations/RendersMany.js +84 -0
- package/dist/cjs/src/serializer/decorators/associations/RendersOne.js +87 -0
- package/dist/cjs/src/serializer/decorators/associations/shared.js +10 -0
- package/dist/cjs/src/serializer/decorators/attribute.js +161 -0
- package/dist/cjs/src/serializer/decorators/helpers/dreamAttributeOpenapiShape.js +78 -0
- package/dist/cjs/src/serializer/decorators/helpers/hasSerializersGetter.js +11 -0
- package/dist/cjs/src/serializer/decorators/helpers/maybeSerializableToDreamSerializerCallbackFunction.js +20 -0
- package/dist/cjs/src/serializer/index.js +271 -0
- package/dist/esm/boilerplate/package.json +42 -0
- package/dist/esm/src/Dream.js +2981 -0
- package/dist/esm/src/bin/helpers/sync.js +106 -0
- package/dist/esm/src/bin/index.js +104 -0
- package/dist/esm/src/cli/index.js +152 -0
- package/dist/esm/src/db/ConnectedToDB.js +40 -0
- package/dist/esm/src/db/ConnectionConfRetriever.js +19 -0
- package/dist/esm/src/db/DreamDbConnection.js +72 -0
- package/dist/esm/src/db/dataTypes.js +53 -0
- package/dist/esm/src/db/errors.js +13 -0
- package/dist/esm/src/db/index.js +9 -0
- package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +190 -0
- package/dist/esm/src/db/reflections.js +1 -0
- package/dist/esm/src/db/types.js +1 -0
- package/dist/esm/src/db/validators/validateColumn.js +8 -0
- package/dist/esm/src/db/validators/validateTable.js +6 -0
- package/dist/esm/src/db/validators/validateTableAlias.js +52 -0
- package/dist/esm/src/decorators/DecoratorContextType.js +1 -0
- package/dist/esm/src/decorators/Decorators.js +323 -0
- package/dist/esm/src/decorators/Encrypted.js +80 -0
- package/dist/esm/src/decorators/ReplicaSafe.js +9 -0
- package/dist/esm/src/decorators/STI.js +31 -0
- package/dist/esm/src/decorators/Scope.js +27 -0
- package/dist/esm/src/decorators/SoftDelete.js +50 -0
- package/dist/esm/src/decorators/Virtual.js +25 -0
- package/dist/esm/src/decorators/associations/BelongsTo.js +74 -0
- package/dist/esm/src/decorators/associations/HasMany.js +97 -0
- package/dist/esm/src/decorators/associations/HasOne.js +93 -0
- package/dist/esm/src/decorators/associations/associationToGetterSetterProp.js +3 -0
- package/dist/esm/src/decorators/associations/shared.js +123 -0
- package/dist/esm/src/decorators/helpers/freezeBaseClassArrayMap.js +7 -0
- package/dist/esm/src/decorators/hooks/AfterCreate.js +22 -0
- package/dist/esm/src/decorators/hooks/AfterCreateCommit.js +39 -0
- package/dist/esm/src/decorators/hooks/AfterDestroy.js +21 -0
- package/dist/esm/src/decorators/hooks/AfterDestroyCommit.js +36 -0
- package/dist/esm/src/decorators/hooks/AfterSave.js +22 -0
- package/dist/esm/src/decorators/hooks/AfterSaveCommit.js +39 -0
- package/dist/esm/src/decorators/hooks/AfterUpdate.js +22 -0
- package/dist/esm/src/decorators/hooks/AfterUpdateCommit.js +39 -0
- package/dist/esm/src/decorators/hooks/BeforeCreate.js +22 -0
- package/dist/esm/src/decorators/hooks/BeforeDestroy.js +21 -0
- package/dist/esm/src/decorators/hooks/BeforeSave.js +22 -0
- package/dist/esm/src/decorators/hooks/BeforeUpdate.js +22 -0
- package/dist/esm/src/decorators/hooks/shared.js +20 -0
- package/dist/esm/src/decorators/sortable/Sortable.js +157 -0
- package/dist/esm/src/decorators/sortable/helpers/applySortableScopeToQuery.js +14 -0
- package/dist/esm/src/decorators/sortable/helpers/clearCachedSortableValues.js +8 -0
- package/dist/esm/src/decorators/sortable/helpers/decrementScopedRecordsGreaterThanPosition.js +23 -0
- package/dist/esm/src/decorators/sortable/helpers/getColumnForSortableScope.js +15 -0
- package/dist/esm/src/decorators/sortable/helpers/isSortedCorrectly.js +4 -0
- package/dist/esm/src/decorators/sortable/helpers/positionIsInvalid.js +8 -0
- package/dist/esm/src/decorators/sortable/helpers/resortAllRecords.js +35 -0
- package/dist/esm/src/decorators/sortable/helpers/scopeArray.js +7 -0
- package/dist/esm/src/decorators/sortable/helpers/setPosition.js +154 -0
- package/dist/esm/src/decorators/sortable/helpers/sortableCacheKeyName.js +4 -0
- package/dist/esm/src/decorators/sortable/helpers/sortableCacheValuesName.js +4 -0
- package/dist/esm/src/decorators/sortable/helpers/sortableQueryExcludingDream.js +7 -0
- package/dist/esm/src/decorators/sortable/hooks/afterSortableCreate.js +15 -0
- package/dist/esm/src/decorators/sortable/hooks/afterSortableDestroy.js +11 -0
- package/dist/esm/src/decorators/sortable/hooks/afterSortableUpdate.js +28 -0
- package/dist/esm/src/decorators/sortable/hooks/beforeSortableSave.js +62 -0
- package/dist/esm/src/decorators/validations/Validate.js +19 -0
- package/dist/esm/src/decorators/validations/Validates.js +64 -0
- package/dist/esm/src/decorators/validations/shared.js +1 -0
- package/dist/esm/src/dream/DreamClassTransactionBuilder.js +589 -0
- package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +477 -0
- package/dist/esm/src/dream/DreamTransaction.js +23 -0
- package/dist/esm/src/dream/LeftJoinLoadBuilder.js +74 -0
- package/dist/esm/src/dream/LoadBuilder.js +65 -0
- package/dist/esm/src/dream/Query.js +2615 -0
- package/dist/esm/src/dream/internal/applyScopeBypassingSettingsToQuery.js +8 -0
- package/dist/esm/src/dream/internal/associations/associationQuery.js +20 -0
- package/dist/esm/src/dream/internal/associations/associationUpdateQuery.js +33 -0
- package/dist/esm/src/dream/internal/associations/createAssociation.js +52 -0
- package/dist/esm/src/dream/internal/associations/destroyAssociation.js +14 -0
- package/dist/esm/src/dream/internal/associations/undestroyAssociation.js +9 -0
- package/dist/esm/src/dream/internal/checkSingleValidation.js +49 -0
- package/dist/esm/src/dream/internal/destroyAssociatedRecords.js +18 -0
- package/dist/esm/src/dream/internal/destroyDream.js +69 -0
- package/dist/esm/src/dream/internal/destroyOptions.js +27 -0
- package/dist/esm/src/dream/internal/ensureSTITypeFieldIsSet.js +7 -0
- package/dist/esm/src/dream/internal/executeDatabaseQuery.js +21 -0
- package/dist/esm/src/dream/internal/extractAssociationMetadataFromAssociationName.js +5 -0
- package/dist/esm/src/dream/internal/orderByDirection.js +12 -0
- package/dist/esm/src/dream/internal/reload.js +18 -0
- package/dist/esm/src/dream/internal/runHooksFor.js +95 -0
- package/dist/esm/src/dream/internal/runValidations.js +13 -0
- package/dist/esm/src/dream/internal/safelyRunCommitHooks.js +12 -0
- package/dist/esm/src/dream/internal/saveDream.js +64 -0
- package/dist/esm/src/dream/internal/scopeHelpers.js +9 -0
- package/dist/esm/src/dream/internal/shouldBypassDefaultScope.js +9 -0
- package/dist/esm/src/dream/internal/similarity/SimilarityBuilder.js +327 -0
- package/dist/esm/src/dream/internal/similarity/similaritySelectSql.js +18 -0
- package/dist/esm/src/dream/internal/similarity/similarityWhereSql.js +18 -0
- package/dist/esm/src/dream/internal/softDeleteDream.js +19 -0
- package/dist/esm/src/dream/internal/sqlResultToDreamInstance.js +34 -0
- package/dist/esm/src/dream/internal/undestroyDream.js +87 -0
- package/dist/esm/src/dream/types.js +95 -0
- package/dist/esm/src/dream-application/cache.js +9 -0
- package/dist/esm/src/dream-application/helpers/DreamImporter.js +49 -0
- package/dist/esm/src/dream-application/helpers/globalModelKeyFromPath.js +7 -0
- package/dist/esm/src/dream-application/helpers/globalSerializerKeyFromPath.js +14 -0
- package/dist/esm/src/dream-application/helpers/globalServiceKeyFromPath.js +8 -0
- package/dist/esm/src/dream-application/helpers/importers/importModels.js +75 -0
- package/dist/esm/src/dream-application/helpers/importers/importSerializers.js +57 -0
- package/dist/esm/src/dream-application/helpers/importers/importServices.js +37 -0
- package/dist/esm/src/dream-application/helpers/lookupClassByGlobalName.js +14 -0
- package/dist/esm/src/dream-application/helpers/lookupModelByGlobalName.js +10 -0
- package/dist/esm/src/dream-application/helpers/lookupModelByGlobalNameOrNames.js +7 -0
- package/dist/esm/src/dream-application/index.js +281 -0
- package/dist/esm/src/encrypt/InternalEncrypt.js +29 -0
- package/dist/esm/src/encrypt/algorithms/aes-gcm/decryptAESGCM.js +23 -0
- package/dist/esm/src/encrypt/algorithms/aes-gcm/encryptAESGCM.js +9 -0
- package/dist/esm/src/encrypt/algorithms/aes-gcm/generateKeyAESGCM.js +4 -0
- package/dist/esm/src/encrypt/algorithms/aes-gcm/validateKeyAESGCM.js +8 -0
- package/dist/esm/src/encrypt/index.js +92 -0
- package/dist/esm/src/errors/AttemptingToMarshalInvalidArrayType.js +17 -0
- package/dist/esm/src/errors/CannotCallUndestroyOnANonSoftDeleteModel.js +18 -0
- package/dist/esm/src/errors/CannotDefineAssociationWithBothDependentAndPassthrough.js +16 -0
- package/dist/esm/src/errors/CannotDefineAssociationWithBothDependentAndRequiredOnClause.js +16 -0
- package/dist/esm/src/errors/CannotNegateSimilarityClause.js +19 -0
- package/dist/esm/src/errors/CannotPassAdditionalFieldsToPluckEachAfterCallback.js +19 -0
- package/dist/esm/src/errors/CannotPassUndefinedAsAValueToAWhereClause.js +17 -0
- package/dist/esm/src/errors/CannotReloadUnsavedDream.js +13 -0
- package/dist/esm/src/errors/ConstructorOnlyForInternalUse.js +6 -0
- package/dist/esm/src/errors/CreateOrFindByFailedToCreateAndFind.js +15 -0
- package/dist/esm/src/errors/DoNotSetEncryptedFieldsDirectly.js +20 -0
- package/dist/esm/src/errors/InvalidColumnName.js +16 -0
- package/dist/esm/src/errors/InvalidDecimalFieldPassedToGenerator.js +16 -0
- package/dist/esm/src/errors/InvalidTableAlias.js +27 -0
- package/dist/esm/src/errors/InvalidTableName.js +20 -0
- package/dist/esm/src/errors/LeftJoinPreloadIncompatibleWithFindEach.js +9 -0
- package/dist/esm/src/errors/MissingDB.js +7 -0
- package/dist/esm/src/errors/MissingDeletedAtFieldForSoftDelete.js +21 -0
- package/dist/esm/src/errors/MissingRequiredCallbackFunctionToPluckEach.js +19 -0
- package/dist/esm/src/errors/MissingSerializersDefinition.js +23 -0
- package/dist/esm/src/errors/MissingTable.js +24 -0
- package/dist/esm/src/errors/NoUpdateAllOnJoins.js +10 -0
- package/dist/esm/src/errors/NoUpdateOnAssociationQuery.js +7 -0
- package/dist/esm/src/errors/NonBelongsToAssociationProvidedAsSortableDecoratorScope.js +20 -0
- package/dist/esm/src/errors/NonExistentScopeProvidedToResort.js +20 -0
- package/dist/esm/src/errors/PrototypePollutingAssignment.js +10 -0
- package/dist/esm/src/errors/RecordNotFound.js +12 -0
- package/dist/esm/src/errors/SortableDecoratorRequiresColumnOrBelongsToAssociation.js +23 -0
- package/dist/esm/src/errors/ValidationError.js +16 -0
- package/dist/esm/src/errors/associations/CanOnlyPassBelongsToModelParam.js +17 -0
- package/dist/esm/src/errors/associations/CannotAssociateThroughPolymorphic.js +16 -0
- package/dist/esm/src/errors/associations/CannotCreateAssociationWithThroughContext.js +16 -0
- package/dist/esm/src/errors/associations/CannotJoinPolymorphicBelongsToError.js +24 -0
- package/dist/esm/src/errors/associations/CannotPassNullOrUndefinedToRequiredBelongsTo.js +16 -0
- package/dist/esm/src/errors/associations/InvalidComputedForeignKey.js +58 -0
- package/dist/esm/src/errors/associations/JoinAttemptedOnMissingAssociation.js +24 -0
- package/dist/esm/src/errors/associations/MissingRequiredAssociationOnClause.js +16 -0
- package/dist/esm/src/errors/associations/MissingRequiredPassthroughForAssociationOnClause.js +13 -0
- package/dist/esm/src/errors/associations/MissingThroughAssociation.js +24 -0
- package/dist/esm/src/errors/associations/MissingThroughAssociationSource.js +39 -0
- package/dist/esm/src/errors/associations/NonLoadedAssociation.js +15 -0
- package/dist/esm/src/errors/dream-application/DreamApplicationInitMissingCallToLoadModels.js +15 -0
- package/dist/esm/src/errors/dream-application/DreamApplicationInitMissingMissingProjectRoot.js +16 -0
- package/dist/esm/src/errors/dream-application/GlobalNameNotSet.js +11 -0
- package/dist/esm/src/errors/dream-application/SerializerNameConflict.js +12 -0
- package/dist/esm/src/errors/encrypt/MissingColumnEncryptionOpts.js +24 -0
- package/dist/esm/src/errors/encrypt/MissingEncryptionKey.js +9 -0
- package/dist/esm/src/errors/environment/MissingRequiredEnvironmentVariable.js +10 -0
- package/dist/esm/src/errors/ops/AnyRequiresArrayColumn.js +15 -0
- package/dist/esm/src/errors/ops/ScoreMustBeANormalNumber.js +14 -0
- package/dist/esm/src/errors/schema-builder/FailedToIdentifyAssociation.js +77 -0
- package/dist/esm/src/errors/serializers/FailedToRenderThroughAssociationForSerializer.js +14 -0
- package/dist/esm/src/errors/sortable/CannotCallSortableOnSTIChild.js +15 -0
- package/dist/esm/src/errors/sti/STIChildMissing.js +20 -0
- package/dist/esm/src/errors/sti/StiChildCannotDefineNewAssociations.js +17 -0
- package/dist/esm/src/errors/sti/StiChildIncompatibleWithReplicaSafeDecorator.js +14 -0
- package/dist/esm/src/errors/sti/StiChildIncompatibleWithSoftDeleteDecorator.js +14 -0
- package/dist/esm/src/global-cli/dream.js +44 -0
- package/dist/esm/src/global-cli/file-builders/DreamtsBuilder.js +66 -0
- package/dist/esm/src/global-cli/file-builders/EnvBuilder.js +24 -0
- package/dist/esm/src/global-cli/file-builders/EslintConfBuilder.js +26 -0
- package/dist/esm/src/global-cli/file-builders/PackagejsonBuilder.js +6 -0
- package/dist/esm/src/global-cli/helpers/argAndValue.js +12 -0
- package/dist/esm/src/global-cli/helpers/autogeneratedFileMessage.js +68 -0
- package/dist/esm/src/global-cli/helpers/buildNewDreamApp.js +60 -0
- package/dist/esm/src/global-cli/helpers/copyRecursive.js +17 -0
- package/dist/esm/src/global-cli/helpers/filterObjectByKey.js +20 -0
- package/dist/esm/src/global-cli/helpers/generateEncryptionKey.js +23 -0
- package/dist/esm/src/global-cli/helpers/globalCliSnakeify.js +1 -0
- package/dist/esm/src/global-cli/helpers/initDreamAppIntoExistingProject.js +82 -0
- package/dist/esm/src/global-cli/helpers/log.js +24 -0
- package/dist/esm/src/global-cli/helpers/logo.js +77 -0
- package/dist/esm/src/global-cli/helpers/primaryKeyTypes.js +10 -0
- package/dist/esm/src/global-cli/helpers/prompt.js +30 -0
- package/dist/esm/src/global-cli/helpers/select.js +110 -0
- package/dist/esm/src/global-cli/helpers/sleep.js +7 -0
- package/dist/esm/src/global-cli/helpers/sspawn.js +17 -0
- package/dist/esm/src/global-cli/helpers/welcomeMessage.js +38 -0
- package/dist/esm/src/global-cli/init.js +53 -0
- package/dist/esm/src/global-cli/new.js +7 -0
- package/dist/esm/src/helpers/CalendarDate.js +169 -0
- package/dist/esm/src/helpers/Env.js +75 -0
- package/dist/esm/src/helpers/EnvInternal.js +3 -0
- package/dist/esm/src/helpers/allNestedObjectKeys.js +9 -0
- package/dist/esm/src/helpers/benchmark.js +15 -0
- package/dist/esm/src/helpers/camelize.js +11 -0
- package/dist/esm/src/helpers/capitalize.js +3 -0
- package/dist/esm/src/helpers/cli/SchemaBuilder.js +375 -0
- package/dist/esm/src/helpers/cli/generateDream.js +45 -0
- package/dist/esm/src/helpers/cli/generateDreamContent.js +104 -0
- package/dist/esm/src/helpers/cli/generateFactory.js +23 -0
- package/dist/esm/src/helpers/cli/generateFactoryContent.js +55 -0
- package/dist/esm/src/helpers/cli/generateMigration.js +53 -0
- package/dist/esm/src/helpers/cli/generateMigrationContent.js +193 -0
- package/dist/esm/src/helpers/cli/generateSerializer.js +23 -0
- package/dist/esm/src/helpers/cli/generateSerializerContent.js +127 -0
- package/dist/esm/src/helpers/cli/generateStiMigrationContent.js +4 -0
- package/dist/esm/src/helpers/cli/generateUnitSpec.js +23 -0
- package/dist/esm/src/helpers/cli/generateUnitSpecContent.js +7 -0
- package/dist/esm/src/helpers/cloneDeepSafe.js +64 -0
- package/dist/esm/src/helpers/compact.js +11 -0
- package/dist/esm/src/helpers/customPgParsers.js +31 -0
- package/dist/esm/src/helpers/db/cachedTypeForAttribute.js +3 -0
- package/dist/esm/src/helpers/db/createDb.js +17 -0
- package/dist/esm/src/helpers/db/dropDb.js +33 -0
- package/dist/esm/src/helpers/db/foreignKeyTypeFromPrimaryKey.js +8 -0
- package/dist/esm/src/helpers/db/loadPgClient.js +17 -0
- package/dist/esm/src/helpers/db/primaryKeyType.js +20 -0
- package/dist/esm/src/helpers/db/runMigration.js +94 -0
- package/dist/esm/src/helpers/db/truncateDb.js +24 -0
- package/dist/esm/src/helpers/db/types/isDatabaseArrayColumn.js +3 -0
- package/dist/esm/src/helpers/db/types/isDateColumn.js +3 -0
- package/dist/esm/src/helpers/db/types/isDateTimeColumn.js +3 -0
- package/dist/esm/src/helpers/db/types/isJsonColumn.js +3 -0
- package/dist/esm/src/helpers/debug.js +8 -0
- package/dist/esm/src/helpers/dreamOrPsychicCoreDevelopment.js +7 -0
- package/dist/esm/src/helpers/filterObjectByKey.js +11 -0
- package/dist/esm/src/helpers/getFiles.js +17 -0
- package/dist/esm/src/helpers/globalClassNameFromFullyQualifiedModelName.js +4 -0
- package/dist/esm/src/helpers/hyphenize.js +8 -0
- package/dist/esm/src/helpers/inferSerializerFromDreamOrViewModel.js +12 -0
- package/dist/esm/src/helpers/isEmpty.js +5 -0
- package/dist/esm/src/helpers/loadEnv.js +35 -0
- package/dist/esm/src/helpers/loadRepl.js +22 -0
- package/dist/esm/src/helpers/migrationVersion.js +3 -0
- package/dist/esm/src/helpers/namespaceColumn.js +5 -0
- package/dist/esm/src/helpers/objectPathsToArrays.js +16 -0
- package/dist/esm/src/helpers/pascalize.js +9 -0
- package/dist/esm/src/helpers/pascalizePath.js +7 -0
- package/dist/esm/src/helpers/path/dreamFileAndDirPaths.js +13 -0
- package/dist/esm/src/helpers/path/dreamPath.js +22 -0
- package/dist/esm/src/helpers/path/relativeDreamPath.js +46 -0
- package/dist/esm/src/helpers/path/sharedPathPrefix.js +11 -0
- package/dist/esm/src/helpers/propertyNameFromFullyQualifiedModelName.js +5 -0
- package/dist/esm/src/helpers/protectAgainstPollutingAssignment.js +11 -0
- package/dist/esm/src/helpers/range.js +15 -0
- package/dist/esm/src/helpers/round.js +4 -0
- package/dist/esm/src/helpers/serializerNameFromFullyQualifiedModelName.js +10 -0
- package/dist/esm/src/helpers/snakeify.js +10 -0
- package/dist/esm/src/helpers/sortBy.js +26 -0
- package/dist/esm/src/helpers/sqlAttributes.js +25 -0
- package/dist/esm/src/helpers/sspawn.js +17 -0
- package/dist/esm/src/helpers/standardizeFullyQualifiedModelName.js +7 -0
- package/dist/esm/src/helpers/stringCasing.js +31 -0
- package/dist/esm/src/helpers/typechecks.js +12 -0
- package/dist/esm/src/helpers/typeutils.js +1 -0
- package/dist/esm/src/helpers/uncapitalize.js +3 -0
- package/dist/esm/src/helpers/uniq.js +18 -0
- package/dist/esm/src/index.js +73 -0
- package/dist/esm/src/openapi/types.js +23 -0
- package/dist/esm/src/ops/curried-ops-statement.js +9 -0
- package/dist/esm/src/ops/index.js +40 -0
- package/dist/esm/src/ops/ops-statement.js +35 -0
- package/dist/esm/src/serializer/decorators/associations/RendersMany.js +81 -0
- package/dist/esm/src/serializer/decorators/associations/RendersOne.js +84 -0
- package/dist/esm/src/serializer/decorators/associations/shared.js +7 -0
- package/dist/esm/src/serializer/decorators/attribute.js +158 -0
- package/dist/esm/src/serializer/decorators/helpers/dreamAttributeOpenapiShape.js +73 -0
- package/dist/esm/src/serializer/decorators/helpers/hasSerializersGetter.js +8 -0
- package/dist/esm/src/serializer/decorators/helpers/maybeSerializableToDreamSerializerCallbackFunction.js +17 -0
- package/dist/esm/src/serializer/index.js +268 -0
- package/dist/types/src/Dream.d.ts +2211 -0
- package/dist/types/src/bin/helpers/sync.d.ts +2 -0
- package/dist/types/src/bin/index.d.ts +20 -0
- package/dist/types/src/cli/index.d.ts +20 -0
- package/dist/types/src/db/ConnectedToDB.d.ts +26 -0
- package/dist/types/src/db/ConnectionConfRetriever.d.ts +6 -0
- package/dist/types/src/db/DreamDbConnection.d.ts +10 -0
- package/dist/types/src/db/dataTypes.d.ts +6 -0
- package/dist/types/src/db/errors.d.ts +6 -0
- package/dist/types/src/db/index.d.ts +5 -0
- package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +116 -0
- package/dist/types/src/db/reflections.d.ts +5 -0
- package/dist/types/src/db/types.d.ts +1 -0
- package/dist/types/src/db/validators/validateColumn.d.ts +1 -0
- package/dist/types/src/db/validators/validateTable.d.ts +1 -0
- package/dist/types/src/db/validators/validateTableAlias.d.ts +1 -0
- package/dist/types/src/decorators/DecoratorContextType.d.ts +13 -0
- package/dist/types/src/decorators/Decorators.d.ts +214 -0
- package/dist/types/src/decorators/Encrypted.d.ts +5 -0
- package/dist/types/src/decorators/ReplicaSafe.d.ts +1 -0
- package/dist/types/src/decorators/STI.d.ts +5 -0
- package/dist/types/src/decorators/Scope.d.ts +11 -0
- package/dist/types/src/decorators/SoftDelete.d.ts +37 -0
- package/dist/types/src/decorators/Virtual.d.ts +6 -0
- package/dist/types/src/decorators/associations/BelongsTo.d.ts +33 -0
- package/dist/types/src/decorators/associations/HasMany.d.ts +19 -0
- package/dist/types/src/decorators/associations/HasOne.d.ts +11 -0
- package/dist/types/src/decorators/associations/associationToGetterSetterProp.d.ts +5 -0
- package/dist/types/src/decorators/associations/shared.d.ts +118 -0
- package/dist/types/src/decorators/helpers/freezeBaseClassArrayMap.d.ts +1 -0
- package/dist/types/src/decorators/hooks/AfterCreate.d.ts +4 -0
- package/dist/types/src/decorators/hooks/AfterCreateCommit.d.ts +21 -0
- package/dist/types/src/decorators/hooks/AfterDestroy.d.ts +3 -0
- package/dist/types/src/decorators/hooks/AfterDestroyCommit.d.ts +18 -0
- package/dist/types/src/decorators/hooks/AfterSave.d.ts +4 -0
- package/dist/types/src/decorators/hooks/AfterSaveCommit.d.ts +21 -0
- package/dist/types/src/decorators/hooks/AfterUpdate.d.ts +4 -0
- package/dist/types/src/decorators/hooks/AfterUpdateCommit.d.ts +21 -0
- package/dist/types/src/decorators/hooks/BeforeCreate.d.ts +4 -0
- package/dist/types/src/decorators/hooks/BeforeDestroy.d.ts +3 -0
- package/dist/types/src/decorators/hooks/BeforeSave.d.ts +4 -0
- package/dist/types/src/decorators/hooks/BeforeUpdate.d.ts +4 -0
- package/dist/types/src/decorators/hooks/shared.d.ts +34 -0
- package/dist/types/src/decorators/sortable/Sortable.d.ts +9 -0
- package/dist/types/src/decorators/sortable/helpers/applySortableScopeToQuery.d.ts +9 -0
- package/dist/types/src/decorators/sortable/helpers/clearCachedSortableValues.d.ts +2 -0
- package/dist/types/src/decorators/sortable/helpers/decrementScopedRecordsGreaterThanPosition.d.ts +8 -0
- package/dist/types/src/decorators/sortable/helpers/getColumnForSortableScope.d.ts +2 -0
- package/dist/types/src/decorators/sortable/helpers/isSortedCorrectly.d.ts +1 -0
- package/dist/types/src/decorators/sortable/helpers/positionIsInvalid.d.ts +8 -0
- package/dist/types/src/decorators/sortable/helpers/resortAllRecords.d.ts +2 -0
- package/dist/types/src/decorators/sortable/helpers/scopeArray.d.ts +1 -0
- package/dist/types/src/decorators/sortable/helpers/setPosition.d.ts +14 -0
- package/dist/types/src/decorators/sortable/helpers/sortableCacheKeyName.d.ts +1 -0
- package/dist/types/src/decorators/sortable/helpers/sortableCacheValuesName.d.ts +1 -0
- package/dist/types/src/decorators/sortable/helpers/sortableQueryExcludingDream.d.ts +9 -0
- package/dist/types/src/decorators/sortable/hooks/afterSortableCreate.d.ts +10 -0
- package/dist/types/src/decorators/sortable/hooks/afterSortableDestroy.d.ts +8 -0
- package/dist/types/src/decorators/sortable/hooks/afterSortableUpdate.d.ts +10 -0
- package/dist/types/src/decorators/sortable/hooks/beforeSortableSave.d.ts +8 -0
- package/dist/types/src/decorators/validations/Validate.d.ts +1 -0
- package/dist/types/src/decorators/validations/Validates.d.ts +18 -0
- package/dist/types/src/decorators/validations/shared.d.ts +19 -0
- package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +549 -0
- package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +316 -0
- package/dist/types/src/dream/DreamTransaction.d.ts +15 -0
- package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +48 -0
- package/dist/types/src/dream/LoadBuilder.d.ts +47 -0
- package/dist/types/src/dream/Query.d.ts +1132 -0
- package/dist/types/src/dream/internal/applyScopeBypassingSettingsToQuery.d.ts +13 -0
- package/dist/types/src/dream/internal/associations/associationQuery.d.ts +9 -0
- package/dist/types/src/dream/internal/associations/associationUpdateQuery.d.ts +9 -0
- package/dist/types/src/dream/internal/associations/createAssociation.d.ts +4 -0
- package/dist/types/src/dream/internal/associations/destroyAssociation.d.ts +11 -0
- package/dist/types/src/dream/internal/associations/undestroyAssociation.d.ts +10 -0
- package/dist/types/src/dream/internal/checkSingleValidation.d.ts +3 -0
- package/dist/types/src/dream/internal/destroyAssociatedRecords.d.ts +10 -0
- package/dist/types/src/dream/internal/destroyDream.d.ts +19 -0
- package/dist/types/src/dream/internal/destroyOptions.d.ts +46 -0
- package/dist/types/src/dream/internal/ensureSTITypeFieldIsSet.d.ts +2 -0
- package/dist/types/src/dream/internal/executeDatabaseQuery.d.ts +1 -0
- package/dist/types/src/dream/internal/extractAssociationMetadataFromAssociationName.d.ts +4 -0
- package/dist/types/src/dream/internal/orderByDirection.d.ts +2 -0
- package/dist/types/src/dream/internal/reload.d.ts +3 -0
- package/dist/types/src/dream/internal/runHooksFor.d.ts +8 -0
- package/dist/types/src/dream/internal/runValidations.d.ts +2 -0
- package/dist/types/src/dream/internal/safelyRunCommitHooks.d.ts +7 -0
- package/dist/types/src/dream/internal/saveDream.d.ts +5 -0
- package/dist/types/src/dream/internal/scopeHelpers.d.ts +7 -0
- package/dist/types/src/dream/internal/shouldBypassDefaultScope.d.ts +4 -0
- package/dist/types/src/dream/internal/similarity/SimilarityBuilder.d.ts +38 -0
- package/dist/types/src/dream/internal/similarity/similaritySelectSql.d.ts +11 -0
- package/dist/types/src/dream/internal/similarity/similarityWhereSql.d.ts +10 -0
- package/dist/types/src/dream/internal/softDeleteDream.d.ts +3 -0
- package/dist/types/src/dream/internal/sqlResultToDreamInstance.d.ts +4 -0
- package/dist/types/src/dream/internal/undestroyDream.d.ts +16 -0
- package/dist/types/src/dream/types.d.ts +184 -0
- package/dist/types/src/dream-application/cache.d.ts +3 -0
- package/dist/types/src/dream-application/helpers/DreamImporter.d.ts +8 -0
- package/dist/types/src/dream-application/helpers/globalModelKeyFromPath.d.ts +1 -0
- package/dist/types/src/dream-application/helpers/globalSerializerKeyFromPath.d.ts +1 -0
- package/dist/types/src/dream-application/helpers/globalServiceKeyFromPath.d.ts +1 -0
- package/dist/types/src/dream-application/helpers/importers/importModels.d.ts +5 -0
- package/dist/types/src/dream-application/helpers/importers/importSerializers.d.ts +5 -0
- package/dist/types/src/dream-application/helpers/importers/importServices.d.ts +4 -0
- package/dist/types/src/dream-application/helpers/lookupClassByGlobalName.d.ts +1 -0
- package/dist/types/src/dream-application/helpers/lookupModelByGlobalName.d.ts +1 -0
- package/dist/types/src/dream-application/helpers/lookupModelByGlobalNameOrNames.d.ts +1 -0
- package/dist/types/src/dream-application/index.d.ts +143 -0
- package/dist/types/src/encrypt/InternalEncrypt.d.ts +6 -0
- package/dist/types/src/encrypt/algorithms/aes-gcm/decryptAESGCM.d.ts +2 -0
- package/dist/types/src/encrypt/algorithms/aes-gcm/encryptAESGCM.d.ts +2 -0
- package/dist/types/src/encrypt/algorithms/aes-gcm/generateKeyAESGCM.d.ts +2 -0
- package/dist/types/src/encrypt/algorithms/aes-gcm/validateKeyAESGCM.d.ts +2 -0
- package/dist/types/src/encrypt/index.d.ts +26 -0
- package/dist/types/src/errors/AttemptingToMarshalInvalidArrayType.d.ts +5 -0
- package/dist/types/src/errors/CannotCallUndestroyOnANonSoftDeleteModel.d.ts +6 -0
- package/dist/types/src/errors/CannotDefineAssociationWithBothDependentAndPassthrough.d.ts +7 -0
- package/dist/types/src/errors/CannotDefineAssociationWithBothDependentAndRequiredOnClause.d.ts +7 -0
- package/dist/types/src/errors/CannotNegateSimilarityClause.d.ts +7 -0
- package/dist/types/src/errors/CannotPassAdditionalFieldsToPluckEachAfterCallback.d.ts +6 -0
- package/dist/types/src/errors/CannotPassUndefinedAsAValueToAWhereClause.d.ts +7 -0
- package/dist/types/src/errors/CannotReloadUnsavedDream.d.ts +6 -0
- package/dist/types/src/errors/ConstructorOnlyForInternalUse.d.ts +3 -0
- package/dist/types/src/errors/CreateOrFindByFailedToCreateAndFind.d.ts +6 -0
- package/dist/types/src/errors/DoNotSetEncryptedFieldsDirectly.d.ts +8 -0
- package/dist/types/src/errors/InvalidColumnName.d.ts +6 -0
- package/dist/types/src/errors/InvalidDecimalFieldPassedToGenerator.d.ts +5 -0
- package/dist/types/src/errors/InvalidTableAlias.d.ts +5 -0
- package/dist/types/src/errors/InvalidTableName.d.ts +6 -0
- package/dist/types/src/errors/LeftJoinPreloadIncompatibleWithFindEach.d.ts +3 -0
- package/dist/types/src/errors/MissingDB.d.ts +3 -0
- package/dist/types/src/errors/MissingDeletedAtFieldForSoftDelete.d.ts +6 -0
- package/dist/types/src/errors/MissingRequiredCallbackFunctionToPluckEach.d.ts +6 -0
- package/dist/types/src/errors/MissingSerializersDefinition.d.ts +6 -0
- package/dist/types/src/errors/MissingTable.d.ts +6 -0
- package/dist/types/src/errors/NoUpdateAllOnJoins.d.ts +3 -0
- package/dist/types/src/errors/NoUpdateOnAssociationQuery.d.ts +3 -0
- package/dist/types/src/errors/NonBelongsToAssociationProvidedAsSortableDecoratorScope.d.ts +7 -0
- package/dist/types/src/errors/NonExistentScopeProvidedToResort.d.ts +7 -0
- package/dist/types/src/errors/PrototypePollutingAssignment.d.ts +5 -0
- package/dist/types/src/errors/RecordNotFound.d.ts +5 -0
- package/dist/types/src/errors/SortableDecoratorRequiresColumnOrBelongsToAssociation.d.ts +7 -0
- package/dist/types/src/errors/ValidationError.d.ts +11 -0
- package/dist/types/src/errors/associations/CanOnlyPassBelongsToModelParam.d.ts +9 -0
- package/dist/types/src/errors/associations/CannotAssociateThroughPolymorphic.d.ts +12 -0
- package/dist/types/src/errors/associations/CannotCreateAssociationWithThroughContext.d.ts +12 -0
- package/dist/types/src/errors/associations/CannotJoinPolymorphicBelongsToError.d.ts +15 -0
- package/dist/types/src/errors/associations/CannotPassNullOrUndefinedToRequiredBelongsTo.d.ts +8 -0
- package/dist/types/src/errors/associations/InvalidComputedForeignKey.d.ts +19 -0
- package/dist/types/src/errors/associations/JoinAttemptedOnMissingAssociation.d.ts +10 -0
- package/dist/types/src/errors/associations/MissingRequiredAssociationOnClause.d.ts +8 -0
- package/dist/types/src/errors/associations/MissingRequiredPassthroughForAssociationOnClause.d.ts +5 -0
- package/dist/types/src/errors/associations/MissingThroughAssociation.d.ts +12 -0
- package/dist/types/src/errors/associations/MissingThroughAssociationSource.d.ts +14 -0
- package/dist/types/src/errors/associations/NonLoadedAssociation.d.ts +10 -0
- package/dist/types/src/errors/dream-application/DreamApplicationInitMissingCallToLoadModels.d.ts +3 -0
- package/dist/types/src/errors/dream-application/DreamApplicationInitMissingMissingProjectRoot.d.ts +3 -0
- package/dist/types/src/errors/dream-application/GlobalNameNotSet.d.ts +5 -0
- package/dist/types/src/errors/dream-application/SerializerNameConflict.d.ts +5 -0
- package/dist/types/src/errors/encrypt/MissingColumnEncryptionOpts.d.ts +3 -0
- package/dist/types/src/errors/encrypt/MissingEncryptionKey.d.ts +3 -0
- package/dist/types/src/errors/environment/MissingRequiredEnvironmentVariable.d.ts +5 -0
- package/dist/types/src/errors/ops/AnyRequiresArrayColumn.d.ts +7 -0
- package/dist/types/src/errors/ops/ScoreMustBeANormalNumber.d.ts +5 -0
- package/dist/types/src/errors/schema-builder/FailedToIdentifyAssociation.d.ts +9 -0
- package/dist/types/src/errors/serializers/FailedToRenderThroughAssociationForSerializer.d.ts +6 -0
- package/dist/types/src/errors/sortable/CannotCallSortableOnSTIChild.d.ts +6 -0
- package/dist/types/src/errors/sti/STIChildMissing.d.ts +8 -0
- package/dist/types/src/errors/sti/StiChildCannotDefineNewAssociations.d.ts +7 -0
- package/dist/types/src/errors/sti/StiChildIncompatibleWithReplicaSafeDecorator.d.ts +6 -0
- package/dist/types/src/errors/sti/StiChildIncompatibleWithSoftDeleteDecorator.d.ts +6 -0
- package/dist/types/src/global-cli/dream.d.ts +2 -0
- package/dist/types/src/global-cli/file-builders/DreamtsBuilder.d.ts +4 -0
- package/dist/types/src/global-cli/file-builders/EnvBuilder.d.ts +6 -0
- package/dist/types/src/global-cli/file-builders/EslintConfBuilder.d.ts +3 -0
- package/dist/types/src/global-cli/file-builders/PackagejsonBuilder.d.ts +3 -0
- package/dist/types/src/global-cli/helpers/argAndValue.d.ts +1 -0
- package/dist/types/src/global-cli/helpers/autogeneratedFileMessage.d.ts +1 -0
- package/dist/types/src/global-cli/helpers/buildNewDreamApp.d.ts +2 -0
- package/dist/types/src/global-cli/helpers/copyRecursive.d.ts +1 -0
- package/dist/types/src/global-cli/helpers/filterObjectByKey.d.ts +1 -0
- package/dist/types/src/global-cli/helpers/generateEncryptionKey.d.ts +1 -0
- package/dist/types/src/global-cli/helpers/globalCliSnakeify.d.ts +0 -0
- package/dist/types/src/global-cli/helpers/initDreamAppIntoExistingProject.d.ts +2 -0
- package/dist/types/src/global-cli/helpers/log.d.ts +10 -0
- package/dist/types/src/global-cli/helpers/logo.d.ts +2 -0
- package/dist/types/src/global-cli/helpers/primaryKeyTypes.d.ts +22 -0
- package/dist/types/src/global-cli/helpers/prompt.d.ts +8 -0
- package/dist/types/src/global-cli/helpers/select.d.ts +17 -0
- package/dist/types/src/global-cli/helpers/sleep.d.ts +1 -0
- package/dist/types/src/global-cli/helpers/sspawn.d.ts +2 -0
- package/dist/types/src/global-cli/helpers/welcomeMessage.d.ts +1 -0
- package/dist/types/src/global-cli/init.d.ts +2 -0
- package/dist/types/src/global-cli/new.d.ts +2 -0
- package/dist/types/src/helpers/CalendarDate.d.ts +51 -0
- package/dist/types/src/helpers/Env.d.ts +37 -0
- package/dist/types/src/helpers/EnvInternal.d.ts +6 -0
- package/dist/types/src/helpers/allNestedObjectKeys.d.ts +1 -0
- package/dist/types/src/helpers/benchmark.d.ts +6 -0
- package/dist/types/src/helpers/camelize.d.ts +3 -0
- package/dist/types/src/helpers/capitalize.d.ts +1 -0
- package/dist/types/src/helpers/cli/SchemaBuilder.d.ts +17 -0
- package/dist/types/src/helpers/cli/generateDream.d.ts +8 -0
- package/dist/types/src/helpers/cli/generateDreamContent.d.ts +6 -0
- package/dist/types/src/helpers/cli/generateFactory.d.ts +4 -0
- package/dist/types/src/helpers/cli/generateFactoryContent.d.ts +4 -0
- package/dist/types/src/helpers/cli/generateMigration.d.ts +6 -0
- package/dist/types/src/helpers/cli/generateMigrationContent.d.ts +7 -0
- package/dist/types/src/helpers/cli/generateSerializer.d.ts +5 -0
- package/dist/types/src/helpers/cli/generateSerializerContent.d.ts +5 -0
- package/dist/types/src/helpers/cli/generateStiMigrationContent.d.ts +6 -0
- package/dist/types/src/helpers/cli/generateUnitSpec.d.ts +3 -0
- package/dist/types/src/helpers/cli/generateUnitSpecContent.d.ts +3 -0
- package/dist/types/src/helpers/cloneDeepSafe.d.ts +18 -0
- package/dist/types/src/helpers/compact.d.ts +19 -0
- package/dist/types/src/helpers/customPgParsers.d.ts +9 -0
- package/dist/types/src/helpers/db/cachedTypeForAttribute.d.ts +2 -0
- package/dist/types/src/helpers/db/createDb.d.ts +2 -0
- package/dist/types/src/helpers/db/dropDb.d.ts +2 -0
- package/dist/types/src/helpers/db/foreignKeyTypeFromPrimaryKey.d.ts +2 -0
- package/dist/types/src/helpers/db/loadPgClient.d.ts +3 -0
- package/dist/types/src/helpers/db/primaryKeyType.d.ts +1 -0
- package/dist/types/src/helpers/db/runMigration.d.ts +6 -0
- package/dist/types/src/helpers/db/truncateDb.d.ts +1 -0
- package/dist/types/src/helpers/db/types/isDatabaseArrayColumn.d.ts +2 -0
- package/dist/types/src/helpers/db/types/isDateColumn.d.ts +2 -0
- package/dist/types/src/helpers/db/types/isDateTimeColumn.d.ts +2 -0
- package/dist/types/src/helpers/db/types/isJsonColumn.d.ts +2 -0
- package/dist/types/src/helpers/debug.d.ts +4 -0
- package/dist/types/src/helpers/dreamOrPsychicCoreDevelopment.d.ts +1 -0
- package/dist/types/src/helpers/filterObjectByKey.d.ts +1 -0
- package/dist/types/src/helpers/getFiles.d.ts +1 -0
- package/dist/types/src/helpers/globalClassNameFromFullyQualifiedModelName.d.ts +1 -0
- package/dist/types/src/helpers/hyphenize.d.ts +2 -0
- package/dist/types/src/helpers/inferSerializerFromDreamOrViewModel.d.ts +4 -0
- package/dist/types/src/helpers/isEmpty.d.ts +1 -0
- package/dist/types/src/helpers/loadEnv.d.ts +1 -0
- package/dist/types/src/helpers/loadRepl.d.ts +2 -0
- package/dist/types/src/helpers/migrationVersion.d.ts +1 -0
- package/dist/types/src/helpers/namespaceColumn.d.ts +1 -0
- package/dist/types/src/helpers/objectPathsToArrays.d.ts +2 -0
- package/dist/types/src/helpers/pascalize.d.ts +2 -0
- package/dist/types/src/helpers/pascalizePath.d.ts +1 -0
- package/dist/types/src/helpers/path/dreamFileAndDirPaths.d.ts +5 -0
- package/dist/types/src/helpers/path/dreamPath.d.ts +3 -0
- package/dist/types/src/helpers/path/relativeDreamPath.d.ts +3 -0
- package/dist/types/src/helpers/path/sharedPathPrefix.d.ts +1 -0
- package/dist/types/src/helpers/propertyNameFromFullyQualifiedModelName.d.ts +1 -0
- package/dist/types/src/helpers/protectAgainstPollutingAssignment.d.ts +1 -0
- package/dist/types/src/helpers/range.d.ts +7 -0
- package/dist/types/src/helpers/round.d.ts +2 -0
- package/dist/types/src/helpers/serializerNameFromFullyQualifiedModelName.d.ts +1 -0
- package/dist/types/src/helpers/snakeify.d.ts +3 -0
- package/dist/types/src/helpers/sortBy.d.ts +8 -0
- package/dist/types/src/helpers/sqlAttributes.d.ts +4 -0
- package/dist/types/src/helpers/sspawn.d.ts +2 -0
- package/dist/types/src/helpers/standardizeFullyQualifiedModelName.d.ts +1 -0
- package/dist/types/src/helpers/stringCasing.d.ts +28 -0
- package/dist/types/src/helpers/typechecks.d.ts +2 -0
- package/dist/types/src/helpers/typeutils.d.ts +115 -0
- package/dist/types/src/helpers/uncapitalize.d.ts +1 -0
- package/dist/types/src/helpers/uniq.d.ts +1 -0
- package/dist/types/src/index.d.ts +78 -0
- package/dist/types/src/openapi/types.d.ts +139 -0
- package/dist/types/src/ops/curried-ops-statement.d.ts +7 -0
- package/dist/types/src/ops/index.d.ts +49 -0
- package/dist/types/src/ops/ops-statement.d.ts +14 -0
- package/dist/types/src/serializer/decorators/associations/RendersMany.d.ts +42 -0
- package/dist/types/src/serializer/decorators/associations/RendersOne.d.ts +46 -0
- package/dist/types/src/serializer/decorators/associations/shared.d.ts +23 -0
- package/dist/types/src/serializer/decorators/attribute.d.ts +29 -0
- package/dist/types/src/serializer/decorators/helpers/dreamAttributeOpenapiShape.d.ts +7 -0
- package/dist/types/src/serializer/decorators/helpers/hasSerializersGetter.d.ts +2 -0
- package/dist/types/src/serializer/decorators/helpers/maybeSerializableToDreamSerializerCallbackFunction.d.ts +2 -0
- package/dist/types/src/serializer/index.d.ts +56 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/highlight.css +92 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1448 -0
- package/docs/classes/Benchmark.html +4 -0
- package/docs/classes/CalendarDate.html +34 -0
- package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +12 -0
- package/docs/classes/Decorators.html +81 -0
- package/docs/classes/Dream.html +896 -0
- package/docs/classes/DreamApplication.html +37 -0
- package/docs/classes/DreamBin.html +11 -0
- package/docs/classes/DreamCLI.html +7 -0
- package/docs/classes/DreamImporter.html +6 -0
- package/docs/classes/DreamMigrationHelpers.html +32 -0
- package/docs/classes/DreamSerializer.html +19 -0
- package/docs/classes/DreamTransaction.html +5 -0
- package/docs/classes/Encrypt.html +8 -0
- package/docs/classes/Env.html +20 -0
- package/docs/classes/GlobalNameNotSet.html +12 -0
- package/docs/classes/NonLoadedAssociation.html +14 -0
- package/docs/classes/Query.html +383 -0
- package/docs/classes/Range.html +5 -0
- package/docs/classes/RecordNotFound.html +13 -0
- package/docs/classes/ValidationError.html +14 -0
- package/docs/functions/AfterCreate.html +1 -0
- package/docs/functions/AfterCreateCommit.html +13 -0
- package/docs/functions/AfterDestroy.html +1 -0
- package/docs/functions/AfterDestroyCommit.html +13 -0
- package/docs/functions/AfterSave.html +1 -0
- package/docs/functions/AfterSaveCommit.html +13 -0
- package/docs/functions/AfterUpdate.html +1 -0
- package/docs/functions/AfterUpdateCommit.html +13 -0
- package/docs/functions/Attribute.html +1 -0
- package/docs/functions/BeforeCreate.html +1 -0
- package/docs/functions/BeforeDestroy.html +1 -0
- package/docs/functions/BeforeSave.html +1 -0
- package/docs/functions/BeforeUpdate.html +1 -0
- package/docs/functions/RendersMany.html +16 -0
- package/docs/functions/RendersOne.html +16 -0
- package/docs/functions/ReplicaSafe.html +1 -0
- package/docs/functions/STI.html +1 -0
- package/docs/functions/Scope.html +1 -0
- package/docs/functions/SoftDelete.html +19 -0
- package/docs/functions/Sortable.html +1 -0
- package/docs/functions/Validate.html +1 -0
- package/docs/functions/Validates.html +1 -0
- package/docs/functions/Virtual.html +1 -0
- package/docs/functions/camelize.html +1 -0
- package/docs/functions/capitalize.html +1 -0
- package/docs/functions/closeAllDbConnections.html +1 -0
- package/docs/functions/compact.html +1 -0
- package/docs/functions/db.html +1 -0
- package/docs/functions/debug.html +1 -0
- package/docs/functions/dreamDbConnections.html +1 -0
- package/docs/functions/dreamPath.html +1 -0
- package/docs/functions/generateDream.html +1 -0
- package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -0
- package/docs/functions/hyphenize.html +1 -0
- package/docs/functions/inferSerializerFromDreamClassOrViewModelClass.html +1 -0
- package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -0
- package/docs/functions/isEmpty.html +1 -0
- package/docs/functions/loadRepl.html +1 -0
- package/docs/functions/lookupClassByGlobalName.html +1 -0
- package/docs/functions/pascalize.html +1 -0
- package/docs/functions/pgErrorType.html +1 -0
- package/docs/functions/range-1.html +1 -0
- package/docs/functions/relativeDreamPath.html +1 -0
- package/docs/functions/round.html +1 -0
- package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -0
- package/docs/functions/sharedPathPrefix.html +1 -0
- package/docs/functions/snakeify.html +1 -0
- package/docs/functions/sortBy.html +1 -0
- package/docs/functions/standardizeFullyQualifiedModelName.html +1 -0
- package/docs/functions/uncapitalize.html +1 -0
- package/docs/functions/uniq.html +1 -0
- package/docs/functions/validateColumn.html +1 -0
- package/docs/functions/validateTable.html +1 -0
- package/docs/index.html +123 -0
- package/docs/interfaces/AttributeStatement.html +6 -0
- package/docs/interfaces/DecoratorContext.html +8 -0
- package/docs/interfaces/DreamApplicationInitOptions.html +2 -0
- package/docs/interfaces/DreamApplicationOpts.html +8 -0
- package/docs/interfaces/DreamSerializerAssociationStatement.html +11 -0
- package/docs/interfaces/EncryptOptions.html +3 -0
- package/docs/interfaces/OpenapiSchemaProperties.html +1 -0
- package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -0
- package/docs/interfaces/OpenapiTypeFieldObject.html +1 -0
- package/docs/modules.html +163 -0
- package/docs/types/Camelized.html +1 -0
- package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -0
- package/docs/types/DreamAssociationMetadata.html +1 -0
- package/docs/types/DreamAttributes.html +1 -0
- package/docs/types/DreamClassColumn.html +1 -0
- package/docs/types/DreamColumn.html +1 -0
- package/docs/types/DreamColumnNames.html +1 -0
- package/docs/types/DreamLogLevel.html +1 -0
- package/docs/types/DreamLogger.html +1 -0
- package/docs/types/DreamOrViewModelSerializerKey.html +1 -0
- package/docs/types/DreamParamSafeAttributes.html +1 -0
- package/docs/types/DreamParamSafeColumnNames.html +1 -0
- package/docs/types/DreamSerializerKey.html +1 -0
- package/docs/types/DreamSerializers.html +1 -0
- package/docs/types/DreamTableSchema.html +1 -0
- package/docs/types/DreamVirtualColumns.html +1 -0
- package/docs/types/EncryptAlgorithm.html +1 -0
- package/docs/types/Hyphenized.html +1 -0
- package/docs/types/IdType.html +1 -0
- package/docs/types/OpenapiAllTypes.html +1 -0
- package/docs/types/OpenapiFormats.html +1 -0
- package/docs/types/OpenapiNumberFormats.html +1 -0
- package/docs/types/OpenapiPrimitiveTypes.html +1 -0
- package/docs/types/OpenapiSchemaArray.html +1 -0
- package/docs/types/OpenapiSchemaArrayShorthand.html +1 -0
- package/docs/types/OpenapiSchemaBase.html +1 -0
- package/docs/types/OpenapiSchemaBody.html +1 -0
- package/docs/types/OpenapiSchemaBodyShorthand.html +1 -0
- package/docs/types/OpenapiSchemaCommonFields.html +1 -0
- package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -0
- package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -0
- package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -0
- package/docs/types/OpenapiSchemaExpressionRef.html +1 -0
- package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -0
- package/docs/types/OpenapiSchemaInteger.html +1 -0
- package/docs/types/OpenapiSchemaNull.html +1 -0
- package/docs/types/OpenapiSchemaNumber.html +1 -0
- package/docs/types/OpenapiSchemaObject.html +1 -0
- package/docs/types/OpenapiSchemaObjectAllOf.html +1 -0
- package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -0
- package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -0
- package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -0
- package/docs/types/OpenapiSchemaObjectBase.html +1 -0
- package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -0
- package/docs/types/OpenapiSchemaObjectOneOf.html +1 -0
- package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -0
- package/docs/types/OpenapiSchemaObjectShorthand.html +1 -0
- package/docs/types/OpenapiSchemaPartialSegment.html +1 -0
- package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -0
- package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -0
- package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -0
- package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -0
- package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -0
- package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -0
- package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -0
- package/docs/types/OpenapiSchemaString.html +1 -0
- package/docs/types/OpenapiShorthandAllTypes.html +1 -0
- package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -0
- package/docs/types/OpenapiTypeField.html +1 -0
- package/docs/types/Pascalized.html +1 -0
- package/docs/types/PrimaryKeyType.html +1 -0
- package/docs/types/RoundingPrecision.html +1 -0
- package/docs/types/SerializableClassOrSerializerCallback.html +1 -0
- package/docs/types/SerializableDreamClassOrViewModelClass.html +1 -0
- package/docs/types/SerializableDreamOrViewModel.html +1 -0
- package/docs/types/SerializableTypes.html +1 -0
- package/docs/types/Snakeified.html +1 -0
- package/docs/types/Timestamp.html +1 -0
- package/docs/types/UpdateableAssociationProperties.html +1 -0
- package/docs/types/UpdateableProperties.html +1 -0
- package/docs/types/ValidationType.html +1 -0
- package/docs/types/ViewModelSerializerKey.html +1 -0
- package/docs/types/WhereStatementForDream.html +1 -0
- package/docs/types/WhereStatementForDreamClass.html +1 -0
- package/docs/variables/DreamConst.html +1 -0
- package/docs/variables/TRIGRAM_OPERATORS.html +1 -0
- package/docs/variables/openapiPrimitiveTypes-1.html +1 -0
- package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -0
- package/docs/variables/ops.html +1 -0
- package/docs/variables/primaryKeyTypes.html +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,2984 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const luxon_1 = require("luxon");
|
|
4
|
+
const errors_js_1 = require("./db/errors.js");
|
|
5
|
+
const index_js_1 = require("./db/index.js");
|
|
6
|
+
const associationToGetterSetterProp_js_1 = require("./decorators/associations/associationToGetterSetterProp.js");
|
|
7
|
+
const shared_js_1 = require("./decorators/associations/shared.js");
|
|
8
|
+
const shared_js_2 = require("./decorators/hooks/shared.js");
|
|
9
|
+
const resortAllRecords_js_1 = require("./decorators/sortable/helpers/resortAllRecords.js");
|
|
10
|
+
const DreamClassTransactionBuilder_js_1 = require("./dream/DreamClassTransactionBuilder.js");
|
|
11
|
+
const DreamInstanceTransactionBuilder_js_1 = require("./dream/DreamInstanceTransactionBuilder.js");
|
|
12
|
+
const DreamTransaction_js_1 = require("./dream/DreamTransaction.js");
|
|
13
|
+
const associationQuery_js_1 = require("./dream/internal/associations/associationQuery.js");
|
|
14
|
+
const associationUpdateQuery_js_1 = require("./dream/internal/associations/associationUpdateQuery.js");
|
|
15
|
+
const createAssociation_js_1 = require("./dream/internal/associations/createAssociation.js");
|
|
16
|
+
const destroyAssociation_js_1 = require("./dream/internal/associations/destroyAssociation.js");
|
|
17
|
+
const undestroyAssociation_js_1 = require("./dream/internal/associations/undestroyAssociation.js");
|
|
18
|
+
const destroyDream_js_1 = require("./dream/internal/destroyDream.js");
|
|
19
|
+
const destroyOptions_js_1 = require("./dream/internal/destroyOptions.js");
|
|
20
|
+
const ensureSTITypeFieldIsSet_js_1 = require("./dream/internal/ensureSTITypeFieldIsSet.js");
|
|
21
|
+
const extractAssociationMetadataFromAssociationName_js_1 = require("./dream/internal/extractAssociationMetadataFromAssociationName.js");
|
|
22
|
+
const reload_js_1 = require("./dream/internal/reload.js");
|
|
23
|
+
const runValidations_js_1 = require("./dream/internal/runValidations.js");
|
|
24
|
+
const saveDream_js_1 = require("./dream/internal/saveDream.js");
|
|
25
|
+
const scopeHelpers_js_1 = require("./dream/internal/scopeHelpers.js");
|
|
26
|
+
const undestroyDream_js_1 = require("./dream/internal/undestroyDream.js");
|
|
27
|
+
const LeftJoinLoadBuilder_js_1 = require("./dream/LeftJoinLoadBuilder.js");
|
|
28
|
+
const LoadBuilder_js_1 = require("./dream/LoadBuilder.js");
|
|
29
|
+
const Query_js_1 = require("./dream/Query.js");
|
|
30
|
+
const CannotPassNullOrUndefinedToRequiredBelongsTo_js_1 = require("./errors/associations/CannotPassNullOrUndefinedToRequiredBelongsTo.js");
|
|
31
|
+
const CanOnlyPassBelongsToModelParam_js_1 = require("./errors/associations/CanOnlyPassBelongsToModelParam.js");
|
|
32
|
+
const NonLoadedAssociation_js_1 = require("./errors/associations/NonLoadedAssociation.js");
|
|
33
|
+
const CannotCallUndestroyOnANonSoftDeleteModel_js_1 = require("./errors/CannotCallUndestroyOnANonSoftDeleteModel.js");
|
|
34
|
+
const ConstructorOnlyForInternalUse_js_1 = require("./errors/ConstructorOnlyForInternalUse.js");
|
|
35
|
+
const CreateOrFindByFailedToCreateAndFind_js_1 = require("./errors/CreateOrFindByFailedToCreateAndFind.js");
|
|
36
|
+
const GlobalNameNotSet_js_1 = require("./errors/dream-application/GlobalNameNotSet.js");
|
|
37
|
+
const MissingSerializersDefinition_js_1 = require("./errors/MissingSerializersDefinition.js");
|
|
38
|
+
const MissingTable_js_1 = require("./errors/MissingTable.js");
|
|
39
|
+
const NonExistentScopeProvidedToResort_js_1 = require("./errors/NonExistentScopeProvidedToResort.js");
|
|
40
|
+
const CalendarDate_js_1 = require("./helpers/CalendarDate.js");
|
|
41
|
+
const cloneDeepSafe_js_1 = require("./helpers/cloneDeepSafe.js");
|
|
42
|
+
const cachedTypeForAttribute_js_1 = require("./helpers/db/cachedTypeForAttribute.js");
|
|
43
|
+
const isJsonColumn_js_1 = require("./helpers/db/types/isJsonColumn.js");
|
|
44
|
+
const inferSerializerFromDreamOrViewModel_js_1 = require("./helpers/inferSerializerFromDreamOrViewModel.js");
|
|
45
|
+
const typechecks_js_1 = require("./helpers/typechecks.js");
|
|
46
|
+
class Dream {
|
|
47
|
+
DB;
|
|
48
|
+
/**
|
|
49
|
+
* @internal
|
|
50
|
+
*
|
|
51
|
+
* This getter will throw an error when developers use .toEqual instead of
|
|
52
|
+
* useToMatchDreamModels or useToMatchDreamModel in a jest spec. This
|
|
53
|
+
* must be the first getter in the class in order for this to work, so don't move it.
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
get _useToMatchDreamModels() {
|
|
57
|
+
throw new Error(`
|
|
58
|
+
Hi there! It looks like you're trying to compare a Dream model in
|
|
59
|
+
a Jest expectation using \`toEqual\`. That won't work.
|
|
60
|
+
Instead, use \`toMatchDreamModel\` or \`toMatchDreamModels\`.
|
|
61
|
+
|
|
62
|
+
For example, instead of:
|
|
63
|
+
|
|
64
|
+
expect(balloons).toEqual([balloon])
|
|
65
|
+
|
|
66
|
+
write:
|
|
67
|
+
|
|
68
|
+
expect(balloons).toMatchDreamModels([balloon])
|
|
69
|
+
`);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* @internal
|
|
73
|
+
*
|
|
74
|
+
* Modern Javascript sets all properties that do not have an explicit
|
|
75
|
+
* assignment within the constructor to undefined in an implicit constructor.
|
|
76
|
+
* Since the Dream constructor sets the value of properties of instances of
|
|
77
|
+
* classes that extend Dream (e.g. when passing attributes to #new or #create
|
|
78
|
+
* or when loading a model via one of the #find methods or #all), we need to
|
|
79
|
+
* prevent those properties from being set back to undefined. Since all
|
|
80
|
+
* properties corresponding to a database column get a setter, we achieve this
|
|
81
|
+
* protection by including a guard in the setters that returns if this
|
|
82
|
+
* property is set.
|
|
83
|
+
*
|
|
84
|
+
*/
|
|
85
|
+
columnSetterGuardActivated = false;
|
|
86
|
+
/**
|
|
87
|
+
* @internal
|
|
88
|
+
*
|
|
89
|
+
* Certain features (e.g. passing a Dream instance to `create` so that it automatically destructures polymorphic type and primary key)
|
|
90
|
+
* need static access to things set up by decorators (e.g. associations). Stage 3 Decorators change the context that is available
|
|
91
|
+
* at decoration time such that the class of a property being decorated is only avilable during instance instantiation. In order
|
|
92
|
+
* to only apply static values once, on boot, `globallyInitializingDecorators` is set to true on Dream, and all Dream models are instantiated.
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
static globallyInitializingDecorators = false;
|
|
96
|
+
get schema() {
|
|
97
|
+
throw new Error('Must define schema getter in ApplicationModel');
|
|
98
|
+
}
|
|
99
|
+
get globalSchema() {
|
|
100
|
+
throw new Error('Must define schema getter in ApplicationModel');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Shadows #primaryKey, a getter which can be overwritten to customize the id field
|
|
104
|
+
* for a given model.
|
|
105
|
+
*
|
|
106
|
+
* @returns string
|
|
107
|
+
*/
|
|
108
|
+
static get primaryKey() {
|
|
109
|
+
return this.prototype.primaryKey;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Shadows #table, a getter which can be overwritten to customize the table field
|
|
113
|
+
* for a given model.
|
|
114
|
+
*
|
|
115
|
+
* @returns string
|
|
116
|
+
*/
|
|
117
|
+
static get table() {
|
|
118
|
+
return this.prototype.table;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* A getter which can be overwritten to customize the automatic createdAt timestamp field
|
|
122
|
+
* for a given model.
|
|
123
|
+
*
|
|
124
|
+
* ```ts
|
|
125
|
+
* class User extends ApplicationModel {
|
|
126
|
+
* public get createdAtField() {
|
|
127
|
+
* return 'createdAtTimestamp' as const
|
|
128
|
+
* }
|
|
129
|
+
* }
|
|
130
|
+
*
|
|
131
|
+
* const user = await User.first()
|
|
132
|
+
* user.createdAtTimestamp // returns the DateTime that this user was created
|
|
133
|
+
*
|
|
134
|
+
* @returns string
|
|
135
|
+
*/
|
|
136
|
+
get createdAtField() {
|
|
137
|
+
return 'createdAt';
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* A getter which can be overwritten to customize the automatic updatedAt timestamp field
|
|
141
|
+
* for a given model.
|
|
142
|
+
*
|
|
143
|
+
* ```ts
|
|
144
|
+
* class User extends ApplicationModel {
|
|
145
|
+
* public get updatedAtField() {
|
|
146
|
+
* return 'updatedAtTimestamp' as const
|
|
147
|
+
* }
|
|
148
|
+
* }
|
|
149
|
+
*
|
|
150
|
+
* const user = await User.first()
|
|
151
|
+
* user.updatedAtTimestamp // returns the DateTime that this user was updated
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @returns string
|
|
155
|
+
*/
|
|
156
|
+
get updatedAtField() {
|
|
157
|
+
return 'updatedAt';
|
|
158
|
+
}
|
|
159
|
+
get deletedAtField() {
|
|
160
|
+
return 'deletedAt';
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* @internal
|
|
164
|
+
*
|
|
165
|
+
* Model storage for association metadata, set when using the association decorators like:
|
|
166
|
+
* @Deco.HasOne
|
|
167
|
+
* @Deco.HasMany
|
|
168
|
+
* @Deco.BelongsTo
|
|
169
|
+
*/
|
|
170
|
+
static associationMetadataByType = (0, shared_js_1.blankAssociationsFactory)(this, {
|
|
171
|
+
freeze: true,
|
|
172
|
+
});
|
|
173
|
+
/**
|
|
174
|
+
* @internal
|
|
175
|
+
*
|
|
176
|
+
* Model storage for scope metadata, set when using the Scope decorator
|
|
177
|
+
* (this default assignment simply ensures that it is
|
|
178
|
+
* always an array rather than undefined,
|
|
179
|
+
* freezing ensures that we never modify the static array on the inherited Dream class)
|
|
180
|
+
*/
|
|
181
|
+
static scopes = Object.freeze({
|
|
182
|
+
default: Object.freeze([]),
|
|
183
|
+
named: Object.freeze([]),
|
|
184
|
+
});
|
|
185
|
+
/**
|
|
186
|
+
* @internal
|
|
187
|
+
*
|
|
188
|
+
* Model storage for virtual attribute metadata, set on the inheriting class when
|
|
189
|
+
* using the Virtual decorator (this default assignment simply ensures that it is
|
|
190
|
+
* always an array rather than undefined,
|
|
191
|
+
* freezing ensures that we never modify the static array on the inherited Dream class)
|
|
192
|
+
*/
|
|
193
|
+
static virtualAttributes = Object.freeze([]);
|
|
194
|
+
/**
|
|
195
|
+
* @internal
|
|
196
|
+
*
|
|
197
|
+
* Model storage for additional columns that may not be set via the new/create/update
|
|
198
|
+
* methods. Set on the inheriting class when using the Virtual decorator (this default
|
|
199
|
+
* assignment simply ensures that it is always an array rather than undefined)
|
|
200
|
+
*/
|
|
201
|
+
static explicitUnsafeParamColumns = Object.freeze([]);
|
|
202
|
+
/**
|
|
203
|
+
* @internal
|
|
204
|
+
*
|
|
205
|
+
* Model storage for sortable metadata, set when using the Sortable decorator
|
|
206
|
+
* (this default assignment simply ensures that it is always an array rather than undefined,
|
|
207
|
+
* freezing ensures that we never modify the static array on the inherited Dream class)
|
|
208
|
+
*
|
|
209
|
+
*/
|
|
210
|
+
static sortableFields = Object.freeze([]);
|
|
211
|
+
/**
|
|
212
|
+
* @internal
|
|
213
|
+
*
|
|
214
|
+
* Model storage for STI metadata, set when using the STI decorator
|
|
215
|
+
*/
|
|
216
|
+
static extendedBy = null;
|
|
217
|
+
/**
|
|
218
|
+
* @internal
|
|
219
|
+
*
|
|
220
|
+
* Model storage for STI metadata, set when using the STI decorator
|
|
221
|
+
* (this default assignment simply ensures that it is always a valid object rather than undefined,
|
|
222
|
+
* freezing ensures that we never modify the static array on the inherited Dream class)
|
|
223
|
+
*/
|
|
224
|
+
static sti = Object.freeze({
|
|
225
|
+
active: false,
|
|
226
|
+
baseClass: null,
|
|
227
|
+
value: null,
|
|
228
|
+
});
|
|
229
|
+
/**
|
|
230
|
+
* @internal
|
|
231
|
+
*
|
|
232
|
+
* Model storage for model hook metadata, set when using the following decorators:
|
|
233
|
+
* BeforeCreate
|
|
234
|
+
* BeforeUpdate
|
|
235
|
+
* BeforeSave
|
|
236
|
+
* BeforeDestroy
|
|
237
|
+
* AfterCreate
|
|
238
|
+
* AfterCreateCommit
|
|
239
|
+
* AfterUpdate
|
|
240
|
+
* AfterUpdateCommit
|
|
241
|
+
* AfterSave
|
|
242
|
+
* AfterSaveCommit
|
|
243
|
+
* AfterDestroy
|
|
244
|
+
* AfterDestroyCommit
|
|
245
|
+
*/
|
|
246
|
+
static hooks = (0, shared_js_2.blankHooksFactory)(this, { freeze: true });
|
|
247
|
+
/**
|
|
248
|
+
* @internal
|
|
249
|
+
*
|
|
250
|
+
* Model storage for validation metadata, set when using the Validates decorator
|
|
251
|
+
* (this default assignment simply ensures that it is always an array rather than undefined,
|
|
252
|
+
* freezing ensures that we never modify the static array on the inherited Dream class)
|
|
253
|
+
*/
|
|
254
|
+
static validations = Object.freeze([]);
|
|
255
|
+
/**
|
|
256
|
+
* @internal
|
|
257
|
+
*
|
|
258
|
+
* Model storage for custom validation metadata, set when using the Validate decorator
|
|
259
|
+
* (this default assignment simply ensures that it is always an array rather than undefined,
|
|
260
|
+
* freezing ensures that we never modify the static array on the inherited Dream class)
|
|
261
|
+
*
|
|
262
|
+
*/
|
|
263
|
+
static customValidations = Object.freeze([]);
|
|
264
|
+
/**
|
|
265
|
+
* @internal
|
|
266
|
+
*
|
|
267
|
+
* Model storage for replica-safe metadata, set when using the ReplicaSafe decorator
|
|
268
|
+
*/
|
|
269
|
+
static replicaSafe = false;
|
|
270
|
+
/**
|
|
271
|
+
* @internal
|
|
272
|
+
*
|
|
273
|
+
* Model storage for soft-delete metadata, set when using the SoftDelete decorator
|
|
274
|
+
*/
|
|
275
|
+
static softDelete = false;
|
|
276
|
+
/**
|
|
277
|
+
* @internal
|
|
278
|
+
*
|
|
279
|
+
* Provided to distinguish between Dream and other classes
|
|
280
|
+
*
|
|
281
|
+
* @returns true
|
|
282
|
+
*/
|
|
283
|
+
static get isDream() {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* @internal
|
|
288
|
+
*
|
|
289
|
+
* Returns true if this model class is the base class of other STI models
|
|
290
|
+
*
|
|
291
|
+
* @returns boolean
|
|
292
|
+
*/
|
|
293
|
+
static get isSTIBase() {
|
|
294
|
+
return !!this.extendedBy?.length && !this.isSTIChild;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* @internal
|
|
298
|
+
*
|
|
299
|
+
* Returns true if this model class a child class of a base STI model
|
|
300
|
+
*
|
|
301
|
+
* @returns boolean
|
|
302
|
+
*/
|
|
303
|
+
static get isSTIChild() {
|
|
304
|
+
return !!this.sti?.active;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* @internal
|
|
308
|
+
*
|
|
309
|
+
* Returns either the base STI class, or else this class
|
|
310
|
+
*
|
|
311
|
+
* @returns A dream class
|
|
312
|
+
*/
|
|
313
|
+
static get stiBaseClassOrOwnClass() {
|
|
314
|
+
return this.sti.baseClass || this;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* @internal
|
|
318
|
+
*
|
|
319
|
+
* Shadows .stiBaseClassOrOwnClass. Returns either the base STI class, or else this class
|
|
320
|
+
*
|
|
321
|
+
* @returns A dream class
|
|
322
|
+
*/
|
|
323
|
+
get stiBaseClassOrOwnClass() {
|
|
324
|
+
return this.constructor.stiBaseClassOrOwnClass;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* @internal
|
|
328
|
+
*
|
|
329
|
+
* Used by model hook decorators to apply a hook to a specific model.
|
|
330
|
+
*
|
|
331
|
+
* @param hookType - the type of hook you want to attach the provided statement to
|
|
332
|
+
* @param statement - the statement to couple to the provided hookType
|
|
333
|
+
* @returns void
|
|
334
|
+
*/
|
|
335
|
+
static addHook(hookType, statement) {
|
|
336
|
+
const existingHook = this.hooks[hookType].find(hook => hook.method === statement.method);
|
|
337
|
+
if (existingHook)
|
|
338
|
+
return;
|
|
339
|
+
this.hooks[hookType] = [...this.hooks[hookType], statement];
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* @internal
|
|
343
|
+
*
|
|
344
|
+
* Returns a unique global name for the given model.
|
|
345
|
+
*
|
|
346
|
+
* @returns A string representing a unique key for this model
|
|
347
|
+
*/
|
|
348
|
+
static get globalName() {
|
|
349
|
+
if (!this._globalName)
|
|
350
|
+
throw new GlobalNameNotSet_js_1.default(this);
|
|
351
|
+
return this._globalName;
|
|
352
|
+
}
|
|
353
|
+
static _globalName;
|
|
354
|
+
/**
|
|
355
|
+
* @internal
|
|
356
|
+
*
|
|
357
|
+
* Used by DreamApplication during the load process
|
|
358
|
+
* for models, services, and controllers to assign
|
|
359
|
+
* unique global names to each model based on the file
|
|
360
|
+
* name of that model.
|
|
361
|
+
*/
|
|
362
|
+
static setGlobalName(globalName) {
|
|
363
|
+
this._globalName = globalName;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Returns the column names for the given model
|
|
367
|
+
*
|
|
368
|
+
* @returns The column names for the given model
|
|
369
|
+
*/
|
|
370
|
+
static columns() {
|
|
371
|
+
if (this._columns)
|
|
372
|
+
return this._columns;
|
|
373
|
+
const columns = this.prototype.schema[this.table]?.columns;
|
|
374
|
+
this._columns = new Set(columns ? Object.keys(columns) : []);
|
|
375
|
+
return this._columns;
|
|
376
|
+
}
|
|
377
|
+
static _columns;
|
|
378
|
+
/**
|
|
379
|
+
* Returns the list of column names that are safe for
|
|
380
|
+
* casting automatically using `.paramsFor` within a
|
|
381
|
+
* psychic controller. It will return a subset of the
|
|
382
|
+
* `.columns` getter, but which filters out the following:
|
|
383
|
+
* * createdAt
|
|
384
|
+
* * updatedAt
|
|
385
|
+
* * deletedAt
|
|
386
|
+
* * type fields for STI models
|
|
387
|
+
* * foreign key fields for belongs to associations (these should usually be verified before being set)
|
|
388
|
+
* * type fields corresponding to polymorphic associations
|
|
389
|
+
*
|
|
390
|
+
* @returns A subset of columns for the given dream class
|
|
391
|
+
*/
|
|
392
|
+
static paramSafeColumnsOrFallback() {
|
|
393
|
+
const defaultParams = this.defaultParamSafeColumns();
|
|
394
|
+
const userDefinedParams = this.prototype.paramSafeColumns;
|
|
395
|
+
if (Array.isArray(userDefinedParams)) {
|
|
396
|
+
return userDefinedParams.filter(param => defaultParams.includes(param));
|
|
397
|
+
}
|
|
398
|
+
return defaultParams;
|
|
399
|
+
}
|
|
400
|
+
static defaultParamSafeColumns() {
|
|
401
|
+
const columns = [...this.columns()].filter(column => {
|
|
402
|
+
if (this.prototype.primaryKey === column)
|
|
403
|
+
return false;
|
|
404
|
+
if (this.prototype.createdAtField === column)
|
|
405
|
+
return false;
|
|
406
|
+
if (this.prototype.updatedAtField === column)
|
|
407
|
+
return false;
|
|
408
|
+
if (this.prototype.deletedAtField === column)
|
|
409
|
+
return false;
|
|
410
|
+
if (this.explicitUnsafeParamColumns.includes(column))
|
|
411
|
+
return false;
|
|
412
|
+
if (this.isBelongsToAssociationForeignKey(column))
|
|
413
|
+
return false;
|
|
414
|
+
if (this.isBelongsToAssociationPolymorphicTypeField(column))
|
|
415
|
+
return false;
|
|
416
|
+
if (this.sti.active && column === 'type')
|
|
417
|
+
return false;
|
|
418
|
+
return true;
|
|
419
|
+
});
|
|
420
|
+
return [
|
|
421
|
+
...new Set([...columns, ...this.virtualAttributes.map(attr => attr.property)]),
|
|
422
|
+
];
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* @internal
|
|
426
|
+
*
|
|
427
|
+
* Returns true if the column is virtual (set using the Virtual decorator)
|
|
428
|
+
*
|
|
429
|
+
* @param columnName - the name of the property you are checking for
|
|
430
|
+
* @returns boolean
|
|
431
|
+
*/
|
|
432
|
+
static isVirtualColumn(columnName) {
|
|
433
|
+
return this.prototype.isVirtualColumn(columnName);
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* @internal
|
|
437
|
+
*
|
|
438
|
+
* Locates an association's metadata by key
|
|
439
|
+
*
|
|
440
|
+
* ```ts
|
|
441
|
+
* Post.getAssociationMetadata('user')
|
|
442
|
+
* // {
|
|
443
|
+
* // modelCB: [Function (anonymous)],
|
|
444
|
+
* // type: 'BelongsTo',
|
|
445
|
+
* // as: 'user',
|
|
446
|
+
* // optional: false,
|
|
447
|
+
* // polymorphic: false,
|
|
448
|
+
* // primaryKeyOverride: null,
|
|
449
|
+
* // primaryKey: [Function: primaryKey],
|
|
450
|
+
* // primaryKeyValue: [Function: primaryKeyValue],
|
|
451
|
+
* // foreignKey: [Function: foreignKey],
|
|
452
|
+
* // foreignKeyTypeField: [Function: foreignKeyTypeField]
|
|
453
|
+
* // }
|
|
454
|
+
* ```
|
|
455
|
+
*
|
|
456
|
+
* @param associationName - the name of the association you wish to retrieve metadata for
|
|
457
|
+
* @returns Association metadata for the requested association
|
|
458
|
+
*/
|
|
459
|
+
static getAssociationMetadata(associationName) {
|
|
460
|
+
return this.associationMetadataMap()[(0, extractAssociationMetadataFromAssociationName_js_1.default)(associationName).name];
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* @internal
|
|
464
|
+
*
|
|
465
|
+
* Returns an array containing all of the associations for this dream class
|
|
466
|
+
*
|
|
467
|
+
* @returns An array containing all of the associations for this dream class
|
|
468
|
+
*/
|
|
469
|
+
static associationMetadataMap() {
|
|
470
|
+
const allAssociations = [
|
|
471
|
+
...this.associationMetadataByType.belongsTo,
|
|
472
|
+
...this.associationMetadataByType.hasOne,
|
|
473
|
+
...this.associationMetadataByType.hasMany,
|
|
474
|
+
];
|
|
475
|
+
const map = {};
|
|
476
|
+
for (const association of allAssociations) {
|
|
477
|
+
map[association.as] = association;
|
|
478
|
+
}
|
|
479
|
+
return map;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* @internal
|
|
483
|
+
*
|
|
484
|
+
* Returns all of the association names for this dream class
|
|
485
|
+
*
|
|
486
|
+
* @returns All of the association names for this dream class
|
|
487
|
+
*/
|
|
488
|
+
static get associationNames() {
|
|
489
|
+
const allAssociations = [
|
|
490
|
+
...this.associationMetadataByType.belongsTo,
|
|
491
|
+
...this.associationMetadataByType.hasOne,
|
|
492
|
+
...this.associationMetadataByType.hasMany,
|
|
493
|
+
];
|
|
494
|
+
return allAssociations.map(association => {
|
|
495
|
+
return association.as;
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Returns a query for this model which disregards default scopes
|
|
500
|
+
*
|
|
501
|
+
* @returns A query for this model which disregards default scopes
|
|
502
|
+
*/
|
|
503
|
+
static removeAllDefaultScopes() {
|
|
504
|
+
return this.query().removeAllDefaultScopes();
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Prevents a specific default scope from applying when
|
|
508
|
+
* the Query is executed
|
|
509
|
+
*
|
|
510
|
+
* @returns A new Query which will prevent a specific default scope from applying
|
|
511
|
+
*/
|
|
512
|
+
static removeDefaultScope(scopeName) {
|
|
513
|
+
return this.query().removeDefaultScope(scopeName);
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Retrieves an array containing all records corresponding to
|
|
517
|
+
* this model. Be careful using this, since it will attempt to
|
|
518
|
+
* pull every record into memory at once. For a large number
|
|
519
|
+
* of records, consider using `.findEach`, which will pull
|
|
520
|
+
* the records in batches.
|
|
521
|
+
*
|
|
522
|
+
* ```ts
|
|
523
|
+
* await User.all()
|
|
524
|
+
* ```
|
|
525
|
+
*
|
|
526
|
+
* @returns an array of dreams
|
|
527
|
+
*/
|
|
528
|
+
static async all(options = {}) {
|
|
529
|
+
return await this.query().all(options);
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Forces use of a database connection (e.g. 'primary') during the query.
|
|
533
|
+
*
|
|
534
|
+
* NOTE: all queries within a transaction always use the 'primary' replica, so
|
|
535
|
+
* explicitly setting connection within a transaction has no effect.
|
|
536
|
+
*
|
|
537
|
+
* @param connection - The connection you wish to access ('primary' or 'replica')
|
|
538
|
+
* @returns A Query with the requested connection
|
|
539
|
+
*/
|
|
540
|
+
static connection(connection) {
|
|
541
|
+
return new Query_js_1.default(this.prototype, {
|
|
542
|
+
connection,
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Retrieves the number of records corresponding
|
|
547
|
+
* to this model.
|
|
548
|
+
*
|
|
549
|
+
* @returns The number of records corresponding to this model
|
|
550
|
+
*/
|
|
551
|
+
static async count() {
|
|
552
|
+
return await this.query().count();
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Retrieves the max value of the specified column
|
|
556
|
+
* for this model's records.
|
|
557
|
+
*
|
|
558
|
+
* ```ts
|
|
559
|
+
* await User.max('id')
|
|
560
|
+
* // 99
|
|
561
|
+
* ```
|
|
562
|
+
*
|
|
563
|
+
* @param columnName - a column name on the model
|
|
564
|
+
* @returns the max value of the specified column for this model's records
|
|
565
|
+
*/
|
|
566
|
+
static async max(columnName) {
|
|
567
|
+
return await this.query().max(columnName);
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Retrieves the min value of the specified column
|
|
571
|
+
* for this model's records.
|
|
572
|
+
*
|
|
573
|
+
*
|
|
574
|
+
* ```ts
|
|
575
|
+
* await User.min('id')
|
|
576
|
+
* // 1
|
|
577
|
+
* ```
|
|
578
|
+
*
|
|
579
|
+
* @param columnName - a column name on the model
|
|
580
|
+
* @returns the min value of the specified column for this model's records
|
|
581
|
+
*/
|
|
582
|
+
static async min(columnName) {
|
|
583
|
+
return await this.query().min(columnName);
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Persists a new record, setting the provided attributes
|
|
587
|
+
*
|
|
588
|
+
* ```ts
|
|
589
|
+
* const user = await User.create({ email: 'how@yadoin' })
|
|
590
|
+
* await Post.create({ body: 'howdy', user })
|
|
591
|
+
* ```
|
|
592
|
+
*
|
|
593
|
+
* @param attributes - attributes or belongs to associations you wish to set on this model before persisting
|
|
594
|
+
* @returns A newly persisted dream instance
|
|
595
|
+
*/
|
|
596
|
+
static async create(attributes) {
|
|
597
|
+
const dreamModel = this.new(attributes);
|
|
598
|
+
await dreamModel.save();
|
|
599
|
+
return dreamModel;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Attempt to create the model. If creation fails
|
|
603
|
+
* due to uniqueness constraint, then find the existing
|
|
604
|
+
* model.
|
|
605
|
+
*
|
|
606
|
+
* This is useful in situations where we want to avoid
|
|
607
|
+
* a race condition creating duplicate records.
|
|
608
|
+
*
|
|
609
|
+
* IMPORTANT: A unique index/uniqueness constraint must exist on
|
|
610
|
+
* at least one of the provided attributes
|
|
611
|
+
*
|
|
612
|
+
* ```ts
|
|
613
|
+
* const logEntry = await LogEntry.createOrFindBy({ externalId }, { createWith: params })
|
|
614
|
+
* ```
|
|
615
|
+
*
|
|
616
|
+
* @param attributes - The base attributes to persist, but also the attributes to use to find when create fails
|
|
617
|
+
* @param extraOpts.createWith - additional attributes to persist when creating, but not used for finding
|
|
618
|
+
* @returns A dream instance
|
|
619
|
+
*/
|
|
620
|
+
static async createOrFindBy(attributes, extraOpts = {}) {
|
|
621
|
+
try {
|
|
622
|
+
const dreamModel = this.new({
|
|
623
|
+
...attributes,
|
|
624
|
+
...(extraOpts?.createWith || {}),
|
|
625
|
+
});
|
|
626
|
+
await dreamModel.save();
|
|
627
|
+
return dreamModel;
|
|
628
|
+
}
|
|
629
|
+
catch (err) {
|
|
630
|
+
if ((0, errors_js_1.pgErrorType)(err) === 'UNIQUE_CONSTRAINT_VIOLATION') {
|
|
631
|
+
const dreamModel = await this.findBy(this.extractAttributesFromUpdateableProperties(attributes));
|
|
632
|
+
if (!dreamModel)
|
|
633
|
+
throw new CreateOrFindByFailedToCreateAndFind_js_1.default(this);
|
|
634
|
+
return dreamModel;
|
|
635
|
+
}
|
|
636
|
+
throw err;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Returns a new query instance with the distinct query applied.
|
|
641
|
+
* If no columnName is provided, then distinct will apply to the
|
|
642
|
+
* primary key by default.
|
|
643
|
+
*
|
|
644
|
+
* ```ts
|
|
645
|
+
* await User.distinct('name').pluck('name')
|
|
646
|
+
* ```
|
|
647
|
+
*
|
|
648
|
+
* @param columnName - The column name you wish to apply the distinct clause to
|
|
649
|
+
* @returns A Query scoped to this Dream model with the distinct clause applied
|
|
650
|
+
*/
|
|
651
|
+
static distinct(columnName) {
|
|
652
|
+
return this.query().distinct(columnName);
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Finds a record for the corresponding model with the
|
|
656
|
+
* specified primary key. If not found, null
|
|
657
|
+
* is returned
|
|
658
|
+
*
|
|
659
|
+
* ```ts
|
|
660
|
+
* await User.query().find(123)
|
|
661
|
+
* // User{id: 123}
|
|
662
|
+
* ```
|
|
663
|
+
*
|
|
664
|
+
* @param primaryKey - The primaryKey of the record to look up
|
|
665
|
+
* @returns Either the found record, or else null
|
|
666
|
+
*/
|
|
667
|
+
static async find(primaryKey) {
|
|
668
|
+
return await this.query().find(primaryKey);
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Finds a record for the corresponding model with the
|
|
672
|
+
* specified primary key. If not found, an exception is raised.
|
|
673
|
+
*
|
|
674
|
+
* ```ts
|
|
675
|
+
* await User.query().findOrFail(123)
|
|
676
|
+
* // User{id: 123}
|
|
677
|
+
* ```
|
|
678
|
+
*
|
|
679
|
+
* @param primaryKey - The primaryKey of the record to look up
|
|
680
|
+
* @returns Either the found record, or else null
|
|
681
|
+
*/
|
|
682
|
+
static async findOrFail(primaryKey) {
|
|
683
|
+
return await this.query().findOrFail(primaryKey);
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Finds all records for the corresponding model in batches,
|
|
687
|
+
* and then calls the provided callback
|
|
688
|
+
* for each found record. Once all records
|
|
689
|
+
* have been passed for a given batch, the next set of
|
|
690
|
+
* records will be fetched and passed to your callback, until all
|
|
691
|
+
* records matching the corresponding model have been fetched.
|
|
692
|
+
*
|
|
693
|
+
* ```ts
|
|
694
|
+
* await User.findEach(user => {
|
|
695
|
+
* console.log(user)
|
|
696
|
+
* })
|
|
697
|
+
* // User{email: 'hello@world'}
|
|
698
|
+
* // User{email: 'goodbye@world'}
|
|
699
|
+
* ```
|
|
700
|
+
*
|
|
701
|
+
* @param cb - The callback to call for each found record
|
|
702
|
+
* @param opts.batchSize - the batch size you wish to collect records in. If not provided, it will default to 1000
|
|
703
|
+
* @returns void
|
|
704
|
+
*/
|
|
705
|
+
static async findEach(cb, opts) {
|
|
706
|
+
await this.query().findEach(cb, opts);
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Returns a new instance of Query scoped to the given
|
|
710
|
+
* model class
|
|
711
|
+
*
|
|
712
|
+
* ```ts
|
|
713
|
+
* await User.query().all()
|
|
714
|
+
* // [User{id: 1}, User{id: 2}, ...]
|
|
715
|
+
* ```
|
|
716
|
+
*
|
|
717
|
+
* @returns A new Query instance scoped to this Dream class
|
|
718
|
+
*
|
|
719
|
+
*/
|
|
720
|
+
static query() {
|
|
721
|
+
return new Query_js_1.default(this.prototype);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* @internal
|
|
725
|
+
*
|
|
726
|
+
* Returns a new instance of Query scoped to the given
|
|
727
|
+
* Dream instance
|
|
728
|
+
*
|
|
729
|
+
* ```ts
|
|
730
|
+
* await user = User.first()
|
|
731
|
+
* await user.query()
|
|
732
|
+
* ```
|
|
733
|
+
*
|
|
734
|
+
* @returns A new Query instance scoped to this Dream instance
|
|
735
|
+
*
|
|
736
|
+
*/
|
|
737
|
+
query() {
|
|
738
|
+
const dreamClass = this.constructor;
|
|
739
|
+
return dreamClass.where({ [this.primaryKey]: this.primaryKeyValue });
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Finds the first record—ordered by primary key—matching
|
|
743
|
+
* the corresponding model and the specified where statement.
|
|
744
|
+
* If not found, null is returned.
|
|
745
|
+
*
|
|
746
|
+
* ```ts
|
|
747
|
+
* await User.findBy({ email: 'how@yadoin' })
|
|
748
|
+
* // User{email: 'how@yadoin'}
|
|
749
|
+
* ```
|
|
750
|
+
*
|
|
751
|
+
* @param whereStatement - The where statement used to locate the record
|
|
752
|
+
* @returns The first model found matching the whereStatement
|
|
753
|
+
*/
|
|
754
|
+
static async findBy(whereStatement) {
|
|
755
|
+
return await this.query().findBy(whereStatement);
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Finds the first record—ordered by primary key—matching
|
|
759
|
+
* the corresponding model and the specified where statement.
|
|
760
|
+
* If not found, an exception is raised.
|
|
761
|
+
*
|
|
762
|
+
* ```ts
|
|
763
|
+
* await User.findOrFailBy({ email: 'how@yadoin' })
|
|
764
|
+
* // User{email: 'how@yadoin'}
|
|
765
|
+
* ```
|
|
766
|
+
*
|
|
767
|
+
* @param whereStatement - The where statement used to locate the record
|
|
768
|
+
* @returns The first model found matching the whereStatement
|
|
769
|
+
*/
|
|
770
|
+
static async findOrFailBy(whereStatement) {
|
|
771
|
+
return await this.query().findOrFailBy(whereStatement);
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Attempt to find the model with the given attributes.
|
|
775
|
+
* If no record is found, then a new record is created.
|
|
776
|
+
*
|
|
777
|
+
* ```ts
|
|
778
|
+
* const user = await User.findOrCreateBy({ email }, { createWith: params })
|
|
779
|
+
* ```
|
|
780
|
+
*
|
|
781
|
+
* @param attributes - The base attributes for finding, but also the attributes to use when creating
|
|
782
|
+
* @param extraOpts.createWith - additional attributes to persist when creating, but not used for finding
|
|
783
|
+
* @returns A dream instance
|
|
784
|
+
*/
|
|
785
|
+
static async findOrCreateBy(attributes, extraOpts = {}) {
|
|
786
|
+
const existingRecord = await this.findBy(this.extractAttributesFromUpdateableProperties(attributes));
|
|
787
|
+
if (existingRecord)
|
|
788
|
+
return existingRecord;
|
|
789
|
+
const dreamModel = this.new({
|
|
790
|
+
...attributes,
|
|
791
|
+
...(extraOpts?.createWith || {}),
|
|
792
|
+
});
|
|
793
|
+
await dreamModel.save();
|
|
794
|
+
return dreamModel;
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Returns true if a record exists for the given
|
|
798
|
+
* model class
|
|
799
|
+
*
|
|
800
|
+
* ```ts
|
|
801
|
+
* await User.exists()
|
|
802
|
+
* // false
|
|
803
|
+
*
|
|
804
|
+
* await User.create({ email: 'how@yadoin' })
|
|
805
|
+
*
|
|
806
|
+
* await User.exists()
|
|
807
|
+
* // true
|
|
808
|
+
* ```
|
|
809
|
+
*
|
|
810
|
+
* @returns boolean
|
|
811
|
+
*/
|
|
812
|
+
static async exists() {
|
|
813
|
+
return await this.query().exists();
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Load each specified association using a single SQL query.
|
|
817
|
+
* See {@link #preload} for preloading in separate queries.
|
|
818
|
+
*
|
|
819
|
+
* Note: since leftJoinPreload loads via single query, it has
|
|
820
|
+
* some downsides and that may be avoided using {@link #preload}:
|
|
821
|
+
* 1. `limit` and `offset` will be automatically removed
|
|
822
|
+
* 2. `through` associations will bring additional namespaces into the query that can conflict with through associations from other associations, creating an invalid query
|
|
823
|
+
* 3. each nested association will result in an additional record which duplicates data from the outer record. E.g., given `.leftJoinPreload('a', 'b', 'c')`, if each `a` has 10 `b` and each `b` has 10 `c`, then for one `a`, 100 records will be returned, each of which has all of the columns of `a`. `.preload('a', 'b', 'c')` would perform three separate SQL queries, but the data for a single `a` would only be returned once.
|
|
824
|
+
* 4. the individual query becomes more complex the more associations are included
|
|
825
|
+
* 5. associations loading associations loading associations could result in exponential amounts of data; in those cases, `.preload(...).findEach(...)` avoids instantiating massive amounts of data at once
|
|
826
|
+
*
|
|
827
|
+
* ```ts
|
|
828
|
+
* const user = await User.leftJoinPreload('posts', 'comments', { visibilty: 'public' }, 'replies').first()
|
|
829
|
+
* console.log(user.posts[0].comments[0].replies)
|
|
830
|
+
* // [Reply{id: 1}, Reply{id: 2}]
|
|
831
|
+
* ```
|
|
832
|
+
*
|
|
833
|
+
* @param args - A chain of association names and where clauses
|
|
834
|
+
* @returns A query for this model with the include statement applied
|
|
835
|
+
*/
|
|
836
|
+
static leftJoinPreload(...args) {
|
|
837
|
+
return this.query().leftJoinPreload(...args);
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Applies preload statement to a Query scoped to this model.
|
|
841
|
+
* Upon instantiating records of this model type,
|
|
842
|
+
* specified associations will be preloaded.
|
|
843
|
+
*
|
|
844
|
+
* Preloading/loading/including is necessary prior to accessing associations
|
|
845
|
+
* on a Dream instance.
|
|
846
|
+
*
|
|
847
|
+
* Preload is useful for avoiding the N+1 query problem
|
|
848
|
+
*
|
|
849
|
+
* ```ts
|
|
850
|
+
* const user = await User.preload('posts', 'comments', { visibilty: 'public' }, 'replies').first()
|
|
851
|
+
* console.log(user.posts[0].comments[0].replies)
|
|
852
|
+
* // [Reply{id: 1}, Reply{id: 2}]
|
|
853
|
+
* ```
|
|
854
|
+
*
|
|
855
|
+
* @param args - A chain of association names and where clauses
|
|
856
|
+
* @returns A query for this model with the preload statement applied
|
|
857
|
+
*/
|
|
858
|
+
static preload(...args) {
|
|
859
|
+
return this.query().preload(...args);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Returns a new Query instance with the provided
|
|
863
|
+
* inner join statement attached
|
|
864
|
+
*
|
|
865
|
+
* ```ts
|
|
866
|
+
* await User.innerJoin('posts').first()
|
|
867
|
+
* ```
|
|
868
|
+
*
|
|
869
|
+
* @param args - A chain of association names and where clauses
|
|
870
|
+
* @returns A Query for this model with the inner join clause applied
|
|
871
|
+
*/
|
|
872
|
+
static innerJoin(...args) {
|
|
873
|
+
return this.query().innerJoin(...args);
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Returns a new Query instance with the provided
|
|
877
|
+
* inner join statement attached
|
|
878
|
+
*
|
|
879
|
+
* ```ts
|
|
880
|
+
* await user.innerJoin('posts').first()
|
|
881
|
+
* ```
|
|
882
|
+
*
|
|
883
|
+
* @param args - A chain of association names and where clauses
|
|
884
|
+
* @returns A Query for this model with the inner join clause applied
|
|
885
|
+
*/
|
|
886
|
+
innerJoin(...args) {
|
|
887
|
+
return this.query().innerJoin(...args);
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Returns a new Query instance with the provided
|
|
891
|
+
* left join statement attached
|
|
892
|
+
*
|
|
893
|
+
* ```ts
|
|
894
|
+
* await User.leftJoin('posts').first()
|
|
895
|
+
* ```
|
|
896
|
+
*
|
|
897
|
+
* @param args - A chain of association names and where clauses
|
|
898
|
+
* @returns A Query for this model with the left join clause applied
|
|
899
|
+
*/
|
|
900
|
+
static leftJoin(...args) {
|
|
901
|
+
return this.query().leftJoin(...args);
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Returns a new Query instance with the provided
|
|
905
|
+
* left join statement attached
|
|
906
|
+
*
|
|
907
|
+
* ```ts
|
|
908
|
+
* await user.leftJoin('posts').first()
|
|
909
|
+
* ```
|
|
910
|
+
*
|
|
911
|
+
* @param args - A chain of association names and where clauses
|
|
912
|
+
* @returns A Query for this model with the left join clause applied
|
|
913
|
+
*/
|
|
914
|
+
leftJoin(...args) {
|
|
915
|
+
return this.query().leftJoin(...args);
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Returns the first record corresponding to the
|
|
919
|
+
* model, ordered by primary key.
|
|
920
|
+
*
|
|
921
|
+
* ```ts
|
|
922
|
+
* await User.first()
|
|
923
|
+
* // User{id: 1}
|
|
924
|
+
* ```
|
|
925
|
+
*
|
|
926
|
+
* @returns First record, or null if no record exists
|
|
927
|
+
*/
|
|
928
|
+
static async first() {
|
|
929
|
+
return await this.query().first();
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* Returns the first record corresponding to the
|
|
933
|
+
* model, ordered by primary key. If no record is
|
|
934
|
+
* found, an exception is raised.
|
|
935
|
+
*
|
|
936
|
+
* ```ts
|
|
937
|
+
* await User.firstOrFail()
|
|
938
|
+
* // User{id: 1}
|
|
939
|
+
* ```
|
|
940
|
+
*
|
|
941
|
+
* @returns First record
|
|
942
|
+
*/
|
|
943
|
+
static async firstOrFail() {
|
|
944
|
+
return await this.query().firstOrFail();
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Returns the last record corresponding to the
|
|
948
|
+
* model, ordered by primary key.
|
|
949
|
+
*
|
|
950
|
+
* ```ts
|
|
951
|
+
* await User.last()
|
|
952
|
+
* // User{id: 99}
|
|
953
|
+
* ```
|
|
954
|
+
*
|
|
955
|
+
* @returns Last record, or null if no record exists
|
|
956
|
+
*/
|
|
957
|
+
static async last() {
|
|
958
|
+
return await this.query().last();
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Returns the last record corresponding to the
|
|
962
|
+
* model, ordered by primary key. If no record
|
|
963
|
+
* is found, an exception is raised.
|
|
964
|
+
*
|
|
965
|
+
* ```ts
|
|
966
|
+
* await User.lastOrFail()
|
|
967
|
+
* // User{id: 99}
|
|
968
|
+
* ```
|
|
969
|
+
*
|
|
970
|
+
* @returns Last record
|
|
971
|
+
*/
|
|
972
|
+
static async lastOrFail() {
|
|
973
|
+
return await this.query().lastOrFail();
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* Returns a new Query instance, specifying a limit
|
|
977
|
+
*
|
|
978
|
+
* ```ts
|
|
979
|
+
* await User.limit(2).all()
|
|
980
|
+
* // [User{}, User{}]
|
|
981
|
+
* ```
|
|
982
|
+
*
|
|
983
|
+
* @returns A Query for this model with the limit clause applied
|
|
984
|
+
*/
|
|
985
|
+
static limit(count) {
|
|
986
|
+
return this.query().limit(count);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Returns a new Query instance, specifying an offset
|
|
990
|
+
*
|
|
991
|
+
* ```ts
|
|
992
|
+
* await User.offset(2).order('id').limit(2).all()
|
|
993
|
+
* // [User{id: 3}, User{id: 4}]
|
|
994
|
+
* ```
|
|
995
|
+
*
|
|
996
|
+
* @returns A Query for this model with the offset clause applied
|
|
997
|
+
*/
|
|
998
|
+
static offset(offset) {
|
|
999
|
+
return this.query().offset(offset);
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Returns a new Query instance, attaching the provided
|
|
1003
|
+
* order statement
|
|
1004
|
+
*
|
|
1005
|
+
* ```ts
|
|
1006
|
+
* await User.order('id').all()
|
|
1007
|
+
* // [User{id: 1}, User{id: 2}, ...]
|
|
1008
|
+
* ```
|
|
1009
|
+
*
|
|
1010
|
+
* ```ts
|
|
1011
|
+
* await User.order({ name: 'asc', id: 'desc' }).all()
|
|
1012
|
+
* // [User{name: 'a', id: 99}, User{name: 'a', id: 97}, User{ name: 'b', id: 98 } ...]
|
|
1013
|
+
* ```
|
|
1014
|
+
*
|
|
1015
|
+
* @param orderStatement - Either a string or an object specifying order. If a string, the order is implicitly ascending. If the orderStatement is an object, statements will be provided in the order of the keys set in the object
|
|
1016
|
+
* @returns A query for this model with the order clause applied
|
|
1017
|
+
*/
|
|
1018
|
+
static order(orderStatement) {
|
|
1019
|
+
return this.query().order(orderStatement);
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Plucks the provided fields from the corresponding model
|
|
1023
|
+
*
|
|
1024
|
+
* ```ts
|
|
1025
|
+
* await User.pluck('id')
|
|
1026
|
+
* // [1, 3, 2]
|
|
1027
|
+
* ```
|
|
1028
|
+
*
|
|
1029
|
+
* If more than one column is requested, a multi-dimensional
|
|
1030
|
+
* array is returned:
|
|
1031
|
+
*
|
|
1032
|
+
* ```ts
|
|
1033
|
+
* await User.order('id').pluck('id', 'email')
|
|
1034
|
+
* // [[1, 'a@a.com'], [2, 'b@b.com']]
|
|
1035
|
+
* ```
|
|
1036
|
+
*
|
|
1037
|
+
* @param columnNames - The column or array of columns to pluck
|
|
1038
|
+
* @returns An array of pluck results
|
|
1039
|
+
*/
|
|
1040
|
+
static async pluck(...columnNames) {
|
|
1041
|
+
return (await this.query().pluck(...columnNames));
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Plucks the specified fields from the given dream class table
|
|
1045
|
+
* in batches, passing each found columns into the
|
|
1046
|
+
* provided callback function
|
|
1047
|
+
*
|
|
1048
|
+
* ```ts
|
|
1049
|
+
* await User.order('id').pluckEach('id', (id) => {
|
|
1050
|
+
* console.log(id)
|
|
1051
|
+
* })
|
|
1052
|
+
* // 1
|
|
1053
|
+
* // 2
|
|
1054
|
+
* // 3
|
|
1055
|
+
* ```
|
|
1056
|
+
*
|
|
1057
|
+
* @param fields - a list of fields to pluck, followed by a callback function to call for each set of found fields
|
|
1058
|
+
* @returns void
|
|
1059
|
+
*/
|
|
1060
|
+
static async pluckEach(...args) {
|
|
1061
|
+
return await this.query().pluckEach(...args);
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* Used in conjunction with the Sortable decorator, `resort`
|
|
1065
|
+
* takes a list of sortable fields, and for each one, finds and
|
|
1066
|
+
* sorts each record in the DB matching the field based on the
|
|
1067
|
+
* scope provided for each Sortable decorator found.
|
|
1068
|
+
*
|
|
1069
|
+
* Calling this method shouldn't be necessary, but if
|
|
1070
|
+
* the contents of the database have shifted without firing the
|
|
1071
|
+
* correct callback mechanisms at the application layer, calling
|
|
1072
|
+
* `resort` will ensure that all sortable fields are set from 1..n
|
|
1073
|
+
* with no gaps, accounting for the scopes specified in the
|
|
1074
|
+
* corresponding Sortable decorator.
|
|
1075
|
+
*
|
|
1076
|
+
* ```ts
|
|
1077
|
+
* class Post extends ApplicationModel {
|
|
1078
|
+
* @Sortable({ scope: ['user']})
|
|
1079
|
+
* public position: DreamColumn<User, 'position'>
|
|
1080
|
+
* }
|
|
1081
|
+
*
|
|
1082
|
+
* await Post.all()
|
|
1083
|
+
* // [Post{position: 1}, Post{position: 3}, Post{position: 5}]
|
|
1084
|
+
*
|
|
1085
|
+
* await Post.resort('position')
|
|
1086
|
+
* await Post.all()
|
|
1087
|
+
* // [Post{position: 1}, Post{position: 2}, Post{position: 3}]
|
|
1088
|
+
* ```
|
|
1089
|
+
*
|
|
1090
|
+
* @param fields - A list of sortable fields to resort
|
|
1091
|
+
* @returns void
|
|
1092
|
+
*
|
|
1093
|
+
*/
|
|
1094
|
+
static async resort(...fields) {
|
|
1095
|
+
for (const field of fields) {
|
|
1096
|
+
const sortableMetadata = this.sortableFields.find(conf => conf.positionField === field);
|
|
1097
|
+
if (!sortableMetadata)
|
|
1098
|
+
throw new NonExistentScopeProvidedToResort_js_1.default(fields, this);
|
|
1099
|
+
await (0, resortAllRecords_js_1.default)(this, field, sortableMetadata.scope);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Returns a Query scoped to this model with
|
|
1104
|
+
* the specified scope applied.
|
|
1105
|
+
*
|
|
1106
|
+
* ```ts
|
|
1107
|
+
* class User extends ApplicationModel {
|
|
1108
|
+
* @Scope()
|
|
1109
|
+
* public visible(query: Query<User>) {
|
|
1110
|
+
* return query.where({ hidden: false })
|
|
1111
|
+
* }
|
|
1112
|
+
* }
|
|
1113
|
+
*
|
|
1114
|
+
* await User.scope('visible').all()
|
|
1115
|
+
* // [User{hidden: false}, User{hidden: false}]
|
|
1116
|
+
* ```
|
|
1117
|
+
*
|
|
1118
|
+
* @param scopeName - The name of the scope
|
|
1119
|
+
* @returns a Query scoped to this model with the specified scope applied
|
|
1120
|
+
*/
|
|
1121
|
+
static scope(scopeName) {
|
|
1122
|
+
return this[scopeName](this.query());
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Returns the sql that would be executed by a Query
|
|
1126
|
+
* scoped to this model.
|
|
1127
|
+
*
|
|
1128
|
+
* ```ts
|
|
1129
|
+
* User.sql()
|
|
1130
|
+
* // {
|
|
1131
|
+
* // query: {
|
|
1132
|
+
* // kind: 'SelectQueryNode',
|
|
1133
|
+
* // from: { kind: 'FromNode', froms: [Array] },
|
|
1134
|
+
* // selections: [ [Object] ],
|
|
1135
|
+
* // distinctOn: undefined,
|
|
1136
|
+
* // joins: undefined,
|
|
1137
|
+
* // groupBy: undefined,
|
|
1138
|
+
* // orderBy: undefined,
|
|
1139
|
+
* // where: { kind: 'WhereNode', where: [Object] },
|
|
1140
|
+
* // frontModifiers: undefined,
|
|
1141
|
+
* // endModifiers: undefined,
|
|
1142
|
+
* // limit: undefined,
|
|
1143
|
+
* // offset: undefined,
|
|
1144
|
+
* // with: undefined,
|
|
1145
|
+
* // having: undefined,
|
|
1146
|
+
* // explain: undefined,
|
|
1147
|
+
* // setOperations: undefined
|
|
1148
|
+
* // },
|
|
1149
|
+
* // sql: 'select "users".* from "users" where "users"."deleted_at" is null',
|
|
1150
|
+
* // parameters: []
|
|
1151
|
+
* //}
|
|
1152
|
+
* ```
|
|
1153
|
+
*
|
|
1154
|
+
* @returns An object representing the underlying sql statement
|
|
1155
|
+
*
|
|
1156
|
+
*/
|
|
1157
|
+
static sql() {
|
|
1158
|
+
return this.query().sql();
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Converts the given Dream class into a Kysely query, enabling
|
|
1162
|
+
* you to build custom queries using the Kysely API
|
|
1163
|
+
*
|
|
1164
|
+
* ```ts
|
|
1165
|
+
* await User.toKysely('select').where('email', '=', 'how@yadoin').execute()
|
|
1166
|
+
* ```
|
|
1167
|
+
*
|
|
1168
|
+
* @param type - The type of Kysely query builder instance you would like to obtain
|
|
1169
|
+
* @returns A Kysely query. Depending on the type passed, it will return either a SelectQueryBuilder, DeleteQueryBuilder, UpdateQueryBuilder, or an InsertQueryBuilder
|
|
1170
|
+
*/
|
|
1171
|
+
static toKysely(type) {
|
|
1172
|
+
switch (type) {
|
|
1173
|
+
case 'select':
|
|
1174
|
+
return this.query().dbFor('select').selectFrom(this.table);
|
|
1175
|
+
case 'delete':
|
|
1176
|
+
return this.query().dbFor('delete').deleteFrom(this.table);
|
|
1177
|
+
case 'update':
|
|
1178
|
+
return this.query().dbFor('update').updateTable(this.table);
|
|
1179
|
+
case 'insert':
|
|
1180
|
+
return this.query().dbFor('insert').insertInto(this.table);
|
|
1181
|
+
default:
|
|
1182
|
+
throw new Error('never');
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Applies transaction to a new Query scoped
|
|
1187
|
+
* to this model
|
|
1188
|
+
*
|
|
1189
|
+
* ```ts
|
|
1190
|
+
* await ApplicationModel.transaction(async txn => {
|
|
1191
|
+
* await User.txn(txn).create({ email: 'how@yadoin' })
|
|
1192
|
+
* })
|
|
1193
|
+
* ```
|
|
1194
|
+
*
|
|
1195
|
+
* @param txn - A DreamTransaction instance (usually collected by calling `ApplicationModel.transaction`)
|
|
1196
|
+
* @returns A Query scoped to this model with the transaction applied
|
|
1197
|
+
*/
|
|
1198
|
+
static txn(txn) {
|
|
1199
|
+
return new DreamClassTransactionBuilder_js_1.default(this.prototype, txn);
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Builds a new DreamTransaction instance, provides
|
|
1203
|
+
* the instance to the provided callback.
|
|
1204
|
+
*
|
|
1205
|
+
* ```ts
|
|
1206
|
+
* await ApplicationModel.transaction(async txn => {
|
|
1207
|
+
* const user = await User.txn(txn).create({ email: 'how@yadoin' })
|
|
1208
|
+
* await Pet.txn(txn).create({ user })
|
|
1209
|
+
* })
|
|
1210
|
+
* ```
|
|
1211
|
+
*
|
|
1212
|
+
* @param callback - A callback function to call. The transaction provided to the callback can be passed to subsequent database calls within the transaction callback
|
|
1213
|
+
* @returns void
|
|
1214
|
+
*/
|
|
1215
|
+
static async transaction(callback) {
|
|
1216
|
+
const dreamTransaction = new DreamTransaction_js_1.default();
|
|
1217
|
+
let callbackResponse = undefined;
|
|
1218
|
+
await (0, index_js_1.default)('primary')
|
|
1219
|
+
.transaction()
|
|
1220
|
+
.execute(async (kyselyTransaction) => {
|
|
1221
|
+
dreamTransaction.kyselyTransaction = kyselyTransaction;
|
|
1222
|
+
callbackResponse = (await callback(dreamTransaction));
|
|
1223
|
+
});
|
|
1224
|
+
await dreamTransaction.runAfterCommitHooks(dreamTransaction);
|
|
1225
|
+
return callbackResponse;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Sends data through for use as passthrough data
|
|
1229
|
+
* for the associations that require it.
|
|
1230
|
+
*
|
|
1231
|
+
* ```ts
|
|
1232
|
+
* class Post {
|
|
1233
|
+
* @Deco.HasMany('LocalizedText')
|
|
1234
|
+
* public localizedTexts: LocalizedText[]
|
|
1235
|
+
*
|
|
1236
|
+
* @Deco.HasOne('LocalizedText', {
|
|
1237
|
+
* where: { locale: DreamConst.passthrough },
|
|
1238
|
+
* })
|
|
1239
|
+
* public currentLocalizedText: LocalizedText
|
|
1240
|
+
* }
|
|
1241
|
+
*
|
|
1242
|
+
* await User.passthrough({ locale: 'es-ES' })
|
|
1243
|
+
* .preload('posts', 'currentLocalizedText')
|
|
1244
|
+
* .first()
|
|
1245
|
+
* ```
|
|
1246
|
+
*
|
|
1247
|
+
* @param passthroughWhereStatement - Where statement used for associations that require passthrough data
|
|
1248
|
+
* @returns A Query for this model with the passthrough data
|
|
1249
|
+
*/
|
|
1250
|
+
static passthrough(passthroughWhereStatement) {
|
|
1251
|
+
return this.query().passthrough(passthroughWhereStatement);
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Applies a where statement to a new Query instance
|
|
1255
|
+
* scoped to this model
|
|
1256
|
+
*
|
|
1257
|
+
* ```ts
|
|
1258
|
+
* await User.where({ email: 'how@yadoin' }).first()
|
|
1259
|
+
* // User{email: 'how@yadoin'}
|
|
1260
|
+
* ```
|
|
1261
|
+
*
|
|
1262
|
+
* @param whereStatement - Where statement to apply to the Query
|
|
1263
|
+
* @returns A Query for this model with the where clause applied
|
|
1264
|
+
*/
|
|
1265
|
+
static where(whereStatement) {
|
|
1266
|
+
return this.query().where(whereStatement);
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Applies "OR"'d where statements to a Query scoped
|
|
1270
|
+
* to this model.
|
|
1271
|
+
*
|
|
1272
|
+
* ```ts
|
|
1273
|
+
* await User.whereAny([{ email: 'how@yadoin' }, { name: 'fred' }]).first()
|
|
1274
|
+
* // [User{email: 'how@yadoin'}, User{name: 'fred'}, User{name: 'fred'}]
|
|
1275
|
+
* ```
|
|
1276
|
+
*
|
|
1277
|
+
* @param whereStatements - a list of where statements to `OR` together
|
|
1278
|
+
* @returns A Query for this model with the whereAny clause applied
|
|
1279
|
+
*/
|
|
1280
|
+
static whereAny(statements) {
|
|
1281
|
+
return this.query().whereAny(statements);
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Applies a whereNot statement to a new Query instance
|
|
1285
|
+
* scoped to this model.
|
|
1286
|
+
*
|
|
1287
|
+
* ```ts
|
|
1288
|
+
* await User.whereNot({ email: 'how@yadoin' }).first()
|
|
1289
|
+
* // User{email: 'hello@world'}
|
|
1290
|
+
* ```
|
|
1291
|
+
*
|
|
1292
|
+
* @param whereStatement - A where statement to negate and apply to the Query
|
|
1293
|
+
* @returns A Query for this model with the whereNot clause applied
|
|
1294
|
+
*/
|
|
1295
|
+
static whereNot(attributes) {
|
|
1296
|
+
return this.query().whereNot(attributes);
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* @internal
|
|
1300
|
+
*
|
|
1301
|
+
* Given a column, checks to see if it is a foreign key
|
|
1302
|
+
* belonging to a BelongsTo association
|
|
1303
|
+
*
|
|
1304
|
+
* ```ts
|
|
1305
|
+
* Post.isBelongsToAssociationForeignKey('id')
|
|
1306
|
+
* // false
|
|
1307
|
+
* Post.isBelongsToAssociationForeignKey('userId')
|
|
1308
|
+
* // true
|
|
1309
|
+
* ```
|
|
1310
|
+
*
|
|
1311
|
+
* @param column - A column on this Dream class
|
|
1312
|
+
* @returns A boolean
|
|
1313
|
+
*/
|
|
1314
|
+
static isBelongsToAssociationForeignKey(column) {
|
|
1315
|
+
return this.belongsToAssociationForeignKeys().includes(column);
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* @internal
|
|
1319
|
+
*
|
|
1320
|
+
* Given a column, checks to see if it is a belongs to
|
|
1321
|
+
* polymorphic type field
|
|
1322
|
+
*
|
|
1323
|
+
* ```ts
|
|
1324
|
+
* LocalizedText.isBelongsToAssociationPolymorphicTypeField('localizableId')
|
|
1325
|
+
* // false
|
|
1326
|
+
* LocalizedText.isBelongsToAssociationPolymorphicTypeField('localizableType')
|
|
1327
|
+
* // true
|
|
1328
|
+
* ```
|
|
1329
|
+
*
|
|
1330
|
+
* @param column - a column on this dream class
|
|
1331
|
+
* @returns A boolean
|
|
1332
|
+
*/
|
|
1333
|
+
static isBelongsToAssociationPolymorphicTypeField(column) {
|
|
1334
|
+
return this.polymorphicTypeColumns().includes(column);
|
|
1335
|
+
}
|
|
1336
|
+
/**
|
|
1337
|
+
* @internal
|
|
1338
|
+
*
|
|
1339
|
+
* Returns an array of column names that are belongs
|
|
1340
|
+
* to foreign keys on this dream class
|
|
1341
|
+
*
|
|
1342
|
+
* ```ts
|
|
1343
|
+
* Post.belongsToAssociationForeignKeys()
|
|
1344
|
+
* // ['userId']
|
|
1345
|
+
* ```
|
|
1346
|
+
*
|
|
1347
|
+
* @returns An array of column names that are belongs to foreign keys on this dream class
|
|
1348
|
+
*/
|
|
1349
|
+
static belongsToAssociationForeignKeys() {
|
|
1350
|
+
const associationMap = this.associationMetadataMap();
|
|
1351
|
+
return this.belongsToAssociationNames().map(belongsToKey => associationMap[belongsToKey].foreignKey());
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* @internal
|
|
1355
|
+
*
|
|
1356
|
+
* Returns all polymorphic type columns
|
|
1357
|
+
*
|
|
1358
|
+
* ```ts
|
|
1359
|
+
* LocalizedText.polymorphicTypeColumns()
|
|
1360
|
+
* // ['localizableType']
|
|
1361
|
+
* ```
|
|
1362
|
+
*
|
|
1363
|
+
* @returns An array of column names that are polymorphic type fields on the given dream class
|
|
1364
|
+
*/
|
|
1365
|
+
static polymorphicTypeColumns() {
|
|
1366
|
+
const associationMap = this.associationMetadataMap();
|
|
1367
|
+
return this.belongsToAssociationNames()
|
|
1368
|
+
.filter(key => associationMap[key].polymorphic)
|
|
1369
|
+
.map(belongsToKey => associationMap[belongsToKey].foreignKeyTypeField());
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* @internal
|
|
1373
|
+
*
|
|
1374
|
+
* Returns a list of association names which
|
|
1375
|
+
* correspond to belongs to associations
|
|
1376
|
+
* on this model class.
|
|
1377
|
+
*
|
|
1378
|
+
* ```ts
|
|
1379
|
+
* Post.belongsToAssociationNames()
|
|
1380
|
+
* // ['user']
|
|
1381
|
+
* ```
|
|
1382
|
+
*
|
|
1383
|
+
* @returns An array of belongs to association names
|
|
1384
|
+
*/
|
|
1385
|
+
static belongsToAssociationNames() {
|
|
1386
|
+
const associationMap = this.associationMetadataMap();
|
|
1387
|
+
return Object.keys(associationMap).filter(key => associationMap[key].type === 'BelongsTo');
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* @internal
|
|
1391
|
+
*
|
|
1392
|
+
* Returns a list of association names which
|
|
1393
|
+
* have `dependent: destroy` set
|
|
1394
|
+
*
|
|
1395
|
+
* ```ts
|
|
1396
|
+
* Post.dependentDestroyAssociationNames()
|
|
1397
|
+
* // ['user']
|
|
1398
|
+
* ```
|
|
1399
|
+
*
|
|
1400
|
+
* @returns An array of HasOne/HasMany association names with `dependent: 'destroy'` defined
|
|
1401
|
+
*/
|
|
1402
|
+
static dependentDestroyAssociationNames() {
|
|
1403
|
+
const associationMap = this.associationMetadataMap();
|
|
1404
|
+
return Object.keys(associationMap).filter(key => associationMap[key]
|
|
1405
|
+
.dependent === 'destroy');
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* @internal
|
|
1409
|
+
*
|
|
1410
|
+
* Returns the metadata for the provided association
|
|
1411
|
+
*
|
|
1412
|
+
* ```ts
|
|
1413
|
+
* new Post()['getAssociationMetadata']('user')
|
|
1414
|
+
* // {
|
|
1415
|
+
* // modelCB: [Function (anonymous)],
|
|
1416
|
+
* // type: 'BelongsTo',
|
|
1417
|
+
* // as: 'user',
|
|
1418
|
+
* // optional: false,
|
|
1419
|
+
* // polymorphic: false,
|
|
1420
|
+
* // primaryKeyOverride: null,
|
|
1421
|
+
* // primaryKey: [Function: primaryKey],
|
|
1422
|
+
* // primaryKeyValue: [Function: primaryKeyValue],
|
|
1423
|
+
* // foreignKey: [Function: foreignKey],
|
|
1424
|
+
* // foreignKeyTypeField: [Function: foreignKeyTypeField]
|
|
1425
|
+
* // }
|
|
1426
|
+
* ```
|
|
1427
|
+
*
|
|
1428
|
+
* @returns Association metadata
|
|
1429
|
+
*
|
|
1430
|
+
*/
|
|
1431
|
+
getAssociationMetadata(associationName) {
|
|
1432
|
+
return this.constructor.getAssociationMetadata(associationName);
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* @internal
|
|
1436
|
+
*
|
|
1437
|
+
* Returns all association metadata for the given dream class
|
|
1438
|
+
*
|
|
1439
|
+
* ```ts
|
|
1440
|
+
* new Post()['associationMetadataMap']()
|
|
1441
|
+
* // {
|
|
1442
|
+
* // user: {
|
|
1443
|
+
* // modelCB: [Function (anonymous)],
|
|
1444
|
+
* // type: 'BelongsTo',
|
|
1445
|
+
* // as: 'user',
|
|
1446
|
+
* // optional: false,
|
|
1447
|
+
* // polymorphic: false,
|
|
1448
|
+
* // primaryKeyOverride: null,
|
|
1449
|
+
* // primaryKey: [Function: primaryKey],
|
|
1450
|
+
* // primaryKeyValue: [Function: primaryKeyValue],
|
|
1451
|
+
* // foreignKey: [Function: foreignKey],
|
|
1452
|
+
* // foreignKeyTypeField: [Function: foreignKeyTypeField]
|
|
1453
|
+
* // },
|
|
1454
|
+
* // ratings: {
|
|
1455
|
+
* // modelCB: [Function (anonymous)],
|
|
1456
|
+
* // type: 'HasMany',
|
|
1457
|
+
* // as: 'ratings',
|
|
1458
|
+
* // polymorphic: true,
|
|
1459
|
+
* // source: 'ratings',
|
|
1460
|
+
* // preloadThroughColumns: undefined,
|
|
1461
|
+
* // where: undefined,
|
|
1462
|
+
* // whereNot: undefined,
|
|
1463
|
+
* // selfWhere: undefined,
|
|
1464
|
+
* // selfWhereNot: undefined,
|
|
1465
|
+
* // primaryKeyOverride: null,
|
|
1466
|
+
* // primaryKey: [Function: primaryKey],
|
|
1467
|
+
* // primaryKeyValue: [Function: primaryKeyValue],
|
|
1468
|
+
* // through: undefined,
|
|
1469
|
+
* // distinct: undefined,
|
|
1470
|
+
* // order: undefined,
|
|
1471
|
+
* // foreignKey: [Function: foreignKey],
|
|
1472
|
+
* // foreignKeyTypeField: [Function: foreignKeyTypeField]
|
|
1473
|
+
* // },
|
|
1474
|
+
* // ...
|
|
1475
|
+
* // }
|
|
1476
|
+
* ```
|
|
1477
|
+
*
|
|
1478
|
+
* @returns association metadata
|
|
1479
|
+
*/
|
|
1480
|
+
associationMetadataMap() {
|
|
1481
|
+
return this.constructor.associationMetadataMap();
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* @internal
|
|
1485
|
+
*
|
|
1486
|
+
* returns all association data for the given dream class,
|
|
1487
|
+
* organized by the type of association
|
|
1488
|
+
*
|
|
1489
|
+
* ```ts
|
|
1490
|
+
* new Post().associationMetadataByType
|
|
1491
|
+
* // {
|
|
1492
|
+
* // belongsTo: [
|
|
1493
|
+
* // {
|
|
1494
|
+
* // modelCB: [Function (anonymous)],
|
|
1495
|
+
* // type: 'BelongsTo',
|
|
1496
|
+
* // as: 'user',
|
|
1497
|
+
* // optional: false,
|
|
1498
|
+
* // polymorphic: false,
|
|
1499
|
+
* // primaryKeyOverride: null,
|
|
1500
|
+
* // primaryKey: [Function: primaryKey],
|
|
1501
|
+
* // primaryKeyValue: [Function: primaryKeyValue],
|
|
1502
|
+
* // foreignKey: [Function: foreignKey],
|
|
1503
|
+
* // foreignKeyTypeField: [Function: foreignKeyTypeField]
|
|
1504
|
+
* // },
|
|
1505
|
+
* // ],
|
|
1506
|
+
* // hasMany: [
|
|
1507
|
+
* // ],
|
|
1508
|
+
* // hasOne: []
|
|
1509
|
+
* // }
|
|
1510
|
+
* // }
|
|
1511
|
+
* ```
|
|
1512
|
+
*
|
|
1513
|
+
* @returns association metadata by type
|
|
1514
|
+
*
|
|
1515
|
+
*/
|
|
1516
|
+
get associationMetadataByType() {
|
|
1517
|
+
return this.constructor.associationMetadataByType;
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
* @internal
|
|
1521
|
+
*
|
|
1522
|
+
* Returns an array of association names for the
|
|
1523
|
+
* given dream class
|
|
1524
|
+
*
|
|
1525
|
+
* ```ts
|
|
1526
|
+
* new Post().associationNames
|
|
1527
|
+
* // [ 'user', 'postVisibility', 'ratings', 'heartRatings' ]
|
|
1528
|
+
* ```
|
|
1529
|
+
*
|
|
1530
|
+
* @returns association names array
|
|
1531
|
+
*/
|
|
1532
|
+
get associationNames() {
|
|
1533
|
+
return this.constructor.associationNames;
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Returns true if any of the attributes on the instance
|
|
1537
|
+
* have changed since it was last pulled from the database.
|
|
1538
|
+
* It will also return true if the instance is not yet
|
|
1539
|
+
* persisted.
|
|
1540
|
+
*
|
|
1541
|
+
* ```ts
|
|
1542
|
+
* const post = Post.new({ body: 'howyadoin' })
|
|
1543
|
+
* post.isDirty
|
|
1544
|
+
* // true
|
|
1545
|
+
*
|
|
1546
|
+
* await post.save()
|
|
1547
|
+
* post.isDirty
|
|
1548
|
+
* // false
|
|
1549
|
+
*
|
|
1550
|
+
* post.body = 'groiyyyt'
|
|
1551
|
+
* post.isDirty
|
|
1552
|
+
* // true
|
|
1553
|
+
* ```
|
|
1554
|
+
*
|
|
1555
|
+
* @returns A boolean
|
|
1556
|
+
*/
|
|
1557
|
+
get isDirty() {
|
|
1558
|
+
return !!Object.keys(this.dirtyAttributes()).length;
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Returns true. This is useful for identifying
|
|
1562
|
+
* dream instances from other objects
|
|
1563
|
+
*
|
|
1564
|
+
* @returns true
|
|
1565
|
+
*/
|
|
1566
|
+
get isDreamInstance() {
|
|
1567
|
+
return true;
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Runs validation checks against all validations
|
|
1571
|
+
* declared using the Validate and Validates decorators,
|
|
1572
|
+
* and returns true if any of them fail.
|
|
1573
|
+
*
|
|
1574
|
+
* ```ts
|
|
1575
|
+
* class User extends ApplicationModel {
|
|
1576
|
+
* @Validates('presence')
|
|
1577
|
+
* public email: DreamColumn<User, 'email'>
|
|
1578
|
+
* }
|
|
1579
|
+
* const user = User.new()
|
|
1580
|
+
* user.isInvalid
|
|
1581
|
+
* // true
|
|
1582
|
+
*
|
|
1583
|
+
* user.email = 'how@yadoin'
|
|
1584
|
+
* user.isInvalid
|
|
1585
|
+
* // false
|
|
1586
|
+
* ```
|
|
1587
|
+
*
|
|
1588
|
+
* @returns A boolean
|
|
1589
|
+
*/
|
|
1590
|
+
get isInvalid() {
|
|
1591
|
+
return !this.isValid;
|
|
1592
|
+
}
|
|
1593
|
+
/**
|
|
1594
|
+
* Returns true if the model has not been persisted
|
|
1595
|
+
* to the database.
|
|
1596
|
+
*
|
|
1597
|
+
* ```ts
|
|
1598
|
+
* const user = User.new({ email: 'howyadoin' })
|
|
1599
|
+
* user.isNewRecord
|
|
1600
|
+
* // true
|
|
1601
|
+
*
|
|
1602
|
+
* await user.save()
|
|
1603
|
+
* user.isNewRecord
|
|
1604
|
+
* // false
|
|
1605
|
+
* ```
|
|
1606
|
+
*
|
|
1607
|
+
* @returns A boolean
|
|
1608
|
+
*/
|
|
1609
|
+
get isNewRecord() {
|
|
1610
|
+
return !this.isPersisted;
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Runs validation checks against all validations
|
|
1614
|
+
* declared using the Validate and Validates decorators.
|
|
1615
|
+
* Returns true if none of the validations fail.
|
|
1616
|
+
*
|
|
1617
|
+
* NOTE: Any validations that fail will leave the errors
|
|
1618
|
+
* field populated on your model instance.
|
|
1619
|
+
*
|
|
1620
|
+
* ```ts
|
|
1621
|
+
* class User extends ApplicationModel {
|
|
1622
|
+
* @Validates('presence')
|
|
1623
|
+
* public email: DreamColumn<User, 'email'>
|
|
1624
|
+
* }
|
|
1625
|
+
*
|
|
1626
|
+
* const user = User.new()
|
|
1627
|
+
* user.isValid
|
|
1628
|
+
* // false
|
|
1629
|
+
*
|
|
1630
|
+
* user.email = 'how@yadoin'
|
|
1631
|
+
* user.isValid
|
|
1632
|
+
* // true
|
|
1633
|
+
* ```
|
|
1634
|
+
*
|
|
1635
|
+
* @returns A boolean
|
|
1636
|
+
*/
|
|
1637
|
+
get isValid() {
|
|
1638
|
+
this._errors = {};
|
|
1639
|
+
(0, runValidations_js_1.default)(this);
|
|
1640
|
+
return !Object.keys(this.errors).filter(key => !!this.errors[key].length).length;
|
|
1641
|
+
}
|
|
1642
|
+
/**
|
|
1643
|
+
* The name of the primary key column on this model.
|
|
1644
|
+
* NOTE: Must specify `as const` when defining a custom
|
|
1645
|
+
* primary key.
|
|
1646
|
+
*
|
|
1647
|
+
* ```ts
|
|
1648
|
+
* class User extends ApplicationModel {
|
|
1649
|
+
* public customIdField: DreamColumn<User, 'customIdField'>
|
|
1650
|
+
*
|
|
1651
|
+
* public get primaryKey() {
|
|
1652
|
+
* return 'customIdField' as const
|
|
1653
|
+
* }
|
|
1654
|
+
* }
|
|
1655
|
+
* ```
|
|
1656
|
+
*
|
|
1657
|
+
* @returns The primary key column name
|
|
1658
|
+
*/
|
|
1659
|
+
get primaryKey() {
|
|
1660
|
+
return 'id';
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Returns the value of the primary key
|
|
1664
|
+
*
|
|
1665
|
+
* @returns The value of the primary key field for this Dream instance
|
|
1666
|
+
*/
|
|
1667
|
+
get primaryKeyValue() {
|
|
1668
|
+
return this[this.primaryKey] || null;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* This must be defined on every model, and it must point
|
|
1672
|
+
* to a table in your database. In addition, you must
|
|
1673
|
+
* return the value using the `as const` suffix, like so:
|
|
1674
|
+
*
|
|
1675
|
+
* ```ts
|
|
1676
|
+
* class User extends ApplicationModel {
|
|
1677
|
+
* public get table() {
|
|
1678
|
+
* return 'users' as const
|
|
1679
|
+
* }
|
|
1680
|
+
* }
|
|
1681
|
+
* ```
|
|
1682
|
+
*
|
|
1683
|
+
* @returns The table name for this model
|
|
1684
|
+
*/
|
|
1685
|
+
get table() {
|
|
1686
|
+
throw new MissingTable_js_1.default(this.constructor);
|
|
1687
|
+
}
|
|
1688
|
+
/**
|
|
1689
|
+
* @internal
|
|
1690
|
+
*
|
|
1691
|
+
* _errors is used to inform validation errors,
|
|
1692
|
+
* and is built whenever validations are run on
|
|
1693
|
+
* a dream instance.
|
|
1694
|
+
*/
|
|
1695
|
+
_errors = {};
|
|
1696
|
+
/**
|
|
1697
|
+
* @internal
|
|
1698
|
+
*
|
|
1699
|
+
* Used for the changes api
|
|
1700
|
+
*/
|
|
1701
|
+
frozenAttributes = {};
|
|
1702
|
+
/**
|
|
1703
|
+
* @internal
|
|
1704
|
+
*
|
|
1705
|
+
* Used for the changes api
|
|
1706
|
+
*/
|
|
1707
|
+
originalAttributes = {};
|
|
1708
|
+
/**
|
|
1709
|
+
* @internal
|
|
1710
|
+
*
|
|
1711
|
+
* Used for the changes api
|
|
1712
|
+
*/
|
|
1713
|
+
currentAttributes = {};
|
|
1714
|
+
/**
|
|
1715
|
+
* @internal
|
|
1716
|
+
*
|
|
1717
|
+
* Used for the changes api
|
|
1718
|
+
*/
|
|
1719
|
+
attributesFromBeforeLastSave = {};
|
|
1720
|
+
/**
|
|
1721
|
+
* @internal
|
|
1722
|
+
*
|
|
1723
|
+
* Stores whether the record has been persisted or not
|
|
1724
|
+
*/
|
|
1725
|
+
_isPersisted;
|
|
1726
|
+
/**
|
|
1727
|
+
* Returns true if the model has been persisted
|
|
1728
|
+
* to the database.
|
|
1729
|
+
*
|
|
1730
|
+
* ```ts
|
|
1731
|
+
* const user = User.new({ email: 'howyadoin' })
|
|
1732
|
+
* user.isPersisted
|
|
1733
|
+
* // false
|
|
1734
|
+
*
|
|
1735
|
+
* await user.save()
|
|
1736
|
+
* user.isPersisted
|
|
1737
|
+
* // true
|
|
1738
|
+
* ```
|
|
1739
|
+
*
|
|
1740
|
+
* @returns A boolean
|
|
1741
|
+
*/
|
|
1742
|
+
get isPersisted() {
|
|
1743
|
+
return this._isPersisted || false;
|
|
1744
|
+
}
|
|
1745
|
+
set isPersisted(val) {
|
|
1746
|
+
this._isPersisted = val;
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* Since typescript prevents constructor functions
|
|
1750
|
+
* from absorbing type generics, we provide the `new`
|
|
1751
|
+
* method to instantiate with type protection
|
|
1752
|
+
*
|
|
1753
|
+
* ```ts
|
|
1754
|
+
* const user = User.new({ email: 'how@yadoin' })
|
|
1755
|
+
* ```
|
|
1756
|
+
*
|
|
1757
|
+
* @returns A new (unpersisted) instance of the provided dream class
|
|
1758
|
+
*/
|
|
1759
|
+
static new(opts, additionalOpts = {}) {
|
|
1760
|
+
const dreamModel = new this(opts, {
|
|
1761
|
+
...additionalOpts,
|
|
1762
|
+
_internalUseOnly: true,
|
|
1763
|
+
});
|
|
1764
|
+
dreamModel.finalizeConstruction();
|
|
1765
|
+
return dreamModel;
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* @internal
|
|
1769
|
+
*
|
|
1770
|
+
* NOTE: avoid using the constructor function directly.
|
|
1771
|
+
* Use the static `.new` or `.create` methods instead, which
|
|
1772
|
+
* will provide type guarding for your attributes.
|
|
1773
|
+
*
|
|
1774
|
+
* Since typescript prevents constructor functions
|
|
1775
|
+
* from absorbing type generics, we provide the `new`
|
|
1776
|
+
* method to instantiate with type protection.
|
|
1777
|
+
*
|
|
1778
|
+
* ```ts
|
|
1779
|
+
* const user = User.new({ email: 'how@yadoin' })
|
|
1780
|
+
* ```
|
|
1781
|
+
*
|
|
1782
|
+
* @returns A new (unpersisted) instance of the provided dream class
|
|
1783
|
+
*/
|
|
1784
|
+
constructor(opts, additionalOpts) {
|
|
1785
|
+
if (!additionalOpts._internalUseOnly)
|
|
1786
|
+
throw new ConstructorOnlyForInternalUse_js_1.default();
|
|
1787
|
+
this.isPersisted = additionalOpts?.isPersisted || false;
|
|
1788
|
+
this.defineAttributeAccessors();
|
|
1789
|
+
if (opts) {
|
|
1790
|
+
const marshalledOpts = this._setAttributes(opts, additionalOpts);
|
|
1791
|
+
// if id is set, then we freeze attributes after setting them, so that
|
|
1792
|
+
// any modifications afterwards will indicate updates.
|
|
1793
|
+
if (this.isPersisted) {
|
|
1794
|
+
this.freezeAttributes();
|
|
1795
|
+
this.originalAttributes = { ...marshalledOpts };
|
|
1796
|
+
this.attributesFromBeforeLastSave = { ...marshalledOpts };
|
|
1797
|
+
}
|
|
1798
|
+
else {
|
|
1799
|
+
const columns = this.constructor.columns();
|
|
1800
|
+
columns.forEach(column => {
|
|
1801
|
+
this.originalAttributes[column] = undefined;
|
|
1802
|
+
this.attributesFromBeforeLastSave[column] = undefined;
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
/**
|
|
1807
|
+
*
|
|
1808
|
+
* Modern Javascript sets all properties that do not have an explicit
|
|
1809
|
+
* assignment within the constructor to undefined in an implicit constructor.
|
|
1810
|
+
* Since the Dream constructor sets the value of properties of instances of
|
|
1811
|
+
* classes that extend Dream (e.g. when passing attributes to #new or #create
|
|
1812
|
+
* or when loading a model via one of the #find methods or #all), we need to
|
|
1813
|
+
* prevent those properties from being set back to undefined. Since all
|
|
1814
|
+
* properties corresponding to a database column get a setter, we achieve this
|
|
1815
|
+
* protection by including a guard in the setters that returns if this
|
|
1816
|
+
* property is set.
|
|
1817
|
+
*
|
|
1818
|
+
*/
|
|
1819
|
+
this.columnSetterGuardActivated = true;
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* @internal
|
|
1823
|
+
*
|
|
1824
|
+
* Used for determining which attributes to update
|
|
1825
|
+
*/
|
|
1826
|
+
static extractAttributesFromUpdateableProperties(attributes, dreamInstance, { bypassUserDefinedSetters = false } = {}) {
|
|
1827
|
+
const returnValues = {};
|
|
1828
|
+
const setAttributeOnDreamInstance = (attr, value) => {
|
|
1829
|
+
if (!dreamInstance)
|
|
1830
|
+
return;
|
|
1831
|
+
if (bypassUserDefinedSetters) {
|
|
1832
|
+
dreamInstance.setAttribute(attr, value);
|
|
1833
|
+
}
|
|
1834
|
+
else {
|
|
1835
|
+
dreamInstance.assignAttribute(attr, value);
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
Object.keys(attributes).forEach(attr => {
|
|
1839
|
+
const associationMetaData = this.associationMetadataMap()[attr];
|
|
1840
|
+
if (associationMetaData && associationMetaData.type !== 'BelongsTo') {
|
|
1841
|
+
throw new CanOnlyPassBelongsToModelParam_js_1.default(this, associationMetaData);
|
|
1842
|
+
}
|
|
1843
|
+
else if (associationMetaData) {
|
|
1844
|
+
const belongsToAssociationMetaData = associationMetaData;
|
|
1845
|
+
const associatedObject = attributes[attr];
|
|
1846
|
+
// if dream instance is passed, set the loaded association
|
|
1847
|
+
if (dreamInstance && associatedObject !== undefined)
|
|
1848
|
+
dreamInstance[attr] = associatedObject;
|
|
1849
|
+
if (!associationMetaData.optional && !associatedObject)
|
|
1850
|
+
throw new CannotPassNullOrUndefinedToRequiredBelongsTo_js_1.default(this, associationMetaData);
|
|
1851
|
+
const foreignKey = belongsToAssociationMetaData.foreignKey();
|
|
1852
|
+
const foreignKeyValue = belongsToAssociationMetaData.primaryKeyValue(associatedObject);
|
|
1853
|
+
if (foreignKeyValue !== undefined) {
|
|
1854
|
+
returnValues[foreignKey] = foreignKeyValue;
|
|
1855
|
+
setAttributeOnDreamInstance(foreignKey, returnValues[foreignKey]);
|
|
1856
|
+
// Set the belongs-to association
|
|
1857
|
+
setAttributeOnDreamInstance(attr, attributes[attr]);
|
|
1858
|
+
}
|
|
1859
|
+
if (belongsToAssociationMetaData.polymorphic) {
|
|
1860
|
+
const foreignKeyTypeField = belongsToAssociationMetaData.foreignKeyTypeField();
|
|
1861
|
+
returnValues[foreignKeyTypeField] = associatedObject?.stiBaseClassOrOwnClass?.name;
|
|
1862
|
+
setAttributeOnDreamInstance(foreignKeyTypeField, returnValues[foreignKeyTypeField]);
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
else {
|
|
1866
|
+
returnValues[attr] = attributes[attr];
|
|
1867
|
+
setAttributeOnDreamInstance(attr, returnValues[attr]);
|
|
1868
|
+
}
|
|
1869
|
+
});
|
|
1870
|
+
return returnValues;
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* @internal
|
|
1874
|
+
*
|
|
1875
|
+
* defines attribute setters and getters for every column
|
|
1876
|
+
* set within your types/dream.ts file
|
|
1877
|
+
*/
|
|
1878
|
+
defineAttributeAccessors() {
|
|
1879
|
+
const dreamClass = this.constructor;
|
|
1880
|
+
const columns = dreamClass.columns();
|
|
1881
|
+
const dreamPrototype = Object.getPrototypeOf(this);
|
|
1882
|
+
columns.forEach(column => {
|
|
1883
|
+
// this ensures that the currentAttributes object will contain keys
|
|
1884
|
+
// for each of the properties
|
|
1885
|
+
if (this.currentAttributes[column] === undefined)
|
|
1886
|
+
this.currentAttributes[column] = undefined;
|
|
1887
|
+
if (!Object.getOwnPropertyDescriptor(dreamPrototype, column)?.set) {
|
|
1888
|
+
if ((0, isJsonColumn_js_1.default)(this.constructor, column)) {
|
|
1889
|
+
// handle JSON columns
|
|
1890
|
+
Object.defineProperty(dreamPrototype, column, {
|
|
1891
|
+
get() {
|
|
1892
|
+
if ([undefined, null].includes(this.currentAttributes[column]))
|
|
1893
|
+
return this.currentAttributes[column];
|
|
1894
|
+
return JSON.parse(this.currentAttributes[column]);
|
|
1895
|
+
},
|
|
1896
|
+
set(val) {
|
|
1897
|
+
/**
|
|
1898
|
+
*
|
|
1899
|
+
* Modern Javascript sets all properties that do not have an explicit
|
|
1900
|
+
* assignment within the constructor to undefined in an implicit constructor.
|
|
1901
|
+
* Since the Dream constructor sets the value of properties of instances of
|
|
1902
|
+
* classes that extend Dream (e.g. when passing attributes to #new or #create
|
|
1903
|
+
* or when loading a model via one of the #find methods or #all), we need to
|
|
1904
|
+
* prevent those properties from being set back to undefined. Since all
|
|
1905
|
+
* properties corresponding to a database column get a setter, we achieve this
|
|
1906
|
+
* protection by including a guard in the setters that returns if this
|
|
1907
|
+
* property is set.
|
|
1908
|
+
*
|
|
1909
|
+
*/
|
|
1910
|
+
if (this.columnSetterGuardActivated)
|
|
1911
|
+
return;
|
|
1912
|
+
this.currentAttributes[column] = (0, typechecks_js_1.isString)(val) ? val : JSON.stringify(val);
|
|
1913
|
+
},
|
|
1914
|
+
configurable: true,
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
else {
|
|
1918
|
+
// handle all other columns
|
|
1919
|
+
Object.defineProperty(dreamPrototype, column, {
|
|
1920
|
+
get() {
|
|
1921
|
+
return this.currentAttributes[column];
|
|
1922
|
+
},
|
|
1923
|
+
set(val) {
|
|
1924
|
+
/**
|
|
1925
|
+
*
|
|
1926
|
+
* Modern Javascript sets all properties that do not have an explicit
|
|
1927
|
+
* assignment within the constructor to undefined in an implicit constructor.
|
|
1928
|
+
* Since the Dream constructor sets the value of properties of instances of
|
|
1929
|
+
* classes that extend Dream (e.g. when passing attributes to #new or #create
|
|
1930
|
+
* or when loading a model via one of the #find methods or #all), we need to
|
|
1931
|
+
* prevent those properties from being set back to undefined. Since all
|
|
1932
|
+
* properties corresponding to a database column get a setter, we achieve this
|
|
1933
|
+
* protection by including a guard in the setters that returns if this
|
|
1934
|
+
* property is set.
|
|
1935
|
+
*
|
|
1936
|
+
*/
|
|
1937
|
+
if (this.columnSetterGuardActivated)
|
|
1938
|
+
return;
|
|
1939
|
+
this.currentAttributes[column] = val;
|
|
1940
|
+
},
|
|
1941
|
+
configurable: true,
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
});
|
|
1946
|
+
(0, ensureSTITypeFieldIsSet_js_1.default)(this);
|
|
1947
|
+
}
|
|
1948
|
+
/**
|
|
1949
|
+
* @internal
|
|
1950
|
+
*
|
|
1951
|
+
* Modern Javascript applies implicit accessors to instance properties that
|
|
1952
|
+
* shadow prototype accessors applied by Dream. This method is called after
|
|
1953
|
+
* every Dream model is initialized to delete the instance accessors so that
|
|
1954
|
+
* the prototype accessors can be reached.
|
|
1955
|
+
*/
|
|
1956
|
+
unshadowColumnPropertyPrototypeAccessors() {
|
|
1957
|
+
;
|
|
1958
|
+
this.constructor.columns().forEach(column => delete this[column]);
|
|
1959
|
+
}
|
|
1960
|
+
finalizeConstruction() {
|
|
1961
|
+
/**
|
|
1962
|
+
*
|
|
1963
|
+
* Modern Javascript sets all properties that do not have an explicit
|
|
1964
|
+
* assignment within the constructor to undefined in an implicit constructor.
|
|
1965
|
+
* Since the Dream constructor sets the value of properties of instances of
|
|
1966
|
+
* classes that extend Dream (e.g. when passing attributes to #new or #create
|
|
1967
|
+
* or when loading a model via one of the #find methods or #all), we need to
|
|
1968
|
+
* prevent those properties from being set back to undefined. Since all
|
|
1969
|
+
* properties corresponding to a database column get a setter, we achieve this
|
|
1970
|
+
* protection by including a guard in the setters that returns if this
|
|
1971
|
+
* property is set.
|
|
1972
|
+
*
|
|
1973
|
+
*/
|
|
1974
|
+
this.columnSetterGuardActivated = false;
|
|
1975
|
+
/**
|
|
1976
|
+
* Modern Javascript applies implicit accessors to instance properties
|
|
1977
|
+
* that don't have an accessor explicitly defined in the class definition.
|
|
1978
|
+
* The instance accessors shadow prototype accessors applied by Dream.
|
|
1979
|
+
* This method is called after every Dream model is initialized to delete the
|
|
1980
|
+
* instance accessors so that the prototype accessors can be reached.
|
|
1981
|
+
*/
|
|
1982
|
+
this.unshadowColumnPropertyPrototypeAccessors();
|
|
1983
|
+
}
|
|
1984
|
+
/**
|
|
1985
|
+
* Returns true if the columnName passed is marked by a
|
|
1986
|
+
* Virtual attribute decorator
|
|
1987
|
+
*
|
|
1988
|
+
* @param columnName - A property on this model to check
|
|
1989
|
+
* @returns A boolean
|
|
1990
|
+
*/
|
|
1991
|
+
isVirtualColumn(columnName) {
|
|
1992
|
+
return this.constructor.virtualAttributes
|
|
1993
|
+
.map(attr => attr.property)
|
|
1994
|
+
.includes(columnName);
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Returns an object with column names for keys, and an
|
|
1998
|
+
* array of strings representing validation errors for values.
|
|
1999
|
+
*
|
|
2000
|
+
* @returns An error object
|
|
2001
|
+
*/
|
|
2002
|
+
get errors() {
|
|
2003
|
+
return { ...this._errors };
|
|
2004
|
+
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Adds an error to the model. Any errors added to the model
|
|
2007
|
+
* will cause the model to be invalid, and will prevent the
|
|
2008
|
+
* model from saving.
|
|
2009
|
+
*
|
|
2010
|
+
* ```ts
|
|
2011
|
+
* class User extends ApplicationModel {
|
|
2012
|
+
* ...
|
|
2013
|
+
* @Validate()
|
|
2014
|
+
* public async validateName() {
|
|
2015
|
+
* if (typeof this.name === 'number')
|
|
2016
|
+
* this.addError('name', 'name cannot be a number')
|
|
2017
|
+
* }
|
|
2018
|
+
* }
|
|
2019
|
+
* ```
|
|
2020
|
+
*
|
|
2021
|
+
* @returns void
|
|
2022
|
+
*/
|
|
2023
|
+
addError(column, error) {
|
|
2024
|
+
this._errors[column] ||= [];
|
|
2025
|
+
this._errors[column].push(error);
|
|
2026
|
+
}
|
|
2027
|
+
/**
|
|
2028
|
+
* Changes the attribute value for a single attribute,
|
|
2029
|
+
* leveraging any custom-defined setters. If you would like to
|
|
2030
|
+
* bypass custom-defined setters, use #setAttribute instead
|
|
2031
|
+
*
|
|
2032
|
+
* ```ts
|
|
2033
|
+
* const user = new User()
|
|
2034
|
+
* user.assignAttribute('email', 'sally@gmail.com')
|
|
2035
|
+
* ```
|
|
2036
|
+
*/
|
|
2037
|
+
assignAttribute(attr, val) {
|
|
2038
|
+
const self = this;
|
|
2039
|
+
self[attr] = val;
|
|
2040
|
+
}
|
|
2041
|
+
/**
|
|
2042
|
+
* Changes the attribute value for a single attribute internally,
|
|
2043
|
+
* bypassing any custom-defined setters. If you would like to set attributes
|
|
2044
|
+
* without bypassing custom-defined setters, use #assignAttribute instead
|
|
2045
|
+
*
|
|
2046
|
+
* ```ts
|
|
2047
|
+
* const user = new User()
|
|
2048
|
+
* user.setAttribute('email', 'sally@gmail.com')
|
|
2049
|
+
* ```
|
|
2050
|
+
*/
|
|
2051
|
+
setAttribute(attr, val) {
|
|
2052
|
+
const columns = this.constructor.columns();
|
|
2053
|
+
const self = this;
|
|
2054
|
+
if (columns.has(attr)) {
|
|
2055
|
+
self.currentAttributes[attr] = (0, isJsonColumn_js_1.default)(this.constructor, attr)
|
|
2056
|
+
? (0, typechecks_js_1.isString)(val)
|
|
2057
|
+
? val
|
|
2058
|
+
: JSON.stringify(val)
|
|
2059
|
+
: val;
|
|
2060
|
+
}
|
|
2061
|
+
else {
|
|
2062
|
+
self.currentAttributes[attr] = val;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
/**
|
|
2066
|
+
* Returns the value for a columnName provided,
|
|
2067
|
+
* bypassing the getters.
|
|
2068
|
+
*
|
|
2069
|
+
* ```ts
|
|
2070
|
+
* const user = User.new({ email: 'how@yadoin' })
|
|
2071
|
+
* user.getAttribute('email') // 'how@yadoin'
|
|
2072
|
+
* ```
|
|
2073
|
+
*/
|
|
2074
|
+
getAttribute(columnName) {
|
|
2075
|
+
const columns = this.constructor.columns();
|
|
2076
|
+
const self = this;
|
|
2077
|
+
if (columns.has(columnName)) {
|
|
2078
|
+
return self.currentAttributes[columnName];
|
|
2079
|
+
}
|
|
2080
|
+
else {
|
|
2081
|
+
return self[columnName];
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
/**
|
|
2085
|
+
* Returns an object containing all the columns
|
|
2086
|
+
* on this dream class, as well as their values,
|
|
2087
|
+
* bypassing getters.
|
|
2088
|
+
*
|
|
2089
|
+
* ```ts
|
|
2090
|
+
* const user = User.new({ email: 'how@yadoin' })
|
|
2091
|
+
* user.attributes()
|
|
2092
|
+
* // {
|
|
2093
|
+
* // email: 'how@yadoin',
|
|
2094
|
+
* // ...
|
|
2095
|
+
* // }
|
|
2096
|
+
* ```
|
|
2097
|
+
*/
|
|
2098
|
+
getAttributes() {
|
|
2099
|
+
return { ...this.currentAttributes };
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* @internal
|
|
2103
|
+
*
|
|
2104
|
+
* Returns the db type stored within the database
|
|
2105
|
+
*/
|
|
2106
|
+
static cachedTypeFor(attribute) {
|
|
2107
|
+
return (0, cachedTypeForAttribute_js_1.default)(this, attribute);
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Returns the attributes that have changed since
|
|
2111
|
+
* being persisted to the database, with the values
|
|
2112
|
+
* that were last persisted to the database.
|
|
2113
|
+
*
|
|
2114
|
+
* ```ts
|
|
2115
|
+
* const user = User.new({ email: 'original@email', password: 'howyadoin' })
|
|
2116
|
+
* await user.save()
|
|
2117
|
+
*
|
|
2118
|
+
* user.email = 'new@email'
|
|
2119
|
+
* user.changedAttributes()
|
|
2120
|
+
* // { email: 'original@email' }
|
|
2121
|
+
*
|
|
2122
|
+
* user.email = 'original@email'
|
|
2123
|
+
* user.changedAttributes()
|
|
2124
|
+
* // {}
|
|
2125
|
+
* ```
|
|
2126
|
+
*
|
|
2127
|
+
* @returns An object containing changed attributes and their original values
|
|
2128
|
+
*/
|
|
2129
|
+
changedAttributes() {
|
|
2130
|
+
const obj = {};
|
|
2131
|
+
Object.keys(this.dirtyAttributes()).forEach(column => {
|
|
2132
|
+
;
|
|
2133
|
+
obj[column] = this.frozenAttributes[column];
|
|
2134
|
+
});
|
|
2135
|
+
return obj;
|
|
2136
|
+
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Returns an object containing the attributes that have
|
|
2139
|
+
* changed since last persisting, along with their current
|
|
2140
|
+
* and previously persisted values.
|
|
2141
|
+
*
|
|
2142
|
+
* ```ts
|
|
2143
|
+
* const pet = Pet.new({ species: 'dog' })
|
|
2144
|
+
* pet.changes()
|
|
2145
|
+
* // {
|
|
2146
|
+
* // species: {
|
|
2147
|
+
* // was: undefined,
|
|
2148
|
+
* // now: 'dog',
|
|
2149
|
+
* // }
|
|
2150
|
+
* // }
|
|
2151
|
+
*
|
|
2152
|
+
* await pet.save()
|
|
2153
|
+
* pet.changes()
|
|
2154
|
+
* // {
|
|
2155
|
+
* // species: {
|
|
2156
|
+
* // was: undefined,
|
|
2157
|
+
* // now: 'dog',
|
|
2158
|
+
* // }
|
|
2159
|
+
* // }
|
|
2160
|
+
*
|
|
2161
|
+
* pet.species = 'cat'
|
|
2162
|
+
* pet.species = 'frog'
|
|
2163
|
+
* pet.changes()
|
|
2164
|
+
* // {
|
|
2165
|
+
* // species: {
|
|
2166
|
+
* // was: 'dog',
|
|
2167
|
+
* // now: 'frog',
|
|
2168
|
+
* // }
|
|
2169
|
+
* // }
|
|
2170
|
+
*
|
|
2171
|
+
* await pet.save()
|
|
2172
|
+
* pet.changes()
|
|
2173
|
+
* // {
|
|
2174
|
+
* // species: {
|
|
2175
|
+
* // was: 'dog',
|
|
2176
|
+
* // now: 'frog',
|
|
2177
|
+
* // }
|
|
2178
|
+
* // }
|
|
2179
|
+
* ```
|
|
2180
|
+
*
|
|
2181
|
+
* @returns An object containing changed attributes
|
|
2182
|
+
*/
|
|
2183
|
+
changes() {
|
|
2184
|
+
const obj = {};
|
|
2185
|
+
this.constructor.columns().forEach(column => {
|
|
2186
|
+
const was = this.previousValueForAttribute(column);
|
|
2187
|
+
const now = this[column];
|
|
2188
|
+
if (was !== now) {
|
|
2189
|
+
;
|
|
2190
|
+
obj[column] = {
|
|
2191
|
+
was,
|
|
2192
|
+
now,
|
|
2193
|
+
};
|
|
2194
|
+
}
|
|
2195
|
+
});
|
|
2196
|
+
return obj;
|
|
2197
|
+
}
|
|
2198
|
+
/**
|
|
2199
|
+
* Returns the value most recently persisted
|
|
2200
|
+
* to the database.
|
|
2201
|
+
*
|
|
2202
|
+
* ```ts
|
|
2203
|
+
* const pet = Pet.new({ species: 'cat' })
|
|
2204
|
+
* pet.previousValueForAttribute('species')
|
|
2205
|
+
* // undefined
|
|
2206
|
+
*
|
|
2207
|
+
* await pet.save()
|
|
2208
|
+
* pet.previousValueForAttribute('species')
|
|
2209
|
+
* // undefined
|
|
2210
|
+
*
|
|
2211
|
+
* pet.species = 'dog'
|
|
2212
|
+
* pet.previousValueForAttribute('species')
|
|
2213
|
+
* // 'cat'
|
|
2214
|
+
*
|
|
2215
|
+
* await pet.save()
|
|
2216
|
+
* pet.previousValueForAttribute('species')
|
|
2217
|
+
* // 'cat'
|
|
2218
|
+
*
|
|
2219
|
+
* await pet.update({ species: 'cat' })
|
|
2220
|
+
* pet.previousValueForAttribute('species')
|
|
2221
|
+
* // 'dog'
|
|
2222
|
+
* ```
|
|
2223
|
+
*
|
|
2224
|
+
* @param columName - The column name you want the previous value for
|
|
2225
|
+
* @returns Returns the previous value for an attribute
|
|
2226
|
+
*/
|
|
2227
|
+
previousValueForAttribute(columnName) {
|
|
2228
|
+
if (this.frozenAttributes[columnName] !== this[columnName])
|
|
2229
|
+
return this.frozenAttributes[columnName];
|
|
2230
|
+
return this.attributesFromBeforeLastSave[columnName];
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Returns true if the columnName provided has
|
|
2234
|
+
* changes that were persisted during the most
|
|
2235
|
+
* recent save.
|
|
2236
|
+
*
|
|
2237
|
+
* @param columnName - the column name to check
|
|
2238
|
+
* @returns A boolean
|
|
2239
|
+
*/
|
|
2240
|
+
savedChangeToAttribute(columnName) {
|
|
2241
|
+
const changes = this.changes();
|
|
2242
|
+
const now = changes?.[columnName]?.now;
|
|
2243
|
+
const was = changes?.[columnName]?.was;
|
|
2244
|
+
return this.isPersisted && now !== was;
|
|
2245
|
+
}
|
|
2246
|
+
/**
|
|
2247
|
+
* Returns true if the columnName provided has
|
|
2248
|
+
* changes that have not yet been persisted.
|
|
2249
|
+
*
|
|
2250
|
+
* @param columnName - the column name to check
|
|
2251
|
+
* @returns A boolean
|
|
2252
|
+
*/
|
|
2253
|
+
willSaveChangeToAttribute(attribute) {
|
|
2254
|
+
return this.attributeIsDirty(attribute);
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Returns the column names for the given model
|
|
2258
|
+
*
|
|
2259
|
+
* @returns The column names for the given model
|
|
2260
|
+
*/
|
|
2261
|
+
columns() {
|
|
2262
|
+
return this.constructor.columns();
|
|
2263
|
+
}
|
|
2264
|
+
/**
|
|
2265
|
+
* Returns an object containing the column names
|
|
2266
|
+
* of columns that have changed since last persist,
|
|
2267
|
+
* and their current values.
|
|
2268
|
+
*
|
|
2269
|
+
* ```ts
|
|
2270
|
+
* const user = User.new({ email: 'hello@world' })
|
|
2271
|
+
* user.dirtyAttributes()
|
|
2272
|
+
* // { email: 'hello@world' }
|
|
2273
|
+
*
|
|
2274
|
+
* await user.save()
|
|
2275
|
+
*
|
|
2276
|
+
* user.email = 'hello@world'
|
|
2277
|
+
* user.dirtyAttributes()
|
|
2278
|
+
* // {}
|
|
2279
|
+
*
|
|
2280
|
+
* user.email = 'goodbye@world'
|
|
2281
|
+
* user.dirtyAttributes()
|
|
2282
|
+
* // { email: 'goodbye@world' }
|
|
2283
|
+
*
|
|
2284
|
+
* user.email = 'hello@world'
|
|
2285
|
+
* user.dirtyAttributes()
|
|
2286
|
+
* // {}
|
|
2287
|
+
* ```
|
|
2288
|
+
*
|
|
2289
|
+
* @returns An object containing the changed attributes
|
|
2290
|
+
*/
|
|
2291
|
+
dirtyAttributes() {
|
|
2292
|
+
const obj = {};
|
|
2293
|
+
this.columns().forEach(column => {
|
|
2294
|
+
// TODO: clean up types
|
|
2295
|
+
if (this.attributeIsDirty(column))
|
|
2296
|
+
obj[column] = this.getAttributes()[column];
|
|
2297
|
+
});
|
|
2298
|
+
return obj;
|
|
2299
|
+
}
|
|
2300
|
+
/**
|
|
2301
|
+
* Returns true if an attribute has changes since last persist
|
|
2302
|
+
*
|
|
2303
|
+
* @returns A boolean
|
|
2304
|
+
*/
|
|
2305
|
+
attributeIsDirty(attribute) {
|
|
2306
|
+
const frozenValue = this.frozenAttributes[attribute];
|
|
2307
|
+
const currentValue = this.getAttributes()[attribute];
|
|
2308
|
+
if (this.isNewRecord)
|
|
2309
|
+
return true;
|
|
2310
|
+
if (frozenValue instanceof luxon_1.DateTime) {
|
|
2311
|
+
return frozenValue.toMillis() !== this.unknownValueToMillis(currentValue);
|
|
2312
|
+
}
|
|
2313
|
+
else if (frozenValue instanceof CalendarDate_js_1.default) {
|
|
2314
|
+
return frozenValue.toISO() !== this.unknownValueToDateString(currentValue);
|
|
2315
|
+
}
|
|
2316
|
+
else {
|
|
2317
|
+
return frozenValue !== currentValue;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* @internal
|
|
2322
|
+
*/
|
|
2323
|
+
unknownValueToMillis(currentValue) {
|
|
2324
|
+
if (!currentValue)
|
|
2325
|
+
return;
|
|
2326
|
+
if ((0, typechecks_js_1.isString)(currentValue))
|
|
2327
|
+
currentValue = luxon_1.DateTime.fromISO(currentValue);
|
|
2328
|
+
if (currentValue instanceof CalendarDate_js_1.default)
|
|
2329
|
+
currentValue = currentValue.toDateTime();
|
|
2330
|
+
if (currentValue instanceof luxon_1.DateTime && currentValue.isValid)
|
|
2331
|
+
return currentValue.toMillis();
|
|
2332
|
+
}
|
|
2333
|
+
/**
|
|
2334
|
+
* @internal
|
|
2335
|
+
*/
|
|
2336
|
+
unknownValueToDateString(currentValue) {
|
|
2337
|
+
if (!currentValue)
|
|
2338
|
+
return;
|
|
2339
|
+
if ((0, typechecks_js_1.isString)(currentValue))
|
|
2340
|
+
currentValue = CalendarDate_js_1.default.fromISO(currentValue);
|
|
2341
|
+
if (currentValue instanceof luxon_1.DateTime)
|
|
2342
|
+
currentValue = CalendarDate_js_1.default.fromDateTime(currentValue);
|
|
2343
|
+
if (currentValue instanceof CalendarDate_js_1.default && currentValue.isValid)
|
|
2344
|
+
return currentValue.toISO();
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* Deletes the record represented by this instance
|
|
2348
|
+
* from the database, calling any destroy
|
|
2349
|
+
* hooks on this model.
|
|
2350
|
+
*
|
|
2351
|
+
* ```ts
|
|
2352
|
+
* const user = await User.last()
|
|
2353
|
+
* await user.destroy()
|
|
2354
|
+
* ```
|
|
2355
|
+
*
|
|
2356
|
+
* @param options - Options for destroying the instance
|
|
2357
|
+
* @param options.skipHooks - If true, skips applying model hooks during the destroy operation. Defaults to false
|
|
2358
|
+
* @param options.cascade - If false, skips destroying associations marked `dependent: 'destroy'`. Defaults to true
|
|
2359
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when cascade destroying. Defaults to false
|
|
2360
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when cascade destroying. Defaults to an empty array
|
|
2361
|
+
* @returns The instance that was destroyed
|
|
2362
|
+
*/
|
|
2363
|
+
async destroy(options = {}) {
|
|
2364
|
+
return await (0, destroyDream_js_1.default)(this, null, (0, destroyOptions_js_1.destroyOptions)(options));
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Deletes the record represented by this instance
|
|
2368
|
+
* from the database, calling any destroy
|
|
2369
|
+
* hooks on this model.
|
|
2370
|
+
*
|
|
2371
|
+
* If the record being destroyed is using
|
|
2372
|
+
* a SoftDelete decorator, the soft delete
|
|
2373
|
+
* will be bypassed, causing the record
|
|
2374
|
+
* to be permanently removed from the database.
|
|
2375
|
+
*
|
|
2376
|
+
* ```ts
|
|
2377
|
+
* const user = await User.last()
|
|
2378
|
+
* await user.reallyDestroy()
|
|
2379
|
+
* ```
|
|
2380
|
+
*
|
|
2381
|
+
* @param options - Options for destroying the instance
|
|
2382
|
+
* @param options.skipHooks - If true, skips applying model hooks during the destroy operation. Defaults to false
|
|
2383
|
+
* @param options.cascade - If false, skips destroying associations marked `dependent: 'destroy'`. Defaults to true
|
|
2384
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when cascade destroying. Defaults to false
|
|
2385
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when cascade destroying. Defaults to an empty array
|
|
2386
|
+
* @returns The instance that was destroyed
|
|
2387
|
+
*/
|
|
2388
|
+
async reallyDestroy(options = {}) {
|
|
2389
|
+
return await (0, destroyDream_js_1.default)(this, null, (0, destroyOptions_js_1.reallyDestroyOptions)(options));
|
|
2390
|
+
}
|
|
2391
|
+
/**
|
|
2392
|
+
* Undestroys a SoftDelete model, unsetting
|
|
2393
|
+
* the `deletedAt` field in the database.
|
|
2394
|
+
*
|
|
2395
|
+
* If the model is not a SoftDelete model,
|
|
2396
|
+
* this will raise an exception.
|
|
2397
|
+
*
|
|
2398
|
+
* ```ts
|
|
2399
|
+
* const user = await User.removeAllDefaultScopes().last()
|
|
2400
|
+
* await user.undestroy()
|
|
2401
|
+
* ```
|
|
2402
|
+
*
|
|
2403
|
+
* @param options - Options for undestroying the instance
|
|
2404
|
+
* @param options.skipHooks - If true, skips applying model hooks during the undestroy operation. Defaults to false
|
|
2405
|
+
* @param options.cascade - If false, skips undestroying associations marked `dependent: 'destroy'`. Defaults to true
|
|
2406
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when cascade undestroying. Defaults to false
|
|
2407
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when cascade undestroying (soft delete is always bypassed). Defaults to an empty array
|
|
2408
|
+
* @returns The undestroyed record
|
|
2409
|
+
*/
|
|
2410
|
+
async undestroy(options = {}) {
|
|
2411
|
+
const dreamClass = this.constructor;
|
|
2412
|
+
if (!dreamClass['softDelete'])
|
|
2413
|
+
throw new CannotCallUndestroyOnANonSoftDeleteModel_js_1.default(dreamClass);
|
|
2414
|
+
await (0, undestroyDream_js_1.default)(this, null, (0, destroyOptions_js_1.undestroyOptions)(options));
|
|
2415
|
+
return this;
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Returns true if the argument is the same Dream class
|
|
2419
|
+
* with the same primary key value.
|
|
2420
|
+
*
|
|
2421
|
+
* NOTE: This does not compare attribute values other than
|
|
2422
|
+
* the primary key.
|
|
2423
|
+
*
|
|
2424
|
+
* @returns A boolean
|
|
2425
|
+
*/
|
|
2426
|
+
equals(other) {
|
|
2427
|
+
return other?.constructor === this.constructor && other.primaryKeyValue === this.primaryKeyValue;
|
|
2428
|
+
}
|
|
2429
|
+
/**
|
|
2430
|
+
* @internal
|
|
2431
|
+
*
|
|
2432
|
+
* Used for changes API
|
|
2433
|
+
*/
|
|
2434
|
+
freezeAttributes() {
|
|
2435
|
+
this.frozenAttributes = { ...this.getAttributes() };
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Deep clones the model and its non-association attributes.
|
|
2439
|
+
* Unsets primaryKey, created and updated fields.
|
|
2440
|
+
*
|
|
2441
|
+
* @returns Non-persisted, cloned Dream instance
|
|
2442
|
+
*/
|
|
2443
|
+
dup() {
|
|
2444
|
+
const clone = this.clone({ includeAssociations: false });
|
|
2445
|
+
clone.isPersisted = false;
|
|
2446
|
+
clone[clone.primaryKey] = undefined;
|
|
2447
|
+
clone[clone.createdAtField] = undefined;
|
|
2448
|
+
clone[clone.updatedAtField] = undefined;
|
|
2449
|
+
const dreamClass = this.constructor;
|
|
2450
|
+
dreamClass.sortableFields.forEach(data => {
|
|
2451
|
+
;
|
|
2452
|
+
clone[data.positionField] = undefined;
|
|
2453
|
+
});
|
|
2454
|
+
clone.freezeAttributes();
|
|
2455
|
+
clone.originalAttributes = { ...clone.getAttributes() };
|
|
2456
|
+
clone.attributesFromBeforeLastSave = { ...clone.getAttributes() };
|
|
2457
|
+
return clone;
|
|
2458
|
+
}
|
|
2459
|
+
/**
|
|
2460
|
+
* Deep clones the model and it's attributes, but maintains references to
|
|
2461
|
+
* loaded associations
|
|
2462
|
+
*/
|
|
2463
|
+
clone({ includeAssociations = true } = {}) {
|
|
2464
|
+
const self = this;
|
|
2465
|
+
const clone = self.constructor.new({});
|
|
2466
|
+
const associationDataKeys = Object.values(this.constructor.associationMetadataMap()).map(association => (0, associationToGetterSetterProp_js_1.default)(association));
|
|
2467
|
+
Object.keys(this).forEach(property => {
|
|
2468
|
+
if (!associationDataKeys.includes(property))
|
|
2469
|
+
clone[property] = (0, cloneDeepSafe_js_1.default)(self[property]);
|
|
2470
|
+
});
|
|
2471
|
+
if (includeAssociations) {
|
|
2472
|
+
associationDataKeys.forEach(associationDataKey => (clone[associationDataKey] = self[associationDataKey]));
|
|
2473
|
+
}
|
|
2474
|
+
return clone;
|
|
2475
|
+
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Creates an association for an instance. Automatically
|
|
2478
|
+
* handles setting foreign key and, in the case of polymorphism,
|
|
2479
|
+
* foreign key type.
|
|
2480
|
+
*
|
|
2481
|
+
* ```ts
|
|
2482
|
+
* await user.createAssociation('posts', { body: 'hello world' })
|
|
2483
|
+
* ```
|
|
2484
|
+
*
|
|
2485
|
+
* @param associationName - the name of the association to create
|
|
2486
|
+
* @param attributes - the attributes with which to create the associated model
|
|
2487
|
+
* @returns The created association
|
|
2488
|
+
*/
|
|
2489
|
+
async createAssociation(associationName, attributes = {}) {
|
|
2490
|
+
return (0, createAssociation_js_1.default)(this, null, associationName, attributes);
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2493
|
+
* Destroys models associated with the current instance,
|
|
2494
|
+
* deleting their corresponding records within the database.
|
|
2495
|
+
*
|
|
2496
|
+
* ```ts
|
|
2497
|
+
* await user.destroyAssociation('posts', { body: 'hello world' })
|
|
2498
|
+
* ```
|
|
2499
|
+
*
|
|
2500
|
+
* @param associationName - The name of the association to destroy
|
|
2501
|
+
* @param options - Options for destroying the association
|
|
2502
|
+
* @param options.on - Optional where statement to apply to query before destroying
|
|
2503
|
+
* @param options.skipHooks - If true, skips applying model hooks during the destroy operation. Defaults to false
|
|
2504
|
+
* @param options.cascade - If false, skips destroying associations marked `dependent: 'destroy'`. Defaults to true
|
|
2505
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when destroying the association. Defaults to false
|
|
2506
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when destroying the association. Defaults to an empty array
|
|
2507
|
+
* @returns The number of records deleted
|
|
2508
|
+
*/
|
|
2509
|
+
async destroyAssociation(associationName, options) {
|
|
2510
|
+
return await (0, destroyAssociation_js_1.default)(this, null, associationName, {
|
|
2511
|
+
...(0, destroyOptions_js_1.destroyOptions)(options),
|
|
2512
|
+
joinOnStatements: {
|
|
2513
|
+
on: options?.on,
|
|
2514
|
+
notOn: options?.notOn,
|
|
2515
|
+
onAny: options?.onAny,
|
|
2516
|
+
},
|
|
2517
|
+
});
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Destroys models associated with the current instance,
|
|
2521
|
+
* deleting their corresponding records within the database.
|
|
2522
|
+
*
|
|
2523
|
+
* If the record, or else any of its associations
|
|
2524
|
+
* which are marked cascade: "destroy", are using
|
|
2525
|
+
* the SoftDelete decorator, it will be bypassed,
|
|
2526
|
+
* causing those records to be deleted from the database.
|
|
2527
|
+
*
|
|
2528
|
+
* ```ts
|
|
2529
|
+
* await user.reallyDestroyAssociation('posts', { body: 'hello world' })
|
|
2530
|
+
* ```
|
|
2531
|
+
*
|
|
2532
|
+
* @param associationName - The name of the association to destroy
|
|
2533
|
+
* @param options - Options for destroying the association
|
|
2534
|
+
* @param options.on - Optional where statement to apply to query before destroying
|
|
2535
|
+
* @param options.skipHooks - If true, skips applying model hooks during the destroy operation. Defaults to false
|
|
2536
|
+
* @param options.cascade - If true, cascades the destroy operation to associations marked with `dependent: 'destroy'`. Defaults to true
|
|
2537
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when destroying the association. Defaults to false
|
|
2538
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when destroying the association. Defaults to an empty array
|
|
2539
|
+
* @returns The number of records deleted
|
|
2540
|
+
*/
|
|
2541
|
+
async reallyDestroyAssociation(associationName, options) {
|
|
2542
|
+
return await (0, destroyAssociation_js_1.default)(this, null, associationName, {
|
|
2543
|
+
...(0, destroyOptions_js_1.reallyDestroyOptions)(options),
|
|
2544
|
+
joinOnStatements: {
|
|
2545
|
+
on: options?.on,
|
|
2546
|
+
notOn: options?.notOn,
|
|
2547
|
+
onAny: options?.onAny,
|
|
2548
|
+
},
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2551
|
+
/**
|
|
2552
|
+
* Undestroys a SoftDelete association.
|
|
2553
|
+
* If cascade: true is passed, any child
|
|
2554
|
+
* associations that have been soft deleted
|
|
2555
|
+
* will also be undeleted.
|
|
2556
|
+
*
|
|
2557
|
+
* ```ts
|
|
2558
|
+
* await user.undestroyAssociation('posts', { body: 'hello world' })
|
|
2559
|
+
* ```
|
|
2560
|
+
*
|
|
2561
|
+
* @param associationName - The name of the association to undestroy
|
|
2562
|
+
* @param options - Options for undestroying the association
|
|
2563
|
+
* @param options.on - Optional where statement to apply to query before undestroying
|
|
2564
|
+
* @param options.skipHooks - If true, skips applying model hooks during the undestroy operation. Defaults to false
|
|
2565
|
+
* @param options.cascade - If false, skips undestroying associations marked `dependent: 'destroy'`. Defaults to true
|
|
2566
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when undestroying the association. Defaults to false
|
|
2567
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when undestroying the association. Defaults to an empty array
|
|
2568
|
+
* @returns The number of records undestroyed
|
|
2569
|
+
*/
|
|
2570
|
+
async undestroyAssociation(associationName, options) {
|
|
2571
|
+
return await (0, undestroyAssociation_js_1.default)(this, null, associationName, {
|
|
2572
|
+
...(0, destroyOptions_js_1.undestroyOptions)(options),
|
|
2573
|
+
joinOnStatements: {
|
|
2574
|
+
on: options?.on,
|
|
2575
|
+
notOn: options?.notOn,
|
|
2576
|
+
onAny: options?.onAny,
|
|
2577
|
+
},
|
|
2578
|
+
});
|
|
2579
|
+
}
|
|
2580
|
+
/**
|
|
2581
|
+
* Returns a Query instance for the specified
|
|
2582
|
+
* association on the current instance.
|
|
2583
|
+
*
|
|
2584
|
+
* ```ts
|
|
2585
|
+
* await user.associationQuery('posts').all()
|
|
2586
|
+
* // only user posts returned
|
|
2587
|
+
* ```
|
|
2588
|
+
*
|
|
2589
|
+
* @returns A Query scoped to the specified association on the current instance
|
|
2590
|
+
*
|
|
2591
|
+
*/
|
|
2592
|
+
associationQuery(associationName, joinOnStatements) {
|
|
2593
|
+
return (0, associationQuery_js_1.default)(this, null, associationName, {
|
|
2594
|
+
joinOnStatements: joinOnStatements,
|
|
2595
|
+
bypassAllDefaultScopes: scopeHelpers_js_1.DEFAULT_BYPASS_ALL_DEFAULT_SCOPES,
|
|
2596
|
+
defaultScopesToBypass: scopeHelpers_js_1.DEFAULT_DEFAULT_SCOPES_TO_BYPASS,
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Updates all records matching the association with
|
|
2601
|
+
* the provided attributes. If a where statement is passed,
|
|
2602
|
+
* The on statement will be applied to the query
|
|
2603
|
+
* before updating.
|
|
2604
|
+
*
|
|
2605
|
+
* ```ts
|
|
2606
|
+
* await user.createAssociation('posts', { body: 'hello world' })
|
|
2607
|
+
* await user.createAssociation('posts', { body: 'howyadoin' })
|
|
2608
|
+
* await user.updateAssociation('posts', { body: 'goodbye world' }, { on: { body: 'hello world' }})
|
|
2609
|
+
* // 1
|
|
2610
|
+
* ```
|
|
2611
|
+
*
|
|
2612
|
+
* @param associationName - The name of the association to update
|
|
2613
|
+
* @param attributes - The attributes to update on the association
|
|
2614
|
+
* @param options - Options for updating the association
|
|
2615
|
+
* @param options.on - Optional on statement to apply to query before updating
|
|
2616
|
+
* @param options.skipHooks - If true, skips applying model hooks during the update operation. Defaults to false
|
|
2617
|
+
* @param options.bypassAllDefaultScopes - If true, bypasses all default scopes when updating the association. Defaults to false
|
|
2618
|
+
* @param options.defaultScopesToBypass - An array of default scope names to bypass when updating the association. Defaults to an empty array
|
|
2619
|
+
* @returns The number of updated records
|
|
2620
|
+
*/
|
|
2621
|
+
async updateAssociation(associationName, attributes, updateAssociationOptions) {
|
|
2622
|
+
return (0, associationUpdateQuery_js_1.default)(this, null, associationName, {
|
|
2623
|
+
joinOnStatements: {
|
|
2624
|
+
on: updateAssociationOptions?.on,
|
|
2625
|
+
notOn: updateAssociationOptions?.notOn,
|
|
2626
|
+
onAny: updateAssociationOptions?.onAny,
|
|
2627
|
+
},
|
|
2628
|
+
bypassAllDefaultScopes: updateAssociationOptions?.bypassAllDefaultScopes ?? scopeHelpers_js_1.DEFAULT_BYPASS_ALL_DEFAULT_SCOPES,
|
|
2629
|
+
defaultScopesToBypass: updateAssociationOptions?.defaultScopesToBypass ?? scopeHelpers_js_1.DEFAULT_DEFAULT_SCOPES_TO_BYPASS,
|
|
2630
|
+
}).update(attributes, { skipHooks: updateAssociationOptions?.skipHooks ?? scopeHelpers_js_1.DEFAULT_SKIP_HOOKS });
|
|
2631
|
+
}
|
|
2632
|
+
///////////////////
|
|
2633
|
+
// end: updateAssociation
|
|
2634
|
+
///////////////////
|
|
2635
|
+
/**
|
|
2636
|
+
* Sends data through for use as passthrough data
|
|
2637
|
+
* for the associations that require it.
|
|
2638
|
+
*
|
|
2639
|
+
* ```ts
|
|
2640
|
+
* class Post {
|
|
2641
|
+
* @Deco.HasMany('LocalizedText')
|
|
2642
|
+
* public localizedTexts: LocalizedText[]
|
|
2643
|
+
*
|
|
2644
|
+
* @Deco.HasOne('LocalizedText', {
|
|
2645
|
+
* where: { locale: DreamConst.passthrough },
|
|
2646
|
+
* })
|
|
2647
|
+
* public currentLocalizedText: LocalizedText
|
|
2648
|
+
* }
|
|
2649
|
+
*
|
|
2650
|
+
* await User.passthrough({ locale: 'es-ES' })
|
|
2651
|
+
* .preload('posts', 'currentLocalizedText')
|
|
2652
|
+
* .first()
|
|
2653
|
+
* ```
|
|
2654
|
+
*
|
|
2655
|
+
* @param passthroughWhereStatement - where statement used for associations that require passthrough data
|
|
2656
|
+
* @returns A cloned Query with the passthrough data
|
|
2657
|
+
*/
|
|
2658
|
+
passthrough(passthroughWhereStatement) {
|
|
2659
|
+
return new LoadBuilder_js_1.default(this).passthrough(passthroughWhereStatement);
|
|
2660
|
+
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Loads the requested associations upon execution
|
|
2663
|
+
*
|
|
2664
|
+
* NOTE: {@link #preload} is often a preferrable way of achieving the
|
|
2665
|
+
* same goal.
|
|
2666
|
+
*
|
|
2667
|
+
* ```ts
|
|
2668
|
+
* await user
|
|
2669
|
+
* .load('posts', { body: ops.ilike('%hello world%') }, 'comments', 'replies')
|
|
2670
|
+
* .load('images')
|
|
2671
|
+
* .execute()
|
|
2672
|
+
*
|
|
2673
|
+
* user.posts[0].comments[0].replies[0]
|
|
2674
|
+
* // Reply{}
|
|
2675
|
+
*
|
|
2676
|
+
* user.images[0]
|
|
2677
|
+
* // Image{}
|
|
2678
|
+
* ```
|
|
2679
|
+
*
|
|
2680
|
+
* @param args - A list of associations (and optional where clauses) to load
|
|
2681
|
+
* @returns A chainable LoadBuilder instance
|
|
2682
|
+
*/
|
|
2683
|
+
load(...args) {
|
|
2684
|
+
return new LoadBuilder_js_1.default(this).load(...args);
|
|
2685
|
+
}
|
|
2686
|
+
/**
|
|
2687
|
+
* Load each specified association using a single SQL query.
|
|
2688
|
+
* See {@link #load} for loading in separate queries.
|
|
2689
|
+
*
|
|
2690
|
+
* Note: since leftJoinPreload loads via single query, it has
|
|
2691
|
+
* some downsides and that may be avoided using {@link #load}:
|
|
2692
|
+
* 1. `limit` and `offset` will be automatically removed
|
|
2693
|
+
* 2. `through` associations will bring additional namespaces into the query that can conflict with through associations from other associations, creating an invalid query
|
|
2694
|
+
* 3. each nested association will result in an additional record which duplicates data from the outer record. E.g., given `.leftJoinPreload('a', 'b', 'c')`, if each `a` has 10 `b` and each `b` has 10 `c`, then for one `a`, 100 records will be returned, each of which has all of the columns of `a`. `.load('a', 'b', 'c')` would perform three separate SQL queries, but the data for a single `a` would only be returned once.
|
|
2695
|
+
* 4. the individual query becomes more complex the more associations are included
|
|
2696
|
+
* 5. associations loading associations loading associations could result in exponential amounts of data; in those cases, `.load(...).findEach(...)` avoids instantiating massive amounts of data at once
|
|
2697
|
+
* Loads the requested associations upon execution
|
|
2698
|
+
*
|
|
2699
|
+
* NOTE: {@link #leftJoinPreload} is often a preferrable way of achieving the
|
|
2700
|
+
* same goal.
|
|
2701
|
+
*
|
|
2702
|
+
* ```ts
|
|
2703
|
+
* await user
|
|
2704
|
+
* .leftJoinLoad('posts', { body: ops.ilike('%hello world%') }, 'comments', 'replies')
|
|
2705
|
+
* .leftJoinLoad('images')
|
|
2706
|
+
* .execute()
|
|
2707
|
+
*
|
|
2708
|
+
* user.posts[0].comments[0].replies[0]
|
|
2709
|
+
* // Reply{}
|
|
2710
|
+
*
|
|
2711
|
+
* user.images[0]
|
|
2712
|
+
* // Image{}
|
|
2713
|
+
* ```
|
|
2714
|
+
*
|
|
2715
|
+
* @param args - A list of associations (and optional where clauses) to load
|
|
2716
|
+
* @returns A chainable LeftJoinLoadBuilder instance
|
|
2717
|
+
*/
|
|
2718
|
+
leftJoinLoad(...args) {
|
|
2719
|
+
return new LeftJoinLoadBuilder_js_1.default(this).leftJoinLoad(...args);
|
|
2720
|
+
}
|
|
2721
|
+
/**
|
|
2722
|
+
* Returns true if the association specified has
|
|
2723
|
+
* been loaded on this instance
|
|
2724
|
+
*
|
|
2725
|
+
* Since accessing associations that haven't been
|
|
2726
|
+
* loaded/preloaded will raise an exception, `loaded`
|
|
2727
|
+
* is useful for conditionally loading from the database
|
|
2728
|
+
* in contexts where an association may not yet be loaded.
|
|
2729
|
+
*
|
|
2730
|
+
* ```ts
|
|
2731
|
+
* user.loaded('posts')
|
|
2732
|
+
* // false
|
|
2733
|
+
*
|
|
2734
|
+
* user = await user.load('posts').execute()
|
|
2735
|
+
* user.loaded('posts')
|
|
2736
|
+
* // true
|
|
2737
|
+
* ```
|
|
2738
|
+
*
|
|
2739
|
+
* @param associationName - the association name you wish to check the loading of
|
|
2740
|
+
* @returns A boolean
|
|
2741
|
+
*/
|
|
2742
|
+
loaded(associationName) {
|
|
2743
|
+
try {
|
|
2744
|
+
;
|
|
2745
|
+
this[associationName];
|
|
2746
|
+
return true;
|
|
2747
|
+
}
|
|
2748
|
+
catch (error) {
|
|
2749
|
+
if (error.constructor !== NonLoadedAssociation_js_1.default)
|
|
2750
|
+
throw error;
|
|
2751
|
+
return false;
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
/**
|
|
2755
|
+
* Reloads an instance, refreshing all it's attribute values
|
|
2756
|
+
* to those in the database.
|
|
2757
|
+
*
|
|
2758
|
+
* NOTE: this does not refresh associations
|
|
2759
|
+
*
|
|
2760
|
+
* ```ts
|
|
2761
|
+
* await user.reload()
|
|
2762
|
+
* ```
|
|
2763
|
+
*
|
|
2764
|
+
* @returns void
|
|
2765
|
+
*/
|
|
2766
|
+
async reload() {
|
|
2767
|
+
await (0, reload_js_1.default)(this);
|
|
2768
|
+
}
|
|
2769
|
+
/**
|
|
2770
|
+
* Serializes an instance. You can specify a serializer key,
|
|
2771
|
+
* or else the default will be used
|
|
2772
|
+
*
|
|
2773
|
+
* ```ts
|
|
2774
|
+
* // uses the default serializer provided in the model's `serializers` getter
|
|
2775
|
+
* await user.serialize()
|
|
2776
|
+
*
|
|
2777
|
+
* // uses the summary serializer provided in the model's `serializers` getter
|
|
2778
|
+
* await user.serialize({ serializerKey: 'summary' })
|
|
2779
|
+
* ```
|
|
2780
|
+
*
|
|
2781
|
+
* @param args.casing - Which casing to use when serializing (camel or snake, default camel)
|
|
2782
|
+
* @param args.serializerKey - The key to use when referencing the object returned by the `serializers` getter on the given model instance (defaults to "default")
|
|
2783
|
+
* @returns A serialized representation of the model
|
|
2784
|
+
*/
|
|
2785
|
+
serialize({ casing = null, serializerKey } = {}) {
|
|
2786
|
+
const serializerClass = (0, inferSerializerFromDreamOrViewModel_js_1.default)(this, serializerKey?.toString());
|
|
2787
|
+
if (!serializerClass)
|
|
2788
|
+
throw new MissingSerializersDefinition_js_1.default(this.constructor);
|
|
2789
|
+
const serializer = new serializerClass(this);
|
|
2790
|
+
if (casing)
|
|
2791
|
+
serializer.casing(casing);
|
|
2792
|
+
return serializer.render();
|
|
2793
|
+
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Takes the attributes passed in and sets their values,
|
|
2796
|
+
* leveraging any custom setters defined for these attributes.
|
|
2797
|
+
*
|
|
2798
|
+
* NOTE:
|
|
2799
|
+
* To bypass custom-defined setters, use `#setAttributes` instead.
|
|
2800
|
+
*
|
|
2801
|
+
* ```ts
|
|
2802
|
+
* const user = new User()
|
|
2803
|
+
* user.assignAttributes({ email: 'my@email', password: 'my password' })
|
|
2804
|
+
* ```
|
|
2805
|
+
*/
|
|
2806
|
+
assignAttributes(attributes) {
|
|
2807
|
+
return this._setAttributes(attributes, { bypassUserDefinedSetters: false });
|
|
2808
|
+
}
|
|
2809
|
+
/**
|
|
2810
|
+
* Takes the attributes passed in and sets their values internally,
|
|
2811
|
+
* bypassing any custom setters defined for these attributes.
|
|
2812
|
+
*
|
|
2813
|
+
* NOTE:
|
|
2814
|
+
* To leverage custom-defined setters, use `#assignAttributes` instead.
|
|
2815
|
+
*
|
|
2816
|
+
* ```ts
|
|
2817
|
+
* const user = new User()
|
|
2818
|
+
* user.setAttributes({ email: 'my@email', password: 'my password' })
|
|
2819
|
+
* ```
|
|
2820
|
+
*/
|
|
2821
|
+
setAttributes(attributes) {
|
|
2822
|
+
return this._setAttributes(attributes, { bypassUserDefinedSetters: true });
|
|
2823
|
+
}
|
|
2824
|
+
_setAttributes(attributes, additionalOpts = {}) {
|
|
2825
|
+
const dreamClass = this.constructor;
|
|
2826
|
+
const marshalledOpts = dreamClass.extractAttributesFromUpdateableProperties(attributes, this, additionalOpts);
|
|
2827
|
+
return marshalledOpts;
|
|
2828
|
+
}
|
|
2829
|
+
/**
|
|
2830
|
+
* Saves the state of the current instance to the
|
|
2831
|
+
* database. For new instances (that have not been
|
|
2832
|
+
* persisted), `save` and `create` model hooks will be called.
|
|
2833
|
+
* For instances that have already been persisted,
|
|
2834
|
+
* the `save` and `update` model hooks will be called.
|
|
2835
|
+
*
|
|
2836
|
+
* Upon saving a new instance, the primary key, timestamp
|
|
2837
|
+
* fields (if defined), and `type` (if STI) will be set on
|
|
2838
|
+
* the model.
|
|
2839
|
+
*
|
|
2840
|
+
* Upon updating an instance, the update timestamp (if defined)
|
|
2841
|
+
* will be updated on the model.
|
|
2842
|
+
*
|
|
2843
|
+
* ```ts
|
|
2844
|
+
* const user = User.new({ email: 'how@yadoin' })
|
|
2845
|
+
* user.name = 'fred'
|
|
2846
|
+
* await user.save()
|
|
2847
|
+
*
|
|
2848
|
+
* user.email // 'how@yadoin'
|
|
2849
|
+
* user.name // 'fred'
|
|
2850
|
+
* user.id // 1
|
|
2851
|
+
* user.createdAt // A DateTime object
|
|
2852
|
+
* user.updatedAt // A DateTime object
|
|
2853
|
+
*
|
|
2854
|
+
* // If User were STI:
|
|
2855
|
+
* user.type // 'User'
|
|
2856
|
+
* ```
|
|
2857
|
+
*
|
|
2858
|
+
* @param opts.skipHooks - if true, will skip applying model hooks. Defaults to false
|
|
2859
|
+
* @returns void
|
|
2860
|
+
*/
|
|
2861
|
+
async save({ skipHooks } = {}) {
|
|
2862
|
+
await (0, saveDream_js_1.default)(this, null, { skipHooks });
|
|
2863
|
+
}
|
|
2864
|
+
/**
|
|
2865
|
+
* Applies transaction to a new Query instance
|
|
2866
|
+
*
|
|
2867
|
+
* ```ts
|
|
2868
|
+
* await ApplicationModel.transaction(async txn => {
|
|
2869
|
+
* const user = await User.txn(txn).create({ email: 'how@yadoin' })
|
|
2870
|
+
* await Pet.txn(txn).create({ user })
|
|
2871
|
+
* })
|
|
2872
|
+
* ```
|
|
2873
|
+
*
|
|
2874
|
+
* @param txn - A DreamTransaction instance (collected by calling `ApplicationModel.transaction`)
|
|
2875
|
+
* @returns A Query scoped to this model with the transaction applied
|
|
2876
|
+
*/
|
|
2877
|
+
txn(txn) {
|
|
2878
|
+
return new DreamInstanceTransactionBuilder_js_1.default(this, txn);
|
|
2879
|
+
}
|
|
2880
|
+
/**
|
|
2881
|
+
* Applies all attribute changes passed to the Dream
|
|
2882
|
+
* instance, leveraging any custom-defined setters,
|
|
2883
|
+
* and then saves the Dream instance. Can be called
|
|
2884
|
+
* on an unpersisted Dream instance.
|
|
2885
|
+
*
|
|
2886
|
+
* See {@link Dream.save | save} for details on
|
|
2887
|
+
* the side effects of saving.
|
|
2888
|
+
*
|
|
2889
|
+
* NOTE:
|
|
2890
|
+
* To bypass custom-defined setters, use {@link Dream.updateAttributes | updateAttributes} instead.
|
|
2891
|
+
*
|
|
2892
|
+
* ```ts
|
|
2893
|
+
* const user = await User.create({ email: 'saly@gmail.com' })
|
|
2894
|
+
* await user.update({ email: 'sally@gmail.com' })
|
|
2895
|
+
* ```
|
|
2896
|
+
*
|
|
2897
|
+
* @param attributes - the attributes to set on the model
|
|
2898
|
+
* @param opts.skipHooks - if true, will skip applying model hooks. Defaults to false
|
|
2899
|
+
* @returns void
|
|
2900
|
+
*/
|
|
2901
|
+
async update(attributes, { skipHooks } = {}) {
|
|
2902
|
+
// use #assignAttributes to leverage any custom-defined setters
|
|
2903
|
+
this.assignAttributes(attributes);
|
|
2904
|
+
await this.save({ skipHooks });
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Applies all attribute changes passed to the dream,
|
|
2908
|
+
* bypassing any custom-defined setters,
|
|
2909
|
+
* and then saves the dream instance. Does not bypass
|
|
2910
|
+
* model hooks.
|
|
2911
|
+
*
|
|
2912
|
+
* See {@link Dream.save | save} for details on
|
|
2913
|
+
* the side effects of saving.
|
|
2914
|
+
*
|
|
2915
|
+
* NOTE:
|
|
2916
|
+
* To update the values without bypassing any custom-defined
|
|
2917
|
+
* setters, use {@link Dream.update | update} instead.
|
|
2918
|
+
*
|
|
2919
|
+
* ```ts
|
|
2920
|
+
* const user = await User.create({ email: 'saly@gmail.com' })
|
|
2921
|
+
* await user.updateAttributes({ email: 'sally@gmail.com' })
|
|
2922
|
+
* ```
|
|
2923
|
+
*
|
|
2924
|
+
* @param attributes - The attributes to update on this instance
|
|
2925
|
+
* @param opts.skipHooks - if true, will skip applying model hooks. Defaults to false
|
|
2926
|
+
* @returns - void
|
|
2927
|
+
*/
|
|
2928
|
+
async updateAttributes(attributes, { skipHooks } = {}) {
|
|
2929
|
+
// use #setAttributes to bypass any custom-defined setters
|
|
2930
|
+
this.setAttributes(attributes);
|
|
2931
|
+
await this.save({ skipHooks });
|
|
2932
|
+
}
|
|
2933
|
+
/**
|
|
2934
|
+
* Flags a dream model so that it does not
|
|
2935
|
+
* actually destroy when in a destroy phase.
|
|
2936
|
+
* This is usually used for a soft-delete
|
|
2937
|
+
* pattern
|
|
2938
|
+
*
|
|
2939
|
+
* ```ts
|
|
2940
|
+
* class User extends ApplicationModel {
|
|
2941
|
+
* @Deco.BeforeDestroy()
|
|
2942
|
+
* public softDelete() {
|
|
2943
|
+
* await this.update({ deletedAt: DateTime.now() })
|
|
2944
|
+
* this.preventDeletion()
|
|
2945
|
+
* }
|
|
2946
|
+
* }
|
|
2947
|
+
* ```
|
|
2948
|
+
*
|
|
2949
|
+
* @returns void
|
|
2950
|
+
*/
|
|
2951
|
+
preventDeletion() {
|
|
2952
|
+
this._preventDeletion = true;
|
|
2953
|
+
}
|
|
2954
|
+
/**
|
|
2955
|
+
* Flags a dream model so that it allows
|
|
2956
|
+
* deletion once again.
|
|
2957
|
+
*
|
|
2958
|
+
* Undoes {@link Dream.(preventDeletion:instance) | preventDeletion}
|
|
2959
|
+
*
|
|
2960
|
+
* ```ts
|
|
2961
|
+
* class User extends ApplicationModel {
|
|
2962
|
+
* @Deco.BeforeDestroy()
|
|
2963
|
+
* public async softDelete() {
|
|
2964
|
+
* await this.update({ deletedAt: DateTime.now() })
|
|
2965
|
+
* this.preventDeletion()
|
|
2966
|
+
* }
|
|
2967
|
+
*
|
|
2968
|
+
* @Deco.BeforeDestroy()
|
|
2969
|
+
* public async undoSoftDelete() {
|
|
2970
|
+
* await this.update({ deletedAt: null })
|
|
2971
|
+
* this.unpreventDeletion()
|
|
2972
|
+
* }
|
|
2973
|
+
* }
|
|
2974
|
+
* ```
|
|
2975
|
+
*
|
|
2976
|
+
* @returns void
|
|
2977
|
+
*/
|
|
2978
|
+
unpreventDeletion() {
|
|
2979
|
+
this._preventDeletion = false;
|
|
2980
|
+
return this;
|
|
2981
|
+
}
|
|
2982
|
+
_preventDeletion = false;
|
|
2983
|
+
}
|
|
2984
|
+
exports.default = Dream;
|