@orchestr-sh/orchestr 1.11.0 → 1.11.2
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/CHANGELOG.md +20 -0
- package/CODE_OF_CONDUCT.md +43 -0
- package/CONTRIBUTING.md +274 -0
- package/dist/Cache/CacheManager.cjs +1 -1
- package/dist/Cache/CacheManager.mjs +1 -1
- package/dist/Cache/CacheManager.mjs.map +1 -1
- package/dist/Cache/Events/CacheFlushed.cjs +1 -1
- package/dist/Cache/Events/CacheFlushed.mjs +1 -1
- package/dist/Cache/Events/CacheFlushed.mjs.map +1 -1
- package/dist/Cache/Events/CacheHit.cjs +1 -1
- package/dist/Cache/Events/CacheHit.mjs +1 -1
- package/dist/Cache/Events/CacheHit.mjs.map +1 -1
- package/dist/Cache/Events/CacheMissed.cjs +1 -1
- package/dist/Cache/Events/CacheMissed.mjs +1 -1
- package/dist/Cache/Events/CacheMissed.mjs.map +1 -1
- package/dist/Cache/Events/KeyForgotten.cjs +1 -1
- package/dist/Cache/Events/KeyForgotten.mjs +1 -1
- package/dist/Cache/Events/KeyForgotten.mjs.map +1 -1
- package/dist/Cache/Events/KeyWritten.cjs +1 -1
- package/dist/Cache/Events/KeyWritten.mjs +1 -1
- package/dist/Cache/Events/KeyWritten.mjs.map +1 -1
- package/dist/Cache/Locks/CacheLock.cjs +1 -1
- package/dist/Cache/Locks/CacheLock.mjs +1 -1
- package/dist/Cache/Locks/CacheLock.mjs.map +1 -1
- package/dist/Cache/Locks/Lock.cjs +1 -1
- package/dist/Cache/Locks/Lock.mjs +1 -1
- package/dist/Cache/Locks/Lock.mjs.map +1 -1
- package/dist/Cache/Repository.cjs +1 -1
- package/dist/Cache/Repository.mjs +1 -1
- package/dist/Cache/Repository.mjs.map +1 -1
- package/dist/Cache/Stores/ArrayStore.cjs +1 -1
- package/dist/Cache/Stores/ArrayStore.mjs +1 -1
- package/dist/Cache/Stores/ArrayStore.mjs.map +1 -1
- package/dist/Cache/Stores/DatabaseStore.cjs +1 -1
- package/dist/Cache/Stores/DatabaseStore.mjs +1 -1
- package/dist/Cache/Stores/DatabaseStore.mjs.map +1 -1
- package/dist/Cache/Stores/FileStore.cjs +1 -1
- package/dist/Cache/Stores/FileStore.mjs +1 -1
- package/dist/Cache/Stores/FileStore.mjs.map +1 -1
- package/dist/Cache/Tags/TagSet.cjs +1 -1
- package/dist/Cache/Tags/TagSet.mjs +1 -1
- package/dist/Cache/Tags/TagSet.mjs.map +1 -1
- package/dist/Cache/Tags/TaggedCache.cjs +1 -1
- package/dist/Cache/Tags/TaggedCache.mjs +1 -1
- package/dist/Cache/Tags/TaggedCache.mjs.map +1 -1
- package/dist/Console/Commands/CacheClearCommand.cjs +1 -1
- package/dist/Console/Commands/CacheClearCommand.mjs +1 -1
- package/dist/Console/Commands/CacheClearCommand.mjs.map +1 -1
- package/dist/Console/Commands/CacheForgetCommand.cjs +1 -1
- package/dist/Console/Commands/CacheForgetCommand.mjs +1 -1
- package/dist/Console/Commands/CacheForgetCommand.mjs.map +1 -1
- package/dist/Console/Commands/CacheTableCommand.cjs +1 -1
- package/dist/Console/Commands/CacheTableCommand.mjs +1 -1
- package/dist/Console/Commands/CacheTableCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployEnvCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployInitCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployProvisionCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployRollbackCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployServerCommand.mjs.map +1 -1
- package/dist/Console/Commands/DeployStatusCommand.mjs.map +1 -1
- package/dist/Console/Commands/EventCacheCommand.cjs +1 -1
- package/dist/Console/Commands/EventCacheCommand.mjs +1 -1
- package/dist/Console/Commands/EventCacheCommand.mjs.map +1 -1
- package/dist/Console/Commands/EventClearCommand.cjs +1 -1
- package/dist/Console/Commands/EventClearCommand.mjs +1 -1
- package/dist/Console/Commands/EventClearCommand.mjs.map +1 -1
- package/dist/Console/Commands/EventListCommand.cjs +1 -1
- package/dist/Console/Commands/EventListCommand.mjs +1 -1
- package/dist/Console/Commands/EventListCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeControllerCommand.cjs +1 -1
- package/dist/Console/Commands/MakeControllerCommand.mjs +1 -1
- package/dist/Console/Commands/MakeControllerCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeEventCommand.cjs +1 -1
- package/dist/Console/Commands/MakeEventCommand.mjs +1 -1
- package/dist/Console/Commands/MakeEventCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeJobCommand.cjs +1 -1
- package/dist/Console/Commands/MakeJobCommand.mjs +1 -1
- package/dist/Console/Commands/MakeJobCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeListenerCommand.cjs +1 -1
- package/dist/Console/Commands/MakeListenerCommand.mjs +1 -1
- package/dist/Console/Commands/MakeListenerCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeMigrationCommand.cjs +1 -1
- package/dist/Console/Commands/MakeMigrationCommand.mjs +1 -1
- package/dist/Console/Commands/MakeMigrationCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeSeederCommand.cjs +1 -1
- package/dist/Console/Commands/MakeSeederCommand.mjs +1 -1
- package/dist/Console/Commands/MakeSeederCommand.mjs.map +1 -1
- package/dist/Console/Commands/MakeViewCommand.cjs +1 -1
- package/dist/Console/Commands/MakeViewCommand.mjs +1 -1
- package/dist/Console/Commands/MakeViewCommand.mjs.map +1 -1
- package/dist/Console/Commands/MigrateCommand.cjs +1 -1
- package/dist/Console/Commands/MigrateCommand.mjs +1 -1
- package/dist/Console/Commands/MigrateCommand.mjs.map +1 -1
- package/dist/Console/Commands/MigrateFreshCommand.cjs +1 -1
- package/dist/Console/Commands/MigrateFreshCommand.mjs +1 -1
- package/dist/Console/Commands/MigrateFreshCommand.mjs.map +1 -1
- package/dist/Console/Commands/MigrateRefreshCommand.cjs +1 -1
- package/dist/Console/Commands/MigrateRefreshCommand.mjs +1 -1
- package/dist/Console/Commands/MigrateRefreshCommand.mjs.map +1 -1
- package/dist/Console/Commands/MigrateResetCommand.cjs +1 -1
- package/dist/Console/Commands/MigrateResetCommand.mjs +1 -1
- package/dist/Console/Commands/MigrateResetCommand.mjs.map +1 -1
- package/dist/Console/Commands/MigrateRollbackCommand.cjs +1 -1
- package/dist/Console/Commands/MigrateRollbackCommand.mjs +1 -1
- package/dist/Console/Commands/MigrateRollbackCommand.mjs.map +1 -1
- package/dist/Console/Commands/MigrateStatusCommand.cjs +1 -1
- package/dist/Console/Commands/MigrateStatusCommand.mjs +1 -1
- package/dist/Console/Commands/MigrateStatusCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueBatchesTableCommand.cjs +1 -1
- package/dist/Console/Commands/QueueBatchesTableCommand.mjs +1 -1
- package/dist/Console/Commands/QueueBatchesTableCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueClearCommand.cjs +1 -1
- package/dist/Console/Commands/QueueClearCommand.mjs +1 -1
- package/dist/Console/Commands/QueueClearCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueFailedCommand.cjs +1 -1
- package/dist/Console/Commands/QueueFailedCommand.mjs +1 -1
- package/dist/Console/Commands/QueueFailedCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueFailedTableCommand.cjs +1 -1
- package/dist/Console/Commands/QueueFailedTableCommand.mjs +1 -1
- package/dist/Console/Commands/QueueFailedTableCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueFlushCommand.cjs +1 -1
- package/dist/Console/Commands/QueueFlushCommand.mjs +1 -1
- package/dist/Console/Commands/QueueFlushCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueForgetCommand.cjs +1 -1
- package/dist/Console/Commands/QueueForgetCommand.mjs +1 -1
- package/dist/Console/Commands/QueueForgetCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueMonitorCommand.cjs +1 -1
- package/dist/Console/Commands/QueueMonitorCommand.mjs +1 -1
- package/dist/Console/Commands/QueueMonitorCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueuePruneBatchesCommand.cjs +1 -1
- package/dist/Console/Commands/QueuePruneBatchesCommand.mjs +1 -1
- package/dist/Console/Commands/QueuePruneBatchesCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueuePruneFailedCommand.cjs +1 -1
- package/dist/Console/Commands/QueuePruneFailedCommand.mjs +1 -1
- package/dist/Console/Commands/QueuePruneFailedCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueRestartCommand.cjs +1 -1
- package/dist/Console/Commands/QueueRestartCommand.mjs +1 -1
- package/dist/Console/Commands/QueueRestartCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueRetryCommand.cjs +1 -1
- package/dist/Console/Commands/QueueRetryCommand.mjs +1 -1
- package/dist/Console/Commands/QueueRetryCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueTableCommand.cjs +1 -1
- package/dist/Console/Commands/QueueTableCommand.mjs +1 -1
- package/dist/Console/Commands/QueueTableCommand.mjs.map +1 -1
- package/dist/Console/Commands/QueueWorkCommand.cjs +1 -1
- package/dist/Console/Commands/QueueWorkCommand.mjs +1 -1
- package/dist/Console/Commands/QueueWorkCommand.mjs.map +1 -1
- package/dist/Console/Commands/SeedCommand.cjs +1 -1
- package/dist/Console/Commands/SeedCommand.mjs +1 -1
- package/dist/Console/Commands/SeedCommand.mjs.map +1 -1
- package/dist/Console/ConsoleKernel.cjs +1 -1
- package/dist/Console/ConsoleKernel.mjs +1 -1
- package/dist/Console/ConsoleKernel.mjs.map +1 -1
- package/dist/Console/orchestr.cjs +2 -0
- package/dist/Console/orchestr.d.cts +1 -0
- package/dist/Console/orchestr.d.mts +1 -0
- package/dist/Console/orchestr.mjs +3 -0
- package/dist/Console/orchestr.mjs.map +1 -0
- package/dist/Container/Container.mjs.map +1 -1
- package/dist/Database/Adapters/DrizzleAdapter.cjs +1 -1
- package/dist/Database/Adapters/DrizzleAdapter.mjs +1 -1
- package/dist/Database/Adapters/DrizzleAdapter.mjs.map +1 -1
- package/dist/Database/Connection.cjs +1 -1
- package/dist/Database/Connection.mjs +1 -1
- package/dist/Database/Connection.mjs.map +1 -1
- package/dist/Database/DatabaseManager.cjs +1 -1
- package/dist/Database/DatabaseManager.mjs +1 -1
- package/dist/Database/DatabaseManager.mjs.map +1 -1
- package/dist/Database/Ensemble/Ensemble.mjs.map +1 -1
- package/dist/Database/Ensemble/EnsembleBuilder.mjs.map +1 -1
- package/dist/Database/Ensemble/EnsembleCollection.cjs +1 -1
- package/dist/Database/Ensemble/EnsembleCollection.mjs +1 -1
- package/dist/Database/Ensemble/EnsembleCollection.mjs.map +1 -1
- package/dist/Database/Ensemble/Relations/BelongsTo.mjs.map +1 -1
- package/dist/Database/Ensemble/Relations/BelongsToMany.cjs +1 -1
- package/dist/Database/Ensemble/Relations/BelongsToMany.mjs +1 -1
- package/dist/Database/Ensemble/Relations/BelongsToMany.mjs.map +1 -1
- package/dist/Database/Ensemble/Relations/HasMany.mjs.map +1 -1
- package/dist/Database/Ensemble/Relations/MorphTo.mjs.map +1 -1
- package/dist/Database/Ensemble/Relations/MorphToMany.mjs.map +1 -1
- package/dist/Database/Migrations/Blueprint.cjs +1 -1
- package/dist/Database/Migrations/Blueprint.mjs +1 -1
- package/dist/Database/Migrations/Blueprint.mjs.map +1 -1
- package/dist/Database/Migrations/MigrationCreator.cjs +1 -1
- package/dist/Database/Migrations/MigrationCreator.mjs +1 -1
- package/dist/Database/Migrations/MigrationCreator.mjs.map +1 -1
- package/dist/Database/Migrations/MigrationRepository.cjs +1 -1
- package/dist/Database/Migrations/MigrationRepository.mjs +1 -1
- package/dist/Database/Migrations/MigrationRepository.mjs.map +1 -1
- package/dist/Database/Migrations/Migrator.cjs +1 -1
- package/dist/Database/Migrations/Migrator.mjs +1 -1
- package/dist/Database/Migrations/Migrator.mjs.map +1 -1
- package/dist/Database/Migrations/SchemaBuilder.cjs +1 -1
- package/dist/Database/Migrations/SchemaBuilder.mjs +1 -1
- package/dist/Database/Migrations/SchemaBuilder.mjs.map +1 -1
- package/dist/Database/Query/Builder.cjs +1 -1
- package/dist/Database/Query/Builder.mjs +1 -1
- package/dist/Database/Query/Builder.mjs.map +1 -1
- package/dist/Database/Query/Expression.cjs +1 -1
- package/dist/Database/Query/Expression.mjs +1 -1
- package/dist/Database/Query/Expression.mjs.map +1 -1
- package/dist/Database/Seeders/SeederRunner.cjs +1 -1
- package/dist/Database/Seeders/SeederRunner.mjs +1 -1
- package/dist/Database/Seeders/SeederRunner.mjs.map +1 -1
- package/dist/Deploy/Deployer.cjs +1 -1
- package/dist/Deploy/Deployer.mjs +1 -1
- package/dist/Deploy/Deployer.mjs.map +1 -1
- package/dist/Deploy/ProjectConfig.mjs.map +1 -1
- package/dist/Deploy/Provisioner.cjs +1 -1
- package/dist/Deploy/Provisioner.mjs +1 -1
- package/dist/Deploy/Provisioner.mjs.map +1 -1
- package/dist/Deploy/SSHConnection.mjs.map +1 -1
- package/dist/Deploy/SymphonyClient.cjs +1 -1
- package/dist/Deploy/SymphonyClient.mjs +1 -1
- package/dist/Deploy/SymphonyClient.mjs.map +1 -1
- package/dist/Deploy/TarBuilder.mjs.map +1 -1
- package/dist/Deploy/prompt.mjs.map +1 -1
- package/dist/Events/Dispatcher.cjs +1 -1
- package/dist/Events/Dispatcher.d.cts +1 -1
- package/dist/Events/Dispatcher.d.mts +1 -1
- package/dist/Events/Dispatcher.mjs +1 -1
- package/dist/Events/Dispatcher.mjs.map +1 -1
- package/dist/Events/EventServiceProvider.cjs +1 -1
- package/dist/Events/EventServiceProvider.d.cts +1 -1
- package/dist/Events/EventServiceProvider.d.mts +1 -1
- package/dist/Events/EventServiceProvider.mjs.map +1 -1
- package/dist/Events/index.cjs +1 -0
- package/dist/Events/index.d.cts +7 -0
- package/dist/Events/index.d.mts +7 -0
- package/dist/Events/index.mjs +1 -0
- package/dist/Facades/Bus.mjs.map +1 -1
- package/dist/Facades/Cache.mjs.map +1 -1
- package/dist/Facades/Config.mjs.map +1 -1
- package/dist/Facades/DB.mjs.map +1 -1
- package/dist/Facades/Event.d.cts +1 -1
- package/dist/Facades/Event.d.mts +1 -1
- package/dist/Facades/Event.mjs.map +1 -1
- package/dist/Facades/Queue.mjs.map +1 -1
- package/dist/Facades/Route.d.cts +1 -1
- package/dist/Facades/Route.d.mts +1 -1
- package/dist/Facades/Route.mjs.map +1 -1
- package/dist/Facades/View.mjs.map +1 -1
- package/dist/Facades/index.cjs +1 -0
- package/dist/Facades/index.d.cts +9 -0
- package/dist/Facades/index.d.mts +9 -0
- package/dist/Facades/index.mjs +1 -0
- package/dist/Foundation/Application.mjs.map +1 -1
- package/dist/Foundation/Config/ConfigServiceProvider.d.cts +1 -1
- package/dist/Foundation/Config/ConfigServiceProvider.d.mts +1 -1
- package/dist/Foundation/Http/FormRequest.d.cts +1 -1
- package/dist/Foundation/Http/FormRequest.d.mts +1 -1
- package/dist/Foundation/Http/FormRequest.mjs.map +1 -1
- package/dist/Foundation/Http/Rules/AnyOfRule.mjs.map +1 -1
- package/dist/Foundation/Http/Rules/ImageFileRule.mjs.map +1 -1
- package/dist/Foundation/Http/Validator.mjs.map +1 -1
- package/dist/Queue/Batching/Batch.cjs +1 -1
- package/dist/Queue/Batching/Batch.mjs +1 -1
- package/dist/Queue/Batching/Batch.mjs.map +1 -1
- package/dist/Queue/Batching/PendingBatch.cjs +1 -1
- package/dist/Queue/Batching/PendingBatch.mjs +1 -1
- package/dist/Queue/Batching/PendingBatch.mjs.map +1 -1
- package/dist/Queue/Concerns/Dispatchable.mjs.map +1 -1
- package/dist/Queue/Drivers/DatabaseDriver.cjs +1 -1
- package/dist/Queue/Drivers/DatabaseDriver.mjs +1 -1
- package/dist/Queue/Drivers/DatabaseDriver.mjs.map +1 -1
- package/dist/Queue/Drivers/NullDriver.cjs +1 -1
- package/dist/Queue/Drivers/NullDriver.mjs +1 -1
- package/dist/Queue/Drivers/NullDriver.mjs.map +1 -1
- package/dist/Queue/Drivers/SyncDriver.cjs +1 -1
- package/dist/Queue/Drivers/SyncDriver.mjs +1 -1
- package/dist/Queue/Drivers/SyncDriver.mjs.map +1 -1
- package/dist/Queue/Events/JobExceptionOccurred.cjs +1 -1
- package/dist/Queue/Events/JobExceptionOccurred.mjs +1 -1
- package/dist/Queue/Events/JobExceptionOccurred.mjs.map +1 -1
- package/dist/Queue/Events/JobFailed.cjs +1 -1
- package/dist/Queue/Events/JobFailed.mjs +1 -1
- package/dist/Queue/Events/JobFailed.mjs.map +1 -1
- package/dist/Queue/Events/JobProcessed.cjs +1 -1
- package/dist/Queue/Events/JobProcessed.mjs +1 -1
- package/dist/Queue/Events/JobProcessed.mjs.map +1 -1
- package/dist/Queue/Events/JobProcessing.cjs +1 -1
- package/dist/Queue/Events/JobProcessing.mjs +1 -1
- package/dist/Queue/Events/JobProcessing.mjs.map +1 -1
- package/dist/Queue/Events/JobQueued.cjs +1 -1
- package/dist/Queue/Events/JobQueued.mjs +1 -1
- package/dist/Queue/Events/JobQueued.mjs.map +1 -1
- package/dist/Queue/Events/JobRetryRequested.cjs +1 -1
- package/dist/Queue/Events/JobRetryRequested.mjs +1 -1
- package/dist/Queue/Events/JobRetryRequested.mjs.map +1 -1
- package/dist/Queue/Events/WorkerStopping.cjs +1 -1
- package/dist/Queue/Events/WorkerStopping.mjs +1 -1
- package/dist/Queue/Events/WorkerStopping.mjs.map +1 -1
- package/dist/Queue/Failed/DatabaseFailedJobProvider.cjs +1 -1
- package/dist/Queue/Failed/DatabaseFailedJobProvider.mjs +1 -1
- package/dist/Queue/Failed/DatabaseFailedJobProvider.mjs.map +1 -1
- package/dist/Queue/Middleware/RateLimited.cjs +1 -1
- package/dist/Queue/Middleware/RateLimited.mjs +1 -1
- package/dist/Queue/Middleware/RateLimited.mjs.map +1 -1
- package/dist/Queue/Middleware/ThrottlesExceptions.cjs +1 -1
- package/dist/Queue/Middleware/ThrottlesExceptions.mjs +1 -1
- package/dist/Queue/Middleware/ThrottlesExceptions.mjs.map +1 -1
- package/dist/Queue/Middleware/WithoutOverlapping.cjs +1 -1
- package/dist/Queue/Middleware/WithoutOverlapping.mjs +1 -1
- package/dist/Queue/Middleware/WithoutOverlapping.mjs.map +1 -1
- package/dist/Queue/PendingChain.cjs +1 -1
- package/dist/Queue/PendingChain.mjs +1 -1
- package/dist/Queue/PendingChain.mjs.map +1 -1
- package/dist/Queue/PendingDispatch.cjs +1 -1
- package/dist/Queue/PendingDispatch.mjs +1 -1
- package/dist/Queue/PendingDispatch.mjs.map +1 -1
- package/dist/Queue/QueueManager.cjs +1 -1
- package/dist/Queue/QueueManager.mjs +1 -1
- package/dist/Queue/QueueManager.mjs.map +1 -1
- package/dist/Queue/QueueServiceProvider.mjs.map +1 -1
- package/dist/Queue/Workers/Worker.cjs +1 -1
- package/dist/Queue/Workers/Worker.mjs +1 -1
- package/dist/Queue/Workers/Worker.mjs.map +1 -1
- package/dist/Routing/Request.mjs.map +1 -1
- package/dist/Routing/Response.mjs.map +1 -1
- package/dist/Routing/Route.d.cts +1 -1
- package/dist/Routing/Route.d.mts +1 -1
- package/dist/Routing/Router.d.cts +1 -1
- package/dist/Routing/Router.d.mts +1 -1
- package/dist/Support/EventDiscovery.cjs +1 -1
- package/dist/Support/EventDiscovery.mjs +1 -1
- package/dist/Support/EventDiscovery.mjs.map +1 -1
- package/dist/Support/Testing/Fakes/EventFake.cjs +1 -1
- package/dist/Support/Testing/Fakes/EventFake.d.cts +1 -1
- package/dist/Support/Testing/Fakes/EventFake.d.mts +1 -1
- package/dist/Support/Testing/Fakes/EventFake.mjs +1 -1
- package/dist/Support/Testing/Fakes/EventFake.mjs.map +1 -1
- package/dist/Support/helpers.mjs.map +1 -1
- package/dist/View/Engines/TemplateEngine.mjs.map +1 -1
- package/dist/index.d.cts +19 -19
- package/dist/index.d.mts +19 -19
- package/docs/events-typescript-usage.md +126 -0
- package/docs/future-improvements.md +49 -0
- package/docs/validation.md +201 -0
- package/package.json +65 -31
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Validator.mjs","names":[],"sources":["../../../src/Foundation/Http/Validator.ts"],"sourcesContent":["/**\n * Validator - Laravel's validation engine\n * Illuminate\\Validation\\Validator\n *\n * Provides validation rules and error handling\n */\n\nexport type ValidationRule = string | Array<string | ValidationRuleObject> | ValidationRuleObject;\nexport type ValidationRules = Record<string, ValidationRule>;\n\nexport interface ValidationRuleObject {\n rule: string;\n message?: string;\n}\n\nexport class Validator {\n private data: Record<string, any>;\n private rules: ValidationRules;\n private customMessages: Record<string, string>;\n private customAttributes: Record<string, string>;\n private errorMessages: Record<string, string[]> = {};\n private validatedFields: Record<string, any> = {};\n\n constructor(\n data: Record<string, any>,\n rules: ValidationRules,\n customMessages: Record<string, string> = {},\n customAttributes: Record<string, string> = {}\n ) {\n this.data = data;\n this.rules = rules;\n this.customMessages = customMessages;\n this.customAttributes = customAttributes;\n }\n\n /**\n * Validate the data against the rules\n *\n * @returns {Promise<boolean>} True if validation passes\n */\n async validate(): Promise<boolean> {\n this.errorMessages = {};\n this.validatedFields = {};\n\n for (const [field, rule] of Object.entries(this.rules)) {\n const rules = this.parseRules(rule);\n const items: Array<string | Record<string, any>> =\n typeof rule === 'string'\n ? rule.split('|').map((r) => r.trim())\n : Array.isArray(rule)\n ? rule\n : typeof rule === 'object'\n ? [rule]\n : [];\n const value = this.getFieldValue(field);\n const hasSometimes = rules.includes('sometimes');\n const hasNullable = rules.includes('nullable');\n let excluded = false;\n\n if (hasSometimes && value === undefined) {\n continue;\n }\n\n if (hasNullable && (value === undefined || value === null)) {\n if (rules.includes('required')) {\n const result = await this.validateRule(field, value, 'required', []);\n if (!result.passes) {\n this.addError(field, result.message);\n } else {\n this.validatedFields[field] = value;\n }\n } else {\n this.validatedFields[field] = value;\n }\n continue;\n }\n\n for (const item of items) {\n if (excluded) {\n break;\n }\n if (typeof item === 'string') {\n const [ruleKey, ...params] = item.split(':');\n if (ruleKey === 'exclude') {\n excluded = true;\n break;\n }\n if (ruleKey === 'exclude_if') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) === expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_unless') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) !== expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_with') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) !== undefined)) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_without') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) === undefined)) {\n excluded = true;\n break;\n }\n }\n const result = await this.validateRule(field, value, ruleKey, params);\n if (!result.passes) {\n this.addError(field, result.message);\n }\n continue;\n }\n if (\n typeof item === 'object' &&\n item &&\n (item as any).invokable === true &&\n typeof (item as any).passes === 'function'\n ) {\n const attribute = this.getAttribute(field);\n const ctx = {\n field,\n attribute,\n other: (name: string) => this.getFieldValue(name),\n helpers: {\n isPresent: (v: any) => v !== undefined,\n isEmpty: (v: any) => v === undefined || v === null || v === '',\n toNumber: (v: any) => (typeof v === 'number' ? v : parseFloat(String(v))),\n toString: (v: any) => (typeof v === 'string' ? v : String(v)),\n isDate: (v: any) => {\n const d = new Date(v);\n return !isNaN(d.getTime());\n },\n },\n };\n const passes = await (item as any).passes(attribute, value, ctx);\n if (!passes) {\n const custom =\n typeof (item as any).messageFor === 'function'\n ? (item as any).messageFor(attribute, value, ctx)\n : typeof (item as any).message === 'function'\n ? (item as any).message(attribute, value, ctx)\n : (item as any).message;\n const msg = custom || this.getMessage(field, (item as any).rule || 'rule', `The ${attribute} is invalid.`);\n this.addError(field, msg);\n }\n continue;\n }\n if (typeof item === 'object' && item && 'rule' in item) {\n const [ruleKey, ...params] = String((item as any).rule).split(':');\n if (ruleKey === 'exclude') {\n excluded = true;\n break;\n }\n if (ruleKey === 'exclude_if') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) === expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_unless') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) !== expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_with') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) !== undefined)) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_without') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) === undefined)) {\n excluded = true;\n break;\n }\n }\n const result = await this.validateRule(field, value, ruleKey, params);\n if (!result.passes) {\n this.addError(field, result.message);\n }\n continue;\n }\n }\n\n // If no errors for this field, add to validated data\n if (!excluded && !this.errorMessages[field]) {\n this.validatedFields[field] = value;\n }\n }\n\n return Object.keys(this.errorMessages).length === 0;\n }\n\n /**\n * Parse validation rules from various formats\n */\n private parseRules(rule: ValidationRule): string[] {\n if (typeof rule === 'string') {\n return rule.split('|').map((r) => r.trim());\n }\n\n if (Array.isArray(rule)) {\n return rule\n .map((r) => {\n if (typeof r === 'string') {\n return r.trim();\n }\n if (typeof r === 'object' && 'rule' in r) {\n return r.rule;\n }\n return '';\n })\n .filter((r) => r.length > 0);\n }\n\n if (typeof rule === 'object' && 'rule' in rule) {\n return [rule.rule];\n }\n\n return [];\n }\n\n /**\n * Get field value from data, supporting dot notation\n */\n private getFieldValue(field: string): any {\n const keys = field.split('.');\n let value: any = this.data;\n\n for (const key of keys) {\n if (value && typeof value === 'object' && key in value) {\n value = value[key];\n } else {\n return undefined;\n }\n }\n\n return value;\n }\n\n /**\n * Validate a single rule\n */\n private async validateRule(\n field: string,\n value: any,\n rule: string,\n params: string[]\n ): Promise<{ passes: boolean; message: string }> {\n const attribute = this.getAttribute(field);\n const listParams = params.length\n ? params\n .join(':')\n .split(/[,:]/)\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n : [];\n const other = (name: string) => this.getFieldValue(name);\n const isPresent = (v: any) => v !== undefined;\n const isEmpty = (v: any) => v === undefined || v === null || v === '';\n const toNumber = (v: any) => (typeof v === 'number' ? v : parseFloat(String(v)));\n const toString = (v: any) => (typeof v === 'string' ? v : String(v));\n const isDate = (v: any) => {\n const d = new Date(v);\n return !isNaN(d.getTime());\n };\n\n switch (rule) {\n case 'bail':\n return { passes: true, message: '' };\n\n case 'exclude':\n return { passes: true, message: '' };\n\n case 'exclude_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected) {\n return { passes: true, message: '' };\n }\n return { passes: true, message: '' };\n }\n\n case 'exclude_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected) {\n return { passes: true, message: '' };\n }\n return { passes: true, message: '' };\n }\n case 'required':\n if (value === undefined || value === null || value === '') {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'required_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_with': {\n const others = listParams;\n if (others.some((o) => isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_with_all': {\n const others = listParams;\n if (others.every((o) => isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_without': {\n const others = listParams;\n if (others.some((o) => !isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_without_all': {\n const others = listParams;\n if (others.every((o) => !isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'present':\n if (!isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n case 'present_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n case 'present_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n case 'present_with': {\n const fields = listParams;\n if (fields.some((f) => isPresent(other(f))) && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n case 'present_with_all': {\n const fields = listParams;\n if (fields.every((f) => isPresent(other(f))) && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'filled':\n if (isPresent(value) && isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must have a value.`) };\n }\n return { passes: true, message: '' };\n\n case 'accepted': {\n const acceptedValues = ['yes', 'on', '1', 1, true, 'true'];\n if (!acceptedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be accepted.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'accepted_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected) {\n const acceptedValues = ['yes', 'on', '1', 1, true, 'true'];\n if (!acceptedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be accepted.`) };\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'declined': {\n const declinedValues = ['no', 'off', '0', 0, false, 'false'];\n if (!declinedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be declined.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'declined_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected) {\n const declinedValues = ['no', 'off', '0', 0, false, 'false'];\n if (!declinedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be declined.`) };\n }\n }\n return { passes: true, message: '' };\n }\n case 'nullable':\n return { passes: true, message: '' };\n\n case 'sometimes':\n return { passes: true, message: '' };\n\n case 'email':\n if (value && !this.isValidEmail(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid email address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'string':\n if (value && typeof value !== 'string') {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a string.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'numeric':\n case 'number':\n if (value && isNaN(Number(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a number.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'integer':\n if (value && (!Number.isInteger(Number(value)) || isNaN(Number(value)))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be an integer.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'boolean':\n if (\n value !== undefined &&\n typeof value !== 'boolean' &&\n value !== 'true' &&\n value !== 'false' &&\n value !== 1 &&\n value !== 0\n ) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be true or false.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'min': {\n const minValue = params[0];\n if (typeof value === 'string' && value.length < parseInt(minValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at least ${minValue} characters.`),\n };\n }\n if (typeof value === 'number' && value < parseFloat(minValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at least ${minValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'max': {\n const maxValue = params[0];\n if (typeof value === 'string' && value.length > parseInt(maxValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may not be greater than ${maxValue} characters.`),\n };\n }\n if (typeof value === 'number' && value > parseFloat(maxValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may not be greater than ${maxValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'between': {\n const [minBetween, maxBetween] = params;\n const numValue = typeof value === 'string' ? value.length : Number(value);\n if (numValue < parseFloat(minBetween) || numValue > parseFloat(maxBetween)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be between ${minBetween} and ${maxBetween}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'size': {\n const sizeValue = params[0];\n if (typeof value === 'string' && value.length !== parseInt(sizeValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be ${sizeValue} characters.`),\n };\n }\n if (typeof value === 'number' && value !== parseFloat(sizeValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be ${sizeValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'in':\n if (value && !listParams.includes(String(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The selected ${attribute} is invalid.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'not_in':\n if (value && listParams.includes(String(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The selected ${attribute} is invalid.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'array':\n if (value && !Array.isArray(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be an array.`),\n };\n }\n return { passes: true, message: '' };\n case 'required_array_keys': {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const keys = listParams;\n const hasAll = keys.every((k) => Object.prototype.hasOwnProperty.call(value, k));\n if (!hasAll) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must contain keys: ${keys.join(', ')}.`),\n };\n }\n return { passes: true, message: '' };\n }\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be an array.`) };\n }\n\n case 'confirmed': {\n const confirmationField = `${field}_confirmation`;\n const confirmationValue = this.data[confirmationField];\n if (value !== confirmationValue) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} confirmation does not match.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'url':\n if (value && !this.isValidUrl(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid URL.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'alpha':\n if (value && !/^[a-zA-Z]+$/.test(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may only contain letters.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'alpha_num':\n if (value && !/^[a-zA-Z0-9]+$/.test(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may only contain letters and numbers.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'alpha_dash':\n if (value && !/^[a-zA-Z0-9_-]+$/.test(value)) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} may only contain letters, numbers, dashes and underscores.`\n ),\n };\n }\n return { passes: true, message: '' };\n\n case 'regex': {\n const pattern = new RegExp(params.join(':'));\n if (value && !pattern.test(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} format is invalid.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'not_regex': {\n const pattern = new RegExp(params.join(':'));\n if (value && pattern.test(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} format is invalid.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'json':\n if (value) {\n try {\n JSON.parse(typeof value === 'string' ? value : String(value));\n } catch {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a valid JSON.`) };\n }\n }\n return { passes: true, message: '' };\n\n case 'ascii':\n if (value && /[^\\x00-\\x7F]/.test(toString(value))) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be ASCII characters.`) };\n }\n return { passes: true, message: '' };\n\n case 'decimal': {\n const places = params[0] ? parseInt(params[0]) : undefined;\n if (value !== undefined) {\n const s = toString(value);\n const m = s.match(/^[-+]?\\d+(\\.(\\d+))?$/);\n if (!m) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a decimal.`) };\n }\n if (places !== undefined) {\n const dp = m[2]?.length || 0;\n if (dp !== places) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must have ${places} decimal places.`),\n };\n }\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'starts_with':\n if (value) {\n const s = toString(value);\n if (!listParams.some((p) => s.startsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must start with one of: ${listParams.join(', ')}.`\n ),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'ends_with':\n if (value) {\n const s = toString(value);\n if (!listParams.some((p) => s.endsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must end with one of: ${listParams.join(', ')}.`),\n };\n }\n }\n return { passes: true, message: '' };\n case 'doesnt_start_with':\n if (value) {\n const s = toString(value);\n if (listParams.some((p) => s.startsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must not start with one of: ${listParams.join(', ')}.`\n ),\n };\n }\n }\n return { passes: true, message: '' };\n case 'doesnt_end_with':\n if (value) {\n const s = toString(value);\n if (listParams.some((p) => s.endsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must not end with one of: ${listParams.join(', ')}.`\n ),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'distinct':\n if (Array.isArray(value)) {\n const set = new Set(value.map((v) => JSON.stringify(v)));\n if (set.size !== value.length) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must not have duplicates.`),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'same': {\n const [otherField] = params;\n if (toString(value) !== toString(other(otherField))) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must match ${otherField}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'different': {\n const [otherField] = params;\n if (toString(value) === toString(other(otherField))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be different from ${otherField}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'gt': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) > toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be greater than ${otherFieldOrValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'gte': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) >= toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must be greater than or equal to ${otherFieldOrValue}.`\n ),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'lt': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) < toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be less than ${otherFieldOrValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'lte': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) <= toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must be less than or equal to ${otherFieldOrValue}.`\n ),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'uuid':\n if (\n value &&\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{4}-[0-9a-f]{12}$/i.test(toString(value))\n ) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a valid UUID.`) };\n }\n return { passes: true, message: '' };\n\n case 'timezone':\n if (value) {\n const v = toString(value);\n const zones = (Intl as any).supportedValuesOf ? (Intl as any).supportedValuesOf('timeZone') : [];\n if (!zones.includes(v)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid timezone.`),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'date':\n if (value && !isDate(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} is not a valid date.`) };\n }\n return { passes: true, message: '' };\n\n case 'date_equals':\n if (value) {\n const d1 = new Date(value).getTime();\n const d2 = new Date(params[0]).getTime();\n if (isNaN(d1) || isNaN(d2) || d1 !== d2) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must equal ${params[0]}.`),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'after': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v <= c) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be after ${cmp}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'after_or_equal': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v < c) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be after or equal to ${cmp}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'before': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v >= c) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be before ${cmp}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'before_or_equal': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v > c) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be before or equal to ${cmp}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'digits': {\n const len = parseInt(params[0]);\n if (!/^\\d+$/.test(String(value)) || String(value).length !== len) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be ${len} digits.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'digits_between': {\n const minD = parseInt(params[0]);\n const maxD = parseInt(params[1]);\n const s = String(value);\n if (!/^\\d+$/.test(s) || s.length < minD || s.length > maxD) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be between ${minD} and ${maxD} digits.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'min_digits': {\n const minD = parseInt(params[0]);\n const s = String(value);\n if (!/^\\d+$/.test(s) || s.length < minD) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at least ${minD} digits.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'max_digits': {\n const maxD = parseInt(params[0]);\n const s = String(value);\n if (!/^\\d+$/.test(s) || s.length > maxD) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at most ${maxD} digits.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'multiple_of': {\n const base = parseFloat(params[0]);\n if (Number.isFinite(base) && toNumber(value) % base !== 0) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a multiple of ${base}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'ip':\n if (value && !/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid IP address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'ipv4':\n if (value && !/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid IPv4 address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'ipv6':\n if (value && !/^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$/i.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid IPv6 address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'mac_address':\n if (value && !/^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid MAC address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'lowercase':\n if (value && toString(value) !== toString(value).toLowerCase()) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be lowercase.`) };\n }\n return { passes: true, message: '' };\n\n case 'uppercase':\n if (value && toString(value) !== toString(value).toUpperCase()) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be uppercase.`) };\n }\n return { passes: true, message: '' };\n\n case 'in_array': {\n const [otherField] = params;\n const arr = other(otherField);\n if (!Array.isArray(arr) || !arr.map((v: any) => String(v)).includes(String(value))) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be in ${otherField}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'prohibited':\n if (isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field is prohibited.`) };\n }\n return { passes: true, message: '' };\n\n case 'prohibited_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field is prohibited.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'prohibited_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field is prohibited.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'prohibits': {\n const others = listParams;\n if (isPresent(value) && others.some((o) => isPresent(other(o)))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} prohibits ${others.join(', ')} from being present.`\n ),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'file':\n if (value && typeof value !== 'object') {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a file.`) };\n }\n return { passes: true, message: '' };\n\n case 'image':\n if (value && typeof value === 'object') {\n const type = (value.mimetype || value.type || '').toString();\n if (!type.startsWith('image/')) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be an image.`) };\n }\n }\n return { passes: true, message: '' };\n\n case 'mimetypes': {\n const allowed = listParams;\n if (value && typeof value === 'object') {\n const type = (value.mimetype || value.type || '').toString();\n if (!allowed.includes(type)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} has an invalid mimetype.`),\n };\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'mimes': {\n const allowed = listParams;\n if (value && typeof value === 'object') {\n const type = (value.mimetype || value.type || '').toString();\n const ext = (value.extension || '').toString();\n if (!(allowed.includes(ext) || allowed.some((m) => type.endsWith(`/${m}`)))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} has an invalid file type.`),\n };\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'active_url':\n if (value && !this.isValidUrl(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} is not a valid URL.`) };\n }\n return { passes: true, message: '' };\n case 'missing':\n if (isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n case 'missing_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'missing_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'missing_with': {\n const fields = listParams;\n if (fields.some((f) => isPresent(other(f))) && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'missing_with_all': {\n const fields = listParams;\n if (fields.every((f) => isPresent(other(f))) && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'current_password':\n return { passes: true, message: '' };\n\n default:\n console.warn(`Unknown validation rule: ${rule}`);\n return { passes: true, message: '' };\n }\n }\n\n /**\n * Validate email format\n */\n private isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n\n /**\n * Validate URL format\n */\n private isValidUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get custom message or default message\n */\n private getMessage(field: string, rule: string, defaultMessage: string): string {\n const customKey = `${field}.${rule}`;\n return this.customMessages[customKey] || this.customMessages[rule] || defaultMessage;\n }\n\n /**\n * Get custom attribute name or use field name\n */\n private getAttribute(field: string): string {\n return this.customAttributes[field] || field.replace(/_/g, ' ');\n }\n\n /**\n * Add an error message for a field\n */\n private addError(field: string, message: string): void {\n if (!this.errorMessages[field]) {\n this.errorMessages[field] = [];\n }\n this.errorMessages[field].push(message);\n }\n\n /**\n * Get all error messages\n * Laravel: $validator->errors()\n */\n errors(): Record<string, string[]> {\n return this.errorMessages;\n }\n\n /**\n * Check if validation failed\n * Laravel: $validator->fails()\n */\n fails(): boolean {\n return Object.keys(this.errorMessages).length > 0;\n }\n\n /**\n * Check if validation passed\n * Laravel: $validator->passes()\n */\n passes(): boolean {\n return !this.fails();\n }\n\n /**\n * Get the validated data\n * Laravel: $validator->validated()\n */\n validated(): Record<string, any> {\n return this.validatedFields;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Validator.mjs","names":["others","fields"],"sources":["../../../src/Foundation/Http/Validator.ts"],"sourcesContent":["/**\n * Validator - Laravel's validation engine\n * Illuminate\\Validation\\Validator\n *\n * Provides validation rules and error handling\n */\n\nexport type ValidationRule = string | Array<string | ValidationRuleObject> | ValidationRuleObject;\nexport type ValidationRules = Record<string, ValidationRule>;\n\nexport interface ValidationRuleObject {\n rule: string;\n message?: string;\n}\n\nexport class Validator {\n private data: Record<string, any>;\n private rules: ValidationRules;\n private customMessages: Record<string, string>;\n private customAttributes: Record<string, string>;\n private errorMessages: Record<string, string[]> = {};\n private validatedFields: Record<string, any> = {};\n\n constructor(\n data: Record<string, any>,\n rules: ValidationRules,\n customMessages: Record<string, string> = {},\n customAttributes: Record<string, string> = {}\n ) {\n this.data = data;\n this.rules = rules;\n this.customMessages = customMessages;\n this.customAttributes = customAttributes;\n }\n\n /**\n * Validate the data against the rules\n *\n * @returns {Promise<boolean>} True if validation passes\n */\n async validate(): Promise<boolean> {\n this.errorMessages = {};\n this.validatedFields = {};\n\n for (const [field, rule] of Object.entries(this.rules)) {\n const rules = this.parseRules(rule);\n const items: Array<string | Record<string, any>> =\n typeof rule === 'string'\n ? rule.split('|').map((r) => r.trim())\n : Array.isArray(rule)\n ? rule\n : typeof rule === 'object'\n ? [rule]\n : [];\n const value = this.getFieldValue(field);\n const hasSometimes = rules.includes('sometimes');\n const hasNullable = rules.includes('nullable');\n let excluded = false;\n\n if (hasSometimes && value === undefined) {\n continue;\n }\n\n if (hasNullable && (value === undefined || value === null)) {\n if (rules.includes('required')) {\n const result = await this.validateRule(field, value, 'required', []);\n if (!result.passes) {\n this.addError(field, result.message);\n } else {\n this.validatedFields[field] = value;\n }\n } else {\n this.validatedFields[field] = value;\n }\n continue;\n }\n\n for (const item of items) {\n if (excluded) {\n break;\n }\n if (typeof item === 'string') {\n const [ruleKey, ...params] = item.split(':');\n if (ruleKey === 'exclude') {\n excluded = true;\n break;\n }\n if (ruleKey === 'exclude_if') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) === expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_unless') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) !== expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_with') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) !== undefined)) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_without') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) === undefined)) {\n excluded = true;\n break;\n }\n }\n const result = await this.validateRule(field, value, ruleKey, params);\n if (!result.passes) {\n this.addError(field, result.message);\n }\n continue;\n }\n if (\n typeof item === 'object' &&\n item &&\n (item as any).invokable === true &&\n typeof (item as any).passes === 'function'\n ) {\n const attribute = this.getAttribute(field);\n const ctx = {\n field,\n attribute,\n other: (name: string) => this.getFieldValue(name),\n helpers: {\n isPresent: (v: any) => v !== undefined,\n isEmpty: (v: any) => v === undefined || v === null || v === '',\n toNumber: (v: any) => (typeof v === 'number' ? v : parseFloat(String(v))),\n toString: (v: any) => (typeof v === 'string' ? v : String(v)),\n isDate: (v: any) => {\n const d = new Date(v);\n return !isNaN(d.getTime());\n },\n },\n };\n const passes = await (item as any).passes(attribute, value, ctx);\n if (!passes) {\n const custom =\n typeof (item as any).messageFor === 'function'\n ? (item as any).messageFor(attribute, value, ctx)\n : typeof (item as any).message === 'function'\n ? (item as any).message(attribute, value, ctx)\n : (item as any).message;\n const msg = custom || this.getMessage(field, (item as any).rule || 'rule', `The ${attribute} is invalid.`);\n this.addError(field, msg);\n }\n continue;\n }\n if (typeof item === 'object' && item && 'rule' in item) {\n const [ruleKey, ...params] = String((item as any).rule).split(':');\n if (ruleKey === 'exclude') {\n excluded = true;\n break;\n }\n if (ruleKey === 'exclude_if') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) === expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_unless') {\n const [otherField, expected] = params;\n const ov = this.getFieldValue(otherField);\n if (String(ov) !== expected) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_with') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) !== undefined)) {\n excluded = true;\n break;\n }\n }\n if (ruleKey === 'exclude_without') {\n const fields = params\n .join(':')\n .split(',')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n if (fields.some((f) => this.getFieldValue(f) === undefined)) {\n excluded = true;\n break;\n }\n }\n const result = await this.validateRule(field, value, ruleKey, params);\n if (!result.passes) {\n this.addError(field, result.message);\n }\n continue;\n }\n }\n\n // If no errors for this field, add to validated data\n if (!excluded && !this.errorMessages[field]) {\n this.validatedFields[field] = value;\n }\n }\n\n return Object.keys(this.errorMessages).length === 0;\n }\n\n /**\n * Parse validation rules from various formats\n */\n private parseRules(rule: ValidationRule): string[] {\n if (typeof rule === 'string') {\n return rule.split('|').map((r) => r.trim());\n }\n\n if (Array.isArray(rule)) {\n return rule\n .map((r) => {\n if (typeof r === 'string') {\n return r.trim();\n }\n if (typeof r === 'object' && 'rule' in r) {\n return r.rule;\n }\n return '';\n })\n .filter((r) => r.length > 0);\n }\n\n if (typeof rule === 'object' && 'rule' in rule) {\n return [rule.rule];\n }\n\n return [];\n }\n\n /**\n * Get field value from data, supporting dot notation\n */\n private getFieldValue(field: string): any {\n const keys = field.split('.');\n let value: any = this.data;\n\n for (const key of keys) {\n if (value && typeof value === 'object' && key in value) {\n value = value[key];\n } else {\n return undefined;\n }\n }\n\n return value;\n }\n\n /**\n * Validate a single rule\n */\n private async validateRule(\n field: string,\n value: any,\n rule: string,\n params: string[]\n ): Promise<{ passes: boolean; message: string }> {\n const attribute = this.getAttribute(field);\n const listParams = params.length\n ? params\n .join(':')\n .split(/[,:]/)\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n : [];\n const other = (name: string) => this.getFieldValue(name);\n const isPresent = (v: any) => v !== undefined;\n const isEmpty = (v: any) => v === undefined || v === null || v === '';\n const toNumber = (v: any) => (typeof v === 'number' ? v : parseFloat(String(v)));\n const toString = (v: any) => (typeof v === 'string' ? v : String(v));\n const isDate = (v: any) => {\n const d = new Date(v);\n return !isNaN(d.getTime());\n };\n\n switch (rule) {\n case 'bail':\n return { passes: true, message: '' };\n\n case 'exclude':\n return { passes: true, message: '' };\n\n case 'exclude_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected) {\n return { passes: true, message: '' };\n }\n return { passes: true, message: '' };\n }\n\n case 'exclude_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected) {\n return { passes: true, message: '' };\n }\n return { passes: true, message: '' };\n }\n case 'required':\n if (value === undefined || value === null || value === '') {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'required_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_with': {\n const others = listParams;\n if (others.some((o) => isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_with_all': {\n const others = listParams;\n if (others.every((o) => isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_without': {\n const others = listParams;\n if (others.some((o) => !isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'required_without_all': {\n const others = listParams;\n if (others.every((o) => !isPresent(other(o))) && isEmpty(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} field is required.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'present':\n if (!isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n case 'present_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n case 'present_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n case 'present_with': {\n const fields = listParams;\n if (fields.some((f) => isPresent(other(f))) && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n case 'present_with_all': {\n const fields = listParams;\n if (fields.every((f) => isPresent(other(f))) && !isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field must be present.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'filled':\n if (isPresent(value) && isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must have a value.`) };\n }\n return { passes: true, message: '' };\n\n case 'accepted': {\n const acceptedValues = ['yes', 'on', '1', 1, true, 'true'];\n if (!acceptedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be accepted.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'accepted_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected) {\n const acceptedValues = ['yes', 'on', '1', 1, true, 'true'];\n if (!acceptedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be accepted.`) };\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'declined': {\n const declinedValues = ['no', 'off', '0', 0, false, 'false'];\n if (!declinedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be declined.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'declined_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected) {\n const declinedValues = ['no', 'off', '0', 0, false, 'false'];\n if (!declinedValues.includes(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be declined.`) };\n }\n }\n return { passes: true, message: '' };\n }\n case 'nullable':\n return { passes: true, message: '' };\n\n case 'sometimes':\n return { passes: true, message: '' };\n\n case 'email':\n if (value && !this.isValidEmail(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid email address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'string':\n if (value && typeof value !== 'string') {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a string.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'numeric':\n case 'number':\n if (value && isNaN(Number(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a number.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'integer':\n if (value && (!Number.isInteger(Number(value)) || isNaN(Number(value)))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be an integer.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'boolean':\n if (\n value !== undefined &&\n typeof value !== 'boolean' &&\n value !== 'true' &&\n value !== 'false' &&\n value !== 1 &&\n value !== 0\n ) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be true or false.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'min': {\n const minValue = params[0];\n if (typeof value === 'string' && value.length < parseInt(minValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at least ${minValue} characters.`),\n };\n }\n if (typeof value === 'number' && value < parseFloat(minValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at least ${minValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'max': {\n const maxValue = params[0];\n if (typeof value === 'string' && value.length > parseInt(maxValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may not be greater than ${maxValue} characters.`),\n };\n }\n if (typeof value === 'number' && value > parseFloat(maxValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may not be greater than ${maxValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'between': {\n const [minBetween, maxBetween] = params;\n const numValue = typeof value === 'string' ? value.length : Number(value);\n if (numValue < parseFloat(minBetween) || numValue > parseFloat(maxBetween)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be between ${minBetween} and ${maxBetween}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'size': {\n const sizeValue = params[0];\n if (typeof value === 'string' && value.length !== parseInt(sizeValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be ${sizeValue} characters.`),\n };\n }\n if (typeof value === 'number' && value !== parseFloat(sizeValue)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be ${sizeValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'in':\n if (value && !listParams.includes(String(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The selected ${attribute} is invalid.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'not_in':\n if (value && listParams.includes(String(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The selected ${attribute} is invalid.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'array':\n if (value && !Array.isArray(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be an array.`),\n };\n }\n return { passes: true, message: '' };\n case 'required_array_keys': {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const keys = listParams;\n const hasAll = keys.every((k) => Object.prototype.hasOwnProperty.call(value, k));\n if (!hasAll) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must contain keys: ${keys.join(', ')}.`),\n };\n }\n return { passes: true, message: '' };\n }\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be an array.`) };\n }\n\n case 'confirmed': {\n const confirmationField = `${field}_confirmation`;\n const confirmationValue = this.data[confirmationField];\n if (value !== confirmationValue) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} confirmation does not match.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'url':\n if (value && !this.isValidUrl(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid URL.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'alpha':\n if (value && !/^[a-zA-Z]+$/.test(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may only contain letters.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'alpha_num':\n if (value && !/^[a-zA-Z0-9]+$/.test(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} may only contain letters and numbers.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'alpha_dash':\n if (value && !/^[a-zA-Z0-9_-]+$/.test(value)) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} may only contain letters, numbers, dashes and underscores.`\n ),\n };\n }\n return { passes: true, message: '' };\n\n case 'regex': {\n const pattern = new RegExp(params.join(':'));\n if (value && !pattern.test(value)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} format is invalid.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'not_regex': {\n const pattern = new RegExp(params.join(':'));\n if (value && pattern.test(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} format is invalid.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'json':\n if (value) {\n try {\n JSON.parse(typeof value === 'string' ? value : String(value));\n } catch {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a valid JSON.`) };\n }\n }\n return { passes: true, message: '' };\n\n case 'ascii':\n if (value && /[^\\x00-\\x7F]/.test(toString(value))) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be ASCII characters.`) };\n }\n return { passes: true, message: '' };\n\n case 'decimal': {\n const places = params[0] ? parseInt(params[0]) : undefined;\n if (value !== undefined) {\n const s = toString(value);\n const m = s.match(/^[-+]?\\d+(\\.(\\d+))?$/);\n if (!m) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a decimal.`) };\n }\n if (places !== undefined) {\n const dp = m[2]?.length || 0;\n if (dp !== places) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must have ${places} decimal places.`),\n };\n }\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'starts_with':\n if (value) {\n const s = toString(value);\n if (!listParams.some((p) => s.startsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must start with one of: ${listParams.join(', ')}.`\n ),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'ends_with':\n if (value) {\n const s = toString(value);\n if (!listParams.some((p) => s.endsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must end with one of: ${listParams.join(', ')}.`),\n };\n }\n }\n return { passes: true, message: '' };\n case 'doesnt_start_with':\n if (value) {\n const s = toString(value);\n if (listParams.some((p) => s.startsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must not start with one of: ${listParams.join(', ')}.`\n ),\n };\n }\n }\n return { passes: true, message: '' };\n case 'doesnt_end_with':\n if (value) {\n const s = toString(value);\n if (listParams.some((p) => s.endsWith(p))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must not end with one of: ${listParams.join(', ')}.`\n ),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'distinct':\n if (Array.isArray(value)) {\n const set = new Set(value.map((v) => JSON.stringify(v)));\n if (set.size !== value.length) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must not have duplicates.`),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'same': {\n const [otherField] = params;\n if (toString(value) !== toString(other(otherField))) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must match ${otherField}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'different': {\n const [otherField] = params;\n if (toString(value) === toString(other(otherField))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be different from ${otherField}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'gt': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) > toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be greater than ${otherFieldOrValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'gte': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) >= toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must be greater than or equal to ${otherFieldOrValue}.`\n ),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'lt': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) < toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be less than ${otherFieldOrValue}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'lte': {\n const [otherFieldOrValue] = params;\n const cmp = isNaN(Number(otherFieldOrValue)) ? other(otherFieldOrValue) : parseFloat(otherFieldOrValue);\n if (!(toNumber(value) <= toNumber(cmp))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} must be less than or equal to ${otherFieldOrValue}.`\n ),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'uuid':\n if (\n value &&\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{4}-[0-9a-f]{12}$/i.test(toString(value))\n ) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a valid UUID.`) };\n }\n return { passes: true, message: '' };\n\n case 'timezone':\n if (value) {\n const v = toString(value);\n const zones = (Intl as any).supportedValuesOf ? (Intl as any).supportedValuesOf('timeZone') : [];\n if (!zones.includes(v)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid timezone.`),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'date':\n if (value && !isDate(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} is not a valid date.`) };\n }\n return { passes: true, message: '' };\n\n case 'date_equals':\n if (value) {\n const d1 = new Date(value).getTime();\n const d2 = new Date(params[0]).getTime();\n if (isNaN(d1) || isNaN(d2) || d1 !== d2) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must equal ${params[0]}.`),\n };\n }\n }\n return { passes: true, message: '' };\n\n case 'after': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v <= c) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be after ${cmp}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'after_or_equal': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v < c) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be after or equal to ${cmp}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'before': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v >= c) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be before ${cmp}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'before_or_equal': {\n const cmp = params[0];\n const v = new Date(value).getTime();\n const ov = other(cmp);\n const c = isDate(ov) ? new Date(ov).getTime() : new Date(cmp).getTime();\n if (isNaN(v) || isNaN(c) || v > c) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be before or equal to ${cmp}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'digits': {\n const len = parseInt(params[0]);\n if (!/^\\d+$/.test(String(value)) || String(value).length !== len) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be ${len} digits.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'digits_between': {\n const minD = parseInt(params[0]);\n const maxD = parseInt(params[1]);\n const s = String(value);\n if (!/^\\d+$/.test(s) || s.length < minD || s.length > maxD) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be between ${minD} and ${maxD} digits.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'min_digits': {\n const minD = parseInt(params[0]);\n const s = String(value);\n if (!/^\\d+$/.test(s) || s.length < minD) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at least ${minD} digits.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'max_digits': {\n const maxD = parseInt(params[0]);\n const s = String(value);\n if (!/^\\d+$/.test(s) || s.length > maxD) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be at most ${maxD} digits.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'multiple_of': {\n const base = parseFloat(params[0]);\n if (Number.isFinite(base) && toNumber(value) % base !== 0) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a multiple of ${base}.`),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'ip':\n if (value && !/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid IP address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'ipv4':\n if (value && !/^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid IPv4 address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'ipv6':\n if (value && !/^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$/i.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid IPv6 address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'mac_address':\n if (value && !/^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/.test(toString(value))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} must be a valid MAC address.`),\n };\n }\n return { passes: true, message: '' };\n\n case 'lowercase':\n if (value && toString(value) !== toString(value).toLowerCase()) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be lowercase.`) };\n }\n return { passes: true, message: '' };\n\n case 'uppercase':\n if (value && toString(value) !== toString(value).toUpperCase()) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be uppercase.`) };\n }\n return { passes: true, message: '' };\n\n case 'in_array': {\n const [otherField] = params;\n const arr = other(otherField);\n if (!Array.isArray(arr) || !arr.map((v: any) => String(v)).includes(String(value))) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be in ${otherField}.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'prohibited':\n if (isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field is prohibited.`) };\n }\n return { passes: true, message: '' };\n\n case 'prohibited_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field is prohibited.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'prohibited_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && isPresent(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} field is prohibited.`) };\n }\n return { passes: true, message: '' };\n }\n\n case 'prohibits': {\n const others = listParams;\n if (isPresent(value) && others.some((o) => isPresent(other(o)))) {\n return {\n passes: false,\n message: this.getMessage(\n field,\n rule,\n `The ${attribute} prohibits ${others.join(', ')} from being present.`\n ),\n };\n }\n return { passes: true, message: '' };\n }\n\n case 'file':\n if (value && typeof value !== 'object') {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be a file.`) };\n }\n return { passes: true, message: '' };\n\n case 'image':\n if (value && typeof value === 'object') {\n const type = (value.mimetype || value.type || '').toString();\n if (!type.startsWith('image/')) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be an image.`) };\n }\n }\n return { passes: true, message: '' };\n\n case 'mimetypes': {\n const allowed = listParams;\n if (value && typeof value === 'object') {\n const type = (value.mimetype || value.type || '').toString();\n if (!allowed.includes(type)) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} has an invalid mimetype.`),\n };\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'mimes': {\n const allowed = listParams;\n if (value && typeof value === 'object') {\n const type = (value.mimetype || value.type || '').toString();\n const ext = (value.extension || '').toString();\n if (!(allowed.includes(ext) || allowed.some((m) => type.endsWith(`/${m}`)))) {\n return {\n passes: false,\n message: this.getMessage(field, rule, `The ${attribute} has an invalid file type.`),\n };\n }\n }\n return { passes: true, message: '' };\n }\n\n case 'active_url':\n if (value && !this.isValidUrl(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} is not a valid URL.`) };\n }\n return { passes: true, message: '' };\n case 'missing':\n if (isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n case 'missing_if': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) === expected && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'missing_unless': {\n const [otherField, expected] = params;\n const ov = other(otherField);\n if (toString(ov) !== expected && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'missing_with': {\n const fields = listParams;\n if (fields.some((f) => isPresent(other(f))) && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'missing_with_all': {\n const fields = listParams;\n if (fields.every((f) => isPresent(other(f))) && isPresent(value) && !isEmpty(value)) {\n return { passes: false, message: this.getMessage(field, rule, `The ${attribute} must be missing.`) };\n }\n return { passes: true, message: '' };\n }\n case 'current_password':\n return { passes: true, message: '' };\n\n default:\n console.warn(`Unknown validation rule: ${rule}`);\n return { passes: true, message: '' };\n }\n }\n\n /**\n * Validate email format\n */\n private isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n\n /**\n * Validate URL format\n */\n private isValidUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get custom message or default message\n */\n private getMessage(field: string, rule: string, defaultMessage: string): string {\n const customKey = `${field}.${rule}`;\n return this.customMessages[customKey] || this.customMessages[rule] || defaultMessage;\n }\n\n /**\n * Get custom attribute name or use field name\n */\n private getAttribute(field: string): string {\n return this.customAttributes[field] || field.replace(/_/g, ' ');\n }\n\n /**\n * Add an error message for a field\n */\n private addError(field: string, message: string): void {\n if (!this.errorMessages[field]) {\n this.errorMessages[field] = [];\n }\n this.errorMessages[field].push(message);\n }\n\n /**\n * Get all error messages\n * Laravel: $validator->errors()\n */\n errors(): Record<string, string[]> {\n return this.errorMessages;\n }\n\n /**\n * Check if validation failed\n * Laravel: $validator->fails()\n */\n fails(): boolean {\n return Object.keys(this.errorMessages).length > 0;\n }\n\n /**\n * Check if validation passed\n * Laravel: $validator->passes()\n */\n passes(): boolean {\n return !this.fails();\n }\n\n /**\n * Get the validated data\n * Laravel: $validator->validated()\n */\n validated(): Record<string, any> {\n return this.validatedFields;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`crypto`);var t=class{id;createdAt;_totalJobs;_pendingJobs;_failedJobs=0;_failedJobIds=[];_cancelled=!1;_finishedAt=null;_options;constructor(t,n,r,i){this.manager=t,this.name=n,this.id=(0,e.randomUUID)(),this.createdAt=new Date,this._totalJobs=r,this._pendingJobs=r,this._options=i}get totalJobs(){return this._totalJobs}get pendingJobs(){return this._pendingJobs}get failedJobs(){return this._failedJobs}get processedJobs(){return this._totalJobs-this._pendingJobs}progress(){return this._totalJobs===0?100:Math.round(this.processedJobs/this._totalJobs*100)}finished(){return this._pendingJobs===0}cancelled(){return this._cancelled}async recordSuccessfulJob(e){this._pendingJobs=Math.max(0,this._pendingJobs-1),this.finished()&&(await this.fireThenCallbacks(),await this.fireFinallyCallbacks(),this._finishedAt=new Date)}async recordFailedJob(e,t){this._failedJobs++,this._failedJobIds.push(e),this._pendingJobs=Math.max(0,this._pendingJobs-1),await this.fireCatchCallbacks(t),this._options.allowFailures||this.cancel(),this.finished()&&(await this.fireFinallyCallbacks(),this._finishedAt=new Date)}cancel(){this._cancelled=!0}async fireThenCallbacks(){for(let e of this._options.thenCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch then callback:`,e)}}async fireCatchCallbacks(e){for(let t of this._options.catchCallbacks)try{await t(this,e)}catch(e){console.error(`[Queue] Error in batch catch callback:`,e)}}async fireFinallyCallbacks(){for(let e of this._options.finallyCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch finally callback:`,e)}}toJSON(){return{id:this.id,name:this.name,totalJobs:this._totalJobs,pendingJobs:this._pendingJobs,failedJobs:this._failedJobs,processedJobs:this.processedJobs,progress:this.progress(),cancelled:this._cancelled,createdAt:this.createdAt.toISOString(),finishedAt:this._finishedAt?.toISOString()||null}}};exports.Batch=t;
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`crypto`);var t=class{manager;name;id;createdAt;_totalJobs;_pendingJobs;_failedJobs=0;_failedJobIds=[];_cancelled=!1;_finishedAt=null;_options;constructor(t,n,r,i){this.manager=t,this.name=n,this.id=(0,e.randomUUID)(),this.createdAt=new Date,this._totalJobs=r,this._pendingJobs=r,this._options=i}get totalJobs(){return this._totalJobs}get pendingJobs(){return this._pendingJobs}get failedJobs(){return this._failedJobs}get processedJobs(){return this._totalJobs-this._pendingJobs}progress(){return this._totalJobs===0?100:Math.round(this.processedJobs/this._totalJobs*100)}finished(){return this._pendingJobs===0}cancelled(){return this._cancelled}async recordSuccessfulJob(e){this._pendingJobs=Math.max(0,this._pendingJobs-1),this.finished()&&(await this.fireThenCallbacks(),await this.fireFinallyCallbacks(),this._finishedAt=new Date)}async recordFailedJob(e,t){this._failedJobs++,this._failedJobIds.push(e),this._pendingJobs=Math.max(0,this._pendingJobs-1),await this.fireCatchCallbacks(t),this._options.allowFailures||this.cancel(),this.finished()&&(await this.fireFinallyCallbacks(),this._finishedAt=new Date)}cancel(){this._cancelled=!0}async fireThenCallbacks(){for(let e of this._options.thenCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch then callback:`,e)}}async fireCatchCallbacks(e){for(let t of this._options.catchCallbacks)try{await t(this,e)}catch(e){console.error(`[Queue] Error in batch catch callback:`,e)}}async fireFinallyCallbacks(){for(let e of this._options.finallyCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch finally callback:`,e)}}toJSON(){return{id:this.id,name:this.name,totalJobs:this._totalJobs,pendingJobs:this._pendingJobs,failedJobs:this._failedJobs,processedJobs:this.processedJobs,progress:this.progress(),cancelled:this._cancelled,createdAt:this.createdAt.toISOString(),finishedAt:this._finishedAt?.toISOString()||null}}};exports.Batch=t;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{randomUUID as e}from"crypto";var t=class{id;createdAt;_totalJobs;_pendingJobs;_failedJobs=0;_failedJobIds=[];_cancelled=!1;_finishedAt=null;_options;constructor(t,n,r,i){this.manager=t,this.name=n,this.id=e(),this.createdAt=new Date,this._totalJobs=r,this._pendingJobs=r,this._options=i}get totalJobs(){return this._totalJobs}get pendingJobs(){return this._pendingJobs}get failedJobs(){return this._failedJobs}get processedJobs(){return this._totalJobs-this._pendingJobs}progress(){return this._totalJobs===0?100:Math.round(this.processedJobs/this._totalJobs*100)}finished(){return this._pendingJobs===0}cancelled(){return this._cancelled}async recordSuccessfulJob(e){this._pendingJobs=Math.max(0,this._pendingJobs-1),this.finished()&&(await this.fireThenCallbacks(),await this.fireFinallyCallbacks(),this._finishedAt=new Date)}async recordFailedJob(e,t){this._failedJobs++,this._failedJobIds.push(e),this._pendingJobs=Math.max(0,this._pendingJobs-1),await this.fireCatchCallbacks(t),this._options.allowFailures||this.cancel(),this.finished()&&(await this.fireFinallyCallbacks(),this._finishedAt=new Date)}cancel(){this._cancelled=!0}async fireThenCallbacks(){for(let e of this._options.thenCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch then callback:`,e)}}async fireCatchCallbacks(e){for(let t of this._options.catchCallbacks)try{await t(this,e)}catch(e){console.error(`[Queue] Error in batch catch callback:`,e)}}async fireFinallyCallbacks(){for(let e of this._options.finallyCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch finally callback:`,e)}}toJSON(){return{id:this.id,name:this.name,totalJobs:this._totalJobs,pendingJobs:this._pendingJobs,failedJobs:this._failedJobs,processedJobs:this.processedJobs,progress:this.progress(),cancelled:this._cancelled,createdAt:this.createdAt.toISOString(),finishedAt:this._finishedAt?.toISOString()||null}}};export{t as Batch};
|
|
1
|
+
import{randomUUID as e}from"crypto";var t=class{manager;name;id;createdAt;_totalJobs;_pendingJobs;_failedJobs=0;_failedJobIds=[];_cancelled=!1;_finishedAt=null;_options;constructor(t,n,r,i){this.manager=t,this.name=n,this.id=e(),this.createdAt=new Date,this._totalJobs=r,this._pendingJobs=r,this._options=i}get totalJobs(){return this._totalJobs}get pendingJobs(){return this._pendingJobs}get failedJobs(){return this._failedJobs}get processedJobs(){return this._totalJobs-this._pendingJobs}progress(){return this._totalJobs===0?100:Math.round(this.processedJobs/this._totalJobs*100)}finished(){return this._pendingJobs===0}cancelled(){return this._cancelled}async recordSuccessfulJob(e){this._pendingJobs=Math.max(0,this._pendingJobs-1),this.finished()&&(await this.fireThenCallbacks(),await this.fireFinallyCallbacks(),this._finishedAt=new Date)}async recordFailedJob(e,t){this._failedJobs++,this._failedJobIds.push(e),this._pendingJobs=Math.max(0,this._pendingJobs-1),await this.fireCatchCallbacks(t),this._options.allowFailures||this.cancel(),this.finished()&&(await this.fireFinallyCallbacks(),this._finishedAt=new Date)}cancel(){this._cancelled=!0}async fireThenCallbacks(){for(let e of this._options.thenCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch then callback:`,e)}}async fireCatchCallbacks(e){for(let t of this._options.catchCallbacks)try{await t(this,e)}catch(e){console.error(`[Queue] Error in batch catch callback:`,e)}}async fireFinallyCallbacks(){for(let e of this._options.finallyCallbacks)try{await e(this)}catch(e){console.error(`[Queue] Error in batch finally callback:`,e)}}toJSON(){return{id:this.id,name:this.name,totalJobs:this._totalJobs,pendingJobs:this._pendingJobs,failedJobs:this._failedJobs,processedJobs:this.processedJobs,progress:this.progress(),cancelled:this._cancelled,createdAt:this.createdAt.toISOString(),finishedAt:this._finishedAt?.toISOString()||null}}};export{t as Batch};
|
|
2
2
|
//# sourceMappingURL=Batch.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Batch.mjs","names":[],"sources":["../../../src/Queue/Batching/Batch.ts"],"sourcesContent":["/**\n * Batch\n *\n * Represents a batch of jobs being processed.\n * Tracks progress and fires callbacks on completion/failure.\n *\n * Mirrors Laravel's Illuminate\\Bus\\Batch.\n */\n\nimport { randomUUID } from 'crypto';\nimport type { QueueManager } from '@/Queue/QueueManager';\n\nexport interface BatchOptions {\n thenCallbacks: Array<(batch: Batch) => void | Promise<void>>;\n catchCallbacks: Array<(batch: Batch, error: Error) => void | Promise<void>>;\n finallyCallbacks: Array<(batch: Batch) => void | Promise<void>>;\n allowFailures: boolean;\n}\n\nexport class Batch {\n public readonly id: string;\n public readonly createdAt: Date;\n\n protected _totalJobs: number;\n protected _pendingJobs: number;\n protected _failedJobs: number = 0;\n protected _failedJobIds: string[] = [];\n protected _cancelled: boolean = false;\n protected _finishedAt: Date | null = null;\n protected _options: BatchOptions;\n\n constructor(\n protected manager: QueueManager,\n public readonly name: string,\n totalJobs: number,\n options: BatchOptions\n ) {\n this.id = randomUUID();\n this.createdAt = new Date();\n this._totalJobs = totalJobs;\n this._pendingJobs = totalJobs;\n this._options = options;\n }\n\n /**\n * Get the total number of jobs in the batch\n */\n get totalJobs(): number {\n return this._totalJobs;\n }\n\n /**\n * Get the number of pending jobs\n */\n get pendingJobs(): number {\n return this._pendingJobs;\n }\n\n /**\n * Get the number of failed jobs\n */\n get failedJobs(): number {\n return this._failedJobs;\n }\n\n /**\n * Get the number of processed jobs\n */\n get processedJobs(): number {\n return this._totalJobs - this._pendingJobs;\n }\n\n /**\n * Get the batch progress percentage (0-100)\n */\n progress(): number {\n if (this._totalJobs === 0) return 100;\n return Math.round((this.processedJobs / this._totalJobs) * 100);\n }\n\n /**\n * Whether the batch has finished\n */\n finished(): boolean {\n return this._pendingJobs === 0;\n }\n\n /**\n * Whether the batch has been cancelled\n */\n cancelled(): boolean {\n return this._cancelled;\n }\n\n /**\n * Record a successful job completion\n */\n async recordSuccessfulJob(jobId: string): Promise<void> {\n this._pendingJobs = Math.max(0, this._pendingJobs - 1);\n\n if (this.finished()) {\n await this.fireThenCallbacks();\n await this.fireFinallyCallbacks();\n this._finishedAt = new Date();\n }\n }\n\n /**\n * Record a failed job\n */\n async recordFailedJob(jobId: string, error: Error): Promise<void> {\n this._failedJobs++;\n this._failedJobIds.push(jobId);\n this._pendingJobs = Math.max(0, this._pendingJobs - 1);\n\n // Fire catch callbacks\n await this.fireCatchCallbacks(error);\n\n if (!this._options.allowFailures) {\n this.cancel();\n }\n\n if (this.finished()) {\n await this.fireFinallyCallbacks();\n this._finishedAt = new Date();\n }\n }\n\n /**\n * Cancel the batch\n */\n cancel(): void {\n this._cancelled = true;\n }\n\n /**\n * Fire the then callbacks\n */\n protected async fireThenCallbacks(): Promise<void> {\n for (const callback of this._options.thenCallbacks) {\n try {\n await callback(this);\n } catch (error) {\n console.error('[Queue] Error in batch then callback:', error);\n }\n }\n }\n\n /**\n * Fire the catch callbacks\n */\n protected async fireCatchCallbacks(error: Error): Promise<void> {\n for (const callback of this._options.catchCallbacks) {\n try {\n await callback(this, error);\n } catch (callbackError) {\n console.error('[Queue] Error in batch catch callback:', callbackError);\n }\n }\n }\n\n /**\n * Fire the finally callbacks\n */\n protected async fireFinallyCallbacks(): Promise<void> {\n for (const callback of this._options.finallyCallbacks) {\n try {\n await callback(this);\n } catch (error) {\n console.error('[Queue] Error in batch finally callback:', error);\n }\n }\n }\n\n /**\n * Convert to a plain object for inspection\n */\n toJSON(): Record<string, any> {\n return {\n id: this.id,\n name: this.name,\n totalJobs: this._totalJobs,\n pendingJobs: this._pendingJobs,\n failedJobs: this._failedJobs,\n processedJobs: this.processedJobs,\n progress: this.progress(),\n cancelled: this._cancelled,\n createdAt: this.createdAt.toISOString(),\n finishedAt: this._finishedAt?.toISOString() || null,\n };\n }\n}\n"],"mappings":"oCAmBA,IAAa,EAAb,KAAmB,
|
|
1
|
+
{"version":3,"file":"Batch.mjs","names":[],"sources":["../../../src/Queue/Batching/Batch.ts"],"sourcesContent":["/**\n * Batch\n *\n * Represents a batch of jobs being processed.\n * Tracks progress and fires callbacks on completion/failure.\n *\n * Mirrors Laravel's Illuminate\\Bus\\Batch.\n */\n\nimport { randomUUID } from 'crypto';\nimport type { QueueManager } from '@/Queue/QueueManager';\n\nexport interface BatchOptions {\n thenCallbacks: Array<(batch: Batch) => void | Promise<void>>;\n catchCallbacks: Array<(batch: Batch, error: Error) => void | Promise<void>>;\n finallyCallbacks: Array<(batch: Batch) => void | Promise<void>>;\n allowFailures: boolean;\n}\n\nexport class Batch {\n public readonly id: string;\n public readonly createdAt: Date;\n\n protected _totalJobs: number;\n protected _pendingJobs: number;\n protected _failedJobs: number = 0;\n protected _failedJobIds: string[] = [];\n protected _cancelled: boolean = false;\n protected _finishedAt: Date | null = null;\n protected _options: BatchOptions;\n\n constructor(\n protected manager: QueueManager,\n public readonly name: string,\n totalJobs: number,\n options: BatchOptions\n ) {\n this.id = randomUUID();\n this.createdAt = new Date();\n this._totalJobs = totalJobs;\n this._pendingJobs = totalJobs;\n this._options = options;\n }\n\n /**\n * Get the total number of jobs in the batch\n */\n get totalJobs(): number {\n return this._totalJobs;\n }\n\n /**\n * Get the number of pending jobs\n */\n get pendingJobs(): number {\n return this._pendingJobs;\n }\n\n /**\n * Get the number of failed jobs\n */\n get failedJobs(): number {\n return this._failedJobs;\n }\n\n /**\n * Get the number of processed jobs\n */\n get processedJobs(): number {\n return this._totalJobs - this._pendingJobs;\n }\n\n /**\n * Get the batch progress percentage (0-100)\n */\n progress(): number {\n if (this._totalJobs === 0) return 100;\n return Math.round((this.processedJobs / this._totalJobs) * 100);\n }\n\n /**\n * Whether the batch has finished\n */\n finished(): boolean {\n return this._pendingJobs === 0;\n }\n\n /**\n * Whether the batch has been cancelled\n */\n cancelled(): boolean {\n return this._cancelled;\n }\n\n /**\n * Record a successful job completion\n */\n async recordSuccessfulJob(jobId: string): Promise<void> {\n this._pendingJobs = Math.max(0, this._pendingJobs - 1);\n\n if (this.finished()) {\n await this.fireThenCallbacks();\n await this.fireFinallyCallbacks();\n this._finishedAt = new Date();\n }\n }\n\n /**\n * Record a failed job\n */\n async recordFailedJob(jobId: string, error: Error): Promise<void> {\n this._failedJobs++;\n this._failedJobIds.push(jobId);\n this._pendingJobs = Math.max(0, this._pendingJobs - 1);\n\n // Fire catch callbacks\n await this.fireCatchCallbacks(error);\n\n if (!this._options.allowFailures) {\n this.cancel();\n }\n\n if (this.finished()) {\n await this.fireFinallyCallbacks();\n this._finishedAt = new Date();\n }\n }\n\n /**\n * Cancel the batch\n */\n cancel(): void {\n this._cancelled = true;\n }\n\n /**\n * Fire the then callbacks\n */\n protected async fireThenCallbacks(): Promise<void> {\n for (const callback of this._options.thenCallbacks) {\n try {\n await callback(this);\n } catch (error) {\n console.error('[Queue] Error in batch then callback:', error);\n }\n }\n }\n\n /**\n * Fire the catch callbacks\n */\n protected async fireCatchCallbacks(error: Error): Promise<void> {\n for (const callback of this._options.catchCallbacks) {\n try {\n await callback(this, error);\n } catch (callbackError) {\n console.error('[Queue] Error in batch catch callback:', callbackError);\n }\n }\n }\n\n /**\n * Fire the finally callbacks\n */\n protected async fireFinallyCallbacks(): Promise<void> {\n for (const callback of this._options.finallyCallbacks) {\n try {\n await callback(this);\n } catch (error) {\n console.error('[Queue] Error in batch finally callback:', error);\n }\n }\n }\n\n /**\n * Convert to a plain object for inspection\n */\n toJSON(): Record<string, any> {\n return {\n id: this.id,\n name: this.name,\n totalJobs: this._totalJobs,\n pendingJobs: this._pendingJobs,\n failedJobs: this._failedJobs,\n processedJobs: this.processedJobs,\n progress: this.progress(),\n cancelled: this._cancelled,\n createdAt: this.createdAt.toISOString(),\n finishedAt: this._finishedAt?.toISOString() || null,\n };\n }\n}\n"],"mappings":"oCAmBA,IAAa,EAAb,KAAmB,CAaL,QACM,KAblB,GACA,UAEA,WACA,aACA,YAAgC,EAChC,cAAoC,EAAE,CACtC,WAAgC,GAChC,YAAqC,KACrC,SAEA,YACE,EACA,EACA,EACA,EACA,CAJU,KAAA,QAAA,EACM,KAAA,KAAA,EAIhB,KAAK,GAAK,GAAY,CACtB,KAAK,UAAY,IAAI,KACrB,KAAK,WAAa,EAClB,KAAK,aAAe,EACpB,KAAK,SAAW,EAMlB,IAAI,WAAoB,CACtB,OAAO,KAAK,WAMd,IAAI,aAAsB,CACxB,OAAO,KAAK,aAMd,IAAI,YAAqB,CACvB,OAAO,KAAK,YAMd,IAAI,eAAwB,CAC1B,OAAO,KAAK,WAAa,KAAK,aAMhC,UAAmB,CAEjB,OADI,KAAK,aAAe,EAAU,IAC3B,KAAK,MAAO,KAAK,cAAgB,KAAK,WAAc,IAAI,CAMjE,UAAoB,CAClB,OAAO,KAAK,eAAiB,EAM/B,WAAqB,CACnB,OAAO,KAAK,WAMd,MAAM,oBAAoB,EAA8B,CACtD,KAAK,aAAe,KAAK,IAAI,EAAG,KAAK,aAAe,EAAE,CAElD,KAAK,UAAU,GACjB,MAAM,KAAK,mBAAmB,CAC9B,MAAM,KAAK,sBAAsB,CACjC,KAAK,YAAc,IAAI,MAO3B,MAAM,gBAAgB,EAAe,EAA6B,CAChE,KAAK,cACL,KAAK,cAAc,KAAK,EAAM,CAC9B,KAAK,aAAe,KAAK,IAAI,EAAG,KAAK,aAAe,EAAE,CAGtD,MAAM,KAAK,mBAAmB,EAAM,CAE/B,KAAK,SAAS,eACjB,KAAK,QAAQ,CAGX,KAAK,UAAU,GACjB,MAAM,KAAK,sBAAsB,CACjC,KAAK,YAAc,IAAI,MAO3B,QAAe,CACb,KAAK,WAAa,GAMpB,MAAgB,mBAAmC,CACjD,IAAK,IAAM,KAAY,KAAK,SAAS,cACnC,GAAI,CACF,MAAM,EAAS,KAAK,OACb,EAAO,CACd,QAAQ,MAAM,wCAAyC,EAAM,EAQnE,MAAgB,mBAAmB,EAA6B,CAC9D,IAAK,IAAM,KAAY,KAAK,SAAS,eACnC,GAAI,CACF,MAAM,EAAS,KAAM,EAAM,OACpB,EAAe,CACtB,QAAQ,MAAM,yCAA0C,EAAc,EAQ5E,MAAgB,sBAAsC,CACpD,IAAK,IAAM,KAAY,KAAK,SAAS,iBACnC,GAAI,CACF,MAAM,EAAS,KAAK,OACb,EAAO,CACd,QAAQ,MAAM,2CAA4C,EAAM,EAQtE,QAA8B,CAC5B,MAAO,CACL,GAAI,KAAK,GACT,KAAM,KAAK,KACX,UAAW,KAAK,WAChB,YAAa,KAAK,aAClB,WAAY,KAAK,YACjB,cAAe,KAAK,cACpB,SAAU,KAAK,UAAU,CACzB,UAAW,KAAK,WAChB,UAAW,KAAK,UAAU,aAAa,CACvC,WAAY,KAAK,aAAa,aAAa,EAAI,KAChD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`./Batch.cjs`);var t=class{_name=``;_connection;_queue;_thenCallbacks=[];_catchCallbacks=[];_finallyCallbacks=[];_allowFailures=!1;constructor(e,t){this.app=e,this.jobs=t}name(e){return this._name=e,this}onConnection(e){return this._connection=e,this}onQueue(e){return this._queue=e,this}then(e){return this._thenCallbacks.push(e),this}catch(e){return this._catchCallbacks.push(e),this}finally(e){return this._finallyCallbacks.push(e),this}allowFailures(e=!0){return this._allowFailures=e,this}async dispatch(){let t=this.app.make(`queue`);for(let e of this.jobs)this._connection&&(e.connection=this._connection),this._queue&&(e.queue=this._queue);let n=new e.Batch(t,this._name,this.jobs.length,{thenCallbacks:this._thenCallbacks,catchCallbacks:this._catchCallbacks,finallyCallbacks:this._finallyCallbacks,allowFailures:this._allowFailures});for(let e of this.jobs)e._batchId=n.id,await t.dispatch(e);return n}};exports.PendingBatch=t;
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`./Batch.cjs`);var t=class{app;jobs;_name=``;_connection;_queue;_thenCallbacks=[];_catchCallbacks=[];_finallyCallbacks=[];_allowFailures=!1;constructor(e,t){this.app=e,this.jobs=t}name(e){return this._name=e,this}onConnection(e){return this._connection=e,this}onQueue(e){return this._queue=e,this}then(e){return this._thenCallbacks.push(e),this}catch(e){return this._catchCallbacks.push(e),this}finally(e){return this._finallyCallbacks.push(e),this}allowFailures(e=!0){return this._allowFailures=e,this}async dispatch(){let t=this.app.make(`queue`);for(let e of this.jobs)this._connection&&(e.connection=this._connection),this._queue&&(e.queue=this._queue);let n=new e.Batch(t,this._name,this.jobs.length,{thenCallbacks:this._thenCallbacks,catchCallbacks:this._catchCallbacks,finallyCallbacks:this._finallyCallbacks,allowFailures:this._allowFailures});for(let e of this.jobs)e._batchId=n.id,await t.dispatch(e);return n}};exports.PendingBatch=t;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Batch as e}from"./Batch.mjs";var t=class{_name=``;_connection;_queue;_thenCallbacks=[];_catchCallbacks=[];_finallyCallbacks=[];_allowFailures=!1;constructor(e,t){this.app=e,this.jobs=t}name(e){return this._name=e,this}onConnection(e){return this._connection=e,this}onQueue(e){return this._queue=e,this}then(e){return this._thenCallbacks.push(e),this}catch(e){return this._catchCallbacks.push(e),this}finally(e){return this._finallyCallbacks.push(e),this}allowFailures(e=!0){return this._allowFailures=e,this}async dispatch(){let t=this.app.make(`queue`);for(let e of this.jobs)this._connection&&(e.connection=this._connection),this._queue&&(e.queue=this._queue);let n=new e(t,this._name,this.jobs.length,{thenCallbacks:this._thenCallbacks,catchCallbacks:this._catchCallbacks,finallyCallbacks:this._finallyCallbacks,allowFailures:this._allowFailures});for(let e of this.jobs)e._batchId=n.id,await t.dispatch(e);return n}};export{t as PendingBatch};
|
|
1
|
+
import{Batch as e}from"./Batch.mjs";var t=class{app;jobs;_name=``;_connection;_queue;_thenCallbacks=[];_catchCallbacks=[];_finallyCallbacks=[];_allowFailures=!1;constructor(e,t){this.app=e,this.jobs=t}name(e){return this._name=e,this}onConnection(e){return this._connection=e,this}onQueue(e){return this._queue=e,this}then(e){return this._thenCallbacks.push(e),this}catch(e){return this._catchCallbacks.push(e),this}finally(e){return this._finallyCallbacks.push(e),this}allowFailures(e=!0){return this._allowFailures=e,this}async dispatch(){let t=this.app.make(`queue`);for(let e of this.jobs)this._connection&&(e.connection=this._connection),this._queue&&(e.queue=this._queue);let n=new e(t,this._name,this.jobs.length,{thenCallbacks:this._thenCallbacks,catchCallbacks:this._catchCallbacks,finallyCallbacks:this._finallyCallbacks,allowFailures:this._allowFailures});for(let e of this.jobs)e._batchId=n.id,await t.dispatch(e);return n}};export{t as PendingBatch};
|
|
2
2
|
//# sourceMappingURL=PendingBatch.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PendingBatch.mjs","names":[],"sources":["../../../src/Queue/Batching/PendingBatch.ts"],"sourcesContent":["/**\n * PendingBatch\n *\n * Fluent builder for creating a batch of jobs.\n * Jobs in a batch can run concurrently, with callbacks\n * for progress, completion, and failure.\n *\n * Mirrors Laravel's Illuminate\\Bus\\PendingBatch.\n *\n * @example\n * ```typescript\n * const batch = await Bus.batch([\n * new ImportCSVRow(1),\n * new ImportCSVRow(2),\n * new ImportCSVRow(3),\n * ])\n * .name('Import CSV')\n * .then((batch) => console.log('All done!'))\n * .catch((batch, error) => console.error('Failed:', error))\n * .finally((batch) => console.log('Batch finished'))\n * .onQueue('imports')\n * .dispatch();\n * ```\n */\n\nimport type { Application } from '@/Foundation/Application';\nimport type { Job } from '@/Queue/Job';\nimport type { QueueManager } from '@/Queue/QueueManager';\nimport { Batch } from './Batch';\n\nexport class PendingBatch {\n protected _name: string = '';\n protected _connection?: string;\n protected _queue?: string;\n protected _thenCallbacks: Array<(batch: Batch) => void | Promise<void>> = [];\n protected _catchCallbacks: Array<(batch: Batch, error: Error) => void | Promise<void>> = [];\n protected _finallyCallbacks: Array<(batch: Batch) => void | Promise<void>> = [];\n protected _allowFailures: boolean = false;\n\n constructor(\n protected app: Application,\n protected jobs: Job[]\n ) {}\n\n /**\n * Set the name for the batch\n */\n name(name: string): this {\n this._name = name;\n return this;\n }\n\n /**\n * Set the connection for all jobs in the batch\n */\n onConnection(connection: string): this {\n this._connection = connection;\n return this;\n }\n\n /**\n * Set the queue for all jobs in the batch\n */\n onQueue(queue: string): this {\n this._queue = queue;\n return this;\n }\n\n /**\n * Register a callback for when all jobs in the batch complete\n */\n then(callback: (batch: Batch) => void | Promise<void>): this {\n this._thenCallbacks.push(callback);\n return this;\n }\n\n /**\n * Register a callback for when a job in the batch fails\n */\n catch(callback: (batch: Batch, error: Error) => void | Promise<void>): this {\n this._catchCallbacks.push(callback);\n return this;\n }\n\n /**\n * Register a callback for when the batch finishes (success or failure)\n */\n finally(callback: (batch: Batch) => void | Promise<void>): this {\n this._finallyCallbacks.push(callback);\n return this;\n }\n\n /**\n * Allow the batch to continue processing even if a job fails\n */\n allowFailures(allow: boolean = true): this {\n this._allowFailures = allow;\n return this;\n }\n\n /**\n * Dispatch the batch\n */\n async dispatch(): Promise<Batch> {\n const manager = this.app.make<QueueManager>('queue');\n\n // Apply connection/queue to all jobs\n for (const job of this.jobs) {\n if (this._connection) {\n job.connection = this._connection;\n }\n if (this._queue) {\n job.queue = this._queue;\n }\n }\n\n // Create batch instance\n const batch = new Batch(manager, this._name, this.jobs.length, {\n thenCallbacks: this._thenCallbacks,\n catchCallbacks: this._catchCallbacks,\n finallyCallbacks: this._finallyCallbacks,\n allowFailures: this._allowFailures,\n });\n\n // Dispatch all jobs with batch metadata\n for (const job of this.jobs) {\n (job as any)._batchId = batch.id;\n await manager.dispatch(job);\n }\n\n return batch;\n }\n}\n"],"mappings":"oCA8BA,IAAa,EAAb,KAA0B,
|
|
1
|
+
{"version":3,"file":"PendingBatch.mjs","names":[],"sources":["../../../src/Queue/Batching/PendingBatch.ts"],"sourcesContent":["/**\n * PendingBatch\n *\n * Fluent builder for creating a batch of jobs.\n * Jobs in a batch can run concurrently, with callbacks\n * for progress, completion, and failure.\n *\n * Mirrors Laravel's Illuminate\\Bus\\PendingBatch.\n *\n * @example\n * ```typescript\n * const batch = await Bus.batch([\n * new ImportCSVRow(1),\n * new ImportCSVRow(2),\n * new ImportCSVRow(3),\n * ])\n * .name('Import CSV')\n * .then((batch) => console.log('All done!'))\n * .catch((batch, error) => console.error('Failed:', error))\n * .finally((batch) => console.log('Batch finished'))\n * .onQueue('imports')\n * .dispatch();\n * ```\n */\n\nimport type { Application } from '@/Foundation/Application';\nimport type { Job } from '@/Queue/Job';\nimport type { QueueManager } from '@/Queue/QueueManager';\nimport { Batch } from './Batch';\n\nexport class PendingBatch {\n protected _name: string = '';\n protected _connection?: string;\n protected _queue?: string;\n protected _thenCallbacks: Array<(batch: Batch) => void | Promise<void>> = [];\n protected _catchCallbacks: Array<(batch: Batch, error: Error) => void | Promise<void>> = [];\n protected _finallyCallbacks: Array<(batch: Batch) => void | Promise<void>> = [];\n protected _allowFailures: boolean = false;\n\n constructor(\n protected app: Application,\n protected jobs: Job[]\n ) {}\n\n /**\n * Set the name for the batch\n */\n name(name: string): this {\n this._name = name;\n return this;\n }\n\n /**\n * Set the connection for all jobs in the batch\n */\n onConnection(connection: string): this {\n this._connection = connection;\n return this;\n }\n\n /**\n * Set the queue for all jobs in the batch\n */\n onQueue(queue: string): this {\n this._queue = queue;\n return this;\n }\n\n /**\n * Register a callback for when all jobs in the batch complete\n */\n then(callback: (batch: Batch) => void | Promise<void>): this {\n this._thenCallbacks.push(callback);\n return this;\n }\n\n /**\n * Register a callback for when a job in the batch fails\n */\n catch(callback: (batch: Batch, error: Error) => void | Promise<void>): this {\n this._catchCallbacks.push(callback);\n return this;\n }\n\n /**\n * Register a callback for when the batch finishes (success or failure)\n */\n finally(callback: (batch: Batch) => void | Promise<void>): this {\n this._finallyCallbacks.push(callback);\n return this;\n }\n\n /**\n * Allow the batch to continue processing even if a job fails\n */\n allowFailures(allow: boolean = true): this {\n this._allowFailures = allow;\n return this;\n }\n\n /**\n * Dispatch the batch\n */\n async dispatch(): Promise<Batch> {\n const manager = this.app.make<QueueManager>('queue');\n\n // Apply connection/queue to all jobs\n for (const job of this.jobs) {\n if (this._connection) {\n job.connection = this._connection;\n }\n if (this._queue) {\n job.queue = this._queue;\n }\n }\n\n // Create batch instance\n const batch = new Batch(manager, this._name, this.jobs.length, {\n thenCallbacks: this._thenCallbacks,\n catchCallbacks: this._catchCallbacks,\n finallyCallbacks: this._finallyCallbacks,\n allowFailures: this._allowFailures,\n });\n\n // Dispatch all jobs with batch metadata\n for (const job of this.jobs) {\n (job as any)._batchId = batch.id;\n await manager.dispatch(job);\n }\n\n return batch;\n }\n}\n"],"mappings":"oCA8BA,IAAa,EAAb,KAA0B,CAUZ,IACA,KAVZ,MAA0B,GAC1B,YACA,OACA,eAA0E,EAAE,CAC5E,gBAAyF,EAAE,CAC3F,kBAA6E,EAAE,CAC/E,eAAoC,GAEpC,YACE,EACA,EACA,CAFU,KAAA,IAAA,EACA,KAAA,KAAA,EAMZ,KAAK,EAAoB,CAEvB,MADA,MAAK,MAAQ,EACN,KAMT,aAAa,EAA0B,CAErC,MADA,MAAK,YAAc,EACZ,KAMT,QAAQ,EAAqB,CAE3B,MADA,MAAK,OAAS,EACP,KAMT,KAAK,EAAwD,CAE3D,OADA,KAAK,eAAe,KAAK,EAAS,CAC3B,KAMT,MAAM,EAAsE,CAE1E,OADA,KAAK,gBAAgB,KAAK,EAAS,CAC5B,KAMT,QAAQ,EAAwD,CAE9D,OADA,KAAK,kBAAkB,KAAK,EAAS,CAC9B,KAMT,cAAc,EAAiB,GAAY,CAEzC,MADA,MAAK,eAAiB,EACf,KAMT,MAAM,UAA2B,CAC/B,IAAM,EAAU,KAAK,IAAI,KAAmB,QAAQ,CAGpD,IAAK,IAAM,KAAO,KAAK,KACjB,KAAK,cACP,EAAI,WAAa,KAAK,aAEpB,KAAK,SACP,EAAI,MAAQ,KAAK,QAKrB,IAAM,EAAQ,IAAI,EAAM,EAAS,KAAK,MAAO,KAAK,KAAK,OAAQ,CAC7D,cAAe,KAAK,eACpB,eAAgB,KAAK,gBACrB,iBAAkB,KAAK,kBACvB,cAAe,KAAK,eACrB,CAAC,CAGF,IAAK,IAAM,KAAO,KAAK,KACrB,EAAa,SAAW,EAAM,GAC9B,MAAM,EAAQ,SAAS,EAAI,CAG7B,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dispatchable.mjs","names":[],"sources":["../../../src/Queue/Concerns/Dispatchable.ts"],"sourcesContent":["/**\n * Dispatchable Concern for Jobs\n *\n * Provides static dispatch methods for Job classes.\n * Similar to the Event Dispatchable mixin, but for queue jobs.\n */\n\nimport type { QueueManager } from '@/Queue/QueueManager';\nimport { PendingDispatch } from '@/Queue/PendingDispatch';\nimport { Facade } from '@/Support/Facade';\n\nexport class JobDispatchable {\n /**\n * Dispatch the job with the given arguments\n *\n * @returns PendingDispatch for fluent configuration\n */\n static dispatch(...args: any[]): PendingDispatch {\n const app = Facade.getFacadeApplication();\n if (!app) {\n throw new Error('Application not initialized. Cannot dispatch job.');\n }\n\n const manager = app.make<QueueManager>('queue');\n const instance = new (this as any)(...args);\n return new PendingDispatch(manager, instance);\n }\n\n /**\n * Dispatch the job synchronously (bypass queue)\n */\n static async dispatchSync(...args: any[]): Promise<void> {\n const app = Facade.getFacadeApplication();\n if (!app) {\n throw new Error('Application not initialized. Cannot dispatch job.');\n }\n\n const manager = app.make<QueueManager>('queue');\n const instance = new (this as any)(...args);\n await manager.dispatchSync(instance);\n }\n\n /**\n * Dispatch the job if the given condition is true\n */\n static dispatchIf(condition: boolean | (() => boolean), ...args: any[]): PendingDispatch | null {\n const shouldDispatch = typeof condition === 'function' ? condition() : condition;\n\n if (shouldDispatch) {\n return this.dispatch(...args);\n }\n\n return null;\n }\n\n /**\n * Dispatch the job unless the given condition is true\n */\n static dispatchUnless(condition: boolean | (() => boolean), ...args: any[]): PendingDispatch | null {\n const shouldNotDispatch = typeof condition === 'function' ? condition() : condition;\n\n if (!shouldNotDispatch) {\n return this.dispatch(...args);\n }\n\n return null;\n }\n\n /**\n * Dispatch the job after the response is sent to the browser\n */\n static dispatchAfterResponse(...args: any[]): void {\n const app = Facade.getFacadeApplication();\n if (!app) {\n throw new Error('Application not initialized. Cannot dispatch job.');\n }\n\n const manager = app.make<QueueManager>('queue');\n const instance = new (this as any)(...args);\n\n // Use setImmediate/nextTick to execute after the current response\n setImmediate(async () => {\n try {\n await manager.dispatchSync(instance);\n } catch (error) {\n console.error(`[Queue] Failed to dispatch after response: ${instance.displayName()}`, error);\n }\n });\n }\n}\n\n/**\n * Apply JobDispatchable mixin to a Job class\n */\nexport function applyJobDispatchable(jobClass: any): void {\n const staticMethods = Object.getOwnPropertyNames(JobDispatchable);\n\n for (const name of staticMethods) {\n if (name === 'constructor' || name === 'prototype' || name === 'length' || name === 'name') {\n continue;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(JobDispatchable, name);\n\n if (descriptor) {\n Object.defineProperty(jobClass, name, {\n value: descriptor.value,\n enumerable: false,\n configurable: true,\n writable: true,\n });\n }\n }\n}\n"],"mappings":"2GAWA,IAAa,EAAb,KAA6B,CAM3B,OAAO,SAAS,GAAG,EAA8B,CAC/C,IAAM,EAAM,EAAO,sBAAsB,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAKtE,OAAO,IAAI,EAFK,EAAI,KAAmB,
|
|
1
|
+
{"version":3,"file":"Dispatchable.mjs","names":[],"sources":["../../../src/Queue/Concerns/Dispatchable.ts"],"sourcesContent":["/**\n * Dispatchable Concern for Jobs\n *\n * Provides static dispatch methods for Job classes.\n * Similar to the Event Dispatchable mixin, but for queue jobs.\n */\n\nimport type { QueueManager } from '@/Queue/QueueManager';\nimport { PendingDispatch } from '@/Queue/PendingDispatch';\nimport { Facade } from '@/Support/Facade';\n\nexport class JobDispatchable {\n /**\n * Dispatch the job with the given arguments\n *\n * @returns PendingDispatch for fluent configuration\n */\n static dispatch(...args: any[]): PendingDispatch {\n const app = Facade.getFacadeApplication();\n if (!app) {\n throw new Error('Application not initialized. Cannot dispatch job.');\n }\n\n const manager = app.make<QueueManager>('queue');\n const instance = new (this as any)(...args);\n return new PendingDispatch(manager, instance);\n }\n\n /**\n * Dispatch the job synchronously (bypass queue)\n */\n static async dispatchSync(...args: any[]): Promise<void> {\n const app = Facade.getFacadeApplication();\n if (!app) {\n throw new Error('Application not initialized. Cannot dispatch job.');\n }\n\n const manager = app.make<QueueManager>('queue');\n const instance = new (this as any)(...args);\n await manager.dispatchSync(instance);\n }\n\n /**\n * Dispatch the job if the given condition is true\n */\n static dispatchIf(condition: boolean | (() => boolean), ...args: any[]): PendingDispatch | null {\n const shouldDispatch = typeof condition === 'function' ? condition() : condition;\n\n if (shouldDispatch) {\n return this.dispatch(...args);\n }\n\n return null;\n }\n\n /**\n * Dispatch the job unless the given condition is true\n */\n static dispatchUnless(condition: boolean | (() => boolean), ...args: any[]): PendingDispatch | null {\n const shouldNotDispatch = typeof condition === 'function' ? condition() : condition;\n\n if (!shouldNotDispatch) {\n return this.dispatch(...args);\n }\n\n return null;\n }\n\n /**\n * Dispatch the job after the response is sent to the browser\n */\n static dispatchAfterResponse(...args: any[]): void {\n const app = Facade.getFacadeApplication();\n if (!app) {\n throw new Error('Application not initialized. Cannot dispatch job.');\n }\n\n const manager = app.make<QueueManager>('queue');\n const instance = new (this as any)(...args);\n\n // Use setImmediate/nextTick to execute after the current response\n setImmediate(async () => {\n try {\n await manager.dispatchSync(instance);\n } catch (error) {\n console.error(`[Queue] Failed to dispatch after response: ${instance.displayName()}`, error);\n }\n });\n }\n}\n\n/**\n * Apply JobDispatchable mixin to a Job class\n */\nexport function applyJobDispatchable(jobClass: any): void {\n const staticMethods = Object.getOwnPropertyNames(JobDispatchable);\n\n for (const name of staticMethods) {\n if (name === 'constructor' || name === 'prototype' || name === 'length' || name === 'name') {\n continue;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(JobDispatchable, name);\n\n if (descriptor) {\n Object.defineProperty(jobClass, name, {\n value: descriptor.value,\n enumerable: false,\n configurable: true,\n writable: true,\n });\n }\n }\n}\n"],"mappings":"2GAWA,IAAa,EAAb,KAA6B,CAM3B,OAAO,SAAS,GAAG,EAA8B,CAC/C,IAAM,EAAM,EAAO,sBAAsB,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAKtE,OAAO,IAAI,EAFK,EAAI,KAAmB,QAEL,CAAE,IADd,KAAa,GAAG,EACM,CAAC,CAM/C,aAAa,aAAa,GAAG,EAA4B,CACvD,IAAM,EAAM,EAAO,sBAAsB,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAGtE,IAAM,EAAU,EAAI,KAAmB,QAAQ,CACzC,EAAW,IAAK,KAAa,GAAG,EAAK,CAC3C,MAAM,EAAQ,aAAa,EAAS,CAMtC,OAAO,WAAW,EAAsC,GAAG,EAAqC,CAO9F,OANuB,OAAO,GAAc,WAAa,GAAW,CAAG,GAG9D,KAAK,SAAS,GAAG,EAAK,CAGxB,KAMT,OAAO,eAAe,EAAsC,GAAG,EAAqC,CAOlG,OAN0B,OAAO,GAAc,WAAa,GAAW,CAAG,GAMnE,KAHE,KAAK,SAAS,GAAG,EAAK,CASjC,OAAO,sBAAsB,GAAG,EAAmB,CACjD,IAAM,EAAM,EAAO,sBAAsB,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAGtE,IAAM,EAAU,EAAI,KAAmB,QAAQ,CACzC,EAAW,IAAK,KAAa,GAAG,EAAK,CAG3C,aAAa,SAAY,CACvB,GAAI,CACF,MAAM,EAAQ,aAAa,EAAS,OAC7B,EAAO,CACd,QAAQ,MAAM,8CAA8C,EAAS,aAAa,GAAI,EAAM,GAE9F,GAON,SAAgB,EAAqB,EAAqB,CACxD,IAAM,EAAgB,OAAO,oBAAoB,EAAgB,CAEjE,IAAK,IAAM,KAAQ,EAAe,CAChC,GAAI,IAAS,eAAiB,IAAS,aAAe,IAAS,UAAY,IAAS,OAClF,SAGF,IAAM,EAAa,OAAO,yBAAyB,EAAiB,EAAK,CAErE,GACF,OAAO,eAAe,EAAU,EAAM,CACpC,MAAO,EAAW,MAClB,WAAY,GACZ,aAAc,GACd,SAAU,GACX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../JobPayload.cjs`);let t=require(`crypto`);var n=class{connectionName=`database`;defaultQueue;table;retryAfter;constructor(e,t){this.config=e,this.app=t,this.defaultQueue=e.queue||`default`,this.table=e.table||`jobs`,this.retryAfter=e.retry_after||90}getConnection(){return this.app.make(`db`).connection(this.config.connection)}async size(e){let t=this.getQueue(e),n=await this.getConnection().table(this.table).where(`queue`,`=`,t).count();return Number(n)||0}async push(t,n){let r=this.getQueue(n),i=e.JobPayload.create(t),a=Math.floor(Date.now()/1e3);return await this.getConnection().table(this.table).insert({queue:r,payload:e.JobPayload.serialize(i),attempts:0,reserved_at:null,available_at:a,created_at:a}),i.uuid}async pushRaw(e,n,r){let i=this.getQueue(n),a=Math.floor(Date.now()/1e3),o=r?.delay||0;return await this.getConnection().table(this.table).insert({queue:i,payload:e,attempts:0,reserved_at:null,available_at:a+o,created_at:a}),(0,t.randomUUID)()}async later(t,n,r){let i=this.getQueue(r),a=e.JobPayload.create(n),o=Math.floor(Date.now()/1e3),s;return s=t instanceof Date?Math.floor(t.getTime()/1e3):o+t,await this.getConnection().table(this.table).insert({queue:i,payload:e.JobPayload.serialize(a),attempts:0,reserved_at:null,available_at:s,created_at:o}),a.uuid}async bulk(e,t){for(let n of e)await this.push(n,t)}async pop(e){let t=this.getQueue(e),n=Math.floor(Date.now()/1e3),r=this.getConnection();await r.table(this.table).where(`queue`,`=`,t).where(`reserved_at`,`<=`,n-this.retryAfter).update({reserved_at:null});let i=await r.table(this.table).where(`queue`,`=`,t).where(`available_at`,`<=`,n).whereNull(`reserved_at`).orderBy(`id`,`asc`).limit(1).first();return i?(await r.table(this.table).where(`id`,`=`,i.id).update({reserved_at:n,attempts:(i.attempts||0)+1}),{id:String(i.id),queue:i.queue,payload:i.payload,attempts:(i.attempts||0)+1,reservedAt:n,availableAt:i.available_at,createdAt:i.created_at}):null}async release(e,t=0){let n=Math.floor(Date.now()/1e3);await this.getConnection().table(this.table).where(`id`,`=`,e).update({reserved_at:null,available_at:n+t})}async delete(e){await this.getConnection().table(this.table).where(`id`,`=`,e).delete()}async clear(e){let t=this.getQueue(e),n=this.getConnection(),r=await this.size(t);return await n.table(this.table).where(`queue`,`=`,t).delete(),r}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.defaultQueue}};exports.DatabaseDriver=n;
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../JobPayload.cjs`);let t=require(`crypto`);var n=class{config;app;connectionName=`database`;defaultQueue;table;retryAfter;constructor(e,t){this.config=e,this.app=t,this.defaultQueue=e.queue||`default`,this.table=e.table||`jobs`,this.retryAfter=e.retry_after||90}getConnection(){return this.app.make(`db`).connection(this.config.connection)}async size(e){let t=this.getQueue(e),n=await this.getConnection().table(this.table).where(`queue`,`=`,t).count();return Number(n)||0}async push(t,n){let r=this.getQueue(n),i=e.JobPayload.create(t),a=Math.floor(Date.now()/1e3);return await this.getConnection().table(this.table).insert({queue:r,payload:e.JobPayload.serialize(i),attempts:0,reserved_at:null,available_at:a,created_at:a}),i.uuid}async pushRaw(e,n,r){let i=this.getQueue(n),a=Math.floor(Date.now()/1e3),o=r?.delay||0;return await this.getConnection().table(this.table).insert({queue:i,payload:e,attempts:0,reserved_at:null,available_at:a+o,created_at:a}),(0,t.randomUUID)()}async later(t,n,r){let i=this.getQueue(r),a=e.JobPayload.create(n),o=Math.floor(Date.now()/1e3),s;return s=t instanceof Date?Math.floor(t.getTime()/1e3):o+t,await this.getConnection().table(this.table).insert({queue:i,payload:e.JobPayload.serialize(a),attempts:0,reserved_at:null,available_at:s,created_at:o}),a.uuid}async bulk(e,t){for(let n of e)await this.push(n,t)}async pop(e){let t=this.getQueue(e),n=Math.floor(Date.now()/1e3),r=this.getConnection();await r.table(this.table).where(`queue`,`=`,t).where(`reserved_at`,`<=`,n-this.retryAfter).update({reserved_at:null});let i=await r.table(this.table).where(`queue`,`=`,t).where(`available_at`,`<=`,n).whereNull(`reserved_at`).orderBy(`id`,`asc`).limit(1).first();return i?(await r.table(this.table).where(`id`,`=`,i.id).update({reserved_at:n,attempts:(i.attempts||0)+1}),{id:String(i.id),queue:i.queue,payload:i.payload,attempts:(i.attempts||0)+1,reservedAt:n,availableAt:i.available_at,createdAt:i.created_at}):null}async release(e,t=0){let n=Math.floor(Date.now()/1e3);await this.getConnection().table(this.table).where(`id`,`=`,e).update({reserved_at:null,available_at:n+t})}async delete(e){await this.getConnection().table(this.table).where(`id`,`=`,e).delete()}async clear(e){let t=this.getQueue(e),n=this.getConnection(),r=await this.size(t);return await n.table(this.table).where(`queue`,`=`,t).delete(),r}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.defaultQueue}};exports.DatabaseDriver=n;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{JobPayload as e}from"../JobPayload.mjs";import{randomUUID as t}from"crypto";var n=class{connectionName=`database`;defaultQueue;table;retryAfter;constructor(e,t){this.config=e,this.app=t,this.defaultQueue=e.queue||`default`,this.table=e.table||`jobs`,this.retryAfter=e.retry_after||90}getConnection(){return this.app.make(`db`).connection(this.config.connection)}async size(e){let t=this.getQueue(e),n=await this.getConnection().table(this.table).where(`queue`,`=`,t).count();return Number(n)||0}async push(t,n){let r=this.getQueue(n),i=e.create(t),a=Math.floor(Date.now()/1e3);return await this.getConnection().table(this.table).insert({queue:r,payload:e.serialize(i),attempts:0,reserved_at:null,available_at:a,created_at:a}),i.uuid}async pushRaw(e,n,r){let i=this.getQueue(n),a=Math.floor(Date.now()/1e3),o=r?.delay||0;return await this.getConnection().table(this.table).insert({queue:i,payload:e,attempts:0,reserved_at:null,available_at:a+o,created_at:a}),t()}async later(t,n,r){let i=this.getQueue(r),a=e.create(n),o=Math.floor(Date.now()/1e3),s;return s=t instanceof Date?Math.floor(t.getTime()/1e3):o+t,await this.getConnection().table(this.table).insert({queue:i,payload:e.serialize(a),attempts:0,reserved_at:null,available_at:s,created_at:o}),a.uuid}async bulk(e,t){for(let n of e)await this.push(n,t)}async pop(e){let t=this.getQueue(e),n=Math.floor(Date.now()/1e3),r=this.getConnection();await r.table(this.table).where(`queue`,`=`,t).where(`reserved_at`,`<=`,n-this.retryAfter).update({reserved_at:null});let i=await r.table(this.table).where(`queue`,`=`,t).where(`available_at`,`<=`,n).whereNull(`reserved_at`).orderBy(`id`,`asc`).limit(1).first();return i?(await r.table(this.table).where(`id`,`=`,i.id).update({reserved_at:n,attempts:(i.attempts||0)+1}),{id:String(i.id),queue:i.queue,payload:i.payload,attempts:(i.attempts||0)+1,reservedAt:n,availableAt:i.available_at,createdAt:i.created_at}):null}async release(e,t=0){let n=Math.floor(Date.now()/1e3);await this.getConnection().table(this.table).where(`id`,`=`,e).update({reserved_at:null,available_at:n+t})}async delete(e){await this.getConnection().table(this.table).where(`id`,`=`,e).delete()}async clear(e){let t=this.getQueue(e),n=this.getConnection(),r=await this.size(t);return await n.table(this.table).where(`queue`,`=`,t).delete(),r}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.defaultQueue}};export{n as DatabaseDriver};
|
|
1
|
+
import{JobPayload as e}from"../JobPayload.mjs";import{randomUUID as t}from"crypto";var n=class{config;app;connectionName=`database`;defaultQueue;table;retryAfter;constructor(e,t){this.config=e,this.app=t,this.defaultQueue=e.queue||`default`,this.table=e.table||`jobs`,this.retryAfter=e.retry_after||90}getConnection(){return this.app.make(`db`).connection(this.config.connection)}async size(e){let t=this.getQueue(e),n=await this.getConnection().table(this.table).where(`queue`,`=`,t).count();return Number(n)||0}async push(t,n){let r=this.getQueue(n),i=e.create(t),a=Math.floor(Date.now()/1e3);return await this.getConnection().table(this.table).insert({queue:r,payload:e.serialize(i),attempts:0,reserved_at:null,available_at:a,created_at:a}),i.uuid}async pushRaw(e,n,r){let i=this.getQueue(n),a=Math.floor(Date.now()/1e3),o=r?.delay||0;return await this.getConnection().table(this.table).insert({queue:i,payload:e,attempts:0,reserved_at:null,available_at:a+o,created_at:a}),t()}async later(t,n,r){let i=this.getQueue(r),a=e.create(n),o=Math.floor(Date.now()/1e3),s;return s=t instanceof Date?Math.floor(t.getTime()/1e3):o+t,await this.getConnection().table(this.table).insert({queue:i,payload:e.serialize(a),attempts:0,reserved_at:null,available_at:s,created_at:o}),a.uuid}async bulk(e,t){for(let n of e)await this.push(n,t)}async pop(e){let t=this.getQueue(e),n=Math.floor(Date.now()/1e3),r=this.getConnection();await r.table(this.table).where(`queue`,`=`,t).where(`reserved_at`,`<=`,n-this.retryAfter).update({reserved_at:null});let i=await r.table(this.table).where(`queue`,`=`,t).where(`available_at`,`<=`,n).whereNull(`reserved_at`).orderBy(`id`,`asc`).limit(1).first();return i?(await r.table(this.table).where(`id`,`=`,i.id).update({reserved_at:n,attempts:(i.attempts||0)+1}),{id:String(i.id),queue:i.queue,payload:i.payload,attempts:(i.attempts||0)+1,reservedAt:n,availableAt:i.available_at,createdAt:i.created_at}):null}async release(e,t=0){let n=Math.floor(Date.now()/1e3);await this.getConnection().table(this.table).where(`id`,`=`,e).update({reserved_at:null,available_at:n+t})}async delete(e){await this.getConnection().table(this.table).where(`id`,`=`,e).delete()}async clear(e){let t=this.getQueue(e),n=this.getConnection(),r=await this.size(t);return await n.table(this.table).where(`queue`,`=`,t).delete(),r}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.defaultQueue}};export{n as DatabaseDriver};
|
|
2
2
|
//# sourceMappingURL=DatabaseDriver.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseDriver.mjs","names":[],"sources":["../../../src/Queue/Drivers/DatabaseDriver.ts"],"sourcesContent":["/**\n * DatabaseDriver\n *\n * Database queue driver that stores jobs in a database table.\n * This is the most common driver for most applications.\n *\n * Mirrors Laravel's Illuminate\\Queue\\DatabaseQueue.\n */\n\nimport { randomUUID } from 'crypto';\nimport type { Connection } from '@/Database/Connection';\nimport type { DatabaseManager } from '@/Database/DatabaseManager';\nimport type { Application } from '@/Foundation/Application';\nimport type { QueueDriver, QueueDriverJob } from '@/Queue/Contracts/QueueDriver';\nimport type { Job } from '@/Queue/Job';\nimport type { QueueConnectionConfig } from '@/Queue/QueueManager';\nimport { JobPayload } from '@/Queue/JobPayload';\n\nexport class DatabaseDriver implements QueueDriver {\n protected connectionName: string = 'database';\n protected defaultQueue: string;\n protected table: string;\n protected retryAfter: number;\n\n constructor(\n protected config: QueueConnectionConfig,\n protected app: Application\n ) {\n this.defaultQueue = config.queue || 'default';\n this.table = config.table || 'jobs';\n this.retryAfter = config.retry_after || 90;\n }\n\n /**\n * Get the database connection\n */\n protected getConnection(): Connection {\n const db = this.app.make<DatabaseManager>('db');\n return db.connection(this.config.connection);\n }\n\n async size(queue?: string): Promise<number> {\n const queueName = this.getQueue(queue);\n const connection = this.getConnection();\n\n const result = await connection.table(this.table).where('queue', '=', queueName).count();\n\n return Number(result) || 0;\n }\n\n async push(job: Job, queue?: string): Promise<string> {\n const queueName = this.getQueue(queue);\n const payload = JobPayload.create(job);\n const now = Math.floor(Date.now() / 1000);\n\n const connection = this.getConnection();\n\n await connection.table(this.table).insert({\n queue: queueName,\n payload: JobPayload.serialize(payload),\n attempts: 0,\n reserved_at: null,\n available_at: now,\n created_at: now,\n });\n\n return payload.uuid;\n }\n\n async pushRaw(payload: string, queue?: string, options?: Record<string, any>): Promise<string> {\n const queueName = this.getQueue(queue);\n const now = Math.floor(Date.now() / 1000);\n const delay = options?.delay || 0;\n\n const connection = this.getConnection();\n\n await connection.table(this.table).insert({\n queue: queueName,\n payload,\n attempts: 0,\n reserved_at: null,\n available_at: now + delay,\n created_at: now,\n });\n\n return randomUUID();\n }\n\n async later(delay: number | Date, job: Job, queue?: string): Promise<string> {\n const queueName = this.getQueue(queue);\n const payload = JobPayload.create(job);\n const now = Math.floor(Date.now() / 1000);\n\n let availableAt: number;\n if (delay instanceof Date) {\n availableAt = Math.floor(delay.getTime() / 1000);\n } else {\n availableAt = now + delay;\n }\n\n const connection = this.getConnection();\n\n await connection.table(this.table).insert({\n queue: queueName,\n payload: JobPayload.serialize(payload),\n attempts: 0,\n reserved_at: null,\n available_at: availableAt,\n created_at: now,\n });\n\n return payload.uuid;\n }\n\n async bulk(jobs: Job[], queue?: string): Promise<void> {\n for (const job of jobs) {\n await this.push(job, queue);\n }\n }\n\n async pop(queue?: string): Promise<QueueDriverJob | null> {\n const queueName = this.getQueue(queue);\n const now = Math.floor(Date.now() / 1000);\n const connection = this.getConnection();\n\n // Find the next available job\n // First, expire any reserved jobs that have been held too long\n await connection\n .table(this.table)\n .where('queue', '=', queueName)\n .where('reserved_at', '<=', now - this.retryAfter)\n .update({\n reserved_at: null,\n });\n\n // Get the next available job and reserve it\n const job = await connection\n .table(this.table)\n .where('queue', '=', queueName)\n .where('available_at', '<=', now)\n .whereNull('reserved_at')\n .orderBy('id', 'asc')\n .limit(1)\n .first();\n\n if (!job) {\n return null;\n }\n\n // Reserve the job\n await connection\n .table(this.table)\n .where('id', '=', job.id)\n .update({\n reserved_at: now,\n attempts: (job.attempts || 0) + 1,\n });\n\n return {\n id: String(job.id),\n queue: job.queue,\n payload: job.payload,\n attempts: (job.attempts || 0) + 1,\n reservedAt: now,\n availableAt: job.available_at,\n createdAt: job.created_at,\n };\n }\n\n async release(id: string, delay: number = 0): Promise<void> {\n const now = Math.floor(Date.now() / 1000);\n const connection = this.getConnection();\n\n await connection\n .table(this.table)\n .where('id', '=', id)\n .update({\n reserved_at: null,\n available_at: now + delay,\n });\n }\n\n async delete(id: string): Promise<void> {\n const connection = this.getConnection();\n\n await connection.table(this.table).where('id', '=', id).delete();\n }\n\n async clear(queue?: string): Promise<number> {\n const queueName = this.getQueue(queue);\n const connection = this.getConnection();\n\n const count = await this.size(queueName);\n\n await connection.table(this.table).where('queue', '=', queueName).delete();\n\n return count;\n }\n\n getConnectionName(): string {\n return this.connectionName;\n }\n\n setConnectionName(name: string): void {\n this.connectionName = name;\n }\n\n getQueue(queue?: string): string {\n return queue || this.defaultQueue;\n }\n}\n"],"mappings":"mFAkBA,IAAa,EAAb,KAAmD,
|
|
1
|
+
{"version":3,"file":"DatabaseDriver.mjs","names":[],"sources":["../../../src/Queue/Drivers/DatabaseDriver.ts"],"sourcesContent":["/**\n * DatabaseDriver\n *\n * Database queue driver that stores jobs in a database table.\n * This is the most common driver for most applications.\n *\n * Mirrors Laravel's Illuminate\\Queue\\DatabaseQueue.\n */\n\nimport { randomUUID } from 'crypto';\nimport type { Connection } from '@/Database/Connection';\nimport type { DatabaseManager } from '@/Database/DatabaseManager';\nimport type { Application } from '@/Foundation/Application';\nimport type { QueueDriver, QueueDriverJob } from '@/Queue/Contracts/QueueDriver';\nimport type { Job } from '@/Queue/Job';\nimport type { QueueConnectionConfig } from '@/Queue/QueueManager';\nimport { JobPayload } from '@/Queue/JobPayload';\n\nexport class DatabaseDriver implements QueueDriver {\n protected connectionName: string = 'database';\n protected defaultQueue: string;\n protected table: string;\n protected retryAfter: number;\n\n constructor(\n protected config: QueueConnectionConfig,\n protected app: Application\n ) {\n this.defaultQueue = config.queue || 'default';\n this.table = config.table || 'jobs';\n this.retryAfter = config.retry_after || 90;\n }\n\n /**\n * Get the database connection\n */\n protected getConnection(): Connection {\n const db = this.app.make<DatabaseManager>('db');\n return db.connection(this.config.connection);\n }\n\n async size(queue?: string): Promise<number> {\n const queueName = this.getQueue(queue);\n const connection = this.getConnection();\n\n const result = await connection.table(this.table).where('queue', '=', queueName).count();\n\n return Number(result) || 0;\n }\n\n async push(job: Job, queue?: string): Promise<string> {\n const queueName = this.getQueue(queue);\n const payload = JobPayload.create(job);\n const now = Math.floor(Date.now() / 1000);\n\n const connection = this.getConnection();\n\n await connection.table(this.table).insert({\n queue: queueName,\n payload: JobPayload.serialize(payload),\n attempts: 0,\n reserved_at: null,\n available_at: now,\n created_at: now,\n });\n\n return payload.uuid;\n }\n\n async pushRaw(payload: string, queue?: string, options?: Record<string, any>): Promise<string> {\n const queueName = this.getQueue(queue);\n const now = Math.floor(Date.now() / 1000);\n const delay = options?.delay || 0;\n\n const connection = this.getConnection();\n\n await connection.table(this.table).insert({\n queue: queueName,\n payload,\n attempts: 0,\n reserved_at: null,\n available_at: now + delay,\n created_at: now,\n });\n\n return randomUUID();\n }\n\n async later(delay: number | Date, job: Job, queue?: string): Promise<string> {\n const queueName = this.getQueue(queue);\n const payload = JobPayload.create(job);\n const now = Math.floor(Date.now() / 1000);\n\n let availableAt: number;\n if (delay instanceof Date) {\n availableAt = Math.floor(delay.getTime() / 1000);\n } else {\n availableAt = now + delay;\n }\n\n const connection = this.getConnection();\n\n await connection.table(this.table).insert({\n queue: queueName,\n payload: JobPayload.serialize(payload),\n attempts: 0,\n reserved_at: null,\n available_at: availableAt,\n created_at: now,\n });\n\n return payload.uuid;\n }\n\n async bulk(jobs: Job[], queue?: string): Promise<void> {\n for (const job of jobs) {\n await this.push(job, queue);\n }\n }\n\n async pop(queue?: string): Promise<QueueDriverJob | null> {\n const queueName = this.getQueue(queue);\n const now = Math.floor(Date.now() / 1000);\n const connection = this.getConnection();\n\n // Find the next available job\n // First, expire any reserved jobs that have been held too long\n await connection\n .table(this.table)\n .where('queue', '=', queueName)\n .where('reserved_at', '<=', now - this.retryAfter)\n .update({\n reserved_at: null,\n });\n\n // Get the next available job and reserve it\n const job = await connection\n .table(this.table)\n .where('queue', '=', queueName)\n .where('available_at', '<=', now)\n .whereNull('reserved_at')\n .orderBy('id', 'asc')\n .limit(1)\n .first();\n\n if (!job) {\n return null;\n }\n\n // Reserve the job\n await connection\n .table(this.table)\n .where('id', '=', job.id)\n .update({\n reserved_at: now,\n attempts: (job.attempts || 0) + 1,\n });\n\n return {\n id: String(job.id),\n queue: job.queue,\n payload: job.payload,\n attempts: (job.attempts || 0) + 1,\n reservedAt: now,\n availableAt: job.available_at,\n createdAt: job.created_at,\n };\n }\n\n async release(id: string, delay: number = 0): Promise<void> {\n const now = Math.floor(Date.now() / 1000);\n const connection = this.getConnection();\n\n await connection\n .table(this.table)\n .where('id', '=', id)\n .update({\n reserved_at: null,\n available_at: now + delay,\n });\n }\n\n async delete(id: string): Promise<void> {\n const connection = this.getConnection();\n\n await connection.table(this.table).where('id', '=', id).delete();\n }\n\n async clear(queue?: string): Promise<number> {\n const queueName = this.getQueue(queue);\n const connection = this.getConnection();\n\n const count = await this.size(queueName);\n\n await connection.table(this.table).where('queue', '=', queueName).delete();\n\n return count;\n }\n\n getConnectionName(): string {\n return this.connectionName;\n }\n\n setConnectionName(name: string): void {\n this.connectionName = name;\n }\n\n getQueue(queue?: string): string {\n return queue || this.defaultQueue;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);var e=class{connectionName=`null`;constructor(e){this.config=e}async size(e){return 0}async push(e,t){return e.uuid}async pushRaw(e,t,n){return``}async later(e,t,n){return t.uuid}async bulk(e,t){}async pop(e){return null}async release(e,t){}async delete(e){}async clear(e){return 0}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.config.queue||`default`}};exports.NullDriver=e;
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);var e=class{config;connectionName=`null`;constructor(e){this.config=e}async size(e){return 0}async push(e,t){return e.uuid}async pushRaw(e,t,n){return``}async later(e,t,n){return t.uuid}async bulk(e,t){}async pop(e){return null}async release(e,t){}async delete(e){}async clear(e){return 0}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.config.queue||`default`}};exports.NullDriver=e;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=class{connectionName=`null`;constructor(e){this.config=e}async size(e){return 0}async push(e,t){return e.uuid}async pushRaw(e,t,n){return``}async later(e,t,n){return t.uuid}async bulk(e,t){}async pop(e){return null}async release(e,t){}async delete(e){}async clear(e){return 0}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.config.queue||`default`}};export{e as NullDriver};
|
|
1
|
+
var e=class{config;connectionName=`null`;constructor(e){this.config=e}async size(e){return 0}async push(e,t){return e.uuid}async pushRaw(e,t,n){return``}async later(e,t,n){return t.uuid}async bulk(e,t){}async pop(e){return null}async release(e,t){}async delete(e){}async clear(e){return 0}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.config.queue||`default`}};export{e as NullDriver};
|
|
2
2
|
//# sourceMappingURL=NullDriver.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NullDriver.mjs","names":[],"sources":["../../../src/Queue/Drivers/NullDriver.ts"],"sourcesContent":["/**\n * NullDriver\n *\n * Null queue driver that discards all jobs.\n * Useful for testing when you want to verify jobs are dispatched\n * but don't want them to actually execute.\n *\n * Mirrors Laravel's Illuminate\\Queue\\NullQueue.\n */\n\nimport type { QueueDriver, QueueDriverJob } from '@/Queue/Contracts/QueueDriver';\nimport type { Job } from '@/Queue/Job';\nimport type { QueueConnectionConfig } from '@/Queue/QueueManager';\n\nexport class NullDriver implements QueueDriver {\n protected connectionName: string = 'null';\n\n constructor(protected config: QueueConnectionConfig) {}\n\n async size(_queue?: string): Promise<number> {\n return 0;\n }\n\n async push(job: Job, _queue?: string): Promise<string> {\n return job.uuid;\n }\n\n async pushRaw(_payload: string, _queue?: string, _options?: Record<string, any>): Promise<string> {\n return '';\n }\n\n async later(_delay: number | Date, job: Job, _queue?: string): Promise<string> {\n return job.uuid;\n }\n\n async bulk(_jobs: Job[], _queue?: string): Promise<void> {\n // Discard all jobs\n }\n\n async pop(_queue?: string): Promise<QueueDriverJob | null> {\n return null;\n }\n\n async release(_id: string, _delay?: number): Promise<void> {\n // No-op\n }\n\n async delete(_id: string): Promise<void> {\n // No-op\n }\n\n async clear(_queue?: string): Promise<number> {\n return 0;\n }\n\n getConnectionName(): string {\n return this.connectionName;\n }\n\n setConnectionName(name: string): void {\n this.connectionName = name;\n }\n\n getQueue(queue?: string): string {\n return queue || this.config.queue || 'default';\n }\n}\n"],"mappings":"AAcA,IAAa,EAAb,KAA+C,
|
|
1
|
+
{"version":3,"file":"NullDriver.mjs","names":[],"sources":["../../../src/Queue/Drivers/NullDriver.ts"],"sourcesContent":["/**\n * NullDriver\n *\n * Null queue driver that discards all jobs.\n * Useful for testing when you want to verify jobs are dispatched\n * but don't want them to actually execute.\n *\n * Mirrors Laravel's Illuminate\\Queue\\NullQueue.\n */\n\nimport type { QueueDriver, QueueDriverJob } from '@/Queue/Contracts/QueueDriver';\nimport type { Job } from '@/Queue/Job';\nimport type { QueueConnectionConfig } from '@/Queue/QueueManager';\n\nexport class NullDriver implements QueueDriver {\n protected connectionName: string = 'null';\n\n constructor(protected config: QueueConnectionConfig) {}\n\n async size(_queue?: string): Promise<number> {\n return 0;\n }\n\n async push(job: Job, _queue?: string): Promise<string> {\n return job.uuid;\n }\n\n async pushRaw(_payload: string, _queue?: string, _options?: Record<string, any>): Promise<string> {\n return '';\n }\n\n async later(_delay: number | Date, job: Job, _queue?: string): Promise<string> {\n return job.uuid;\n }\n\n async bulk(_jobs: Job[], _queue?: string): Promise<void> {\n // Discard all jobs\n }\n\n async pop(_queue?: string): Promise<QueueDriverJob | null> {\n return null;\n }\n\n async release(_id: string, _delay?: number): Promise<void> {\n // No-op\n }\n\n async delete(_id: string): Promise<void> {\n // No-op\n }\n\n async clear(_queue?: string): Promise<number> {\n return 0;\n }\n\n getConnectionName(): string {\n return this.connectionName;\n }\n\n setConnectionName(name: string): void {\n this.connectionName = name;\n }\n\n getQueue(queue?: string): string {\n return queue || this.config.queue || 'default';\n }\n}\n"],"mappings":"AAcA,IAAa,EAAb,KAA+C,CAGvB,OAFtB,eAAmC,OAEnC,YAAY,EAAyC,CAA/B,KAAA,OAAA,EAEtB,MAAM,KAAK,EAAkC,CAC3C,MAAO,GAGT,MAAM,KAAK,EAAU,EAAkC,CACrD,OAAO,EAAI,KAGb,MAAM,QAAQ,EAAkB,EAAiB,EAAiD,CAChG,MAAO,GAGT,MAAM,MAAM,EAAuB,EAAU,EAAkC,CAC7E,OAAO,EAAI,KAGb,MAAM,KAAK,EAAc,EAAgC,EAIzD,MAAM,IAAI,EAAiD,CACzD,OAAO,KAGT,MAAM,QAAQ,EAAa,EAAgC,EAI3D,MAAM,OAAO,EAA4B,EAIzC,MAAM,MAAM,EAAkC,CAC5C,MAAO,GAGT,mBAA4B,CAC1B,OAAO,KAAK,eAGd,kBAAkB,EAAoB,CACpC,KAAK,eAAiB,EAGxB,SAAS,EAAwB,CAC/B,OAAO,GAAS,KAAK,OAAO,OAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);var e=class{connectionName=`sync`;constructor(e){this.config=e}async size(e){return 0}async push(e,t){try{await e.handle()}catch(t){throw e.failed&&await e.failed(t),t}return e.uuid}async pushRaw(e,t,n){throw Error(`Sync driver does not support pushing raw payloads.`)}async later(e,t,n){return this.push(t)}async bulk(e,t){for(let t of e)await this.push(t)}async pop(e){return null}async release(e,t){}async delete(e){}async clear(e){return 0}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.config.queue||`default`}};exports.SyncDriver=e;
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);var e=class{config;connectionName=`sync`;constructor(e){this.config=e}async size(e){return 0}async push(e,t){try{await e.handle()}catch(t){throw e.failed&&await e.failed(t),t}return e.uuid}async pushRaw(e,t,n){throw Error(`Sync driver does not support pushing raw payloads.`)}async later(e,t,n){return this.push(t)}async bulk(e,t){for(let t of e)await this.push(t)}async pop(e){return null}async release(e,t){}async delete(e){}async clear(e){return 0}getConnectionName(){return this.connectionName}setConnectionName(e){this.connectionName=e}getQueue(e){return e||this.config.queue||`default`}};exports.SyncDriver=e;
|