@db3.ai/app 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +31 -0
- package/README.md +241 -0
- package/agent-instructions.md +69 -0
- package/bin/db3-agents.mjs +140 -0
- package/bin/db3.mjs +11 -0
- package/dist/ai/AIErrors.d.ts +33 -0
- package/dist/ai/AIErrors.js +43 -0
- package/dist/ai/AIFailover.d.ts +25 -0
- package/dist/ai/AIFailover.js +96 -0
- package/dist/ai/AIProviders.d.ts +35 -0
- package/dist/ai/AIProviders.js +197 -0
- package/dist/ai/AIQuotaDeferredError.d.ts +19 -0
- package/dist/ai/AIQuotaDeferredError.js +25 -0
- package/dist/ai/AIRateLimiter.d.ts +103 -0
- package/dist/ai/AIRateLimiter.js +690 -0
- package/dist/ai/Agent.d.ts +633 -0
- package/dist/ai/Agent.js +2976 -0
- package/dist/ai/AgentHistory.d.ts +11 -0
- package/dist/ai/AgentHistory.js +495 -0
- package/dist/ai/AgentRunJob.d.ts +21 -0
- package/dist/ai/AgentRunJob.js +53 -0
- package/dist/ai/Ai.d.ts +375 -0
- package/dist/ai/Ai.js +1771 -0
- package/dist/ai/AiConversation.d.ts +17 -0
- package/dist/ai/AiConversation.js +38 -0
- package/dist/ai/AiExecutionContext.d.ts +7 -0
- package/dist/ai/AiExecutionContext.js +16 -0
- package/dist/ai/AiMessage.d.ts +43 -0
- package/dist/ai/AiMessage.js +105 -0
- package/dist/ai/AiRateLimitBucket.d.ts +69 -0
- package/dist/ai/AiRateLimitBucket.js +138 -0
- package/dist/ai/AiRateLimitReservation.d.ts +56 -0
- package/dist/ai/AiRateLimitReservation.js +101 -0
- package/dist/ai/AiRequest.d.ts +78 -0
- package/dist/ai/AiRequest.js +384 -0
- package/dist/ai/Estimates.d.ts +26 -0
- package/dist/ai/Estimates.js +34 -0
- package/dist/ai/Models.d.ts +88 -0
- package/dist/ai/Models.js +328 -0
- package/dist/ai/OpenAIProviderError.d.ts +30 -0
- package/dist/ai/OpenAIProviderError.js +77 -0
- package/dist/ai/OpenAIQuotaRetry.d.ts +27 -0
- package/dist/ai/OpenAIQuotaRetry.js +144 -0
- package/dist/ai/ProviderCosts.d.ts +55 -0
- package/dist/ai/ProviderCosts.js +108 -0
- package/dist/ai/ResponsesProviderCall.d.ts +13 -0
- package/dist/ai/ResponsesProviderCall.js +29 -0
- package/dist/ai/agentCitations.d.ts +27 -0
- package/dist/ai/agentCitations.js +153 -0
- package/dist/ai/contracts/AI.d.ts +347 -0
- package/dist/ai/contracts/AI.js +13 -0
- package/dist/ai/contracts/Agent.d.ts +476 -0
- package/dist/ai/contracts/Agent.js +1 -0
- package/dist/ai/contracts/AiRequestRunCostSummary.d.ts +31 -0
- package/dist/ai/contracts/AiRequestRunCostSummary.js +1 -0
- package/dist/ai/contracts/Pricing.d.ts +88 -0
- package/dist/ai/contracts/Pricing.js +1 -0
- package/dist/ai/contracts/Providers.d.ts +68 -0
- package/dist/ai/contracts/Providers.js +1 -0
- package/dist/ai/contracts/QuotaRetry.d.ts +38 -0
- package/dist/ai/contracts/QuotaRetry.js +1 -0
- package/dist/ai/contracts/RateLimits.d.ts +45 -0
- package/dist/ai/contracts/RateLimits.js +1 -0
- package/dist/ai/contracts/ResponsesProviderCall.d.ts +28 -0
- package/dist/ai/contracts/ResponsesProviderCall.js +1 -0
- package/dist/ai/contracts/index.d.ts +8 -0
- package/dist/ai/contracts/index.js +8 -0
- package/dist/ai/index.d.ts +27 -0
- package/dist/ai/index.js +27 -0
- package/dist/ai/registry.d.ts +28 -0
- package/dist/ai/registry.js +49 -0
- package/dist/ai/sdkNodeCompatibility.d.ts +76 -0
- package/dist/ai/toolCallRecovery.d.ts +16 -0
- package/dist/ai/toolCallRecovery.js +71 -0
- package/dist/ai/toolHelpers.d.ts +65 -0
- package/dist/ai/toolHelpers.js +106 -0
- package/dist/auth/Auth.d.ts +641 -0
- package/dist/auth/Auth.js +927 -0
- package/dist/auth/AuthProvider.d.ts +104 -0
- package/dist/auth/AuthProvider.js +185 -0
- package/dist/auth/AuthToken.d.ts +123 -0
- package/dist/auth/AuthToken.js +156 -0
- package/dist/auth/PasswordResetToken.d.ts +33 -0
- package/dist/auth/PasswordResetToken.js +64 -0
- package/dist/auth/UserIdentity.d.ts +46 -0
- package/dist/auth/UserIdentity.js +72 -0
- package/dist/auth/contracts/AuthProviderDriver.d.ts +94 -0
- package/dist/auth/contracts/AuthProviderDriver.js +1 -0
- package/dist/auth/contracts/index.d.ts +1 -0
- package/dist/auth/contracts/index.js +1 -0
- package/dist/auth/index.d.ts +8 -0
- package/dist/auth/index.js +8 -0
- package/dist/auth/passwordHash.d.ts +26 -0
- package/dist/auth/passwordHash.js +96 -0
- package/dist/auth/providers/GoogleAuthProvider.d.ts +135 -0
- package/dist/auth/providers/GoogleAuthProvider.js +305 -0
- package/dist/auth/providers/PasswordAuthProvider.d.ts +115 -0
- package/dist/auth/providers/PasswordAuthProvider.js +195 -0
- package/dist/auth/providers/index.d.ts +3 -0
- package/dist/auth/providers/index.js +3 -0
- package/dist/auth/providers/resolveAuthProviders.d.ts +29 -0
- package/dist/auth/providers/resolveAuthProviders.js +111 -0
- package/dist/cache/Cache.d.ts +67 -0
- package/dist/cache/Cache.js +115 -0
- package/dist/cache/contracts/CacheDriver.d.ts +10 -0
- package/dist/cache/contracts/CacheDriver.js +1 -0
- package/dist/cache/contracts/CacheOperations.d.ts +26 -0
- package/dist/cache/contracts/CacheOperations.js +1 -0
- package/dist/cache/contracts/CacheOptions.d.ts +51 -0
- package/dist/cache/contracts/CacheOptions.js +1 -0
- package/dist/cache/contracts/CacheRepository.d.ts +45 -0
- package/dist/cache/contracts/CacheRepository.js +1 -0
- package/dist/cache/contracts/index.d.ts +4 -0
- package/dist/cache/contracts/index.js +4 -0
- package/dist/cache/drivers/CacheManagerDriver.d.ts +55 -0
- package/dist/cache/drivers/CacheManagerDriver.js +68 -0
- package/dist/cache/drivers/createCacheDriver.d.ts +8 -0
- package/dist/cache/drivers/createCacheDriver.js +147 -0
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.js +2 -0
- package/dist/cli/Cli.d.ts +17 -0
- package/dist/cli/Cli.js +120 -0
- package/dist/cli/commands/repl.d.ts +9 -0
- package/dist/cli/commands/repl.js +27 -0
- package/dist/cli/contracts/CliCommand.d.ts +30 -0
- package/dist/cli/contracts/CliCommand.js +1 -0
- package/dist/cli/contracts/CliConfig.d.ts +9 -0
- package/dist/cli/contracts/CliConfig.js +1 -0
- package/dist/cli/contracts/CliOptions.d.ts +13 -0
- package/dist/cli/contracts/CliOptions.js +1 -0
- package/dist/cli/contracts/CommandDefinition.d.ts +18 -0
- package/dist/cli/contracts/CommandDefinition.js +1 -0
- package/dist/cli/contracts/ReplOptions.d.ts +11 -0
- package/dist/cli/contracts/ReplOptions.js +1 -0
- package/dist/cli/contracts/index.d.ts +5 -0
- package/dist/cli/contracts/index.js +1 -0
- package/dist/cli/defineCommand.d.ts +10 -0
- package/dist/cli/defineCommand.js +25 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +5 -0
- package/dist/cli/runDb3.d.ts +11 -0
- package/dist/cli/runDb3.js +70 -0
- package/dist/cli/runRepl.d.ts +12 -0
- package/dist/cli/runRepl.js +54 -0
- package/dist/config/Config.d.ts +48 -0
- package/dist/config/Config.js +80 -0
- package/dist/config/env.d.ts +26 -0
- package/dist/config/env.js +117 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +2 -0
- package/dist/db/ActiveProjection.d.ts +90 -0
- package/dist/db/ActiveProjection.js +134 -0
- package/dist/db/ActiveQueryBuilder.d.ts +268 -0
- package/dist/db/ActiveQueryBuilder.js +621 -0
- package/dist/db/ActiveRecord.d.ts +483 -0
- package/dist/db/ActiveRecord.js +765 -0
- package/dist/db/Database.d.ts +277 -0
- package/dist/db/Database.js +827 -0
- package/dist/db/FieldType.d.ts +540 -0
- package/dist/db/FieldType.js +706 -0
- package/dist/db/SoftDeletes.d.ts +30 -0
- package/dist/db/SoftDeletes.js +93 -0
- package/dist/db/commands/check.d.ts +6 -0
- package/dist/db/commands/check.js +8 -0
- package/dist/db/commands/index.d.ts +6 -0
- package/dist/db/commands/index.js +17 -0
- package/dist/db/commands/makeMigration.d.ts +7 -0
- package/dist/db/commands/makeMigration.js +9 -0
- package/dist/db/commands/migrate.d.ts +6 -0
- package/dist/db/commands/migrate.js +8 -0
- package/dist/db/connection.d.ts +10 -0
- package/dist/db/connection.js +55 -0
- package/dist/db/contracts/ActiveRecordDefinition.d.ts +64 -0
- package/dist/db/contracts/ActiveRecordDefinition.js +1 -0
- package/dist/db/contracts/DatabaseBackup.d.ts +7 -0
- package/dist/db/contracts/DatabaseBackup.js +1 -0
- package/dist/db/contracts/DatabaseMigrationsConfig.d.ts +9 -0
- package/dist/db/contracts/DatabaseMigrationsConfig.js +1 -0
- package/dist/db/contracts/index.d.ts +3 -0
- package/dist/db/contracts/index.js +3 -0
- package/dist/db/dialects/columnTypes.d.ts +20 -0
- package/dist/db/dialects/columnTypes.js +67 -0
- package/dist/db/dialects/index.d.ts +6 -0
- package/dist/db/dialects/index.js +6 -0
- package/dist/db/dialects/mariadb.d.ts +7 -0
- package/dist/db/dialects/mariadb.js +35 -0
- package/dist/db/dialects/mysql.d.ts +14 -0
- package/dist/db/dialects/mysql.js +203 -0
- package/dist/db/dialects/postgres.d.ts +5 -0
- package/dist/db/dialects/postgres.js +106 -0
- package/dist/db/dialects/resolveDialect.d.ts +14 -0
- package/dist/db/dialects/resolveDialect.js +57 -0
- package/dist/db/dialects/types.d.ts +44 -0
- package/dist/db/dialects/types.js +1 -0
- package/dist/db/errors.d.ts +15 -0
- package/dist/db/errors.js +20 -0
- package/dist/db/fields/BooleanField.d.ts +29 -0
- package/dist/db/fields/BooleanField.js +89 -0
- package/dist/db/fields/CharUuidField.d.ts +29 -0
- package/dist/db/fields/CharUuidField.js +63 -0
- package/dist/db/fields/ChoiceStringField.d.ts +25 -0
- package/dist/db/fields/ChoiceStringField.js +58 -0
- package/dist/db/fields/DecimalField.d.ts +20 -0
- package/dist/db/fields/DecimalField.js +105 -0
- package/dist/db/fields/EmailField.d.ts +31 -0
- package/dist/db/fields/EmailField.js +52 -0
- package/dist/db/fields/EncryptedJsonField.d.ts +82 -0
- package/dist/db/fields/EncryptedJsonField.js +169 -0
- package/dist/db/fields/IntegerField.d.ts +35 -0
- package/dist/db/fields/IntegerField.js +139 -0
- package/dist/db/fields/JsonField.d.ts +40 -0
- package/dist/db/fields/JsonField.js +79 -0
- package/dist/db/fields/JsonStringField.d.ts +21 -0
- package/dist/db/fields/JsonStringField.js +41 -0
- package/dist/db/fields/LinkField.d.ts +180 -0
- package/dist/db/fields/LinkField.js +359 -0
- package/dist/db/fields/PasswordField.d.ts +93 -0
- package/dist/db/fields/PasswordField.js +180 -0
- package/dist/db/fields/StringField.d.ts +43 -0
- package/dist/db/fields/StringField.js +102 -0
- package/dist/db/fields/StringListField.d.ts +54 -0
- package/dist/db/fields/StringListField.js +124 -0
- package/dist/db/fields/TextField.d.ts +25 -0
- package/dist/db/fields/TextField.js +44 -0
- package/dist/db/fields/TimestampField.d.ts +47 -0
- package/dist/db/fields/TimestampField.js +97 -0
- package/dist/db/fields/UlidField.d.ts +69 -0
- package/dist/db/fields/UlidField.js +114 -0
- package/dist/db/fields/UrlField.d.ts +30 -0
- package/dist/db/fields/UrlField.js +61 -0
- package/dist/db/fields/VectorField.d.ts +64 -0
- package/dist/db/fields/VectorField.js +180 -0
- package/dist/db/fields/createField.d.ts +2 -0
- package/dist/db/fields/createField.js +13 -0
- package/dist/db/fields/field.d.ts +36 -0
- package/dist/db/fields/field.js +101 -0
- package/dist/db/fields/index.d.ts +18 -0
- package/dist/db/fields/index.js +18 -0
- package/dist/db/fields/resolveFields.d.ts +17 -0
- package/dist/db/fields/resolveFields.js +38 -0
- package/dist/db/index.d.ts +13 -0
- package/dist/db/index.js +13 -0
- package/dist/db/migrations/DatabaseMigrationManager.d.ts +57 -0
- package/dist/db/migrations/DatabaseMigrationManager.js +589 -0
- package/dist/db/migrations/DatabaseSchemaInspector.d.ts +19 -0
- package/dist/db/migrations/DatabaseSchemaInspector.js +384 -0
- package/dist/db/migrations/KnexMigrationRenderer.d.ts +11 -0
- package/dist/db/migrations/KnexMigrationRenderer.js +390 -0
- package/dist/db/migrations/ModelSchemaCollector.d.ts +29 -0
- package/dist/db/migrations/ModelSchemaCollector.js +183 -0
- package/dist/db/migrations/SchemaDiffer.d.ts +13 -0
- package/dist/db/migrations/SchemaDiffer.js +427 -0
- package/dist/db/migrations/SchemaNames.d.ts +27 -0
- package/dist/db/migrations/SchemaNames.js +46 -0
- package/dist/db/migrations/SchemaSnapshotSerializer.d.ts +30 -0
- package/dist/db/migrations/SchemaSnapshotSerializer.js +49 -0
- package/dist/db/migrations/contracts/DatabaseMigration.d.ts +118 -0
- package/dist/db/migrations/contracts/DatabaseMigration.js +1 -0
- package/dist/db/migrations/contracts/SchemaChange.d.ts +83 -0
- package/dist/db/migrations/contracts/SchemaChange.js +1 -0
- package/dist/db/migrations/contracts/SchemaSnapshot.d.ts +94 -0
- package/dist/db/migrations/contracts/SchemaSnapshot.js +1 -0
- package/dist/db/migrations/contracts/index.d.ts +3 -0
- package/dist/db/migrations/contracts/index.js +3 -0
- package/dist/db/migrations/errors.d.ts +35 -0
- package/dist/db/migrations/errors.js +45 -0
- package/dist/db/migrations/index.d.ts +10 -0
- package/dist/db/migrations/index.js +10 -0
- package/dist/db/migrations/promoteDestructiveSchemaChanges.d.ts +19 -0
- package/dist/db/migrations/promoteDestructiveSchemaChanges.js +102 -0
- package/dist/db/queryMonitor.d.ts +142 -0
- package/dist/db/queryMonitor.js +357 -0
- package/dist/db/sqlErrors.d.ts +11 -0
- package/dist/db/sqlErrors.js +17 -0
- package/dist/db/test/db.d.ts +11 -0
- package/dist/db/test/db.js +109 -0
- package/dist/devtools/HttpEventDispatcher.d.ts +19 -0
- package/dist/devtools/HttpEventDispatcher.js +180 -0
- package/dist/devtools/contracts/DevtoolsEventDispatcher.d.ts +53 -0
- package/dist/devtools/contracts/DevtoolsEventDispatcher.js +1 -0
- package/dist/devtools/contracts/index.d.ts +1 -0
- package/dist/devtools/contracts/index.js +1 -0
- package/dist/devtools/environment.d.ts +10 -0
- package/dist/devtools/environment.js +14 -0
- package/dist/devtools/index.d.ts +3 -0
- package/dist/devtools/index.js +3 -0
- package/dist/events/Events.d.ts +70 -0
- package/dist/events/Events.js +126 -0
- package/dist/events/contracts/EventConstructor.d.ts +12 -0
- package/dist/events/contracts/EventConstructor.js +1 -0
- package/dist/events/contracts/EventListener.d.ts +6 -0
- package/dist/events/contracts/EventListener.js +1 -0
- package/dist/events/contracts/EventUnsubscribe.d.ts +4 -0
- package/dist/events/contracts/EventUnsubscribe.js +1 -0
- package/dist/events/contracts/index.d.ts +3 -0
- package/dist/events/contracts/index.js +3 -0
- package/dist/events/index.d.ts +2 -0
- package/dist/events/index.js +2 -0
- package/dist/flows/FlowBlockRegistry.d.ts +39 -0
- package/dist/flows/FlowBlockRegistry.js +66 -0
- package/dist/flows/FlowCompiler.d.ts +26 -0
- package/dist/flows/FlowCompiler.js +488 -0
- package/dist/flows/FlowDefinitionError.d.ts +21 -0
- package/dist/flows/FlowDefinitionError.js +16 -0
- package/dist/flows/FlowStepJob.d.ts +28 -0
- package/dist/flows/FlowStepJob.js +31 -0
- package/dist/flows/FlowValueValidator.d.ts +32 -0
- package/dist/flows/FlowValueValidator.js +105 -0
- package/dist/flows/Flows.d.ts +102 -0
- package/dist/flows/Flows.js +871 -0
- package/dist/flows/blocks/FlowInput.d.ts +10 -0
- package/dist/flows/blocks/FlowInput.js +29 -0
- package/dist/flows/blocks/FlowOutput.d.ts +10 -0
- package/dist/flows/blocks/FlowOutput.js +29 -0
- package/dist/flows/blocks/Subflow.d.ts +10 -0
- package/dist/flows/blocks/Subflow.js +21 -0
- package/dist/flows/blocks/index.d.ts +6 -0
- package/dist/flows/blocks/index.js +8 -0
- package/dist/flows/constants.d.ts +55 -0
- package/dist/flows/constants.js +47 -0
- package/dist/flows/contracts/FlowBlock.d.ts +64 -0
- package/dist/flows/contracts/FlowBlock.js +1 -0
- package/dist/flows/contracts/FlowCompiler.d.ts +30 -0
- package/dist/flows/contracts/FlowCompiler.js +1 -0
- package/dist/flows/contracts/FlowDefinition.d.ts +118 -0
- package/dist/flows/contracts/FlowDefinition.js +1 -0
- package/dist/flows/contracts/FlowDefinitionStore.d.ts +47 -0
- package/dist/flows/contracts/FlowDefinitionStore.js +1 -0
- package/dist/flows/contracts/FlowRun.d.ts +40 -0
- package/dist/flows/contracts/FlowRun.js +1 -0
- package/dist/flows/contracts/FlowValue.d.ts +49 -0
- package/dist/flows/contracts/FlowValue.js +1 -0
- package/dist/flows/contracts/FlowsService.d.ts +37 -0
- package/dist/flows/contracts/FlowsService.js +1 -0
- package/dist/flows/contracts/index.d.ts +7 -0
- package/dist/flows/contracts/index.js +7 -0
- package/dist/flows/defineBlock.d.ts +18 -0
- package/dist/flows/defineBlock.js +19 -0
- package/dist/flows/drivers/FileFlowDefinitionStore.d.ts +53 -0
- package/dist/flows/drivers/FileFlowDefinitionStore.js +313 -0
- package/dist/flows/drivers/index.d.ts +1 -0
- package/dist/flows/drivers/index.js +1 -0
- package/dist/flows/errors.d.ts +8 -0
- package/dist/flows/errors.js +19 -0
- package/dist/flows/index.d.ts +13 -0
- package/dist/flows/index.js +13 -0
- package/dist/flows/models/FlowRun.d.ts +55 -0
- package/dist/flows/models/FlowRun.js +126 -0
- package/dist/flows/models/FlowRunEvent.d.ts +41 -0
- package/dist/flows/models/FlowRunEvent.js +85 -0
- package/dist/flows/models/FlowStepRun.d.ts +56 -0
- package/dist/flows/models/FlowStepRun.js +137 -0
- package/dist/flows/models/index.d.ts +10 -0
- package/dist/flows/models/index.js +14 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +16 -0
- package/dist/logging/Log.d.ts +66 -0
- package/dist/logging/Log.js +79 -0
- package/dist/logging/contracts/HttpExchange.d.ts +50 -0
- package/dist/logging/contracts/HttpExchange.js +1 -0
- package/dist/logging/contracts/Logger.d.ts +41 -0
- package/dist/logging/contracts/Logger.js +1 -0
- package/dist/logging/contracts/LoggerDriver.d.ts +16 -0
- package/dist/logging/contracts/LoggerDriver.js +1 -0
- package/dist/logging/contracts/LoggingOptions.d.ts +49 -0
- package/dist/logging/contracts/LoggingOptions.js +1 -0
- package/dist/logging/contracts/index.d.ts +4 -0
- package/dist/logging/contracts/index.js +4 -0
- package/dist/logging/drivers/PinoLoggerDriver.d.ts +24 -0
- package/dist/logging/drivers/PinoLoggerDriver.js +291 -0
- package/dist/logging/drivers/index.d.ts +1 -0
- package/dist/logging/drivers/index.js +1 -0
- package/dist/logging/index.d.ts +3 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/transports/DevtoolsLogTransport.d.ts +35 -0
- package/dist/logging/transports/DevtoolsLogTransport.js +96 -0
- package/dist/mail/Mail.d.ts +62 -0
- package/dist/mail/Mail.js +98 -0
- package/dist/mail/index.d.ts +4 -0
- package/dist/mail/index.js +4 -0
- package/dist/mail/transports/FileMailTransport.d.ts +12 -0
- package/dist/mail/transports/FileMailTransport.js +41 -0
- package/dist/mail/transports/MailgunTransport.d.ts +22 -0
- package/dist/mail/transports/MailgunTransport.js +57 -0
- package/dist/mail/transports/ResendTransport.d.ts +14 -0
- package/dist/mail/transports/ResendTransport.js +55 -0
- package/dist/media/MediaFile.d.ts +48 -0
- package/dist/media/MediaFile.js +104 -0
- package/dist/media/MediaItem.d.ts +47 -0
- package/dist/media/MediaItem.js +106 -0
- package/dist/media/MediaLibrary.d.ts +42 -0
- package/dist/media/MediaLibrary.js +94 -0
- package/dist/media/MediaManager.d.ts +159 -0
- package/dist/media/MediaManager.js +754 -0
- package/dist/media/constants.d.ts +27 -0
- package/dist/media/constants.js +19 -0
- package/dist/media/contracts/MediaOptions.d.ts +8 -0
- package/dist/media/contracts/MediaOptions.js +1 -0
- package/dist/media/contracts/index.d.ts +1 -0
- package/dist/media/contracts/index.js +1 -0
- package/dist/media/image/ImageReconstructionError.d.ts +15 -0
- package/dist/media/image/ImageReconstructionError.js +18 -0
- package/dist/media/image/ImageVariantRenderer.d.ts +44 -0
- package/dist/media/image/ImageVariantRenderer.js +337 -0
- package/dist/media/image/ImageVariantRequest.d.ts +28 -0
- package/dist/media/image/ImageVariantRequest.js +55 -0
- package/dist/media/image/contracts/ImageProcessor.d.ts +46 -0
- package/dist/media/image/contracts/ImageProcessor.js +1 -0
- package/dist/media/image/contracts/ImageVariant.d.ts +31 -0
- package/dist/media/image/contracts/ImageVariant.js +7 -0
- package/dist/media/image/contracts/ImageVariantCacheOptions.d.ts +20 -0
- package/dist/media/image/contracts/ImageVariantCacheOptions.js +1 -0
- package/dist/media/image/contracts/index.d.ts +3 -0
- package/dist/media/image/contracts/index.js +3 -0
- package/dist/media/image/index.d.ts +5 -0
- package/dist/media/image/index.js +5 -0
- package/dist/media/image/processors/SharpImageProcessor.d.ts +25 -0
- package/dist/media/image/processors/SharpImageProcessor.js +112 -0
- package/dist/media/image/processors/index.d.ts +1 -0
- package/dist/media/image/processors/index.js +1 -0
- package/dist/media/index.d.ts +8 -0
- package/dist/media/index.js +8 -0
- package/dist/media/types.d.ts +129 -0
- package/dist/media/types.js +1 -0
- package/dist/queue/FailedJob.d.ts +31 -0
- package/dist/queue/FailedJob.js +41 -0
- package/dist/queue/Queue.d.ts +208 -0
- package/dist/queue/Queue.js +685 -0
- package/dist/queue/QueueEvents.d.ts +31 -0
- package/dist/queue/QueueEvents.js +49 -0
- package/dist/queue/QueueRetryLaterError.d.ts +23 -0
- package/dist/queue/QueueRetryLaterError.js +34 -0
- package/dist/queue/QueueWorker.d.ts +72 -0
- package/dist/queue/QueueWorker.js +236 -0
- package/dist/queue/QueueableJob.d.ts +109 -0
- package/dist/queue/QueueableJob.js +137 -0
- package/dist/queue/QueuedJob.d.ts +31 -0
- package/dist/queue/QueuedJob.js +52 -0
- package/dist/queue/RetryPolicy.d.ts +51 -0
- package/dist/queue/RetryPolicy.js +84 -0
- package/dist/queue/commands/index.d.ts +4 -0
- package/dist/queue/commands/index.js +11 -0
- package/dist/queue/commands/makeJob.d.ts +7 -0
- package/dist/queue/commands/makeJob.js +9 -0
- package/dist/queue/console.d.ts +60 -0
- package/dist/queue/console.js +348 -0
- package/dist/queue/contracts/CreateJob.d.ts +12 -0
- package/dist/queue/contracts/CreateJob.js +1 -0
- package/dist/queue/contracts/QueueDriver.d.ts +122 -0
- package/dist/queue/contracts/QueueDriver.js +1 -0
- package/dist/queue/contracts/QueueEvents.d.ts +61 -0
- package/dist/queue/contracts/QueueEvents.js +1 -0
- package/dist/queue/contracts/QueuePayload.d.ts +136 -0
- package/dist/queue/contracts/QueuePayload.js +1 -0
- package/dist/queue/contracts/QueueRetry.d.ts +43 -0
- package/dist/queue/contracts/QueueRetry.js +1 -0
- package/dist/queue/contracts/QueueService.d.ts +199 -0
- package/dist/queue/contracts/QueueService.js +1 -0
- package/dist/queue/contracts/QueueWorkerLifecycle.d.ts +65 -0
- package/dist/queue/contracts/QueueWorkerLifecycle.js +1 -0
- package/dist/queue/contracts/QueueableJob.d.ts +50 -0
- package/dist/queue/contracts/QueueableJob.js +1 -0
- package/dist/queue/contracts/RedisQueueDriver.d.ts +37 -0
- package/dist/queue/contracts/RedisQueueDriver.js +1 -0
- package/dist/queue/contracts/index.d.ts +9 -0
- package/dist/queue/contracts/index.js +9 -0
- package/dist/queue/createJob.d.ts +18 -0
- package/dist/queue/createJob.js +52 -0
- package/dist/queue/drivers/DatabaseQueueDriver.d.ts +83 -0
- package/dist/queue/drivers/DatabaseQueueDriver.js +393 -0
- package/dist/queue/drivers/RedisQueueDriver.d.ts +102 -0
- package/dist/queue/drivers/RedisQueueDriver.js +641 -0
- package/dist/queue/index.d.ts +13 -0
- package/dist/queue/index.js +13 -0
- package/dist/queue/queueMonitor.d.ts +133 -0
- package/dist/queue/queueMonitor.js +238 -0
- package/dist/scheduler/ScheduledCall.d.ts +25 -0
- package/dist/scheduler/ScheduledCall.js +31 -0
- package/dist/scheduler/ScheduledEvent.d.ts +74 -0
- package/dist/scheduler/ScheduledEvent.js +115 -0
- package/dist/scheduler/ScheduledJob.d.ts +34 -0
- package/dist/scheduler/ScheduledJob.js +50 -0
- package/dist/scheduler/ScheduledOccurrence.d.ts +74 -0
- package/dist/scheduler/ScheduledOccurrence.js +194 -0
- package/dist/scheduler/ScheduledOccurrenceRecorder.d.ts +34 -0
- package/dist/scheduler/ScheduledOccurrenceRecorder.js +106 -0
- package/dist/scheduler/Scheduler.d.ts +76 -0
- package/dist/scheduler/Scheduler.js +186 -0
- package/dist/scheduler/SchedulerWorker.d.ts +37 -0
- package/dist/scheduler/SchedulerWorker.js +119 -0
- package/dist/scheduler/console.d.ts +18 -0
- package/dist/scheduler/console.js +288 -0
- package/dist/scheduler/constants.d.ts +13 -0
- package/dist/scheduler/constants.js +23 -0
- package/dist/scheduler/contracts/Scheduler.d.ts +104 -0
- package/dist/scheduler/contracts/Scheduler.js +1 -0
- package/dist/scheduler/contracts/SchedulerConsole.d.ts +37 -0
- package/dist/scheduler/contracts/SchedulerConsole.js +1 -0
- package/dist/scheduler/contracts/SchedulerWorker.d.ts +18 -0
- package/dist/scheduler/contracts/SchedulerWorker.js +1 -0
- package/dist/scheduler/contracts/index.d.ts +3 -0
- package/dist/scheduler/contracts/index.js +3 -0
- package/dist/scheduler/index.d.ts +9 -0
- package/dist/scheduler/index.js +9 -0
- package/dist/scheduler/scheduleTime.d.ts +30 -0
- package/dist/scheduler/scheduleTime.js +64 -0
- package/dist/security/Security.d.ts +60 -0
- package/dist/security/Security.js +252 -0
- package/dist/security/SecurityError.d.ts +13 -0
- package/dist/security/SecurityError.js +16 -0
- package/dist/security/contracts/SecurityOptions.d.ts +17 -0
- package/dist/security/contracts/SecurityOptions.js +1 -0
- package/dist/security/contracts/SecurityPayload.d.ts +13 -0
- package/dist/security/contracts/SecurityPayload.js +1 -0
- package/dist/security/contracts/index.d.ts +2 -0
- package/dist/security/contracts/index.js +2 -0
- package/dist/security/ensureAppKey.d.ts +16 -0
- package/dist/security/ensureAppKey.js +69 -0
- package/dist/security/index.d.ts +4 -0
- package/dist/security/index.js +4 -0
- package/dist/serialization/Serializable.d.ts +17 -0
- package/dist/serialization/Serializable.js +1 -0
- package/dist/serialization/SerializationError.d.ts +40 -0
- package/dist/serialization/SerializationError.js +42 -0
- package/dist/serialization/SerializationRegistry.d.ts +76 -0
- package/dist/serialization/SerializationRegistry.js +153 -0
- package/dist/serialization/SerializationRegistryError.d.ts +18 -0
- package/dist/serialization/SerializationRegistryError.js +18 -0
- package/dist/serialization/Serializer.d.ts +37 -0
- package/dist/serialization/Serializer.js +477 -0
- package/dist/serialization/contracts/SerializableClass.d.ts +20 -0
- package/dist/serialization/contracts/SerializableClass.js +1 -0
- package/dist/serialization/contracts/SerializedValue.d.ts +59 -0
- package/dist/serialization/contracts/SerializedValue.js +19 -0
- package/dist/serialization/contracts/SerializerOptions.d.ts +17 -0
- package/dist/serialization/contracts/SerializerOptions.js +1 -0
- package/dist/serialization/contracts/SerializerService.d.ts +26 -0
- package/dist/serialization/contracts/SerializerService.js +1 -0
- package/dist/serialization/contracts/index.d.ts +4 -0
- package/dist/serialization/contracts/index.js +4 -0
- package/dist/serialization/index.d.ts +6 -0
- package/dist/serialization/index.js +6 -0
- package/dist/server/App.d.ts +141 -0
- package/dist/server/App.js +225 -0
- package/dist/server/RequestContext.d.ts +42 -0
- package/dist/server/RequestContext.js +95 -0
- package/dist/server/appContext.d.ts +34 -0
- package/dist/server/appContext.js +42 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +3 -0
- package/dist/ssr/constants.d.ts +6 -0
- package/dist/ssr/constants.js +6 -0
- package/dist/ssr/contracts/DocumentHead.d.ts +32 -0
- package/dist/ssr/contracts/DocumentHead.js +1 -0
- package/dist/ssr/contracts/SsrRenderContext.d.ts +23 -0
- package/dist/ssr/contracts/SsrRenderContext.js +1 -0
- package/dist/ssr/contracts/SsrRenderResult.d.ts +21 -0
- package/dist/ssr/contracts/SsrRenderResult.js +1 -0
- package/dist/ssr/contracts/SsrRenderer.d.ts +9 -0
- package/dist/ssr/contracts/SsrRenderer.js +1 -0
- package/dist/ssr/contracts/SsrRequest.d.ts +16 -0
- package/dist/ssr/contracts/SsrRequest.js +1 -0
- package/dist/ssr/contracts/index.d.ts +5 -0
- package/dist/ssr/contracts/index.js +1 -0
- package/dist/ssr/createSsrRenderContext.d.ts +9 -0
- package/dist/ssr/createSsrRenderContext.js +20 -0
- package/dist/ssr/fastify/contracts/FastifySsrOptions.d.ts +21 -0
- package/dist/ssr/fastify/contracts/FastifySsrOptions.js +1 -0
- package/dist/ssr/fastify/contracts/index.d.ts +1 -0
- package/dist/ssr/fastify/contracts/index.js +1 -0
- package/dist/ssr/fastify/fastifySsr.d.ts +25 -0
- package/dist/ssr/fastify/fastifySsr.js +89 -0
- package/dist/ssr/fastify/index.d.ts +2 -0
- package/dist/ssr/fastify/index.js +1 -0
- package/dist/ssr/index.d.ts +6 -0
- package/dist/ssr/index.js +5 -0
- package/dist/ssr/renderDocumentHead.d.ts +8 -0
- package/dist/ssr/renderDocumentHead.js +62 -0
- package/dist/ssr/renderSsrDocument.d.ts +14 -0
- package/dist/ssr/renderSsrDocument.js +28 -0
- package/dist/ssr/serializeSsrState.d.ts +10 -0
- package/dist/ssr/serializeSsrState.js +18 -0
- package/dist/ssr/vite/contracts/ViteSsrOptions.d.ts +45 -0
- package/dist/ssr/vite/contracts/ViteSsrOptions.js +1 -0
- package/dist/ssr/vite/contracts/index.d.ts +1 -0
- package/dist/ssr/vite/contracts/index.js +1 -0
- package/dist/ssr/vite/fastifyViteSsr.d.ts +24 -0
- package/dist/ssr/vite/fastifyViteSsr.js +213 -0
- package/dist/ssr/vite/index.d.ts +4 -0
- package/dist/ssr/vite/index.js +2 -0
- package/dist/ssr/vite/viteSsrManifest.d.ts +16 -0
- package/dist/ssr/vite/viteSsrManifest.js +63 -0
- package/dist/storage/Storage.d.ts +244 -0
- package/dist/storage/Storage.js +348 -0
- package/dist/storage/contents.d.ts +8 -0
- package/dist/storage/contents.js +18 -0
- package/dist/storage/contracts/StorageListing.d.ts +50 -0
- package/dist/storage/contracts/StorageListing.js +1 -0
- package/dist/storage/contracts/index.d.ts +1 -0
- package/dist/storage/contracts/index.js +1 -0
- package/dist/storage/drivers/FlystorageDisk.d.ts +185 -0
- package/dist/storage/drivers/FlystorageDisk.js +250 -0
- package/dist/storage/drivers/FlystorageListing.d.ts +27 -0
- package/dist/storage/drivers/FlystorageListing.js +69 -0
- package/dist/storage/drivers/LocalStorageDisk.d.ts +25 -0
- package/dist/storage/drivers/LocalStorageDisk.js +38 -0
- package/dist/storage/drivers/S3StorageDisk.d.ts +17 -0
- package/dist/storage/drivers/S3StorageDisk.js +102 -0
- package/dist/storage/drivers/index.d.ts +3 -0
- package/dist/storage/drivers/index.js +3 -0
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.js +7 -0
- package/dist/storage/mime.d.ts +7 -0
- package/dist/storage/mime.js +28 -0
- package/dist/storage/path.d.ts +22 -0
- package/dist/storage/path.js +61 -0
- package/dist/storage/types.d.ts +218 -0
- package/dist/storage/types.js +1 -0
- package/dist/url/UrlGenerator.d.ts +32 -0
- package/dist/url/UrlGenerator.js +61 -0
- package/dist/url/contracts/UrlGeneratorOptions.d.ts +13 -0
- package/dist/url/contracts/UrlGeneratorOptions.js +1 -0
- package/dist/url/contracts/index.d.ts +1 -0
- package/dist/url/contracts/index.js +1 -0
- package/dist/url/index.d.ts +2 -0
- package/dist/url/index.js +2 -0
- package/dist/validation/index.d.ts +28 -0
- package/dist/validation/index.js +260 -0
- package/package.json +290 -0
- package/src/ai/AIErrors.ts +46 -0
- package/src/ai/AIFailover.ts +101 -0
- package/src/ai/AIProviders.ts +228 -0
- package/src/ai/AIQuotaDeferredError.ts +26 -0
- package/src/ai/AIRateLimiter.ts +880 -0
- package/src/ai/Agent.ts +3630 -0
- package/src/ai/AgentHistory.ts +576 -0
- package/src/ai/AgentRunJob.ts +65 -0
- package/src/ai/Ai.ts +2176 -0
- package/src/ai/AiConversation.ts +49 -0
- package/src/ai/AiExecutionContext.ts +19 -0
- package/src/ai/AiMessage.ts +131 -0
- package/src/ai/AiRateLimitBucket.ts +163 -0
- package/src/ai/AiRateLimitReservation.ts +117 -0
- package/src/ai/AiRequest.ts +466 -0
- package/src/ai/Estimates.ts +36 -0
- package/src/ai/Models.ts +373 -0
- package/src/ai/OpenAIProviderError.ts +98 -0
- package/src/ai/OpenAIQuotaRetry.ts +183 -0
- package/src/ai/ProviderCosts.ts +156 -0
- package/src/ai/README.md +187 -0
- package/src/ai/ResponsesProviderCall.ts +34 -0
- package/src/ai/agentCitations.ts +186 -0
- package/src/ai/contracts/AI.ts +380 -0
- package/src/ai/contracts/Agent.ts +539 -0
- package/src/ai/contracts/AiRequestRunCostSummary.ts +31 -0
- package/src/ai/contracts/Pricing.ts +95 -0
- package/src/ai/contracts/Providers.ts +73 -0
- package/src/ai/contracts/QuotaRetry.ts +39 -0
- package/src/ai/contracts/RateLimits.ts +49 -0
- package/src/ai/contracts/ResponsesProviderCall.ts +30 -0
- package/src/ai/contracts/index.ts +8 -0
- package/src/ai/examples/Conversation.ts +12 -0
- package/src/ai/examples/HelpAgent.ts +27 -0
- package/src/ai/examples/createHelpImage.ts +13 -0
- package/src/ai/index.ts +27 -0
- package/src/ai/registry.ts +70 -0
- package/src/ai/sdkNodeCompatibility.d.ts +76 -0
- package/src/ai/toolCallRecovery.ts +82 -0
- package/src/ai/toolHelpers.ts +145 -0
- package/src/auth/Auth.ts +1422 -0
- package/src/auth/AuthProvider.ts +251 -0
- package/src/auth/AuthToken.ts +239 -0
- package/src/auth/PasswordResetToken.ts +93 -0
- package/src/auth/README.md +396 -0
- package/src/auth/UserIdentity.ts +112 -0
- package/src/auth/contracts/AuthProviderDriver.ts +114 -0
- package/src/auth/contracts/index.ts +1 -0
- package/src/auth/examples/runPasswordAuth.ts +45 -0
- package/src/auth/index.ts +8 -0
- package/src/auth/passwordHash.ts +160 -0
- package/src/auth/providers/GoogleAuthProvider.ts +470 -0
- package/src/auth/providers/PasswordAuthProvider.ts +256 -0
- package/src/auth/providers/index.ts +3 -0
- package/src/auth/providers/resolveAuthProviders.ts +166 -0
- package/src/cache/Cache.ts +151 -0
- package/src/cache/README.md +137 -0
- package/src/cache/contracts/CacheDriver.ts +11 -0
- package/src/cache/contracts/CacheOperations.ts +28 -0
- package/src/cache/contracts/CacheOptions.ts +56 -0
- package/src/cache/contracts/CacheRepository.ts +62 -0
- package/src/cache/contracts/index.ts +4 -0
- package/src/cache/drivers/CacheManagerDriver.ts +84 -0
- package/src/cache/drivers/createCacheDriver.ts +191 -0
- package/src/cache/examples/runNoteCache.ts +37 -0
- package/src/cache/index.ts +2 -0
- package/src/cli/Cli.ts +110 -0
- package/src/cli/README.md +164 -0
- package/src/cli/commands/repl.ts +29 -0
- package/src/cli/contracts/CliCommand.ts +33 -0
- package/src/cli/contracts/CliConfig.ts +10 -0
- package/src/cli/contracts/CliOptions.ts +13 -0
- package/src/cli/contracts/CommandDefinition.ts +19 -0
- package/src/cli/contracts/ReplOptions.ts +11 -0
- package/src/cli/contracts/index.ts +5 -0
- package/src/cli/defineCommand.ts +25 -0
- package/src/cli/index.ts +5 -0
- package/src/cli/runDb3.ts +63 -0
- package/src/cli/runRepl.ts +55 -0
- package/src/config/Config.ts +110 -0
- package/src/config/README.md +142 -0
- package/src/config/env.ts +164 -0
- package/src/config/examples/loadNotesConfig.ts +29 -0
- package/src/config/examples/runConfig.ts +40 -0
- package/src/config/index.ts +2 -0
- package/src/db/ActiveProjection.ts +311 -0
- package/src/db/ActiveQueryBuilder.ts +831 -0
- package/src/db/ActiveRecord.ts +1317 -0
- package/src/db/Database.ts +1283 -0
- package/src/db/FieldType.ts +1243 -0
- package/src/db/README.md +508 -0
- package/src/db/SoftDeletes.ts +158 -0
- package/src/db/commands/check.ts +10 -0
- package/src/db/commands/index.ts +19 -0
- package/src/db/commands/makeMigration.ts +11 -0
- package/src/db/commands/migrate.ts +10 -0
- package/src/db/connection.ts +68 -0
- package/src/db/contracts/ActiveRecordDefinition.ts +69 -0
- package/src/db/contracts/DatabaseBackup.ts +7 -0
- package/src/db/contracts/DatabaseMigrationsConfig.ts +10 -0
- package/src/db/contracts/index.ts +3 -0
- package/src/db/dialects/columnTypes.ts +103 -0
- package/src/db/dialects/index.ts +6 -0
- package/src/db/dialects/mariadb.ts +51 -0
- package/src/db/dialects/mysql.ts +277 -0
- package/src/db/dialects/postgres.ts +143 -0
- package/src/db/dialects/resolveDialect.ts +88 -0
- package/src/db/dialects/types.ts +59 -0
- package/src/db/errors.ts +22 -0
- package/src/db/examples/DefinedUser.ts +20 -0
- package/src/db/examples/FieldNote.ts +27 -0
- package/src/db/examples/KnowledgeNote.ts +29 -0
- package/src/db/examples/NoteCodeField.ts +9 -0
- package/src/db/examples/createNotesTogether.ts +24 -0
- package/src/db/examples/outputs/workspace-notes.json +9 -0
- package/src/db/examples/runFieldNotes.ts +51 -0
- package/src/db/examples/runNoteMigrations.ts +64 -0
- package/src/db/examples/runWorkspaceNotes.ts +86 -0
- package/src/db/examples/workspaceNotes.ts +57 -0
- package/src/db/fields/BooleanField.ts +128 -0
- package/src/db/fields/CharUuidField.ts +91 -0
- package/src/db/fields/ChoiceStringField.ts +97 -0
- package/src/db/fields/DecimalField.ts +157 -0
- package/src/db/fields/EmailField.ts +79 -0
- package/src/db/fields/EncryptedJsonField.ts +211 -0
- package/src/db/fields/IntegerField.ts +200 -0
- package/src/db/fields/JsonField.ts +108 -0
- package/src/db/fields/JsonStringField.ts +63 -0
- package/src/db/fields/LinkField.ts +502 -0
- package/src/db/fields/PasswordField.ts +294 -0
- package/src/db/fields/StringField.ts +154 -0
- package/src/db/fields/StringListField.ts +179 -0
- package/src/db/fields/TextField.ts +71 -0
- package/src/db/fields/TimestampField.ts +164 -0
- package/src/db/fields/UlidField.ts +189 -0
- package/src/db/fields/UrlField.ts +97 -0
- package/src/db/fields/VectorField.ts +266 -0
- package/src/db/fields/createField.ts +22 -0
- package/src/db/fields/field.ts +209 -0
- package/src/db/fields/index.ts +76 -0
- package/src/db/fields/resolveFields.ts +69 -0
- package/src/db/index.ts +13 -0
- package/src/db/migrations/DatabaseMigrationManager.ts +756 -0
- package/src/db/migrations/DatabaseSchemaInspector.ts +541 -0
- package/src/db/migrations/KnexMigrationRenderer.ts +490 -0
- package/src/db/migrations/ModelSchemaCollector.ts +240 -0
- package/src/db/migrations/SchemaDiffer.ts +541 -0
- package/src/db/migrations/SchemaNames.ts +62 -0
- package/src/db/migrations/SchemaSnapshotSerializer.ts +59 -0
- package/src/db/migrations/contracts/DatabaseMigration.ts +143 -0
- package/src/db/migrations/contracts/SchemaChange.ts +113 -0
- package/src/db/migrations/contracts/SchemaSnapshot.ts +122 -0
- package/src/db/migrations/contracts/index.ts +3 -0
- package/src/db/migrations/errors.ts +45 -0
- package/src/db/migrations/index.ts +10 -0
- package/src/db/migrations/promoteDestructiveSchemaChanges.ts +120 -0
- package/src/db/queryMonitor.ts +549 -0
- package/src/db/sqlErrors.ts +36 -0
- package/src/db/test/db.ts +159 -0
- package/src/devtools/HttpEventDispatcher.ts +214 -0
- package/src/devtools/contracts/DevtoolsEventDispatcher.ts +57 -0
- package/src/devtools/contracts/index.ts +1 -0
- package/src/devtools/environment.ts +18 -0
- package/src/devtools/index.ts +3 -0
- package/src/events/Events.ts +165 -0
- package/src/events/README.md +106 -0
- package/src/events/contracts/EventConstructor.ts +12 -0
- package/src/events/contracts/EventListener.ts +8 -0
- package/src/events/contracts/EventUnsubscribe.ts +4 -0
- package/src/events/contracts/index.ts +3 -0
- package/src/events/examples/NoteSaved.ts +9 -0
- package/src/events/examples/runNoteEvents.ts +31 -0
- package/src/events/index.ts +2 -0
- package/src/flows/FlowBlockRegistry.ts +79 -0
- package/src/flows/FlowCompiler.ts +624 -0
- package/src/flows/FlowDefinitionError.ts +24 -0
- package/src/flows/FlowStepJob.ts +54 -0
- package/src/flows/FlowValueValidator.ts +120 -0
- package/src/flows/Flows.ts +1118 -0
- package/src/flows/README.md +144 -0
- package/src/flows/blocks/FlowInput.ts +32 -0
- package/src/flows/blocks/FlowOutput.ts +32 -0
- package/src/flows/blocks/Subflow.ts +24 -0
- package/src/flows/blocks/index.ts +11 -0
- package/src/flows/constants.ts +62 -0
- package/src/flows/contracts/FlowBlock.ts +73 -0
- package/src/flows/contracts/FlowCompiler.ts +32 -0
- package/src/flows/contracts/FlowDefinition.ts +126 -0
- package/src/flows/contracts/FlowDefinitionStore.ts +52 -0
- package/src/flows/contracts/FlowRun.ts +44 -0
- package/src/flows/contracts/FlowValue.ts +54 -0
- package/src/flows/contracts/FlowsService.ts +39 -0
- package/src/flows/contracts/index.ts +7 -0
- package/src/flows/defineBlock.ts +25 -0
- package/src/flows/drivers/FileFlowDefinitionStore.ts +372 -0
- package/src/flows/drivers/index.ts +1 -0
- package/src/flows/errors.ts +22 -0
- package/src/flows/examples/FlowExampleApp.ts +15 -0
- package/src/flows/examples/createTextFlow.ts +14 -0
- package/src/flows/examples/normalizeTextBlock.ts +15 -0
- package/src/flows/examples/runTextFlow.ts +46 -0
- package/src/flows/examples/uppercaseTextBlock.ts +11 -0
- package/src/flows/index.ts +13 -0
- package/src/flows/models/FlowRun.ts +164 -0
- package/src/flows/models/FlowRunEvent.ts +108 -0
- package/src/flows/models/FlowStepRun.ts +176 -0
- package/src/flows/models/index.ts +16 -0
- package/src/index.ts +40 -0
- package/src/logging/Log.ts +100 -0
- package/src/logging/README.md +139 -0
- package/src/logging/contracts/HttpExchange.ts +53 -0
- package/src/logging/contracts/Logger.ts +45 -0
- package/src/logging/contracts/LoggerDriver.ts +19 -0
- package/src/logging/contracts/LoggingOptions.ts +51 -0
- package/src/logging/contracts/index.ts +4 -0
- package/src/logging/drivers/PinoLoggerDriver.ts +376 -0
- package/src/logging/drivers/index.ts +1 -0
- package/src/logging/examples/runNoteLogs.ts +38 -0
- package/src/logging/index.ts +3 -0
- package/src/logging/transports/DevtoolsLogTransport.ts +142 -0
- package/src/mail/Mail.ts +188 -0
- package/src/mail/README.md +206 -0
- package/src/mail/examples/runMailPreview.ts +44 -0
- package/src/mail/examples/welcomeMessage.ts +26 -0
- package/src/mail/index.ts +4 -0
- package/src/mail/transports/FileMailTransport.ts +58 -0
- package/src/mail/transports/MailgunTransport.ts +85 -0
- package/src/mail/transports/ResendTransport.ts +80 -0
- package/src/media/MediaFile.ts +132 -0
- package/src/media/MediaItem.ts +132 -0
- package/src/media/MediaLibrary.ts +117 -0
- package/src/media/MediaManager.ts +874 -0
- package/src/media/README.md +358 -0
- package/src/media/constants.ts +31 -0
- package/src/media/contracts/MediaOptions.ts +9 -0
- package/src/media/contracts/index.ts +1 -0
- package/src/media/examples/createPrivateFileServer.ts +55 -0
- package/src/media/examples/runPrivateFiles.ts +45 -0
- package/src/media/examples/runProjectMedia.ts +46 -0
- package/src/media/image/ImageReconstructionError.ts +18 -0
- package/src/media/image/ImageVariantRenderer.ts +386 -0
- package/src/media/image/ImageVariantRequest.ts +65 -0
- package/src/media/image/contracts/ImageProcessor.ts +53 -0
- package/src/media/image/contracts/ImageVariant.ts +37 -0
- package/src/media/image/contracts/ImageVariantCacheOptions.ts +21 -0
- package/src/media/image/contracts/index.ts +3 -0
- package/src/media/image/index.ts +5 -0
- package/src/media/image/processors/SharpImageProcessor.ts +121 -0
- package/src/media/image/processors/index.ts +1 -0
- package/src/media/index.ts +8 -0
- package/src/media/types.ts +168 -0
- package/src/queue/FailedJob.ts +58 -0
- package/src/queue/Queue.ts +938 -0
- package/src/queue/QueueEvents.ts +57 -0
- package/src/queue/QueueRetryLaterError.ts +40 -0
- package/src/queue/QueueWorker.ts +296 -0
- package/src/queue/QueueableJob.ts +167 -0
- package/src/queue/QueuedJob.ts +69 -0
- package/src/queue/README.md +368 -0
- package/src/queue/RetryPolicy.ts +129 -0
- package/src/queue/commands/index.ts +13 -0
- package/src/queue/commands/makeJob.ts +11 -0
- package/src/queue/console.ts +518 -0
- package/src/queue/contracts/CreateJob.ts +13 -0
- package/src/queue/contracts/QueueDriver.ts +135 -0
- package/src/queue/contracts/QueueEvents.ts +77 -0
- package/src/queue/contracts/QueuePayload.ts +150 -0
- package/src/queue/contracts/QueueRetry.ts +47 -0
- package/src/queue/contracts/QueueService.ts +219 -0
- package/src/queue/contracts/QueueWorkerLifecycle.ts +71 -0
- package/src/queue/contracts/QueueableJob.ts +56 -0
- package/src/queue/contracts/RedisQueueDriver.ts +37 -0
- package/src/queue/contracts/index.ts +9 -0
- package/src/queue/createJob.ts +54 -0
- package/src/queue/drivers/DatabaseQueueDriver.ts +449 -0
- package/src/queue/drivers/RedisQueueDriver.ts +733 -0
- package/src/queue/examples/DeferredReportJob.ts +25 -0
- package/src/queue/examples/GenerateReportJob.ts +37 -0
- package/src/queue/examples/WriteReportJob.ts +37 -0
- package/src/queue/examples/createAndProcessReportJob.ts +29 -0
- package/src/queue/examples/dispatchReportWorkflows.ts +40 -0
- package/src/queue/examples/manageReportRetries.ts +47 -0
- package/src/queue/examples/outputs/create-and-process-report-job.json +6 -0
- package/src/queue/examples/outputs/dispatch-report-workflows.json +14 -0
- package/src/queue/examples/outputs/manage-report-retries.json +24 -0
- package/src/queue/examples/outputs/queue-reports.json +11 -0
- package/src/queue/examples/reportConsole.ts +47 -0
- package/src/queue/examples/runBackpressure.ts +27 -0
- package/src/queue/examples/runQueueReports.ts +80 -0
- package/src/queue/examples/runQueueWorkflows.ts +43 -0
- package/src/queue/index.ts +13 -0
- package/src/queue/queueMonitor.ts +368 -0
- package/src/scheduler/README.md +139 -0
- package/src/scheduler/ScheduledCall.ts +36 -0
- package/src/scheduler/ScheduledEvent.ts +149 -0
- package/src/scheduler/ScheduledJob.ts +58 -0
- package/src/scheduler/ScheduledOccurrence.ts +250 -0
- package/src/scheduler/ScheduledOccurrenceRecorder.ts +125 -0
- package/src/scheduler/Scheduler.ts +225 -0
- package/src/scheduler/SchedulerWorker.ts +151 -0
- package/src/scheduler/console.ts +368 -0
- package/src/scheduler/constants.ts +27 -0
- package/src/scheduler/contracts/Scheduler.ts +123 -0
- package/src/scheduler/contracts/SchedulerConsole.ts +40 -0
- package/src/scheduler/contracts/SchedulerWorker.ts +23 -0
- package/src/scheduler/contracts/index.ts +3 -0
- package/src/scheduler/examples/RecoverableSummaryJob.ts +18 -0
- package/src/scheduler/examples/WriteDailySummaryJob.ts +17 -0
- package/src/scheduler/examples/registerDailySummary.ts +13 -0
- package/src/scheduler/examples/runDailySummary.ts +46 -0
- package/src/scheduler/examples/runScheduledReplay.ts +60 -0
- package/src/scheduler/index.ts +9 -0
- package/src/scheduler/scheduleTime.ts +78 -0
- package/src/security/README.md +130 -0
- package/src/security/Security.ts +346 -0
- package/src/security/SecurityError.ts +16 -0
- package/src/security/contracts/SecurityOptions.ts +20 -0
- package/src/security/contracts/SecurityPayload.ts +14 -0
- package/src/security/contracts/index.ts +2 -0
- package/src/security/ensureAppKey.ts +82 -0
- package/src/security/examples/runSecretRoundTrip.ts +42 -0
- package/src/security/index.ts +4 -0
- package/src/serialization/README.md +169 -0
- package/src/serialization/Serializable.ts +17 -0
- package/src/serialization/SerializationError.ts +91 -0
- package/src/serialization/SerializationRegistry.ts +208 -0
- package/src/serialization/SerializationRegistryError.ts +24 -0
- package/src/serialization/Serializer.ts +793 -0
- package/src/serialization/contracts/SerializableClass.ts +26 -0
- package/src/serialization/contracts/SerializedValue.ts +71 -0
- package/src/serialization/contracts/SerializerOptions.ts +19 -0
- package/src/serialization/contracts/SerializerService.ts +29 -0
- package/src/serialization/contracts/index.ts +4 -0
- package/src/serialization/examples/ExportRequest.ts +25 -0
- package/src/serialization/examples/runExportSerialization.ts +24 -0
- package/src/serialization/index.ts +6 -0
- package/src/server/App.ts +326 -0
- package/src/server/README.md +219 -0
- package/src/server/RequestContext.ts +122 -0
- package/src/server/appContext.ts +59 -0
- package/src/server/examples/createFirstServer.ts +25 -0
- package/src/server/examples/startFirstServer.ts +19 -0
- package/src/server/index.ts +16 -0
- package/src/ssr/README.md +158 -0
- package/src/ssr/constants.ts +8 -0
- package/src/ssr/contracts/DocumentHead.ts +35 -0
- package/src/ssr/contracts/SsrRenderContext.ts +25 -0
- package/src/ssr/contracts/SsrRenderResult.ts +23 -0
- package/src/ssr/contracts/SsrRenderer.ts +12 -0
- package/src/ssr/contracts/SsrRequest.ts +17 -0
- package/src/ssr/contracts/index.ts +19 -0
- package/src/ssr/createSsrRenderContext.ts +25 -0
- package/src/ssr/examples/createPublicPageServer.ts +32 -0
- package/src/ssr/examples/runPublicPages.ts +25 -0
- package/src/ssr/fastify/contracts/FastifySsrOptions.ts +24 -0
- package/src/ssr/fastify/contracts/index.ts +5 -0
- package/src/ssr/fastify/fastifySsr.ts +110 -0
- package/src/ssr/fastify/index.ts +2 -0
- package/src/ssr/index.ts +10 -0
- package/src/ssr/renderDocumentHead.ts +72 -0
- package/src/ssr/renderSsrDocument.ts +35 -0
- package/src/ssr/serializeSsrState.ts +19 -0
- package/src/ssr/vite/contracts/ViteSsrOptions.ts +52 -0
- package/src/ssr/vite/contracts/index.ts +6 -0
- package/src/ssr/vite/fastifyViteSsr.ts +279 -0
- package/src/ssr/vite/index.ts +4 -0
- package/src/ssr/vite/viteSsrManifest.ts +92 -0
- package/src/storage/README.md +310 -0
- package/src/storage/Storage.ts +392 -0
- package/src/storage/contents.ts +23 -0
- package/src/storage/contracts/StorageListing.ts +55 -0
- package/src/storage/contracts/index.ts +1 -0
- package/src/storage/drivers/FlystorageDisk.ts +295 -0
- package/src/storage/drivers/FlystorageListing.ts +78 -0
- package/src/storage/drivers/LocalStorageDisk.ts +45 -0
- package/src/storage/drivers/S3StorageDisk.ts +114 -0
- package/src/storage/drivers/index.ts +3 -0
- package/src/storage/examples/runStorage.ts +37 -0
- package/src/storage/examples/runStreamExport.ts +41 -0
- package/src/storage/examples/writeCsvExport.ts +45 -0
- package/src/storage/index.ts +7 -0
- package/src/storage/mime.ts +30 -0
- package/src/storage/path.ts +76 -0
- package/src/storage/types.ts +251 -0
- package/src/url/README.md +41 -0
- package/src/url/UrlGenerator.ts +72 -0
- package/src/url/contracts/UrlGeneratorOptions.ts +14 -0
- package/src/url/contracts/index.ts +1 -0
- package/src/url/examples/runApplicationLinks.ts +33 -0
- package/src/url/index.ts +2 -0
- package/src/validation/README.md +433 -0
- package/src/validation/examples/runNoteValidation.ts +18 -0
- package/src/validation/examples/validateNoteInput.ts +31 -0
- package/src/validation/index.ts +398 -0
- package/templates/AGENTS.md +15 -0
|
@@ -0,0 +1,1317 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
import { isRecord, recordFromUnknown } from '@db3.ai/pure';
|
|
4
|
+
|
|
5
|
+
import { databaseDialectForConnection } from './dialects';
|
|
6
|
+
import {
|
|
7
|
+
DbRow,
|
|
8
|
+
DbWriteData,
|
|
9
|
+
DomFormRenderSpec,
|
|
10
|
+
FieldError,
|
|
11
|
+
type FieldClass,
|
|
12
|
+
type FieldDbValue,
|
|
13
|
+
type FieldDefinition,
|
|
14
|
+
type FieldDisplayValue,
|
|
15
|
+
type FieldMap,
|
|
16
|
+
type FieldInputMap,
|
|
17
|
+
type FieldInputValue,
|
|
18
|
+
FieldType,
|
|
19
|
+
type FieldValue,
|
|
20
|
+
FrontendComponentSpec,
|
|
21
|
+
RecordValidationError,
|
|
22
|
+
type DbWriteOptions,
|
|
23
|
+
} from './FieldType';
|
|
24
|
+
import { ActiveQueryBuilder } from './ActiveQueryBuilder';
|
|
25
|
+
import { db as defaultDb } from './connection';
|
|
26
|
+
import { resolveModelFields } from './fields/resolveFields';
|
|
27
|
+
import {
|
|
28
|
+
getAutomaticUpdateTimestampFieldNames,
|
|
29
|
+
getSoftDeleteWriteData,
|
|
30
|
+
modelUsesSoftDeletes,
|
|
31
|
+
requireSoftDeleteField,
|
|
32
|
+
type ActiveRecordSoftDeleteConfig,
|
|
33
|
+
} from './SoftDeletes';
|
|
34
|
+
import type { FieldBuilder } from './fields/field';
|
|
35
|
+
import { RecordNotFoundError, type ActiveRecordLookup } from './errors';
|
|
36
|
+
import { activeAppDatabase } from '../server/appContext';
|
|
37
|
+
import type { ValidationRules } from '../validation';
|
|
38
|
+
import type * as db from './contracts';
|
|
39
|
+
|
|
40
|
+
export type { FieldBuilder } from './fields/field';
|
|
41
|
+
export { RecordNotFoundError } from './errors';
|
|
42
|
+
export type { ActiveRecordLookup } from './errors';
|
|
43
|
+
|
|
44
|
+
const scopedDb = new AsyncLocalStorage<Knex>();
|
|
45
|
+
|
|
46
|
+
export interface ModelFormOptions {
|
|
47
|
+
name?: string;
|
|
48
|
+
mode?: 'create' | 'edit' | 'search';
|
|
49
|
+
includeGenerated?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Options accepted by the ActiveRecord constructor.
|
|
54
|
+
*/
|
|
55
|
+
export interface ActiveRecordOptions {
|
|
56
|
+
/** Optional database connection/session for this record instance. */
|
|
57
|
+
db?: Knex;
|
|
58
|
+
|
|
59
|
+
/** True when the provided input is a raw database row. */
|
|
60
|
+
fromDb?: boolean;
|
|
61
|
+
|
|
62
|
+
/** Whether the record already exists in the database. */
|
|
63
|
+
persisted?: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Options for assigning untrusted request/form values to a record.
|
|
68
|
+
*/
|
|
69
|
+
export interface ActiveRecordRequestOptions {
|
|
70
|
+
/** Whether primary-key fields may be set from request data. Defaults to false. */
|
|
71
|
+
includePrimary?: boolean;
|
|
72
|
+
|
|
73
|
+
/** Whether generated fields may be set from request data. Defaults to false. */
|
|
74
|
+
includeGenerated?: boolean;
|
|
75
|
+
|
|
76
|
+
/** Explicit fillable fields for this request. Defaults to the model config. */
|
|
77
|
+
fillable?: readonly string[];
|
|
78
|
+
|
|
79
|
+
/** Explicit guarded fields for this request. Defaults to the model config. */
|
|
80
|
+
guarded?: readonly string[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ActiveRecordValidationRulesOptions extends ActiveRecordRequestOptions {
|
|
84
|
+
/** Whether hidden fields should be included. Defaults to false. */
|
|
85
|
+
includeHidden?: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type ActiveRecordRequestMap = Record<string, string>;
|
|
89
|
+
|
|
90
|
+
export type ActiveRecordConstructor<TRecord extends ActiveRecord = ActiveRecord> = {
|
|
91
|
+
new(
|
|
92
|
+
input?: Record<string, unknown>,
|
|
93
|
+
options?: ActiveRecordOptions,
|
|
94
|
+
): TRecord;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export type ActiveRecordInstance<TModel extends ActiveRecordConstructor> =
|
|
98
|
+
InstanceType<TModel>;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Static side of an ActiveRecord model class.
|
|
102
|
+
*
|
|
103
|
+
* Each subclass acts as its own schema by defining static `table`, `primaryKey`,
|
|
104
|
+
* and a `fields(field)` method.
|
|
105
|
+
*/
|
|
106
|
+
export type ActiveRecordClass<TRecord extends ActiveRecord = ActiveRecord> = ActiveRecordConstructor<TRecord> & {
|
|
107
|
+
/** Runtime JavaScript class name. */
|
|
108
|
+
readonly name: string;
|
|
109
|
+
|
|
110
|
+
/** Database table name. */
|
|
111
|
+
table: string;
|
|
112
|
+
|
|
113
|
+
/** Developer-facing model note for generated schemas and tooling. */
|
|
114
|
+
comment?: string;
|
|
115
|
+
|
|
116
|
+
/** Logical primary-key field name. */
|
|
117
|
+
primaryKey: string;
|
|
118
|
+
|
|
119
|
+
/** Fields used to render row labels when this model is linked from another model. */
|
|
120
|
+
labelFields?: string[];
|
|
121
|
+
|
|
122
|
+
/** Logical fields that request filling may assign. Undefined means all non-guarded fields. */
|
|
123
|
+
requestFillable?: readonly string[];
|
|
124
|
+
|
|
125
|
+
/** Logical fields that request filling may not assign. */
|
|
126
|
+
requestGuarded?: readonly string[];
|
|
127
|
+
|
|
128
|
+
/** Static field definitions for the model. */
|
|
129
|
+
fields(field: FieldBuilder): FieldInputMap;
|
|
130
|
+
|
|
131
|
+
/** Creates an inferred subclass with inherited and additional field definitions. */
|
|
132
|
+
define: typeof ActiveRecord.define;
|
|
133
|
+
|
|
134
|
+
/** Resolved static field definitions for the model. */
|
|
135
|
+
getFields(): FieldMap;
|
|
136
|
+
|
|
137
|
+
/** Returns a DomForm render spec composed from the model's FieldTypes. */
|
|
138
|
+
getForm(options?: ModelFormOptions): DomFormRenderSpec;
|
|
139
|
+
|
|
140
|
+
/** Returns search filter render specs composed from the model's FieldTypes. */
|
|
141
|
+
getSearchFilters(options?: ModelFormOptions): Record<string, FrontendComponentSpec>;
|
|
142
|
+
|
|
143
|
+
/** Looks up one resolved static field definition. */
|
|
144
|
+
getField(fieldName: string): FieldType<any, any, any, any, any>;
|
|
145
|
+
|
|
146
|
+
/** Optional default database connection for this model. Falls back to the shared app connection. */
|
|
147
|
+
db?: Knex;
|
|
148
|
+
|
|
149
|
+
/** Whether inserts/updates should call `.returning('*')`. */
|
|
150
|
+
returning?: boolean;
|
|
151
|
+
|
|
152
|
+
/** Soft-delete setting. True uses the conventional `deletedAt` logical field. */
|
|
153
|
+
softDeletes: ActiveRecordSoftDeleteConfig;
|
|
154
|
+
|
|
155
|
+
/** Returns the database connection for this model in the current app/scope. */
|
|
156
|
+
getDb(): Knex;
|
|
157
|
+
|
|
158
|
+
/** Runs work with a temporary database connection for all ActiveRecord statics. */
|
|
159
|
+
withDb<TResult>(db: Knex, callback: () => TResult): TResult;
|
|
160
|
+
|
|
161
|
+
/** Binds a default database connection to the model class. */
|
|
162
|
+
useDb<TModel extends ActiveRecordConstructor>(
|
|
163
|
+
this: TModel,
|
|
164
|
+
db: Knex,
|
|
165
|
+
): TModel;
|
|
166
|
+
|
|
167
|
+
/** Creates a new unsaved record bound to the model's current database. */
|
|
168
|
+
create<TModel extends ActiveRecordConstructor>(
|
|
169
|
+
this: TModel,
|
|
170
|
+
input?: NoInfer<ConstructorParameters<TModel>[0]>,
|
|
171
|
+
options?: Omit<ActiveRecordOptions, 'db'>,
|
|
172
|
+
): ActiveRecordInstance<TModel>;
|
|
173
|
+
|
|
174
|
+
/** Starts a field-aware query for the model. */
|
|
175
|
+
query<TModel extends ActiveRecordConstructor>(
|
|
176
|
+
this: TModel,
|
|
177
|
+
db?: Knex,
|
|
178
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
179
|
+
|
|
180
|
+
/** Starts a query that includes soft-deleted rows. */
|
|
181
|
+
withTrashed<TModel extends ActiveRecordConstructor>(
|
|
182
|
+
this: TModel,
|
|
183
|
+
db?: Knex,
|
|
184
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
185
|
+
|
|
186
|
+
/** Starts a query that only includes soft-deleted rows. */
|
|
187
|
+
onlyTrashed<TModel extends ActiveRecordConstructor>(
|
|
188
|
+
this: TModel,
|
|
189
|
+
db?: Knex,
|
|
190
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
191
|
+
|
|
192
|
+
/** Starts a query that excludes soft-deleted rows. */
|
|
193
|
+
withoutTrashed<TModel extends ActiveRecordConstructor>(
|
|
194
|
+
this: TModel,
|
|
195
|
+
db?: Knex,
|
|
196
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
197
|
+
|
|
198
|
+
/** Convenience helper for `query().where(...)`. */
|
|
199
|
+
where<TModel extends ActiveRecordConstructor>(
|
|
200
|
+
this: TModel,
|
|
201
|
+
criteria: Record<string, unknown>,
|
|
202
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
203
|
+
where<TModel extends ActiveRecordConstructor>(
|
|
204
|
+
this: TModel,
|
|
205
|
+
fieldName: string,
|
|
206
|
+
value: unknown,
|
|
207
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
208
|
+
where<TModel extends ActiveRecordConstructor>(
|
|
209
|
+
this: TModel,
|
|
210
|
+
fieldName: string,
|
|
211
|
+
operator: string,
|
|
212
|
+
value: unknown,
|
|
213
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
214
|
+
|
|
215
|
+
/** Finds one record by the configured primary key. */
|
|
216
|
+
findByPk<TModel extends ActiveRecordConstructor>(
|
|
217
|
+
this: TModel,
|
|
218
|
+
id: unknown,
|
|
219
|
+
db?: Knex,
|
|
220
|
+
): Promise<ActiveRecordInstance<TModel> | null>;
|
|
221
|
+
|
|
222
|
+
/** Finds one record by the configured primary key. */
|
|
223
|
+
find<TModel extends ActiveRecordConstructor>(
|
|
224
|
+
this: TModel,
|
|
225
|
+
lookup: ActiveRecordLookup,
|
|
226
|
+
db?: Knex,
|
|
227
|
+
): Promise<ActiveRecordInstance<TModel> | null>;
|
|
228
|
+
|
|
229
|
+
/** Finds one record by the configured primary key or throws an error if not found. */
|
|
230
|
+
findOrFail<TModel extends ActiveRecordConstructor>(
|
|
231
|
+
this: TModel,
|
|
232
|
+
lookup: ActiveRecordLookup,
|
|
233
|
+
db?: Knex,
|
|
234
|
+
): Promise<ActiveRecordInstance<TModel>>;
|
|
235
|
+
|
|
236
|
+
/** Hydrates a model instance from a raw database row. */
|
|
237
|
+
fromDb<TModel extends ActiveRecordConstructor>(
|
|
238
|
+
this: TModel,
|
|
239
|
+
row: DbRow,
|
|
240
|
+
db?: Knex,
|
|
241
|
+
): ActiveRecordInstance<TModel>;
|
|
242
|
+
|
|
243
|
+
/** Returns validation rules generated from model fields. */
|
|
244
|
+
validationRules(options?: ActiveRecordValidationRulesOptions): ValidationRules;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Minimal ActiveRecord base class.
|
|
249
|
+
*
|
|
250
|
+
* Subclasses define their table and fields statically. Each instance creates
|
|
251
|
+
* private live field objects, and public model properties proxy through to those
|
|
252
|
+
* fields.
|
|
253
|
+
*
|
|
254
|
+
* Example:
|
|
255
|
+
*
|
|
256
|
+
* ```ts
|
|
257
|
+
* class User extends ActiveRecord {
|
|
258
|
+
* static table = 'users';
|
|
259
|
+
* static fields(field: FieldBuilder) {
|
|
260
|
+
* return {
|
|
261
|
+
* email: field.email({ required: true }),
|
|
262
|
+
* };
|
|
263
|
+
* }
|
|
264
|
+
* }
|
|
265
|
+
*
|
|
266
|
+
* const user = new User();
|
|
267
|
+
* user.email = 'STEVE@EXAMPLE.COM';
|
|
268
|
+
* console.log(user.email); // 'steve@example.com'
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export abstract class ActiveRecord {
|
|
272
|
+
/** Database table name. Override in subclasses. */
|
|
273
|
+
static table: string;
|
|
274
|
+
|
|
275
|
+
/** Developer-facing model note for generated schemas and tooling. */
|
|
276
|
+
static comment = '';
|
|
277
|
+
|
|
278
|
+
/** Logical primary-key field name. Override if not `id`. */
|
|
279
|
+
static primaryKey = 'id';
|
|
280
|
+
|
|
281
|
+
/** Fields used to render row labels when this model is linked from another model. */
|
|
282
|
+
static labelFields: string[] = [];
|
|
283
|
+
|
|
284
|
+
/** Logical fields that request filling may assign. Undefined means all non-guarded fields. */
|
|
285
|
+
static requestFillable?: readonly string[];
|
|
286
|
+
|
|
287
|
+
/** Logical fields that request filling may not assign. */
|
|
288
|
+
static requestGuarded: readonly string[] = [];
|
|
289
|
+
|
|
290
|
+
/** Static field factory. Override in subclasses. */
|
|
291
|
+
static fields(_field: FieldBuilder): FieldInputMap {
|
|
292
|
+
return {};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Defines an inferred model subclass using the existing field lifecycle.
|
|
297
|
+
*
|
|
298
|
+
* Inherited fields are included automatically. A matching name replaces the
|
|
299
|
+
* complete definition while retaining its application and input value types.
|
|
300
|
+
* Ordinary static field factories continue to control their own inheritance.
|
|
301
|
+
*
|
|
302
|
+
* @param definition - This layer's fields and optional model settings.
|
|
303
|
+
* @returns A subclass that can be extended with application methods.
|
|
304
|
+
* @example
|
|
305
|
+
* class User extends ActiveRecord.define({
|
|
306
|
+
* table: 'users',
|
|
307
|
+
* fields: field => ({ id: field.ulid(), email: field.email({ required: true }) }),
|
|
308
|
+
* }) {}
|
|
309
|
+
*/
|
|
310
|
+
static define<TBase extends db.ActiveRecordDefinitionBase, TFields extends FieldInputMap>(
|
|
311
|
+
this: TBase,
|
|
312
|
+
definition: db.ActiveRecordDefinition<TFields> & { fields(field: FieldBuilder): db.ActiveRecordFieldOverrides<TBase, TFields> },
|
|
313
|
+
): db.DefinedActiveRecord<TBase, TFields> {
|
|
314
|
+
const Base = this;
|
|
315
|
+
const { fields, ...settings } = definition;
|
|
316
|
+
|
|
317
|
+
/** Model layer resolved and cloned by the ordinary ActiveRecord path. */
|
|
318
|
+
class DefinedRecord extends (Base as unknown as typeof ActiveRecord) {
|
|
319
|
+
/** Resolves parent fields for the final subclass before applying overrides. */
|
|
320
|
+
static override fields(field: FieldBuilder): FieldInputMap {
|
|
321
|
+
return { ...Base.fields.call(this, field), ...fields.call(this, field) };
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
Object.assign(DefinedRecord, settings);
|
|
326
|
+
return DefinedRecord as unknown as db.DefinedActiveRecord<TBase, TFields>;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** Optional model-level database connection. Falls back to the shared app connection. */
|
|
330
|
+
static db?: Knex;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Whether to call `.returning('*')` after inserts/updates.
|
|
334
|
+
*
|
|
335
|
+
* This is usually desirable for PostgreSQL. Set to `false` for dialects where
|
|
336
|
+
* returning is unsupported or unwanted.
|
|
337
|
+
*/
|
|
338
|
+
static returning = true;
|
|
339
|
+
|
|
340
|
+
/** Soft-delete setting. True uses the conventional `deletedAt` logical field. */
|
|
341
|
+
static softDeletes: ActiveRecordSoftDeleteConfig = false;
|
|
342
|
+
|
|
343
|
+
/** Per-record live fields, keyed by logical field name. */
|
|
344
|
+
private readonly $fields: Record<string, FieldType<any, any, any, any, any>> = {};
|
|
345
|
+
|
|
346
|
+
/** Whether the record currently represents an existing database row. */
|
|
347
|
+
protected $persisted = false;
|
|
348
|
+
|
|
349
|
+
/** Optional instance-level database connection/session. */
|
|
350
|
+
protected $db?: Knex;
|
|
351
|
+
|
|
352
|
+
constructor(
|
|
353
|
+
input: Record<string, unknown> = {},
|
|
354
|
+
options: ActiveRecordOptions = {},
|
|
355
|
+
) {
|
|
356
|
+
const Model = this.$model();
|
|
357
|
+
|
|
358
|
+
this.$db = options.db ?? Model.db;
|
|
359
|
+
this.$persisted = options.persisted ?? options.fromDb ?? false;
|
|
360
|
+
|
|
361
|
+
for (const [fieldName, field] of Object.entries(Model.getFields())) {
|
|
362
|
+
const liveField = field.clone().bindToRecord(this, fieldName);
|
|
363
|
+
|
|
364
|
+
this.$fields[fieldName] = liveField;
|
|
365
|
+
this.$installAccessor(fieldName);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (options.fromDb) {
|
|
369
|
+
this.$hydrateFromDb(input);
|
|
370
|
+
} else {
|
|
371
|
+
this.assign(input);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Binds a custom default database connection to the model class.
|
|
377
|
+
*
|
|
378
|
+
* Most models can use the active app connection automatically. For tests,
|
|
379
|
+
* prefer creating an app with the test database. For scoped work such as
|
|
380
|
+
* transactions, use `withDb()`.
|
|
381
|
+
*/
|
|
382
|
+
static useDb<TModel extends ActiveRecordConstructor>(
|
|
383
|
+
this: TModel,
|
|
384
|
+
db: Knex,
|
|
385
|
+
): TModel {
|
|
386
|
+
(this as unknown as ActiveRecordClass).db = db;
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Returns the database connection for the current ActiveRecord operation.
|
|
392
|
+
*/
|
|
393
|
+
static getDb(): Knex {
|
|
394
|
+
return scopedDb.getStore()
|
|
395
|
+
?? this.db
|
|
396
|
+
?? activeAppDatabase()
|
|
397
|
+
?? defaultDb();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Runs work with a temporary database connection for all ActiveRecord statics.
|
|
402
|
+
*/
|
|
403
|
+
static withDb<TResult>(db: Knex, callback: () => TResult): TResult {
|
|
404
|
+
return scopedDb.run(db, callback);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Creates a new unsaved record bound to this model's current database.
|
|
409
|
+
*
|
|
410
|
+
* @param input - Constructor input, inferred from fields for defined models.
|
|
411
|
+
* @param options - Record hydration/persistence flags; the database is resolved here.
|
|
412
|
+
* @returns The actual subclass instance, synchronously. Call `save()` to write it.
|
|
413
|
+
*/
|
|
414
|
+
static create<TModel extends ActiveRecordConstructor>(
|
|
415
|
+
this: TModel,
|
|
416
|
+
input: NoInfer<NonNullable<ConstructorParameters<TModel>[0]>> = {},
|
|
417
|
+
options: Omit<ActiveRecordOptions, 'db'> = {},
|
|
418
|
+
): ActiveRecordInstance<TModel> {
|
|
419
|
+
return new this(input, {
|
|
420
|
+
...options,
|
|
421
|
+
db: ActiveRecord.getDb.call(this),
|
|
422
|
+
}) as ActiveRecordInstance<TModel>;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Resolves the model's static field factory with the framework field helper.
|
|
427
|
+
*/
|
|
428
|
+
static getFields<TRecord extends ActiveRecord>(
|
|
429
|
+
this: ActiveRecordClass<TRecord>,
|
|
430
|
+
): FieldMap {
|
|
431
|
+
return resolveModelFields(this);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Returns a DomForm render spec composed from this model's FieldTypes.
|
|
436
|
+
*/
|
|
437
|
+
static getForm<TRecord extends ActiveRecord>(
|
|
438
|
+
this: ActiveRecordClass<TRecord>,
|
|
439
|
+
options: ModelFormOptions = {},
|
|
440
|
+
): DomFormRenderSpec {
|
|
441
|
+
const children = Object.entries(this.getFields()).flatMap(([fieldName, field]) => {
|
|
442
|
+
if (!options.includeGenerated && field.config.generated) return [];
|
|
443
|
+
|
|
444
|
+
return [
|
|
445
|
+
field.getFormComponentFor(this, fieldName, {
|
|
446
|
+
mode: options.mode ?? 'create',
|
|
447
|
+
}),
|
|
448
|
+
];
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
return {
|
|
452
|
+
component: 'DomForm',
|
|
453
|
+
props: {
|
|
454
|
+
name: options.name ?? this.table,
|
|
455
|
+
},
|
|
456
|
+
children,
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Returns search filter render specs composed from this model's FieldTypes.
|
|
462
|
+
*/
|
|
463
|
+
static getSearchFilters<TRecord extends ActiveRecord>(
|
|
464
|
+
this: ActiveRecordClass<TRecord>,
|
|
465
|
+
options: ModelFormOptions = {},
|
|
466
|
+
): Record<string, FrontendComponentSpec> {
|
|
467
|
+
const filters: Record<string, FrontendComponentSpec> = {};
|
|
468
|
+
|
|
469
|
+
for (const [fieldName, field] of Object.entries(this.getFields())) {
|
|
470
|
+
const component = field.getSearchFilterComponentFor(this, fieldName, {
|
|
471
|
+
mode: options.mode ?? 'search',
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
if (component) {
|
|
475
|
+
filters[fieldName] = component;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return filters;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Looks up one resolved field definition by logical field name.
|
|
484
|
+
*/
|
|
485
|
+
static getField<TRecord extends ActiveRecord>(
|
|
486
|
+
this: ActiveRecordClass<TRecord>,
|
|
487
|
+
fieldName: string,
|
|
488
|
+
): FieldType<any, any, any, any, any> {
|
|
489
|
+
const field = this.getFields()[fieldName];
|
|
490
|
+
|
|
491
|
+
if (!field) {
|
|
492
|
+
throw new Error(
|
|
493
|
+
`Unknown field "${fieldName}" on model ${this.name}`,
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return field;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Starts a field-aware query for this model.
|
|
502
|
+
*/
|
|
503
|
+
static query<TModel extends ActiveRecordConstructor>(
|
|
504
|
+
this: TModel,
|
|
505
|
+
db?: Knex,
|
|
506
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>> {
|
|
507
|
+
const Model = this as unknown as ActiveRecordClass<
|
|
508
|
+
ActiveRecordInstance<TModel>
|
|
509
|
+
>;
|
|
510
|
+
const connection = db ?? ActiveRecord.getDb.call(this);
|
|
511
|
+
|
|
512
|
+
return new ActiveQueryBuilder<ActiveRecordInstance<TModel>>(
|
|
513
|
+
Model,
|
|
514
|
+
connection,
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Starts a query that includes soft-deleted rows.
|
|
520
|
+
*/
|
|
521
|
+
static withTrashed<TModel extends ActiveRecordConstructor>(
|
|
522
|
+
this: TModel,
|
|
523
|
+
db?: Knex,
|
|
524
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>> {
|
|
525
|
+
return (
|
|
526
|
+
ActiveRecord.query.call(this, db) as ActiveQueryBuilder<
|
|
527
|
+
ActiveRecordInstance<TModel>
|
|
528
|
+
>
|
|
529
|
+
).withTrashed();
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Starts a query that only includes soft-deleted rows.
|
|
534
|
+
*/
|
|
535
|
+
static onlyTrashed<TModel extends ActiveRecordConstructor>(
|
|
536
|
+
this: TModel,
|
|
537
|
+
db?: Knex,
|
|
538
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>> {
|
|
539
|
+
return (
|
|
540
|
+
ActiveRecord.query.call(this, db) as ActiveQueryBuilder<
|
|
541
|
+
ActiveRecordInstance<TModel>
|
|
542
|
+
>
|
|
543
|
+
).onlyTrashed();
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Starts a query that excludes soft-deleted rows.
|
|
548
|
+
*/
|
|
549
|
+
static withoutTrashed<TModel extends ActiveRecordConstructor>(
|
|
550
|
+
this: TModel,
|
|
551
|
+
db?: Knex,
|
|
552
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>> {
|
|
553
|
+
return (
|
|
554
|
+
ActiveRecord.query.call(this, db) as ActiveQueryBuilder<
|
|
555
|
+
ActiveRecordInstance<TModel>
|
|
556
|
+
>
|
|
557
|
+
).withoutTrashed();
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Convenience helper for `Model.query().where(...)`.
|
|
562
|
+
*/
|
|
563
|
+
static where<TModel extends ActiveRecordConstructor>(
|
|
564
|
+
this: TModel,
|
|
565
|
+
criteria: Record<string, unknown>,
|
|
566
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
567
|
+
static where<TModel extends ActiveRecordConstructor>(
|
|
568
|
+
this: TModel,
|
|
569
|
+
fieldName: string,
|
|
570
|
+
value: unknown,
|
|
571
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
572
|
+
static where<TModel extends ActiveRecordConstructor>(
|
|
573
|
+
this: TModel,
|
|
574
|
+
fieldName: string,
|
|
575
|
+
operator: string,
|
|
576
|
+
value: unknown,
|
|
577
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
|
|
578
|
+
static where<TModel extends ActiveRecordConstructor>(
|
|
579
|
+
this: TModel,
|
|
580
|
+
fieldNameOrCriteria: string | Record<string, unknown>,
|
|
581
|
+
operatorOrValue?: unknown,
|
|
582
|
+
value?: unknown,
|
|
583
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>> {
|
|
584
|
+
const query = ActiveRecord.query.call(this) as ActiveQueryBuilder<
|
|
585
|
+
ActiveRecordInstance<TModel>
|
|
586
|
+
>;
|
|
587
|
+
|
|
588
|
+
if (typeof fieldNameOrCriteria === 'object' && fieldNameOrCriteria !== null) {
|
|
589
|
+
return query.where(fieldNameOrCriteria);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return arguments.length === 3
|
|
593
|
+
? query.where(fieldNameOrCriteria, String(operatorOrValue), value)
|
|
594
|
+
: query.where(fieldNameOrCriteria, operatorOrValue);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Finds one record by the configured primary key.
|
|
599
|
+
*/
|
|
600
|
+
static async findByPk<TModel extends ActiveRecordConstructor>(
|
|
601
|
+
this: TModel,
|
|
602
|
+
id: unknown,
|
|
603
|
+
db?: Knex,
|
|
604
|
+
): Promise<ActiveRecordInstance<TModel> | null> {
|
|
605
|
+
const query = ActiveRecord.query.call(this, db) as ActiveQueryBuilder<
|
|
606
|
+
ActiveRecordInstance<TModel>
|
|
607
|
+
>;
|
|
608
|
+
|
|
609
|
+
return query.wherePk(id).first();
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Finds one record by the configured primary key or field criteria.
|
|
614
|
+
*/
|
|
615
|
+
static async find<TModel extends ActiveRecordConstructor>(
|
|
616
|
+
this: TModel,
|
|
617
|
+
lookup: ActiveRecordLookup,
|
|
618
|
+
db?: Knex,
|
|
619
|
+
): Promise<ActiveRecordInstance<TModel> | null> {
|
|
620
|
+
return ActiveRecord.queryForLookup.call(this, lookup, db).first() as Promise<
|
|
621
|
+
ActiveRecordInstance<TModel> | null
|
|
622
|
+
>;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Finds one record by the configured primary key or field criteria.
|
|
627
|
+
*
|
|
628
|
+
* Throws a `RecordNotFoundError` if no matching row exists.
|
|
629
|
+
*/
|
|
630
|
+
static async findOrFail<TModel extends ActiveRecordConstructor>(
|
|
631
|
+
this: TModel,
|
|
632
|
+
lookup: ActiveRecordLookup,
|
|
633
|
+
db?: Knex,
|
|
634
|
+
): Promise<ActiveRecordInstance<TModel>> {
|
|
635
|
+
const record = await ActiveRecord.find.call(this, lookup, db) as
|
|
636
|
+
| ActiveRecordInstance<TModel>
|
|
637
|
+
| null;
|
|
638
|
+
|
|
639
|
+
if (!record) {
|
|
640
|
+
throw new RecordNotFoundError(this.name, lookup);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
return record;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
private static queryForLookup<TModel extends ActiveRecordConstructor>(
|
|
647
|
+
this: TModel,
|
|
648
|
+
lookup: ActiveRecordLookup,
|
|
649
|
+
db?: Knex,
|
|
650
|
+
): ActiveQueryBuilder<ActiveRecordInstance<TModel>> {
|
|
651
|
+
const query = ActiveRecord.query.call(this, db) as ActiveQueryBuilder<
|
|
652
|
+
ActiveRecordInstance<TModel>
|
|
653
|
+
>;
|
|
654
|
+
|
|
655
|
+
if (isLookupCriteria(lookup)) {
|
|
656
|
+
if (Object.keys(lookup).length === 0) {
|
|
657
|
+
throw new Error('At least one lookup field is required.');
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
return query.where(lookup);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return query.wherePk(lookup);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Hydrates a model instance from a raw database row.
|
|
668
|
+
*/
|
|
669
|
+
static fromDb<TModel extends ActiveRecordConstructor>(
|
|
670
|
+
this: TModel,
|
|
671
|
+
row: DbRow,
|
|
672
|
+
db?: Knex,
|
|
673
|
+
): ActiveRecordInstance<TModel> {
|
|
674
|
+
return new this(row, {
|
|
675
|
+
db,
|
|
676
|
+
fromDb: true,
|
|
677
|
+
persisted: true,
|
|
678
|
+
}) as ActiveRecordInstance<TModel>;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Returns Laravel-style validation rules generated from this model's fields.
|
|
683
|
+
*/
|
|
684
|
+
static validationRules<TRecord extends ActiveRecord>(
|
|
685
|
+
this: ActiveRecordClass<TRecord>,
|
|
686
|
+
options: ActiveRecordValidationRulesOptions = {},
|
|
687
|
+
): ValidationRules {
|
|
688
|
+
const rules: ValidationRules = {};
|
|
689
|
+
|
|
690
|
+
for (const [fieldName, field] of Object.entries(this.getFields())) {
|
|
691
|
+
if (!shouldIncludeFieldValidationRules(this, fieldName, field, options)) continue;
|
|
692
|
+
|
|
693
|
+
rules[fieldName] = field.getValidationRules({
|
|
694
|
+
model: this,
|
|
695
|
+
fieldName,
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return rules;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Assigns app/input values by logical field name.
|
|
704
|
+
*
|
|
705
|
+
* Unknown keys are ignored. Use `set(fieldName, value)` if you want an error
|
|
706
|
+
* for unknown fields.
|
|
707
|
+
*/
|
|
708
|
+
assign(input: Record<string, unknown>): this {
|
|
709
|
+
for (const fieldName of Object.keys(this.$fields)) {
|
|
710
|
+
if (Object.prototype.hasOwnProperty.call(input, fieldName)) {
|
|
711
|
+
this.$set(fieldName, input[fieldName]);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return this;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Assigns request/form values using logical model field names.
|
|
720
|
+
*/
|
|
721
|
+
assignFromRequest(input: unknown, options: ActiveRecordRequestOptions = {}): this {
|
|
722
|
+
return this.setFromRequest(input, options);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Fills this record from request/form values using logical model field names.
|
|
727
|
+
*
|
|
728
|
+
* Unknown keys are ignored. Primary/generated/guarded fields are skipped by
|
|
729
|
+
* default, and model/request fillable config controls what may be assigned.
|
|
730
|
+
*/
|
|
731
|
+
setFromRequest(input: unknown, options: ActiveRecordRequestOptions = {}): this {
|
|
732
|
+
const requestInput = recordFromUnknown(input);
|
|
733
|
+
|
|
734
|
+
for (const [fieldName, field] of Object.entries(this.$fields)) {
|
|
735
|
+
if (!this.$canFillFromRequest(fieldName, field, options)) continue;
|
|
736
|
+
if (!Object.prototype.hasOwnProperty.call(requestInput, fieldName)) continue;
|
|
737
|
+
|
|
738
|
+
this.$set(fieldName, requestInput[fieldName]);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return this;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Fills this record from request/form values using a request-key to model-field map.
|
|
746
|
+
*/
|
|
747
|
+
setFromRequestWithMap(
|
|
748
|
+
input: unknown,
|
|
749
|
+
dataToFieldMap: ActiveRecordRequestMap,
|
|
750
|
+
options: ActiveRecordRequestOptions = {},
|
|
751
|
+
): this {
|
|
752
|
+
const requestInput = recordFromUnknown(input);
|
|
753
|
+
const mappedInput: Record<string, unknown> = {
|
|
754
|
+
...requestInput,
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
for (const [dataKey, fieldName] of Object.entries(dataToFieldMap)) {
|
|
758
|
+
if (Object.prototype.hasOwnProperty.call(requestInput, dataKey)) {
|
|
759
|
+
mappedInput[fieldName] = requestInput[dataKey];
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
return this.setFromRequest(mappedInput, options);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* Dynamically sets a field by logical name.
|
|
768
|
+
*
|
|
769
|
+
* Useful for runtime/database-stored schemas where TypeScript cannot know the
|
|
770
|
+
* field names at compile time.
|
|
771
|
+
*/
|
|
772
|
+
set(fieldName: string, value: unknown): this {
|
|
773
|
+
this.$set(fieldName, value);
|
|
774
|
+
return this;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Dynamically gets a field by logical name.
|
|
779
|
+
*/
|
|
780
|
+
get(fieldName: string): unknown {
|
|
781
|
+
return this.$get(fieldName);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Dynamically binds this record instance to a database connection/session.
|
|
786
|
+
*/
|
|
787
|
+
setDb(db: Knex): this {
|
|
788
|
+
this.$db = db;
|
|
789
|
+
return this;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Returns true if the model has the given logical field.
|
|
794
|
+
*/
|
|
795
|
+
hasField(fieldName: string): boolean {
|
|
796
|
+
return Boolean(this.$fields[fieldName]);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* Returns the bound runtime field for framework-level hydration helpers.
|
|
801
|
+
*/
|
|
802
|
+
getBoundField(fieldName: string): FieldType<any, any, any, any, any> {
|
|
803
|
+
return this.$field(fieldName);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Validates fields and stores field errors on each field state.
|
|
808
|
+
*/
|
|
809
|
+
async validate(options: { onlyDirty?: boolean } = {}): Promise<boolean> {
|
|
810
|
+
for (const field of Object.values(this.$fields)) {
|
|
811
|
+
if (options.onlyDirty && !field.dirty) {
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
await field.validateField();
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
return !this.hasErrors();
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Clears all current validation errors.
|
|
823
|
+
*/
|
|
824
|
+
clearErrors(): void {
|
|
825
|
+
for (const field of Object.values(this.$fields)) {
|
|
826
|
+
field.clearErrors();
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* Returns true if any field currently has validation errors.
|
|
832
|
+
*/
|
|
833
|
+
hasErrors(): boolean {
|
|
834
|
+
return this.getErrors().length > 0;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Returns all field errors on this record.
|
|
839
|
+
*/
|
|
840
|
+
getErrors(): FieldError[] {
|
|
841
|
+
const errors: FieldError[] = [];
|
|
842
|
+
|
|
843
|
+
for (const field of Object.values(this.$fields)) {
|
|
844
|
+
errors.push(...field.errors);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return errors;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Returns current validation errors for one field.
|
|
852
|
+
*/
|
|
853
|
+
getFieldErrors(fieldName: string): FieldError[] {
|
|
854
|
+
return this.$field(fieldName).errors;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Returns database insert/update data for the record.
|
|
859
|
+
*
|
|
860
|
+
* This calls every field's `getDataForDb()` method. This is where passwords
|
|
861
|
+
* are hashed, JSON fields are stringified, link fields produce foreign keys,
|
|
862
|
+
* and compound fields can return multiple columns.
|
|
863
|
+
*/
|
|
864
|
+
async getDataForDb(
|
|
865
|
+
options: Partial<DbWriteOptions> = {},
|
|
866
|
+
): Promise<DbWriteData> {
|
|
867
|
+
const writeOptions = {
|
|
868
|
+
isInsert: options.isInsert ?? !this.$persisted,
|
|
869
|
+
onlyDirty: options.onlyDirty ?? false,
|
|
870
|
+
valueOptions: options.valueOptions,
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
const row: DbWriteData = {};
|
|
874
|
+
|
|
875
|
+
for (const field of Object.values(this.$fields)) {
|
|
876
|
+
const fieldData = await field.getBoundDataForDb(writeOptions);
|
|
877
|
+
|
|
878
|
+
Object.assign(row, fieldData);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
return row;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Inserts or updates this record.
|
|
886
|
+
*
|
|
887
|
+
* Validation runs before any SQL is executed. On validation failure this throws
|
|
888
|
+
* `RecordValidationError` containing all field errors.
|
|
889
|
+
*/
|
|
890
|
+
async save(): Promise<this> {
|
|
891
|
+
const Model = this.$model();
|
|
892
|
+
const connection = this.$db ?? Model.getDb();
|
|
893
|
+
|
|
894
|
+
const isInsert = !this.$persisted;
|
|
895
|
+
const valid = await this.validate({ onlyDirty: false });
|
|
896
|
+
|
|
897
|
+
if (!valid) {
|
|
898
|
+
throw new RecordValidationError(this.getErrors());
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
const row = await this.getDataForDb({
|
|
902
|
+
isInsert,
|
|
903
|
+
onlyDirty: !isInsert,
|
|
904
|
+
valueOptions: {
|
|
905
|
+
db: connection,
|
|
906
|
+
dialect: databaseDialectForConnection(connection),
|
|
907
|
+
},
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
if (isInsert) {
|
|
911
|
+
const query = connection(Model.table).insert(row);
|
|
912
|
+
const result = shouldUseReturningRows(Model, connection)
|
|
913
|
+
? await query.returning('*')
|
|
914
|
+
: await query;
|
|
915
|
+
|
|
916
|
+
const createdRow = Array.isArray(result) ? result[0] : undefined;
|
|
917
|
+
|
|
918
|
+
if (createdRow && typeof createdRow === 'object') {
|
|
919
|
+
this.$hydrateFromDb(createdRow as DbRow);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
this.$persisted = true;
|
|
923
|
+
this.$markClean();
|
|
924
|
+
|
|
925
|
+
return this;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
if (Object.keys(row).length === 0) {
|
|
929
|
+
return this;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
const query = connection(Model.table)
|
|
933
|
+
.where(this.$primaryKeyWhere())
|
|
934
|
+
.update(row);
|
|
935
|
+
|
|
936
|
+
const result = shouldUseReturningRows(Model, connection)
|
|
937
|
+
? await query.returning('*')
|
|
938
|
+
: await query;
|
|
939
|
+
|
|
940
|
+
const updatedRow = Array.isArray(result) ? result[0] : undefined;
|
|
941
|
+
|
|
942
|
+
if (updatedRow && typeof updatedRow === 'object') {
|
|
943
|
+
this.$hydrateFromDb(updatedRow as DbRow);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
this.$markClean();
|
|
947
|
+
|
|
948
|
+
return this;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Deletes the current database row.
|
|
953
|
+
*
|
|
954
|
+
* Models with `softDeletes` enabled update their delete timestamp instead of
|
|
955
|
+
* physically removing the row.
|
|
956
|
+
*/
|
|
957
|
+
async delete(db?: Knex): Promise<number> {
|
|
958
|
+
if (modelUsesSoftDeletes(this.$model())) {
|
|
959
|
+
return this.softDelete(db);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
return this.forceDelete(db);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Physically deletes the current database row.
|
|
967
|
+
*/
|
|
968
|
+
async forceDelete(db?: Knex): Promise<number> {
|
|
969
|
+
const Model = this.$model();
|
|
970
|
+
const connection = db ?? this.$db ?? Model.getDb();
|
|
971
|
+
|
|
972
|
+
const count = await connection(Model.table)
|
|
973
|
+
.where(this.$primaryKeyWhere())
|
|
974
|
+
.delete();
|
|
975
|
+
|
|
976
|
+
this.$persisted = false;
|
|
977
|
+
|
|
978
|
+
return Number(count);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* Restores the current soft-deleted database row.
|
|
983
|
+
*/
|
|
984
|
+
async restore(db?: Knex): Promise<number> {
|
|
985
|
+
const Model = this.$model();
|
|
986
|
+
const connection = db ?? this.$db ?? Model.getDb();
|
|
987
|
+
const softDeleteField = requireSoftDeleteField(Model);
|
|
988
|
+
const updatedAt = new Date();
|
|
989
|
+
const count = await connection(Model.table)
|
|
990
|
+
.where(this.$primaryKeyWhere())
|
|
991
|
+
.whereNotNull(softDeleteField.column)
|
|
992
|
+
.update(getSoftDeleteWriteData(Model, null, updatedAt));
|
|
993
|
+
const restoredCount = Number(count);
|
|
994
|
+
|
|
995
|
+
if (restoredCount > 0) {
|
|
996
|
+
this.$setSoftDeleteFieldValues(null, updatedAt);
|
|
997
|
+
this.$persisted = true;
|
|
998
|
+
this.$markClean();
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
return restoredCount;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Returns true when this soft-deletable record has been trashed.
|
|
1006
|
+
*/
|
|
1007
|
+
trashed(): boolean {
|
|
1008
|
+
const softDeleteField = requireSoftDeleteField(this.$model());
|
|
1009
|
+
const value = this.$get(softDeleteField.fieldName);
|
|
1010
|
+
|
|
1011
|
+
return value !== null && value !== undefined;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Returns hydrated backend values keyed by logical field name.
|
|
1016
|
+
*/
|
|
1017
|
+
toAppData(): Record<string, unknown> {
|
|
1018
|
+
const data: Record<string, unknown> = {};
|
|
1019
|
+
|
|
1020
|
+
for (const [fieldName, field] of Object.entries(this.$fields)) {
|
|
1021
|
+
if (field.config.hidden) continue;
|
|
1022
|
+
|
|
1023
|
+
data[fieldName] = field.value;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
return data;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* Serialises this record using each field's display value.
|
|
1031
|
+
*/
|
|
1032
|
+
toDisplayData(): Record<string, unknown> {
|
|
1033
|
+
const data: Record<string, unknown> = {};
|
|
1034
|
+
|
|
1035
|
+
for (const [fieldName, field] of Object.entries(this.$fields)) {
|
|
1036
|
+
const value = field.getBoundDisplayValue();
|
|
1037
|
+
|
|
1038
|
+
if (value !== undefined) {
|
|
1039
|
+
data[fieldName] = value;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
return data;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* JSON transport alias for display data.
|
|
1048
|
+
*/
|
|
1049
|
+
toJSON(): Record<string, unknown> {
|
|
1050
|
+
return this.toDisplayData();
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Returns true if this record was loaded from or saved to the database.
|
|
1055
|
+
*/
|
|
1056
|
+
isPersisted(): boolean {
|
|
1057
|
+
return this.$persisted;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* Returns whether one field or any field has unsaved in-memory changes.
|
|
1062
|
+
*
|
|
1063
|
+
* @param fieldName - Optional logical field name to inspect.
|
|
1064
|
+
* @returns True when the selected field scope contains unsaved changes.
|
|
1065
|
+
*/
|
|
1066
|
+
isDirty(fieldName?: string): boolean {
|
|
1067
|
+
if (fieldName !== undefined) {
|
|
1068
|
+
return this.$field(fieldName).dirty;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
return Object.values(this.$fields).some(field => field.dirty);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Protected field getter used by generated accessors and `get()`.
|
|
1076
|
+
*/
|
|
1077
|
+
protected $get(fieldName: string): unknown {
|
|
1078
|
+
return this.$field(fieldName).value;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Protected field setter used by generated accessors and `set()`.
|
|
1083
|
+
*/
|
|
1084
|
+
protected $set(fieldName: string, value: unknown): void {
|
|
1085
|
+
this.$field(fieldName).value = value;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Hydrates all fields from a raw database row.
|
|
1090
|
+
*/
|
|
1091
|
+
protected $hydrateFromDb(row: DbRow): void {
|
|
1092
|
+
for (const field of Object.values(this.$fields)) {
|
|
1093
|
+
field.hydrate(row);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
this.$persisted = true;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Marks all fields as clean after a successful save/hydration.
|
|
1101
|
+
*/
|
|
1102
|
+
protected $markClean(): void {
|
|
1103
|
+
for (const field of Object.values(this.$fields)) {
|
|
1104
|
+
field.markBoundClean();
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
/**
|
|
1109
|
+
* Returns a database where-clause object for the primary key.
|
|
1110
|
+
*/
|
|
1111
|
+
protected $primaryKeyWhere(): Record<string, unknown> {
|
|
1112
|
+
const Model = this.$model();
|
|
1113
|
+
const pkName = Model.primaryKey;
|
|
1114
|
+
const pkField = this.$field(pkName);
|
|
1115
|
+
const pkValue = this.$get(pkName);
|
|
1116
|
+
|
|
1117
|
+
return {
|
|
1118
|
+
[pkField.column]: pkField.getBoundQueryValue(pkValue),
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
/**
|
|
1123
|
+
* Returns one of this record's live field objects.
|
|
1124
|
+
*/
|
|
1125
|
+
protected $field(fieldName: string): FieldType<any, any, any, any, any> {
|
|
1126
|
+
const field = this.$fields[fieldName];
|
|
1127
|
+
|
|
1128
|
+
if (!field) {
|
|
1129
|
+
throw new Error(`Unknown field "${fieldName}"`);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
return field;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Soft deletes the current database row.
|
|
1137
|
+
*/
|
|
1138
|
+
private async softDelete(db?: Knex): Promise<number> {
|
|
1139
|
+
const Model = this.$model();
|
|
1140
|
+
const connection = db ?? this.$db ?? Model.getDb();
|
|
1141
|
+
const deletedAt = new Date();
|
|
1142
|
+
const count = await connection(Model.table)
|
|
1143
|
+
.where(this.$primaryKeyWhere())
|
|
1144
|
+
.update(getSoftDeleteWriteData(Model, deletedAt, deletedAt));
|
|
1145
|
+
const deletedCount = Number(count);
|
|
1146
|
+
|
|
1147
|
+
if (deletedCount > 0) {
|
|
1148
|
+
this.$setSoftDeleteFieldValues(deletedAt, deletedAt);
|
|
1149
|
+
this.$markClean();
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
return deletedCount;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Mirrors soft-delete timestamp writes into this record's live field state.
|
|
1157
|
+
*/
|
|
1158
|
+
private $setSoftDeleteFieldValues(
|
|
1159
|
+
deletedAt: Date | null,
|
|
1160
|
+
updatedAt: Date,
|
|
1161
|
+
): void {
|
|
1162
|
+
const Model = this.$model();
|
|
1163
|
+
const softDeleteField = requireSoftDeleteField(Model);
|
|
1164
|
+
const ignoredFieldNames = new Set([softDeleteField.fieldName]);
|
|
1165
|
+
|
|
1166
|
+
this.$set(softDeleteField.fieldName, deletedAt);
|
|
1167
|
+
|
|
1168
|
+
for (const fieldName of getAutomaticUpdateTimestampFieldNames(Model, ignoredFieldNames)) {
|
|
1169
|
+
this.$set(fieldName, updatedAt);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
/**
|
|
1174
|
+
* Returns the static model class for this instance.
|
|
1175
|
+
*/
|
|
1176
|
+
private $model<TRecord extends ActiveRecord>(): ActiveRecordClass<TRecord> {
|
|
1177
|
+
return this.constructor as ActiveRecordClass<TRecord>;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
private $canFillFromRequest(
|
|
1181
|
+
fieldName: string,
|
|
1182
|
+
field: FieldType<any, any, any, any, any>,
|
|
1183
|
+
options: ActiveRecordRequestOptions,
|
|
1184
|
+
): boolean {
|
|
1185
|
+
if (!options.includePrimary && field.config.primary) return false;
|
|
1186
|
+
if (!options.includeGenerated && field.config.generated) return false;
|
|
1187
|
+
|
|
1188
|
+
const Model = this.$model();
|
|
1189
|
+
const fillable = options.fillable ?? Model.requestFillable;
|
|
1190
|
+
const guarded = options.guarded ?? Model.requestGuarded ?? [];
|
|
1191
|
+
|
|
1192
|
+
if (fillable && !fillable.includes(fieldName)) return false;
|
|
1193
|
+
if (guarded.includes(fieldName)) return false;
|
|
1194
|
+
|
|
1195
|
+
return true;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Defines an instance getter/setter for a configured field.
|
|
1200
|
+
*/
|
|
1201
|
+
private $installAccessor(fieldName: string): void {
|
|
1202
|
+
if (
|
|
1203
|
+
Object.prototype.hasOwnProperty.call(this, fieldName)
|
|
1204
|
+
|| this.$hasModelAccessor(fieldName)
|
|
1205
|
+
) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
Object.defineProperty(this, fieldName, {
|
|
1210
|
+
enumerable: true,
|
|
1211
|
+
configurable: true,
|
|
1212
|
+
|
|
1213
|
+
get: () => this.$get(fieldName),
|
|
1214
|
+
|
|
1215
|
+
set: value => {
|
|
1216
|
+
this.$set(fieldName, value);
|
|
1217
|
+
},
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Checks whether a model class owns a custom accessor for a field.
|
|
1223
|
+
*
|
|
1224
|
+
* Explicit model accessors may wrap the underlying field through `$get`
|
|
1225
|
+
* and `$set` when a domain value needs a stable model-owned interface.
|
|
1226
|
+
*
|
|
1227
|
+
* @param fieldName - Logical field name being installed.
|
|
1228
|
+
* @returns True when a subclass prototype defines a getter or setter.
|
|
1229
|
+
*/
|
|
1230
|
+
private $hasModelAccessor(fieldName: string): boolean {
|
|
1231
|
+
let prototype = Object.getPrototypeOf(this);
|
|
1232
|
+
|
|
1233
|
+
while (prototype && prototype !== ActiveRecord.prototype) {
|
|
1234
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, fieldName);
|
|
1235
|
+
|
|
1236
|
+
if (descriptor?.get || descriptor?.set) return true;
|
|
1237
|
+
|
|
1238
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
return false;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
function shouldUseReturningRows(
|
|
1246
|
+
Model: ActiveRecordClass,
|
|
1247
|
+
connection: Knex,
|
|
1248
|
+
): boolean {
|
|
1249
|
+
if (Model.returning === false) return false;
|
|
1250
|
+
|
|
1251
|
+
return supportsReturningRows(connection);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
function supportsReturningRows(connection: Knex): boolean {
|
|
1255
|
+
return databaseDialectForConnection(connection).supportsReturningRows;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
function shouldIncludeFieldValidationRules(
|
|
1259
|
+
Model: ActiveRecordClass,
|
|
1260
|
+
fieldName: string,
|
|
1261
|
+
field: FieldType<any, any, any, any, any>,
|
|
1262
|
+
options: ActiveRecordValidationRulesOptions,
|
|
1263
|
+
): boolean {
|
|
1264
|
+
if (!options.includeHidden && field.config.hidden) return false;
|
|
1265
|
+
if (!options.includePrimary && field.config.primary) return false;
|
|
1266
|
+
if (!options.includeGenerated && field.config.generated) return false;
|
|
1267
|
+
|
|
1268
|
+
const fillable = options.fillable ?? Model.requestFillable;
|
|
1269
|
+
const guarded = options.guarded ?? Model.requestGuarded ?? [];
|
|
1270
|
+
|
|
1271
|
+
if (fillable && !fillable.includes(fieldName)) return false;
|
|
1272
|
+
if (guarded.includes(fieldName)) return false;
|
|
1273
|
+
|
|
1274
|
+
return true;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
function isLookupCriteria(input: ActiveRecordLookup): input is Record<string, unknown> {
|
|
1278
|
+
return isRecord(input)
|
|
1279
|
+
&& !(input instanceof Date);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
type ResolvedFieldInput<TInput> =
|
|
1283
|
+
TInput extends FieldType<any, any, any, any, any>
|
|
1284
|
+
? TInput
|
|
1285
|
+
: TInput extends FieldClass<infer TField>
|
|
1286
|
+
? TField
|
|
1287
|
+
: TInput extends FieldDefinition<infer TField>
|
|
1288
|
+
? TField
|
|
1289
|
+
: never;
|
|
1290
|
+
|
|
1291
|
+
type ModelFieldInputs<TModel extends { fields(field: FieldBuilder): FieldInputMap }> =
|
|
1292
|
+
ReturnType<TModel['fields']>;
|
|
1293
|
+
|
|
1294
|
+
export namespace ActiveRecord {
|
|
1295
|
+
/** Concrete field represented by an instance, constructor or configured definition. */
|
|
1296
|
+
export type ResolvedField<TInput> = ResolvedFieldInput<TInput>;
|
|
1297
|
+
|
|
1298
|
+
export type InferInput<TModel extends { fields(field: FieldBuilder): FieldInputMap }> = {
|
|
1299
|
+
[fieldName in keyof ModelFieldInputs<TModel>]:
|
|
1300
|
+
FieldInputValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
export type InferValue<TModel extends { fields(field: FieldBuilder): FieldInputMap }> = {
|
|
1304
|
+
[fieldName in keyof ModelFieldInputs<TModel>]:
|
|
1305
|
+
FieldValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
export type InferDbRow<TModel extends { fields(field: FieldBuilder): FieldInputMap }> = {
|
|
1309
|
+
[fieldName in keyof ModelFieldInputs<TModel>]:
|
|
1310
|
+
FieldDbValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
export type InferDisplay<TModel extends { fields(field: FieldBuilder): FieldInputMap }> = {
|
|
1314
|
+
[fieldName in keyof ModelFieldInputs<TModel>]:
|
|
1315
|
+
FieldDisplayValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
|
|
1316
|
+
};
|
|
1317
|
+
}
|