@zintrust/core 0.4.27 → 0.4.28
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/app/Controllers/AuthController.d.ts +10 -0
- package/app/Controllers/AuthController.d.ts.map +1 -0
- package/app/Controllers/AuthController.js +233 -0
- package/app/Controllers/TestController.d.ts +22 -0
- package/app/Controllers/TestController.d.ts.map +1 -0
- package/app/Controllers/TestController.js +188 -0
- package/app/Controllers/UserController.d.ts +9 -0
- package/app/Controllers/UserController.d.ts.map +1 -0
- package/app/Controllers/UserController.js +8 -0
- package/app/Controllers/UserQueryBuilderController.d.ts +16 -0
- package/app/Controllers/UserQueryBuilderController.d.ts.map +1 -0
- package/app/Controllers/UserQueryBuilderController.js +404 -0
- package/app/Jobs/AdvancedEmailJobService.d.ts +57 -0
- package/app/Jobs/AdvancedEmailJobService.d.ts.map +1 -0
- package/app/Jobs/AdvancedEmailJobService.js +185 -0
- package/app/Jobs/EmailJobService.d.ts +33 -0
- package/app/Jobs/EmailJobService.d.ts.map +1 -0
- package/app/Jobs/EmailJobService.js +113 -0
- package/app/Middleware/AuthFailureResponder.d.ts +3 -0
- package/app/Middleware/AuthFailureResponder.d.ts.map +1 -0
- package/app/Middleware/AuthFailureResponder.js +8 -0
- package/app/Middleware/ProfilerMiddleware.d.ts +12 -0
- package/app/Middleware/ProfilerMiddleware.d.ts.map +1 -0
- package/app/Middleware/ProfilerMiddleware.js +47 -0
- package/app/Middleware/index.d.ts +59 -0
- package/app/Middleware/index.d.ts.map +1 -0
- package/app/Middleware/index.js +216 -0
- package/app/Models/Post.d.ts +14 -0
- package/app/Models/Post.d.ts.map +1 -0
- package/app/Models/Post.js +27 -0
- package/app/Models/User.d.ts +14 -0
- package/app/Models/User.d.ts.map +1 -0
- package/app/Models/User.js +44 -0
- package/app/Schedules/JobTracking.d.ts +3 -0
- package/app/Schedules/JobTracking.d.ts.map +1 -0
- package/app/Schedules/JobTracking.js +13 -0
- package/app/Schedules/index.d.ts +2 -0
- package/app/Schedules/index.d.ts.map +1 -0
- package/app/Schedules/index.js +1 -0
- package/app/Toolkit/Broadcast/sendBroadcast.d.ts +6 -0
- package/app/Toolkit/Broadcast/sendBroadcast.d.ts.map +1 -0
- package/app/Toolkit/Broadcast/sendBroadcast.js +5 -0
- package/app/Toolkit/Mail/sendWelcomeEmail.d.ts +6 -0
- package/app/Toolkit/Mail/sendWelcomeEmail.d.ts.map +1 -0
- package/app/Toolkit/Mail/sendWelcomeEmail.js +20 -0
- package/app/Toolkit/Notification/sendSlackNotification.d.ts +8 -0
- package/app/Toolkit/Notification/sendSlackNotification.d.ts.map +1 -0
- package/app/Toolkit/Notification/sendSlackNotification.js +5 -0
- package/app/Toolkit/Notification/sendSms.d.ts +6 -0
- package/app/Toolkit/Notification/sendSms.d.ts.map +1 -0
- package/app/Toolkit/Notification/sendSms.js +5 -0
- package/app/Types/controller.d.ts +44 -0
- package/app/Types/controller.d.ts.map +1 -0
- package/app/Types/controller.js +1 -0
- package/app/Workers/AdvancEmailWorker.d.ts +44 -0
- package/app/Workers/AdvancEmailWorker.d.ts.map +1 -0
- package/app/Workers/AdvancEmailWorker.js +192 -0
- package/app/Workers/EmailWorker.d.ts +39 -0
- package/app/Workers/EmailWorker.d.ts.map +1 -0
- package/app/Workers/EmailWorker.js +199 -0
- package/app/Workers/TestWorker.d.ts +16 -0
- package/app/Workers/TestWorker.d.ts.map +1 -0
- package/app/Workers/TestWorker.js +153 -0
- package/bin/z.js +0 -0
- package/bin/zin.js +0 -0
- package/bin/zintrust.js +0 -0
- package/bin/zt.js +0 -0
- package/build-manifest.json +6410 -0
- package/config/broadcast.d.ts +38 -0
- package/config/broadcast.d.ts.map +1 -0
- package/config/broadcast.js +37 -0
- package/config/cache.d.ts +40 -0
- package/config/cache.d.ts.map +1 -0
- package/config/cache.js +39 -0
- package/config/database.d.ts +58 -0
- package/config/database.d.ts.map +1 -0
- package/config/database.js +65 -0
- package/config/mail.d.ts +51 -0
- package/config/mail.d.ts.map +1 -0
- package/config/mail.js +69 -0
- package/config/middleware.d.ts +21 -0
- package/config/middleware.d.ts.map +1 -0
- package/config/middleware.js +61 -0
- package/config/notification.d.ts +33 -0
- package/config/notification.d.ts.map +1 -0
- package/config/notification.js +33 -0
- package/config/queue.d.ts +55 -0
- package/config/queue.d.ts.map +1 -0
- package/config/queue.js +87 -0
- package/config/storage.d.ts +59 -0
- package/config/storage.d.ts.map +1 -0
- package/config/storage.js +59 -0
- package/config/workers.d.ts +54 -0
- package/config/workers.d.ts.map +1 -0
- package/config/workers.js +83 -0
- package/database/factories/UserFactory.d.ts +40 -0
- package/database/factories/UserFactory.d.ts.map +1 -0
- package/database/factories/UserFactory.js +99 -0
- package/database/migrations/20260109074544_create_users_table.d.ts +7 -0
- package/database/migrations/20260109074544_create_users_table.d.ts.map +1 -0
- package/database/migrations/20260109074544_create_users_table.js +21 -0
- package/database/migrations/20260109144731_create_tasks_table.d.ts +7 -0
- package/database/migrations/20260109144731_create_tasks_table.d.ts.map +1 -0
- package/database/migrations/20260109144731_create_tasks_table.js +19 -0
- package/database/migrations/20260109144735_add_done_tasks_table.d.ts +11 -0
- package/database/migrations/20260109144735_add_done_tasks_table.d.ts.map +1 -0
- package/database/migrations/20260109144735_add_done_tasks_table.js +25 -0
- package/database/migrations/20260109150837_add_start_tasks_table.d.ts +11 -0
- package/database/migrations/20260109150837_add_start_tasks_table.d.ts.map +1 -0
- package/database/migrations/20260109150837_add_start_tasks_table.js +22 -0
- package/database/migrations/20260109152114_add_way_tasks_table.d.ts +11 -0
- package/database/migrations/20260109152114_add_way_tasks_table.d.ts.map +1 -0
- package/database/migrations/20260109152114_add_way_tasks_table.js +22 -0
- package/database/migrations/20260218121500_create_jwt_revocations_table.d.ts +7 -0
- package/database/migrations/20260218121500_create_jwt_revocations_table.d.ts.map +1 -0
- package/database/migrations/20260218121500_create_jwt_revocations_table.js +22 -0
- package/database/migrations/20260222120000_add_kind_to_jwt_revocations_table.d.ts +11 -0
- package/database/migrations/20260222120000_add_kind_to_jwt_revocations_table.d.ts.map +1 -0
- package/database/migrations/20260222120000_add_kind_to_jwt_revocations_table.js +20 -0
- package/database/migrations/20260222123000_add_user_id_to_jwt_revocations_table.d.ts +11 -0
- package/database/migrations/20260222123000_add_user_id_to_jwt_revocations_table.d.ts.map +1 -0
- package/database/migrations/20260222123000_add_user_id_to_jwt_revocations_table.js +20 -0
- package/database/migrations/20260327112651_create_posts_table.d.ts +11 -0
- package/database/migrations/20260327112651_create_posts_table.d.ts.map +1 -0
- package/database/migrations/20260327112651_create_posts_table.js +24 -0
- package/database/seeders/DatabaseSeeder.d.ts +5 -0
- package/database/seeders/DatabaseSeeder.d.ts.map +1 -0
- package/database/seeders/DatabaseSeeder.js +15 -0
- package/database/seeders/UserSeeder.d.ts +30 -0
- package/database/seeders/UserSeeder.d.ts.map +1 -0
- package/database/seeders/UserSeeder.js +97 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +26 -77
- package/packages/cache-redis/src/RedisProxyAdapter.d.ts +6 -0
- package/packages/cache-redis/src/RedisProxyAdapter.d.ts.map +1 -0
- package/packages/cache-redis/src/RedisProxyAdapter.js +144 -0
- package/packages/cache-redis/src/index.d.ts +27 -0
- package/packages/cache-redis/src/index.d.ts.map +1 -0
- package/packages/cache-redis/src/index.js +153 -0
- package/packages/db-d1/src/index.d.ts +55 -0
- package/packages/db-d1/src/index.d.ts.map +1 -0
- package/packages/db-d1/src/index.js +118 -0
- package/packages/db-d1/src/register.d.ts +6 -0
- package/packages/db-d1/src/register.d.ts.map +1 -0
- package/packages/db-d1/src/register.js +8 -0
- package/packages/db-mysql/src/common.d.ts +7 -0
- package/packages/db-mysql/src/common.d.ts.map +1 -0
- package/packages/db-mysql/src/common.js +17 -0
- package/packages/db-mysql/src/index.d.ts +43 -0
- package/packages/db-mysql/src/index.d.ts.map +1 -0
- package/packages/db-mysql/src/index.js +265 -0
- package/packages/db-mysql/src/register.d.ts +6 -0
- package/packages/db-mysql/src/register.d.ts.map +1 -0
- package/packages/db-mysql/src/register.js +32 -0
- package/packages/db-postgres/src/index.d.ts +39 -0
- package/packages/db-postgres/src/index.d.ts.map +1 -0
- package/packages/db-postgres/src/index.js +179 -0
- package/packages/db-postgres/src/register.d.ts +6 -0
- package/packages/db-postgres/src/register.d.ts.map +1 -0
- package/packages/db-postgres/src/register.js +8 -0
- package/packages/db-sqlite/src/index.d.ts +9 -0
- package/packages/db-sqlite/src/index.d.ts.map +1 -0
- package/packages/db-sqlite/src/index.js +7 -0
- package/packages/db-sqlite/src/register.d.ts +6 -0
- package/packages/db-sqlite/src/register.d.ts.map +1 -0
- package/packages/db-sqlite/src/register.js +8 -0
- package/packages/db-sqlserver/src/index.d.ts +38 -0
- package/packages/db-sqlserver/src/index.d.ts.map +1 -0
- package/packages/db-sqlserver/src/index.js +73 -0
- package/packages/db-sqlserver/src/register.d.ts +6 -0
- package/packages/db-sqlserver/src/register.d.ts.map +1 -0
- package/packages/db-sqlserver/src/register.js +21 -0
- package/packages/mail-sendgrid/src/register.d.ts +6 -0
- package/packages/mail-sendgrid/src/register.d.ts.map +1 -0
- package/packages/mail-sendgrid/src/register.js +24 -0
- package/packages/mail-smtp/src/register.d.ts +6 -0
- package/packages/mail-smtp/src/register.d.ts.map +1 -0
- package/packages/mail-smtp/src/register.js +29 -0
- package/packages/queue-monitor/src/QueueMonitoringService.d.ts +35 -0
- package/packages/queue-monitor/src/QueueMonitoringService.d.ts.map +1 -0
- package/packages/queue-monitor/src/QueueMonitoringService.js +194 -0
- package/packages/queue-monitor/src/connection.d.ts +3 -0
- package/packages/queue-monitor/src/connection.d.ts.map +1 -0
- package/packages/queue-monitor/src/connection.js +1 -0
- package/packages/queue-monitor/src/dashboard-ui.d.ts +7 -0
- package/packages/queue-monitor/src/dashboard-ui.d.ts.map +1 -0
- package/packages/queue-monitor/src/dashboard-ui.js +997 -0
- package/packages/queue-monitor/src/driver.d.ts +15 -0
- package/packages/queue-monitor/src/driver.d.ts.map +1 -0
- package/packages/queue-monitor/src/driver.js +115 -0
- package/packages/queue-monitor/src/index.d.ts +71 -0
- package/packages/queue-monitor/src/index.d.ts.map +1 -0
- package/packages/queue-monitor/src/index.js +296 -0
- package/packages/queue-monitor/src/metrics.d.ts +27 -0
- package/packages/queue-monitor/src/metrics.d.ts.map +1 -0
- package/packages/queue-monitor/src/metrics.js +92 -0
- package/packages/queue-monitor/src/worker.d.ts +8 -0
- package/packages/queue-monitor/src/worker.d.ts.map +1 -0
- package/packages/queue-monitor/src/worker.js +35 -0
- package/packages/queue-redis/src/BullMQRedisQueue.d.ts +26 -0
- package/packages/queue-redis/src/BullMQRedisQueue.d.ts.map +1 -0
- package/packages/queue-redis/src/BullMQRedisQueue.js +465 -0
- package/packages/queue-redis/src/HttpQueueDriver.d.ts +18 -0
- package/packages/queue-redis/src/HttpQueueDriver.d.ts.map +1 -0
- package/packages/queue-redis/src/HttpQueueDriver.js +249 -0
- package/packages/queue-redis/src/QueueHttpGateway.d.ts +16 -0
- package/packages/queue-redis/src/QueueHttpGateway.d.ts.map +1 -0
- package/packages/queue-redis/src/QueueHttpGateway.js +217 -0
- package/packages/queue-redis/src/RedisPublishClient.d.ts +14 -0
- package/packages/queue-redis/src/RedisPublishClient.d.ts.map +1 -0
- package/packages/queue-redis/src/RedisPublishClient.js +251 -0
- package/packages/queue-redis/src/index.d.ts +12 -0
- package/packages/queue-redis/src/index.d.ts.map +1 -0
- package/packages/queue-redis/src/index.js +10 -0
- package/packages/queue-redis/src/register.d.ts +6 -0
- package/packages/queue-redis/src/register.d.ts.map +1 -0
- package/packages/queue-redis/src/register.js +21 -0
- package/packages/workers/migrations/20260119100000_create_zintrust_workers_table.d.ts +11 -0
- package/packages/workers/migrations/20260119100000_create_zintrust_workers_table.d.ts.map +1 -0
- package/packages/workers/migrations/20260119100000_create_zintrust_workers_table.js +32 -0
- package/packages/workers/migrations/20260123180000_create_queue_jobs_table.d.ts +11 -0
- package/packages/workers/migrations/20260123180000_create_queue_jobs_table.d.ts.map +1 -0
- package/packages/workers/migrations/20260123180000_create_queue_jobs_table.js +46 -0
- package/packages/workers/migrations/20260213142000_create_zintrust_job_tracking_tables.d.ts +7 -0
- package/packages/workers/migrations/20260213142000_create_zintrust_job_tracking_tables.d.ts.map +1 -0
- package/packages/workers/migrations/20260213142000_create_zintrust_job_tracking_tables.js +44 -0
- package/packages/workers/migrations/20260213183000_expand_zintrust_job_tracking_reliability_tables.d.ts +7 -0
- package/packages/workers/migrations/20260213183000_expand_zintrust_job_tracking_reliability_tables.d.ts.map +1 -0
- package/packages/workers/migrations/20260213183000_expand_zintrust_job_tracking_reliability_tables.js +104 -0
- package/packages/workers/src/AnomalyDetection.d.ts +107 -0
- package/packages/workers/src/AnomalyDetection.d.ts.map +1 -0
- package/packages/workers/src/AnomalyDetection.js +329 -0
- package/packages/workers/src/AutoScaler.d.ts +128 -0
- package/packages/workers/src/AutoScaler.d.ts.map +1 -0
- package/packages/workers/src/AutoScaler.js +425 -0
- package/packages/workers/src/BroadcastWorker.d.ts +29 -0
- package/packages/workers/src/BroadcastWorker.d.ts.map +1 -0
- package/packages/workers/src/BroadcastWorker.js +24 -0
- package/packages/workers/src/CanaryController.d.ts +104 -0
- package/packages/workers/src/CanaryController.d.ts.map +1 -0
- package/packages/workers/src/CanaryController.js +424 -0
- package/packages/workers/src/ChaosEngineering.d.ts +80 -0
- package/packages/workers/src/ChaosEngineering.d.ts.map +1 -0
- package/packages/workers/src/ChaosEngineering.js +229 -0
- package/packages/workers/src/CircuitBreaker.d.ts +107 -0
- package/packages/workers/src/CircuitBreaker.d.ts.map +1 -0
- package/packages/workers/src/CircuitBreaker.js +374 -0
- package/packages/workers/src/ClusterLock.d.ts +91 -0
- package/packages/workers/src/ClusterLock.d.ts.map +1 -0
- package/packages/workers/src/ClusterLock.js +397 -0
- package/packages/workers/src/ComplianceManager.d.ts +178 -0
- package/packages/workers/src/ComplianceManager.d.ts.map +1 -0
- package/packages/workers/src/ComplianceManager.js +556 -0
- package/packages/workers/src/DatacenterOrchestrator.d.ts +134 -0
- package/packages/workers/src/DatacenterOrchestrator.d.ts.map +1 -0
- package/packages/workers/src/DatacenterOrchestrator.js +404 -0
- package/packages/workers/src/DeadLetterQueue.d.ts +123 -0
- package/packages/workers/src/DeadLetterQueue.d.ts.map +1 -0
- package/packages/workers/src/DeadLetterQueue.js +544 -0
- package/packages/workers/src/HealthMonitor.d.ts +43 -0
- package/packages/workers/src/HealthMonitor.d.ts.map +1 -0
- package/packages/workers/src/HealthMonitor.js +312 -0
- package/packages/workers/src/MultiQueueWorker.d.ts +90 -0
- package/packages/workers/src/MultiQueueWorker.d.ts.map +1 -0
- package/packages/workers/src/MultiQueueWorker.js +282 -0
- package/packages/workers/src/NotificationWorker.d.ts +29 -0
- package/packages/workers/src/NotificationWorker.d.ts.map +1 -0
- package/packages/workers/src/NotificationWorker.js +23 -0
- package/packages/workers/src/Observability.d.ts +154 -0
- package/packages/workers/src/Observability.d.ts.map +1 -0
- package/packages/workers/src/Observability.js +538 -0
- package/packages/workers/src/PluginManager.d.ts +124 -0
- package/packages/workers/src/PluginManager.d.ts.map +1 -0
- package/packages/workers/src/PluginManager.js +392 -0
- package/packages/workers/src/PriorityQueue.d.ts +118 -0
- package/packages/workers/src/PriorityQueue.d.ts.map +1 -0
- package/packages/workers/src/PriorityQueue.js +276 -0
- package/packages/workers/src/ResourceMonitor.d.ts +165 -0
- package/packages/workers/src/ResourceMonitor.d.ts.map +1 -0
- package/packages/workers/src/ResourceMonitor.js +632 -0
- package/packages/workers/src/SLAMonitor.d.ts +111 -0
- package/packages/workers/src/SLAMonitor.d.ts.map +1 -0
- package/packages/workers/src/SLAMonitor.js +274 -0
- package/packages/workers/src/WorkerFactory.d.ts +226 -0
- package/packages/workers/src/WorkerFactory.d.ts.map +1 -0
- package/packages/workers/src/WorkerFactory.js +2551 -0
- package/packages/workers/src/WorkerInit.d.ts +103 -0
- package/packages/workers/src/WorkerInit.d.ts.map +1 -0
- package/packages/workers/src/WorkerInit.js +359 -0
- package/packages/workers/src/WorkerMetrics.d.ts +116 -0
- package/packages/workers/src/WorkerMetrics.d.ts.map +1 -0
- package/packages/workers/src/WorkerMetrics.js +570 -0
- package/packages/workers/src/WorkerRegistry.d.ts +152 -0
- package/packages/workers/src/WorkerRegistry.d.ts.map +1 -0
- package/packages/workers/src/WorkerRegistry.js +396 -0
- package/packages/workers/src/WorkerShutdown.d.ts +70 -0
- package/packages/workers/src/WorkerShutdown.d.ts.map +1 -0
- package/packages/workers/src/WorkerShutdown.js +185 -0
- package/packages/workers/src/WorkerVersioning.d.ts +108 -0
- package/packages/workers/src/WorkerVersioning.d.ts.map +1 -0
- package/packages/workers/src/WorkerVersioning.js +300 -0
- package/packages/workers/src/config/workerConfig.d.ts +5 -0
- package/packages/workers/src/config/workerConfig.d.ts.map +1 -0
- package/packages/workers/src/config/workerConfig.js +25 -0
- package/packages/workers/src/createQueueWorker.d.ts +31 -0
- package/packages/workers/src/createQueueWorker.d.ts.map +1 -0
- package/packages/workers/src/createQueueWorker.js +382 -0
- package/packages/workers/src/dashboard/index.d.ts +2 -0
- package/packages/workers/src/dashboard/index.d.ts.map +1 -0
- package/packages/workers/src/dashboard/index.js +1 -0
- package/packages/workers/src/dashboard/types.d.ts +123 -0
- package/packages/workers/src/dashboard/types.d.ts.map +1 -0
- package/packages/workers/src/dashboard/types.js +1 -0
- package/packages/workers/src/dashboard/workers-api.d.ts +5 -0
- package/packages/workers/src/dashboard/workers-api.d.ts.map +1 -0
- package/packages/workers/src/dashboard/workers-api.js +776 -0
- package/packages/workers/src/helper/index.d.ts +6 -0
- package/packages/workers/src/helper/index.d.ts.map +1 -0
- package/packages/workers/src/helper/index.js +10 -0
- package/packages/workers/src/http/WorkerApiController.d.ts +39 -0
- package/packages/workers/src/http/WorkerApiController.d.ts.map +1 -0
- package/packages/workers/src/http/WorkerApiController.js +313 -0
- package/packages/workers/src/http/WorkerController.d.ts +375 -0
- package/packages/workers/src/http/WorkerController.d.ts.map +1 -0
- package/packages/workers/src/http/WorkerController.js +1454 -0
- package/packages/workers/src/http/WorkerMonitoringService.d.ts +12 -0
- package/packages/workers/src/http/WorkerMonitoringService.d.ts.map +1 -0
- package/packages/workers/src/http/WorkerMonitoringService.js +89 -0
- package/packages/workers/src/http/middleware/CustomValidation.d.ts +93 -0
- package/packages/workers/src/http/middleware/CustomValidation.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/CustomValidation.js +270 -0
- package/packages/workers/src/http/middleware/DatacenterValidator.d.ts +4 -0
- package/packages/workers/src/http/middleware/DatacenterValidator.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/DatacenterValidator.js +94 -0
- package/packages/workers/src/http/middleware/EditWorkerValidation.d.ts +8 -0
- package/packages/workers/src/http/middleware/EditWorkerValidation.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/EditWorkerValidation.js +56 -0
- package/packages/workers/src/http/middleware/FeaturesValidator.d.ts +4 -0
- package/packages/workers/src/http/middleware/FeaturesValidator.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/FeaturesValidator.js +61 -0
- package/packages/workers/src/http/middleware/InfrastructureValidator.d.ts +32 -0
- package/packages/workers/src/http/middleware/InfrastructureValidator.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/InfrastructureValidator.js +226 -0
- package/packages/workers/src/http/middleware/OptionsValidator.d.ts +4 -0
- package/packages/workers/src/http/middleware/OptionsValidator.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/OptionsValidator.js +112 -0
- package/packages/workers/src/http/middleware/PayloadSanitizer.d.ts +8 -0
- package/packages/workers/src/http/middleware/PayloadSanitizer.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/PayloadSanitizer.js +42 -0
- package/packages/workers/src/http/middleware/ProcessorPathSanitizer.d.ts +4 -0
- package/packages/workers/src/http/middleware/ProcessorPathSanitizer.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/ProcessorPathSanitizer.js +140 -0
- package/packages/workers/src/http/middleware/QueueNameSanitizer.d.ts +4 -0
- package/packages/workers/src/http/middleware/QueueNameSanitizer.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/QueueNameSanitizer.js +45 -0
- package/packages/workers/src/http/middleware/ValidateDriver.d.ts +8 -0
- package/packages/workers/src/http/middleware/ValidateDriver.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/ValidateDriver.js +20 -0
- package/packages/workers/src/http/middleware/VersionSanitizer.d.ts +4 -0
- package/packages/workers/src/http/middleware/VersionSanitizer.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/VersionSanitizer.js +25 -0
- package/packages/workers/src/http/middleware/WorkerNameSanitizer.d.ts +4 -0
- package/packages/workers/src/http/middleware/WorkerNameSanitizer.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/WorkerNameSanitizer.js +46 -0
- package/packages/workers/src/http/middleware/WorkerValidationChain.d.ts +28 -0
- package/packages/workers/src/http/middleware/WorkerValidationChain.d.ts.map +1 -0
- package/packages/workers/src/http/middleware/WorkerValidationChain.js +186 -0
- package/packages/workers/src/index.d.ts +47 -0
- package/packages/workers/src/index.d.ts.map +1 -0
- package/packages/workers/src/index.js +48 -0
- package/packages/workers/src/register.d.ts +10 -0
- package/packages/workers/src/register.d.ts.map +1 -0
- package/packages/workers/src/register.js +43 -0
- package/packages/workers/src/routes/workers.d.ts +13 -0
- package/packages/workers/src/routes/workers.d.ts.map +1 -0
- package/packages/workers/src/routes/workers.js +126 -0
- package/packages/workers/src/storage/WorkerStore.d.ts +52 -0
- package/packages/workers/src/storage/WorkerStore.d.ts.map +1 -0
- package/packages/workers/src/storage/WorkerStore.js +259 -0
- package/packages/workers/src/telemetry/api/TelemetryAPI.d.ts +47 -0
- package/packages/workers/src/telemetry/api/TelemetryAPI.d.ts.map +1 -0
- package/packages/workers/src/telemetry/api/TelemetryAPI.js +219 -0
- package/packages/workers/src/telemetry/api/TelemetryMonitoringService.d.ts +18 -0
- package/packages/workers/src/telemetry/api/TelemetryMonitoringService.d.ts.map +1 -0
- package/packages/workers/src/telemetry/api/TelemetryMonitoringService.js +140 -0
- package/packages/workers/src/telemetry/components/AlertPanel.d.ts +2 -0
- package/packages/workers/src/telemetry/components/AlertPanel.d.ts.map +1 -0
- package/packages/workers/src/telemetry/components/AlertPanel.js +13 -0
- package/packages/workers/src/telemetry/components/CostTracking.d.ts +2 -0
- package/packages/workers/src/telemetry/components/CostTracking.d.ts.map +1 -0
- package/packages/workers/src/telemetry/components/CostTracking.js +14 -0
- package/packages/workers/src/telemetry/components/ResourceUsageChart.d.ts +2 -0
- package/packages/workers/src/telemetry/components/ResourceUsageChart.d.ts.map +1 -0
- package/packages/workers/src/telemetry/components/ResourceUsageChart.js +11 -0
- package/packages/workers/src/telemetry/components/WorkerHealthChart.d.ts +2 -0
- package/packages/workers/src/telemetry/components/WorkerHealthChart.d.ts.map +1 -0
- package/packages/workers/src/telemetry/components/WorkerHealthChart.js +11 -0
- package/packages/workers/src/telemetry/index.d.ts +16 -0
- package/packages/workers/src/telemetry/index.d.ts.map +1 -0
- package/packages/workers/src/telemetry/index.js +60 -0
- package/packages/workers/src/telemetry/routes/dashboard.d.ts +7 -0
- package/packages/workers/src/telemetry/routes/dashboard.d.ts.map +1 -0
- package/packages/workers/src/telemetry/routes/dashboard.js +608 -0
- package/packages/workers/src/type.d.ts +77 -0
- package/packages/workers/src/type.d.ts.map +1 -0
- package/packages/workers/src/type.js +1 -0
- package/packages/workers/src/ui/router/EmbeddedAssets.d.ts +5 -0
- package/packages/workers/src/ui/router/EmbeddedAssets.d.ts.map +1 -0
- package/packages/workers/src/ui/router/EmbeddedAssets.js +13 -0
- package/packages/workers/src/ui/router/ui.d.ts +4 -0
- package/packages/workers/src/ui/router/ui.d.ts.map +1 -0
- package/packages/workers/src/ui/router/ui.js +208 -0
- package/packages/workers/src/ui/types/worker-ui.d.ts +230 -0
- package/packages/workers/src/ui/types/worker-ui.d.ts.map +1 -0
- package/packages/workers/src/ui/types/worker-ui.js +5 -0
- package/routes/DirectTestRoutes.d.ts +25 -0
- package/routes/DirectTestRoutes.d.ts.map +1 -0
- package/routes/DirectTestRoutes.js +480 -0
- package/routes/TestRoutes.d.ts +11 -0
- package/routes/TestRoutes.d.ts.map +1 -0
- package/routes/TestRoutes.js +25 -0
- package/routes/api.d.ts +7 -0
- package/routes/api.d.ts.map +1 -0
- package/routes/api.js +136 -0
- package/routes/apiDev.d.ts +7 -0
- package/routes/apiDev.d.ts.map +1 -0
- package/routes/apiDev.js +92 -0
- package/routes/broadcast.d.ts +9 -0
- package/routes/broadcast.d.ts.map +1 -0
- package/routes/broadcast.js +27 -0
- package/routes/mail.d.ts +12 -0
- package/routes/mail.d.ts.map +1 -0
- package/routes/mail.js +138 -0
- package/routes/storage.d.ts +4 -0
- package/routes/storage.d.ts.map +1 -0
- package/routes/storage.js +35 -0
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +4 -0
- package/src/cli/commands/D1ProxyCommand.d.ts +6 -0
- package/src/cli/commands/D1ProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/D1ProxyCommand.js +170 -0
- package/src/cli/commands/InitContainerCommand.d.ts.map +1 -1
- package/src/cli/commands/InitContainerCommand.js +9 -96
- package/src/cli/commands/KvProxyCommand.d.ts +6 -0
- package/src/cli/commands/KvProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/KvProxyCommand.js +158 -0
- package/src/cli/commands/ProxyCommand.d.ts.map +1 -1
- package/src/cli/commands/ProxyCommand.js +2 -0
- package/src/cli/commands/index.d.ts +2 -0
- package/src/cli/commands/index.d.ts.map +1 -1
- package/src/cli/commands/index.js +2 -0
- package/src/cli/index.d.ts +2 -0
- package/src/cli/index.d.ts.map +1 -1
- package/src/cli/index.js +2 -0
- package/src/cli/scaffolding/GovernanceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/GovernanceScaffolder.js +20 -3
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +13 -4
- package/src/cli/utils/DistPackager.d.ts +2 -2
- package/src/cli/utils/DistPackager.d.ts.map +1 -1
- package/src/cli/utils/DistPackager.js +9 -3
- package/src/index.js +3 -3
- package/src/proxy.d.ts +2 -0
- package/src/proxy.d.ts.map +1 -1
- package/src/proxy.js +2 -0
- package/src/templates/project/basic/package.json.tpl +1 -1
- package/start.d.ts +1 -0
- package/start.js +1 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User QueryBuilder Controller
|
|
3
|
+
* QueryBuilder-backed controller for the users resource.
|
|
4
|
+
*/
|
|
5
|
+
import { Logger, QueryBuilder, Sanitizer, Schema, Validator, getValidatedBody, nowIso, randomBytes, useDatabase, } from '../../src/index.js';
|
|
6
|
+
const isValidationError = (error) => {
|
|
7
|
+
if (typeof error !== 'object' || error === null)
|
|
8
|
+
return false;
|
|
9
|
+
const maybe = error;
|
|
10
|
+
return maybe.name === 'ValidationError' && typeof maybe.toObject === 'function';
|
|
11
|
+
};
|
|
12
|
+
const isSanitizerError = (error) => {
|
|
13
|
+
if (typeof error !== 'object' || error === null)
|
|
14
|
+
return false;
|
|
15
|
+
const maybe = error;
|
|
16
|
+
return maybe.name === 'SanitizerError';
|
|
17
|
+
};
|
|
18
|
+
const toJsonRecord = (value) => {
|
|
19
|
+
if (typeof value !== 'object' || value === null)
|
|
20
|
+
return {};
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
return {};
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
const resolveBody = (req) => {
|
|
26
|
+
return toJsonRecord(getValidatedBody(req) ?? req.body ?? {});
|
|
27
|
+
};
|
|
28
|
+
const getParamCompat = (req, name) => {
|
|
29
|
+
try {
|
|
30
|
+
const anyReq = req;
|
|
31
|
+
if (typeof anyReq.getParam === 'function')
|
|
32
|
+
return anyReq.getParam(name);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// ignore
|
|
36
|
+
}
|
|
37
|
+
const anyReq = req;
|
|
38
|
+
const params = anyReq.params;
|
|
39
|
+
if (typeof params === 'object' && params !== null)
|
|
40
|
+
return params[name];
|
|
41
|
+
return undefined;
|
|
42
|
+
};
|
|
43
|
+
const requireSelf = (req, res, userId) => {
|
|
44
|
+
if (typeof userId !== 'string' || userId.length === 0) {
|
|
45
|
+
res.status(400).json({ error: 'Missing user id' });
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const subject = typeof req.user?.sub === 'string' ? req.user.sub : undefined;
|
|
49
|
+
if (subject === undefined || subject.length === 0) {
|
|
50
|
+
res.status(401).json({ error: 'Unauthorized' });
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (subject !== userId) {
|
|
54
|
+
res.status(403).json({ error: 'Forbidden' });
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
const randomInt = (min, max) => {
|
|
60
|
+
const lo = Math.ceil(min);
|
|
61
|
+
const hi = Math.floor(max);
|
|
62
|
+
return Math.floor(lo + Math.random() * (hi - lo + 1)); // NOSONAR is just a test utility
|
|
63
|
+
};
|
|
64
|
+
const randomName = () => {
|
|
65
|
+
const first = ['Alex', 'Jordan', 'Taylor', 'Sam', 'Casey', 'Riley', 'Morgan'];
|
|
66
|
+
const last = ['Lee', 'Kim', 'Patel', 'Garcia', 'Brown', 'Nguyen', 'Smith'];
|
|
67
|
+
return `${first[randomInt(0, first.length - 1)]} ${last[randomInt(0, last.length - 1)]}`;
|
|
68
|
+
};
|
|
69
|
+
const randomEmail = () => {
|
|
70
|
+
const n = randomInt(10000, 99999);
|
|
71
|
+
return `user${n}@example.com`;
|
|
72
|
+
};
|
|
73
|
+
const randomPassword = () => {
|
|
74
|
+
// Not cryptographically perfect UX-wise, but avoids hard-coded credentials.
|
|
75
|
+
// `base64url` keeps it URL-safe and reasonably short.
|
|
76
|
+
return randomBytes(12).toString('base64url');
|
|
77
|
+
};
|
|
78
|
+
const pickAllowed = (body, allowed) => {
|
|
79
|
+
const out = {};
|
|
80
|
+
for (const [k, v] of Object.entries(body)) {
|
|
81
|
+
if (allowed.has(k))
|
|
82
|
+
out[k] = v;
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
};
|
|
86
|
+
const hasUnknownKeys = (body, allowed) => {
|
|
87
|
+
for (const k of Object.keys(body)) {
|
|
88
|
+
if (!allowed.has(k))
|
|
89
|
+
return k;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
};
|
|
93
|
+
const sanitizeUserUpdateBody = (updateBody) => {
|
|
94
|
+
const sanitizedUpdateBody = {};
|
|
95
|
+
if ('name' in updateBody) {
|
|
96
|
+
sanitizedUpdateBody['name'] = Sanitizer.nameText(updateBody['name']).trim();
|
|
97
|
+
}
|
|
98
|
+
if ('email' in updateBody) {
|
|
99
|
+
sanitizedUpdateBody['email'] = Sanitizer.email(updateBody['email']).trim().toLowerCase();
|
|
100
|
+
}
|
|
101
|
+
if ('password' in updateBody) {
|
|
102
|
+
sanitizedUpdateBody['password'] = Sanitizer.safePasswordChars(updateBody['password']);
|
|
103
|
+
}
|
|
104
|
+
return sanitizedUpdateBody;
|
|
105
|
+
};
|
|
106
|
+
const buildUserUpdateSchema = () => {
|
|
107
|
+
return Schema.create()
|
|
108
|
+
.custom('name', (v) => v === undefined || typeof v === 'string', 'name must be a string')
|
|
109
|
+
.minLength('name', 1)
|
|
110
|
+
.custom('email', (v) => v === undefined || typeof v === 'string', 'email must be a string')
|
|
111
|
+
.custom('password', (v) => v === undefined || typeof v === 'string', 'password must be a string')
|
|
112
|
+
.minLength('password', 8);
|
|
113
|
+
};
|
|
114
|
+
const buildUserStoreSchema = () => {
|
|
115
|
+
return Schema.create()
|
|
116
|
+
.custom('name', (v) => typeof v === 'string', 'name must be a string')
|
|
117
|
+
.minLength('name', 1)
|
|
118
|
+
.custom('email', (v) => typeof v === 'string', 'email must be a string')
|
|
119
|
+
.email('email')
|
|
120
|
+
.custom('password', (v) => typeof v === 'string', 'password must be a string')
|
|
121
|
+
.minLength('password', 8);
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* User Controller Methods
|
|
125
|
+
*/
|
|
126
|
+
const userControllerMethods = {
|
|
127
|
+
/**
|
|
128
|
+
* List all users
|
|
129
|
+
* GET /users
|
|
130
|
+
*/
|
|
131
|
+
async index(req, res) {
|
|
132
|
+
try {
|
|
133
|
+
const subject = typeof req.user?.sub === 'string' ? req.user.sub : undefined;
|
|
134
|
+
if (subject === undefined || subject.length === 0) {
|
|
135
|
+
res.status(401).json({ error: 'Unauthorized' });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const db = useDatabase();
|
|
139
|
+
const users = await QueryBuilder.create('users', db)
|
|
140
|
+
.select('id', 'name', 'email', 'created_at', 'updated_at')
|
|
141
|
+
.where('id', '=', subject)
|
|
142
|
+
.limit(1)
|
|
143
|
+
.get();
|
|
144
|
+
res.json({ data: users });
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
Logger.error('Error fetching users:', error);
|
|
148
|
+
res.status(500).json({ error: 'Failed to fetch users' });
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* Show a specific user
|
|
153
|
+
* GET /users/:id
|
|
154
|
+
*/
|
|
155
|
+
async show(req, res) {
|
|
156
|
+
try {
|
|
157
|
+
const db = useDatabase();
|
|
158
|
+
const rawId = getParamCompat(req, 'id');
|
|
159
|
+
const id = Sanitizer.digitsOnly(rawId); // Zero trust protection for db id
|
|
160
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
161
|
+
// ✅ Good
|
|
162
|
+
res.status(400).json({ error: 'Missing user id' });
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!requireSelf(req, res, id))
|
|
166
|
+
return;
|
|
167
|
+
const user = await QueryBuilder.create('users', db)
|
|
168
|
+
.select('id', 'name', 'email', 'created_at', 'updated_at')
|
|
169
|
+
.where('id', '=', id)
|
|
170
|
+
.limit(1)
|
|
171
|
+
.first();
|
|
172
|
+
if (user === null) {
|
|
173
|
+
res.status(404).json({ error: 'User not found' });
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
res.json({ data: user });
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
if (isSanitizerError(error)) {
|
|
180
|
+
res.status(400).json({ error: error.message });
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
Logger.error('Error fetching user:', error);
|
|
184
|
+
res.status(500).json({ error: 'Failed to fetch user' });
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
/**
|
|
188
|
+
* Show create form
|
|
189
|
+
* GET /users/create
|
|
190
|
+
*/
|
|
191
|
+
async create(_req, res) {
|
|
192
|
+
res.json({ form: 'Create User Form' });
|
|
193
|
+
},
|
|
194
|
+
/**
|
|
195
|
+
* Store a new user
|
|
196
|
+
* POST /users
|
|
197
|
+
*/
|
|
198
|
+
async store(req, res) {
|
|
199
|
+
try {
|
|
200
|
+
// Use validated body if available (already sanitized by middleware), otherwise fallback to raw
|
|
201
|
+
const body = resolveBody(req);
|
|
202
|
+
const required = ['name', 'email', 'password'];
|
|
203
|
+
const missing = {};
|
|
204
|
+
for (const key of required) {
|
|
205
|
+
const val = body[key];
|
|
206
|
+
if (typeof val !== 'string' || val.trim() === '') {
|
|
207
|
+
missing[key] = ['Required'];
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (Object.keys(missing).length > 0) {
|
|
211
|
+
res.status(422).json({ errors: missing });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// Trust middleware for sanitization if validation passed.
|
|
215
|
+
// If we are here, validation ostensibly passed or we are in a context where we must self-validate.
|
|
216
|
+
// To satisfy defense-in-depth without double-sanitization bottleneck:
|
|
217
|
+
// We assume body is safe-ish if it came from resolved validated body.
|
|
218
|
+
// But to be explicit and type-safe, we cast or read fields directly.
|
|
219
|
+
const db = useDatabase();
|
|
220
|
+
const ts = nowIso();
|
|
221
|
+
// Apply bulletproof sanitization for defense-in-depth
|
|
222
|
+
const name = Sanitizer.nameText(body['name']);
|
|
223
|
+
const email = Sanitizer.email(body['email']);
|
|
224
|
+
const password = Sanitizer.safePasswordChars(body['password']);
|
|
225
|
+
Validator.validate({ name, email, password }, buildUserStoreSchema());
|
|
226
|
+
await QueryBuilder.create('users', db).insert({
|
|
227
|
+
name,
|
|
228
|
+
email,
|
|
229
|
+
password, // Hashing should be handled by model/service or here if raw
|
|
230
|
+
created_at: ts,
|
|
231
|
+
updated_at: ts,
|
|
232
|
+
});
|
|
233
|
+
res.status(201).json({ message: 'User created' });
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
if (isSanitizerError(error)) {
|
|
237
|
+
res.status(400).json({ error: error.message });
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (isValidationError(error)) {
|
|
241
|
+
res.status(422).json({ errors: error.toObject?.() ?? {} });
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
Logger.error('Error creating user:', error);
|
|
245
|
+
res.status(500).json({ error: 'Failed to create user' });
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
/**
|
|
249
|
+
* Fill users table with random users
|
|
250
|
+
* POST /users/fill
|
|
251
|
+
*/
|
|
252
|
+
async fill(req, res) {
|
|
253
|
+
try {
|
|
254
|
+
const body = resolveBody(req);
|
|
255
|
+
const countVal = body['count'];
|
|
256
|
+
// Ensure count is a number (middleware validation handles this, but we double check or default)
|
|
257
|
+
let count = typeof countVal === 'number' ? countVal : 10;
|
|
258
|
+
if (count < 1)
|
|
259
|
+
count = 1;
|
|
260
|
+
if (count > 100)
|
|
261
|
+
count = 100;
|
|
262
|
+
const db = useDatabase();
|
|
263
|
+
const ts = nowIso();
|
|
264
|
+
// Optimize: Bulk insert instead of N+1 inserts to reduce IO bottleneck and memory overhead
|
|
265
|
+
const users = Array.from({ length: count }, () => ({
|
|
266
|
+
name: randomName(),
|
|
267
|
+
email: randomEmail(),
|
|
268
|
+
password: randomPassword(),
|
|
269
|
+
created_at: ts,
|
|
270
|
+
updated_at: ts,
|
|
271
|
+
}));
|
|
272
|
+
await QueryBuilder.create('users', db).insert(users);
|
|
273
|
+
res.status(201).json({ message: 'Users filled', count });
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
Logger.error('Error filling users:', error);
|
|
277
|
+
res.status(500).json({ error: 'Failed to fill users' });
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
/**
|
|
281
|
+
* Show edit form
|
|
282
|
+
* GET /users/:id/edit
|
|
283
|
+
*/
|
|
284
|
+
async edit(_req, res) {
|
|
285
|
+
try {
|
|
286
|
+
res.json({ form: 'Edit User Form' });
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
Logger.error('Error loading edit form:', error);
|
|
290
|
+
res.status(500).json({ error: 'Failed to load edit form' });
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
/**
|
|
294
|
+
* Update a user
|
|
295
|
+
* PUT /users/:id
|
|
296
|
+
*/
|
|
297
|
+
async update(req, res) {
|
|
298
|
+
// NOSONAR bulletproof sanitization requires explicit validation steps
|
|
299
|
+
try {
|
|
300
|
+
const db = useDatabase();
|
|
301
|
+
const rawId = getParamCompat(req, 'id');
|
|
302
|
+
const id = Sanitizer.digitsOnly(rawId);
|
|
303
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
304
|
+
res.status(400).json({ error: 'Missing user id' });
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (!requireSelf(req, res, id))
|
|
308
|
+
return;
|
|
309
|
+
const allowed = new Set(['name', 'email', 'password']);
|
|
310
|
+
const body = resolveBody(req);
|
|
311
|
+
const unknown = hasUnknownKeys(body, allowed);
|
|
312
|
+
if (unknown !== null) {
|
|
313
|
+
res.status(422).json({ errors: { [unknown]: ['Unknown field'] } });
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const updateBody = pickAllowed(body, allowed);
|
|
317
|
+
if (Object.keys(updateBody).length === 0) {
|
|
318
|
+
res.status(422).json({ errors: { body: ['No fields to update'] } });
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const sanitizedUpdateBody = sanitizeUserUpdateBody(updateBody);
|
|
322
|
+
Validator.validate(sanitizedUpdateBody, buildUserUpdateSchema());
|
|
323
|
+
const existing = await QueryBuilder.create('users', db)
|
|
324
|
+
.select('id')
|
|
325
|
+
.where('id', '=', id)
|
|
326
|
+
.limit(1)
|
|
327
|
+
.first();
|
|
328
|
+
if (existing === null) {
|
|
329
|
+
res.status(404).json({ error: 'User not found' });
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const ts = nowIso();
|
|
333
|
+
await QueryBuilder.create('users', db)
|
|
334
|
+
.where('id', '=', id)
|
|
335
|
+
.update({ ...sanitizedUpdateBody, updated_at: ts });
|
|
336
|
+
const user = await QueryBuilder.create('users', db)
|
|
337
|
+
.select('id', 'name', 'email', 'created_at', 'updated_at')
|
|
338
|
+
.where('id', '=', id)
|
|
339
|
+
.limit(1)
|
|
340
|
+
.first();
|
|
341
|
+
res.json({ message: 'User updated', user });
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
if (isSanitizerError(error)) {
|
|
345
|
+
res.status(400).json({ error: error.message });
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (isValidationError(error)) {
|
|
349
|
+
res.status(422).json({ errors: error.toObject?.() ?? {} });
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
Logger.error('Error updating user:', error);
|
|
353
|
+
res.status(500).json({ error: 'Failed to update user' });
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
/**
|
|
357
|
+
* Delete a user
|
|
358
|
+
* DELETE /users/:id
|
|
359
|
+
*/
|
|
360
|
+
async destroy(req, res) {
|
|
361
|
+
try {
|
|
362
|
+
const db = useDatabase();
|
|
363
|
+
const rawId = getParamCompat(req, 'id');
|
|
364
|
+
const id = Sanitizer.digitsOnly(rawId);
|
|
365
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
366
|
+
res.status(400).json({ error: 'Missing user id' });
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (!requireSelf(req, res, id))
|
|
370
|
+
return;
|
|
371
|
+
const existing = await QueryBuilder.create('users', db)
|
|
372
|
+
.select('id')
|
|
373
|
+
.where('id', '=', id)
|
|
374
|
+
.limit(1)
|
|
375
|
+
.first();
|
|
376
|
+
if (existing === null) {
|
|
377
|
+
res.status(404).json({ error: 'User not found' });
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
await QueryBuilder.create('users', db).where('id', '=', id).delete();
|
|
381
|
+
res.json({ message: 'User deleted' });
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
if (isSanitizerError(error)) {
|
|
385
|
+
res.status(400).json({ error: error.message });
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
Logger.error('Error deleting user:', error);
|
|
389
|
+
res.status(500).json({ error: 'Failed to delete user' });
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
};
|
|
393
|
+
/**
|
|
394
|
+
* User QueryBuilder Controller Factory
|
|
395
|
+
*/
|
|
396
|
+
export const UserQueryBuilderController = {
|
|
397
|
+
/**
|
|
398
|
+
* Create a new user controller instance
|
|
399
|
+
*/
|
|
400
|
+
create() {
|
|
401
|
+
return userControllerMethods;
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
export default UserQueryBuilderController;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export declare const AdvancedEmailJobService: Readonly<{
|
|
2
|
+
sendScheduledLock(to: string, subject: string, template: string, templateData: Record<string, unknown>, delayMs: number, queueName?: string): Promise<string>;
|
|
3
|
+
/**
|
|
4
|
+
* Send an advanced email with deduplication support
|
|
5
|
+
*/
|
|
6
|
+
sendWithDeduplication(to: string, subject: string, template: string, templateData: Record<string, unknown>, deduplicationId: string, queueName?: string): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Send an email with unique lock to prevent duplicates
|
|
9
|
+
*/
|
|
10
|
+
sendWithUniqueLock(to: string, subject: string, template: string, templateData: Record<string, unknown>, uniqueVia: string, queueName?: string): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Send a high-priority email with custom options
|
|
13
|
+
*/
|
|
14
|
+
sendHighPriority(to: string, subject: string, template: string, templateData: Record<string, unknown>, options?: {
|
|
15
|
+
priority?: number;
|
|
16
|
+
delay?: number;
|
|
17
|
+
attempts?: number;
|
|
18
|
+
}, queueName?: string): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Send a bulk email with batch processing support
|
|
21
|
+
*/
|
|
22
|
+
sendBulk(recipients: string[], subject: string, template: string, templateData: Record<string, unknown>, batchId?: string, queueName?: string): Promise<string[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Send an email with custom envelope metadata
|
|
25
|
+
*/
|
|
26
|
+
sendWithMetadata(to: string, subject: string, template: string, templateData: Record<string, unknown>, metadata: {
|
|
27
|
+
campaign?: string;
|
|
28
|
+
source?: string;
|
|
29
|
+
priority?: string;
|
|
30
|
+
tags?: string[];
|
|
31
|
+
}, queueName?: string): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Send a scheduled email with delay
|
|
34
|
+
*/
|
|
35
|
+
sendScheduled(to: string, subject: string, template: string, templateData: Record<string, unknown>, delayMs: number, queueName?: string): Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Process a single advanced email job
|
|
38
|
+
*/
|
|
39
|
+
processOne(queueName?: string): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Process all advanced email jobs in queue
|
|
42
|
+
*/
|
|
43
|
+
processAll(queueName?: string): Promise<number>;
|
|
44
|
+
/**
|
|
45
|
+
* Start the advanced email worker
|
|
46
|
+
*/
|
|
47
|
+
start(queueName?: string): Promise<void>;
|
|
48
|
+
}>;
|
|
49
|
+
export default AdvancedEmailJobService;
|
|
50
|
+
export declare const testSamples: Readonly<{
|
|
51
|
+
advancedQueuePatternsHeadline: "Advanced Queue Patterns";
|
|
52
|
+
uniqueIdExample: "await AdvancedEmailJobService.sendWithDeduplication('user@example.com', 'Welcome', 'welcome', { name: 'User' }, 'welcome-user-123')";
|
|
53
|
+
uniqueViaExample: "await AdvancedEmailJobService.sendWithUniqueLock('user@example.com', 'Reset Password', 'password-reset', { token: 'abc123' }, 'user-email')";
|
|
54
|
+
bulkExample: "await AdvancedEmailJobService.sendBulk(['user1@example.com', 'user2@example.com'], 'Newsletter', 'newsletter', { issue: 'Q1-2024' })";
|
|
55
|
+
scheduledExample: "await AdvancedEmailJobService.sendScheduled('user@example.com', 'Reminder', 'reminder', { event: 'meeting' }, 3600000)";
|
|
56
|
+
}>;
|
|
57
|
+
//# sourceMappingURL=AdvancedEmailJobService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdvancedEmailJobService.d.ts","sourceRoot":"","sources":["../../../app/Jobs/AdvancedEmailJobService.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB;0BAE5B,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAC5B,MAAM,uBAEd,OAAO,CAAC,MAAM,CAAC;IAmBlB;;OAEG;8BAGG,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBACpB,MAAM,uBAEtB,OAAO,CAAC,MAAM,CAAC;IAwBlB;;OAEG;2BAEG,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAC1B,MAAM,uBAEhB,OAAO,CAAC,MAAM,CAAC;IAelB;;OAEG;yBAEG,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAC5B;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,uBAEA,OAAO,CAAC,MAAM,CAAC;IAyBlB;;OAEG;yBAEW,MAAM,EAAE,WACX,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAC3B,MAAM,uBAEf,OAAO,CAAC,MAAM,EAAE,CAAC;IAkCpB;;OAEG;yBAEG,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAC3B;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,uBAEA,OAAO,CAAC,MAAM,CAAC;IAoBlB;;OAEG;sBAEG,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAC5B,MAAM,uBAEd,OAAO,CAAC,MAAM,CAAC;IAmBlB;;OAEG;oCACmD,OAAO,CAAC,OAAO,CAAC;IAItE;;OAEG;oCACmD,OAAO,CAAC,MAAM,CAAC;IAIrE;;OAEG;+BAC8C,OAAO,CAAC,IAAI,CAAC;EAG9D,CAAC;AAEH,eAAe,uBAAuB,CAAC;AAGvC,eAAO,MAAM,WAAW;;;;;;EAUtB,CAAC"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { AdvancEmailQueue } from '../Workers/AdvancEmailWorker.js';
|
|
2
|
+
import { generateUuid, Logger } from '../../src/index.js';
|
|
3
|
+
export const AdvancedEmailJobService = Object.freeze({
|
|
4
|
+
async sendScheduledLock(to, subject, template, templateData, delayMs, queueName = 'advanced-test-redis2') {
|
|
5
|
+
const payload = {
|
|
6
|
+
to,
|
|
7
|
+
subject,
|
|
8
|
+
template,
|
|
9
|
+
templateData,
|
|
10
|
+
uniqueId: `scheduled-${Date.now()}-${generateUuid()}`,
|
|
11
|
+
};
|
|
12
|
+
const queueOptions = {
|
|
13
|
+
delay: delayMs, // ✅ This passes delay to BullMQ
|
|
14
|
+
};
|
|
15
|
+
const jobId = await AdvancEmailQueue.add(payload, queueName, queueOptions);
|
|
16
|
+
const scheduledTime = new Date(Date.now() + delayMs).toISOString();
|
|
17
|
+
Logger.info('Scheduled advanced email queued', { jobId, to, subject, scheduledTime });
|
|
18
|
+
return jobId;
|
|
19
|
+
},
|
|
20
|
+
/**
|
|
21
|
+
* Send an advanced email with deduplication support
|
|
22
|
+
*/
|
|
23
|
+
async sendWithDeduplication(to, subject, template, templateData, deduplicationId, queueName = 'advanced-test-redis2') {
|
|
24
|
+
const payload = {
|
|
25
|
+
to,
|
|
26
|
+
subject,
|
|
27
|
+
template,
|
|
28
|
+
templateData,
|
|
29
|
+
uniqueId: deduplicationId,
|
|
30
|
+
deduplication: {
|
|
31
|
+
id: deduplicationId,
|
|
32
|
+
ttl: 86400000, // 24 hours
|
|
33
|
+
releaseAfter: 3600000, // 1 hour
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
const jobId = await AdvancEmailQueue.add(payload, queueName);
|
|
37
|
+
Logger.info('Advanced email with deduplication queued', {
|
|
38
|
+
jobId,
|
|
39
|
+
to,
|
|
40
|
+
subject,
|
|
41
|
+
deduplicationId,
|
|
42
|
+
});
|
|
43
|
+
return jobId;
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* Send an email with unique lock to prevent duplicates
|
|
47
|
+
*/
|
|
48
|
+
async sendWithUniqueLock(to, subject, template, templateData, uniqueVia, queueName = 'advanced-test-redis2') {
|
|
49
|
+
const payload = {
|
|
50
|
+
to,
|
|
51
|
+
subject,
|
|
52
|
+
template,
|
|
53
|
+
templateData,
|
|
54
|
+
uniqueId: `unique-${Date.now()}-${generateUuid()}`,
|
|
55
|
+
uniqueVia,
|
|
56
|
+
};
|
|
57
|
+
const jobId = await AdvancEmailQueue.add(payload, queueName);
|
|
58
|
+
Logger.info('Advanced email with unique lock queued', { jobId, to, subject, uniqueVia });
|
|
59
|
+
return jobId;
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* Send a high-priority email with custom options
|
|
63
|
+
*/
|
|
64
|
+
async sendHighPriority(to, subject, template, templateData, options = {}, queueName = 'advanced-test-redis2') {
|
|
65
|
+
const payload = {
|
|
66
|
+
to,
|
|
67
|
+
subject,
|
|
68
|
+
template,
|
|
69
|
+
templateData,
|
|
70
|
+
timestamp: Date.now(),
|
|
71
|
+
attempts: options.attempts ?? 3,
|
|
72
|
+
};
|
|
73
|
+
const queueOptions = {
|
|
74
|
+
priority: options.priority ?? 10,
|
|
75
|
+
delay: options.delay ?? 0,
|
|
76
|
+
};
|
|
77
|
+
const jobId = await AdvancEmailQueue.add(payload, queueName, queueOptions);
|
|
78
|
+
Logger.info('High priority advanced email queued', {
|
|
79
|
+
jobId,
|
|
80
|
+
to,
|
|
81
|
+
subject,
|
|
82
|
+
priority: queueOptions.priority,
|
|
83
|
+
});
|
|
84
|
+
return jobId;
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Send a bulk email with batch processing support
|
|
88
|
+
*/
|
|
89
|
+
async sendBulk(recipients, subject, template, templateData, batchId, queueName = 'advanced-test-redis2') {
|
|
90
|
+
const batchIdentifier = batchId ?? `batch-${Date.now()}-${generateUuid()}`;
|
|
91
|
+
const jobPromises = recipients.map(async (to, index) => {
|
|
92
|
+
const payload = {
|
|
93
|
+
to,
|
|
94
|
+
subject,
|
|
95
|
+
template,
|
|
96
|
+
templateData: {
|
|
97
|
+
...templateData,
|
|
98
|
+
batch_id: batchIdentifier,
|
|
99
|
+
recipient_index: index + 1,
|
|
100
|
+
total_recipients: recipients.length,
|
|
101
|
+
},
|
|
102
|
+
uniqueId: `${batchIdentifier}-${to}`,
|
|
103
|
+
deduplication: {
|
|
104
|
+
id: `${batchIdentifier}-${to}`,
|
|
105
|
+
ttl: 86400000, // 24 hours
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
return AdvancEmailQueue.add(payload, queueName);
|
|
109
|
+
});
|
|
110
|
+
const jobIds = await Promise.all(jobPromises);
|
|
111
|
+
Logger.info('Bulk advanced emails queued', {
|
|
112
|
+
batchId: batchIdentifier,
|
|
113
|
+
recipientCount: recipients.length,
|
|
114
|
+
jobIds: jobIds.length,
|
|
115
|
+
});
|
|
116
|
+
return jobIds;
|
|
117
|
+
},
|
|
118
|
+
/**
|
|
119
|
+
* Send an email with custom envelope metadata
|
|
120
|
+
*/
|
|
121
|
+
async sendWithMetadata(to, subject, template, templateData, metadata, queueName = 'advanced-test-redis2') {
|
|
122
|
+
const payload = {
|
|
123
|
+
to,
|
|
124
|
+
subject,
|
|
125
|
+
template,
|
|
126
|
+
templateData: {
|
|
127
|
+
...templateData,
|
|
128
|
+
campaign: metadata.campaign,
|
|
129
|
+
source: metadata.source,
|
|
130
|
+
priority: metadata.priority,
|
|
131
|
+
tags: metadata.tags,
|
|
132
|
+
},
|
|
133
|
+
uniqueId: `meta-${Date.now()}-${generateUuid()}`,
|
|
134
|
+
};
|
|
135
|
+
const jobId = await AdvancEmailQueue.add(payload, queueName);
|
|
136
|
+
Logger.info('Advanced email with metadata queued', { jobId, to, subject, metadata });
|
|
137
|
+
return jobId;
|
|
138
|
+
},
|
|
139
|
+
/**
|
|
140
|
+
* Send a scheduled email with delay
|
|
141
|
+
*/
|
|
142
|
+
async sendScheduled(to, subject, template, templateData, delayMs, queueName = 'advanced-test-redis2') {
|
|
143
|
+
const payload = {
|
|
144
|
+
to,
|
|
145
|
+
subject,
|
|
146
|
+
template,
|
|
147
|
+
templateData,
|
|
148
|
+
uniqueId: `scheduled-${Date.now()}-${generateUuid()}`,
|
|
149
|
+
};
|
|
150
|
+
const queueOptions = {
|
|
151
|
+
delay: delayMs,
|
|
152
|
+
};
|
|
153
|
+
const jobId = await AdvancEmailQueue.add(payload, queueName, queueOptions);
|
|
154
|
+
const scheduledTime = new Date(Date.now() + delayMs).toISOString();
|
|
155
|
+
Logger.info('Scheduled advanced email queued', { jobId, to, subject, scheduledTime });
|
|
156
|
+
return jobId;
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* Process a single advanced email job
|
|
160
|
+
*/
|
|
161
|
+
async processOne(queueName = 'advanced-test-redis2') {
|
|
162
|
+
return AdvancEmailQueue.processOne(queueName);
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* Process all advanced email jobs in queue
|
|
166
|
+
*/
|
|
167
|
+
async processAll(queueName = 'advanced-test-redis2') {
|
|
168
|
+
return AdvancEmailQueue.processAll(queueName);
|
|
169
|
+
},
|
|
170
|
+
/**
|
|
171
|
+
* Start the advanced email worker
|
|
172
|
+
*/
|
|
173
|
+
async start(queueName = 'advanced-test-redis2') {
|
|
174
|
+
return AdvancEmailQueue.start(queueName);
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
export default AdvancedEmailJobService;
|
|
178
|
+
// Test samples for advanced queue patterns
|
|
179
|
+
export const testSamples = Object.freeze({
|
|
180
|
+
advancedQueuePatternsHeadline: 'Advanced Queue Patterns',
|
|
181
|
+
uniqueIdExample: "await AdvancedEmailJobService.sendWithDeduplication('user@example.com', 'Welcome', 'welcome', { name: 'User' }, 'welcome-user-123')",
|
|
182
|
+
uniqueViaExample: "await AdvancedEmailJobService.sendWithUniqueLock('user@example.com', 'Reset Password', 'password-reset', { token: 'abc123' }, 'user-email')",
|
|
183
|
+
bulkExample: "await AdvancedEmailJobService.sendBulk(['user1@example.com', 'user2@example.com'], 'Newsletter', 'newsletter', { issue: 'Q1-2024' })",
|
|
184
|
+
scheduledExample: "await AdvancedEmailJobService.sendScheduled('user@example.com', 'Reminder', 'reminder', { event: 'meeting' }, 3600000)",
|
|
185
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const EmailJobService: Readonly<{
|
|
2
|
+
/**
|
|
3
|
+
* Send a welcome email using worker queue
|
|
4
|
+
*/
|
|
5
|
+
sendWelcome(to: string, userName: string, _queueName?: string): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Send a password reset email using the worker queue
|
|
8
|
+
*/
|
|
9
|
+
sendPasswordReset(to: string, resetToken: string): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Send a worker alert email using the worker queue
|
|
12
|
+
*/
|
|
13
|
+
sendWorkerAlert(to: string, workerName: string, error: string, jobId?: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Send a general notification email using the worker queue
|
|
16
|
+
*/
|
|
17
|
+
sendGeneral(to: string, subject: string, message: string, options?: {
|
|
18
|
+
actionUrl?: string;
|
|
19
|
+
actionText?: string;
|
|
20
|
+
primaryColor?: string;
|
|
21
|
+
}): Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Send a custom email with any template
|
|
24
|
+
*/
|
|
25
|
+
sendCustom(to: string, subject: string, template: string, templateData: Record<string, unknown>): Promise<string>;
|
|
26
|
+
}>;
|
|
27
|
+
export default EmailJobService;
|
|
28
|
+
export declare const testSamples: Readonly<{
|
|
29
|
+
advancedQueuePatternsHeadline: "Advanced Queue Patterns";
|
|
30
|
+
uniqueIdExample: "await Queue.enqueue('email', { to: 'user@example.com', template: 'welcome' }, { uniqueId: `welcome-email-${userId}` })";
|
|
31
|
+
releaseAfterExample: "deduplication: { id: 'daily-cleanup', ttl: 86400000, releaseAfter: 3600000 }";
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=EmailJobService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmailJobService.d.ts","sourceRoot":"","sources":["../../../app/Jobs/EmailJobService.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe;IAC1B;;OAEG;oBACmB,MAAM,YAAY,MAAM,eAAc,MAAM,GAAe,OAAO,CAAC,MAAM,CAAC;IAoBhG;;OAEG;0BACyB,MAAM,cAAc,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBxE;;OAEG;wBAEG,MAAM,cACE,MAAM,SACX,MAAM,UACL,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAsBlB;;OAEG;oBAEG,MAAM,WACD,MAAM,WACN,MAAM,YACN;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GACA,OAAO,CAAC,MAAM,CAAC;IAoBlB;;OAEG;mBAEG,MAAM,WACD,MAAM,YACL,MAAM,gBACF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,OAAO,CAAC,MAAM,CAAC;EAelB,CAAC;AAEH,eAAe,eAAe,CAAC;AAI/B,eAAO,MAAM,WAAW;;;;EAMtB,CAAC"}
|