alepha 0.18.2 → 0.18.3
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/assets/devtools-ui/200.html +2 -2
- package/assets/devtools-ui/200.html.br +0 -0
- package/assets/devtools-ui/404.html +2 -2
- package/assets/devtools-ui/404.html.br +0 -0
- package/assets/devtools-ui/{asset.BfSBZ5Dd.css → asset.hG_f8HuK.css} +1 -1
- package/assets/devtools-ui/asset.hG_f8HuK.css.br +0 -0
- package/assets/devtools-ui/chunk.B3au4Lhg.js +1 -0
- package/assets/devtools-ui/chunk.B3au4Lhg.js.br +0 -0
- package/assets/devtools-ui/chunk.BLOrlnMB.js +1 -0
- package/assets/devtools-ui/chunk.BLOrlnMB.js.br +0 -0
- package/assets/devtools-ui/chunk.BLR01ljW.js +1 -0
- package/assets/devtools-ui/chunk.BLR01ljW.js.br +0 -0
- package/assets/devtools-ui/chunk.BTXaIUlA.js +1 -0
- package/assets/devtools-ui/chunk.BTXaIUlA.js.br +0 -0
- package/assets/devtools-ui/{chunk.lJL-lgnW.js → chunk.BhJaxmm8.js} +1 -1
- package/assets/devtools-ui/chunk.BhJaxmm8.js.br +0 -0
- package/assets/devtools-ui/chunk.BtoNxFuL.js +1 -0
- package/assets/devtools-ui/chunk.BtoNxFuL.js.br +0 -0
- package/assets/devtools-ui/chunk.C8YUV2Wd.js +1 -0
- package/assets/devtools-ui/chunk.C8YUV2Wd.js.br +0 -0
- package/assets/devtools-ui/{chunk.M6wyKO_3.js → chunk.CBbIgDzE.js} +2 -2
- package/assets/devtools-ui/chunk.CBbIgDzE.js.br +0 -0
- package/assets/devtools-ui/chunk.CFqIniwA.js +1 -0
- package/assets/devtools-ui/chunk.CFqIniwA.js.br +0 -0
- package/assets/devtools-ui/chunk.CLFF7f7-.js +1 -0
- package/assets/devtools-ui/chunk.CLFF7f7-.js.br +0 -0
- package/assets/devtools-ui/chunk.CRsBbA10.js +1 -0
- package/assets/devtools-ui/chunk.CRsBbA10.js.br +0 -0
- package/assets/devtools-ui/{chunk.DbEH1oOB.js → chunk.CZPo6v95.js} +1 -1
- package/assets/devtools-ui/chunk.CZPo6v95.js.br +0 -0
- package/assets/devtools-ui/chunk.D0fWgNos.js +1 -0
- package/assets/devtools-ui/chunk.D0fWgNos.js.br +1 -0
- package/assets/devtools-ui/chunk.D7-0ziQ6.js +1 -0
- package/assets/devtools-ui/chunk.D7-0ziQ6.js.br +0 -0
- package/assets/devtools-ui/chunk.DAewe0vm.js +1 -0
- package/assets/devtools-ui/chunk.DAewe0vm.js.br +0 -0
- package/assets/devtools-ui/chunk.DJRQEYqK.js +1 -0
- package/assets/devtools-ui/chunk.DJRQEYqK.js.br +0 -0
- package/assets/devtools-ui/{chunk.CZl6J9DF.js → chunk.DMAxv14p.js} +1 -1
- package/assets/devtools-ui/chunk.DMAxv14p.js.br +0 -0
- package/assets/devtools-ui/{chunk.BT2IiBkZ.js → chunk.DMImnNjU.js} +1 -1
- package/assets/devtools-ui/chunk.DMImnNjU.js.br +0 -0
- package/assets/devtools-ui/chunk.DeeQsidk.js +9 -0
- package/assets/devtools-ui/chunk.DeeQsidk.js.br +0 -0
- package/assets/devtools-ui/chunk.DqEwn9Vj.js +7 -0
- package/assets/devtools-ui/chunk.DqEwn9Vj.js.br +0 -0
- package/assets/devtools-ui/chunk.Dt8OsQey.js +1 -0
- package/assets/devtools-ui/chunk.Dt8OsQey.js.br +0 -0
- package/assets/devtools-ui/{chunk.B9pX3zit.js → chunk.Dtp8oa_f.js} +1 -1
- package/assets/devtools-ui/chunk.Dtp8oa_f.js.br +0 -0
- package/assets/devtools-ui/chunk.Dx3JzAYM.js +1 -0
- package/assets/devtools-ui/chunk.Dx3JzAYM.js.br +0 -0
- package/assets/devtools-ui/chunk.GCOj1-5E.js +1 -0
- package/assets/devtools-ui/chunk.GCOj1-5E.js.br +0 -0
- package/assets/devtools-ui/chunk.IC1LD8BH.js +1 -0
- package/assets/devtools-ui/chunk.IC1LD8BH.js.br +0 -0
- package/assets/devtools-ui/chunk.IwuB_TqW.js +1 -0
- package/assets/devtools-ui/chunk.IwuB_TqW.js.br +0 -0
- package/assets/devtools-ui/chunk.Qqapj2zq.js +1 -0
- package/assets/devtools-ui/chunk.Qqapj2zq.js.br +0 -0
- package/assets/devtools-ui/{chunk.C79YouPp.js → chunk.TKKKndOy.js} +1 -1
- package/assets/devtools-ui/chunk.TKKKndOy.js.br +0 -0
- package/assets/devtools-ui/chunk.YHTVhFQT.js +1 -0
- package/assets/devtools-ui/chunk.YHTVhFQT.js.br +0 -0
- package/assets/devtools-ui/chunk.fnod6uEi.js +1 -0
- package/assets/devtools-ui/chunk.fnod6uEi.js.br +0 -0
- package/assets/devtools-ui/chunk.mOCRmXjo.js +1 -0
- package/assets/devtools-ui/chunk.mOCRmXjo.js.br +0 -0
- package/assets/devtools-ui/chunk.qZTNEAK0.js +1 -0
- package/assets/devtools-ui/chunk.qZTNEAK0.js.br +0 -0
- package/assets/devtools-ui/chunk.rc9m0y4-.js +1 -0
- package/assets/devtools-ui/chunk.rc9m0y4-.js.br +0 -0
- package/assets/devtools-ui/entry.Cxc5QLCU.js +80 -0
- package/assets/devtools-ui/entry.Cxc5QLCU.js.br +0 -0
- package/assets/devtools-ui/index.html +2 -2
- package/assets/devtools-ui/index.html.br +0 -0
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.d.ts +61 -5
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +61 -5
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +61 -5
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +4 -2
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +5 -5
- package/dist/api/notifications/index.browser.js +44 -1
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +187 -2
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +143 -8
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +61 -5
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +330 -93
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +27 -36
- package/dist/api/users/index.js.map +1 -1
- package/dist/cli/config/index.d.ts +46 -0
- package/dist/cli/config/index.d.ts.map +1 -0
- package/dist/cli/config/index.js +20 -0
- package/dist/cli/config/index.js.map +1 -0
- package/dist/cli/core/index.d.ts +69 -66
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +329 -196
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +302 -63
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +455 -25
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/core/index.browser.js +125 -87
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +62 -53
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +125 -87
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +125 -87
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +125 -87
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.d.ts +18 -1
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.js +29 -3
- package/dist/crypto/index.js.map +1 -1
- package/dist/devtools/index.js +3 -12
- package/dist/devtools/index.js.map +1 -1
- package/dist/logger/index.d.ts +10 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +19 -9
- package/dist/logger/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +57 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +378 -19
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +328 -9
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +384 -21
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +49 -17
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +47 -21
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +52 -17
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/core/index.d.ts +1 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +6 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +28 -18
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +92 -56
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/router/index.browser.js +448 -116
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +102 -40
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +453 -92
- package/dist/react/router/index.js.map +1 -1
- package/dist/security/index.d.ts +3 -11
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +6 -11
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +22 -24
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +102 -82
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +7 -4
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +13 -12
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +288 -4
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +375 -2
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js +10 -71
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +32 -49
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +73 -100
- package/dist/server/links/index.js.map +1 -1
- package/dist/system/index.browser.js +221 -2
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.d.ts +63 -1
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +221 -1
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js +224 -4
- package/dist/system/index.workerd.js.map +1 -1
- package/package.json +10 -5
- package/src/api/jobs/providers/JobProvider.ts +6 -3
- package/src/api/notifications/controllers/AdminNotificationController.ts +83 -0
- package/src/api/notifications/index.browser.ts +3 -0
- package/src/api/notifications/index.ts +14 -2
- package/src/api/notifications/jobs/NotificationJobs.ts +11 -2
- package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +20 -0
- package/src/api/notifications/schemas/notificationQuerySchema.ts +19 -0
- package/src/api/notifications/schemas/notificationResourceSchema.ts +18 -0
- package/src/api/notifications/services/NotificationSenderService.ts +15 -2
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +28 -32
- package/src/api/users/buckets/UserBuckets.ts +1 -1
- package/src/api/users/jobs/UserJobs.ts +1 -1
- package/src/api/users/primitives/$realm.ts +8 -49
- package/src/api/users/providers/RealmProvider.ts +2 -3
- package/src/api/users/services/RegistrationService.spec.ts +7 -7
- package/src/api/users/services/RegistrationService.ts +3 -3
- package/src/api/users/services/SessionService.spec.ts +4 -4
- package/src/api/users/services/SessionService.ts +3 -3
- package/src/cli/{core → config}/defineConfig.ts +14 -20
- package/src/cli/config/index.ts +1 -0
- package/src/cli/core/commands/db.ts +65 -1
- package/src/cli/core/commands/dev.ts +1 -0
- package/src/cli/core/commands/init.ts +2 -192
- package/src/cli/core/index.ts +34 -11
- package/src/cli/core/providers/ViteDevServerProvider.ts +52 -13
- package/src/cli/core/services/PackageManagerUtils.ts +43 -21
- package/src/cli/core/services/ProjectScaffolder.ts +214 -2
- package/src/cli/core/services/ViteUtils.ts +57 -0
- package/src/cli/core/tasks/BuildClientTask.ts +7 -2
- package/src/cli/core/tasks/BuildCloudflareTask.ts +4 -12
- package/src/cli/core/tasks/BuildServerTask.ts +2 -0
- package/src/cli/core/tasks/BuildVercelTask.ts +165 -168
- package/src/cli/core/templates/alephaConfigTs.ts +1 -1
- package/src/cli/core/templates/apiAppSecurityTs.ts +5 -8
- package/src/cli/core/templates/tsconfigJson.ts +6 -1
- package/src/cli/platform/adapters/CloudflareAdapter.spec.ts +1 -1
- package/src/cli/platform/adapters/CloudflareAdapter.ts +30 -29
- package/src/cli/platform/atoms/platformOptions.ts +21 -0
- package/src/cli/platform/commands/SecretsCommand.spec.ts +298 -0
- package/src/cli/platform/commands/SecretsCommand.ts +283 -0
- package/src/cli/platform/commands/platform.ts +12 -0
- package/src/cli/platform/index.ts +14 -28
- package/src/cli/platform/providers/GitHubSecretStore.spec.ts +153 -0
- package/src/cli/platform/providers/GitHubSecretStore.ts +112 -0
- package/src/cli/platform/providers/MemorySecretStore.ts +114 -0
- package/src/cli/platform/providers/SecretStoreProvider.ts +39 -0
- package/src/cli/platform/schemas/cloudflare.ts +2 -0
- package/src/cli/platform/services/CloudflareApi.ts +5 -2
- package/src/cli/platform/services/DockerComposeGenerator.spec.ts +115 -0
- package/src/cli/platform/services/DockerComposeGenerator.ts +46 -1
- package/src/cli/platform/services/SecretFilterService.spec.ts +111 -0
- package/src/cli/platform/services/SecretFilterService.ts +54 -0
- package/src/core/Alepha.ts +94 -25
- package/src/core/__tests__/Alepha-parseEnv.spec.ts +20 -0
- package/src/core/primitives/$memoize.ts +38 -26
- package/src/core/providers/AlsProvider.ts +2 -0
- package/src/core/providers/EventManager.ts +4 -0
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +1 -4
- package/src/core/providers/KeylessJsonSchemaCodec.ts +19 -125
- package/src/core/providers/SchemaValidator.spec.ts +36 -0
- package/src/core/providers/SchemaValidator.ts +9 -0
- package/src/crypto/index.ts +6 -1
- package/src/crypto/providers/SecretProvider.ts +36 -0
- package/src/devtools/providers/DevToolsProvider.ts +3 -12
- package/src/logger/index.ts +33 -6
- package/src/logger/providers/PrettyFormatterProvider.ts +5 -3
- package/src/orm/__tests__/orm-next-tests.ts +492 -0
- package/src/orm/__tests__/orm-next.spec.ts +140 -0
- package/src/orm/core/constants/PG_SYMBOLS.ts +17 -0
- package/src/orm/core/index.bun.ts +3 -6
- package/src/orm/core/index.shared-server.ts +2 -0
- package/src/orm/core/index.shared.ts +2 -0
- package/src/orm/core/index.ts +5 -7
- package/src/orm/core/interfaces/AggregateQuery.ts +103 -0
- package/src/orm/core/interfaces/PgQueryWhere.ts +7 -0
- package/src/orm/core/primitives/$entity.ts +8 -0
- package/src/orm/core/primitives/$repository.ts +6 -3
- package/src/orm/core/primitives/$view.ts +88 -0
- package/src/orm/core/providers/DbCacheProvider.ts +66 -0
- package/src/orm/core/providers/DrizzleKitProvider.ts +42 -0
- package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -3
- package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +12 -0
- package/src/orm/core/providers/drivers/DatabaseProvider.ts +39 -0
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +2 -3
- package/src/orm/core/schemas/databaseEnvSchema.ts +31 -0
- package/src/orm/core/schemas/insertSchema.ts +13 -3
- package/src/orm/core/schemas/updateSchema.ts +14 -3
- package/src/orm/core/services/ModelBuilder.ts +26 -14
- package/src/orm/core/services/QueryManager.ts +13 -0
- package/src/orm/core/services/Repository.ts +307 -5
- package/src/orm/core/services/SqliteModelBuilder.ts +38 -0
- package/src/orm/postgres/index.bun.ts +4 -7
- package/src/orm/postgres/index.ts +4 -7
- package/src/orm/postgres/providers/BunPostgresProvider.ts +12 -2
- package/src/orm/postgres/providers/NodePostgresProvider.ts +7 -0
- package/src/orm/postgres/providers/PglitePostgresProvider.ts +10 -17
- package/src/orm/postgres/providers/PostgresProvider.ts +7 -36
- package/src/orm/postgres/schemas/postgresEnvSchema.ts +32 -0
- package/src/orm/postgres/services/PostgresModelBuilder.ts +40 -0
- package/src/react/core/components/ErrorBoundary.tsx +5 -2
- package/src/react/form/hooks/useFieldValue.ts +34 -0
- package/src/react/form/hooks/useForm.browser.spec.tsx +94 -9
- package/src/react/form/hooks/useForm.ts +14 -2
- package/src/react/form/hooks/useFormState.ts +10 -10
- package/src/react/form/hooks/useFormValues.ts +29 -0
- package/src/react/form/index.ts +3 -1
- package/src/react/form/services/FormModel.ts +53 -122
- package/src/react/router/components/ErrorViewer.tsx +333 -34
- package/src/react/router/components/NestedView.tsx +10 -3
- package/src/react/router/primitives/$page.browser.spec.tsx +34 -0
- package/src/react/router/primitives/$page.spec.tsx +20 -0
- package/src/react/router/primitives/$page.ts +24 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +14 -2
- package/src/react/router/providers/ReactPageProvider.ts +156 -73
- package/src/react/router/providers/ReactServerProvider.ts +40 -2
- package/src/react/router/providers/ReactServerTemplateProvider.ts +13 -1
- package/src/security/providers/SecurityProvider.ts +5 -27
- package/src/server/auth/primitives/$auth.ts +52 -19
- package/src/server/auth/providers/ServerAuthProvider.ts +145 -139
- package/src/server/cookies/providers/ServerCookiesProvider.ts +12 -24
- package/src/server/core/index.ts +3 -1
- package/src/server/core/primitives/$sse.spec.ts +315 -0
- package/src/server/core/primitives/$sse.ts +715 -0
- package/src/server/links/index.browser.ts +1 -3
- package/src/server/links/index.ts +0 -3
- package/src/server/links/providers/LinkProvider.spec.ts +12 -21
- package/src/server/links/providers/LinkProvider.ts +20 -52
- package/src/server/links/providers/ServerLinksProvider.spec.ts +106 -0
- package/src/server/links/providers/ServerLinksProvider.ts +113 -73
- package/src/server/links/schemas/apiLinksResponseSchema.ts +4 -21
- package/src/server/links/services/BatchCollector.ts +5 -3
- package/src/system/index.browser.ts +1 -0
- package/src/system/index.ts +3 -0
- package/src/system/index.workerd.ts +39 -1
- package/src/system/providers/WorkerdFileSystemProvider.ts +365 -0
- package/assets/devtools-ui/asset.BfSBZ5Dd.css.br +0 -0
- package/assets/devtools-ui/chunk.2NYaoqWt.js +0 -1
- package/assets/devtools-ui/chunk.2NYaoqWt.js.br +0 -0
- package/assets/devtools-ui/chunk.B052Z_xQ.js +0 -1
- package/assets/devtools-ui/chunk.B052Z_xQ.js.br +0 -0
- package/assets/devtools-ui/chunk.B4kVY90C.js +0 -1
- package/assets/devtools-ui/chunk.B4kVY90C.js.br +0 -0
- package/assets/devtools-ui/chunk.B7QJXctB.js +0 -1
- package/assets/devtools-ui/chunk.B7QJXctB.js.br +0 -0
- package/assets/devtools-ui/chunk.B9pX3zit.js.br +0 -0
- package/assets/devtools-ui/chunk.BKF9JxIo.js +0 -1
- package/assets/devtools-ui/chunk.BKF9JxIo.js.br +0 -0
- package/assets/devtools-ui/chunk.BOHgdTP-.js +0 -1
- package/assets/devtools-ui/chunk.BOHgdTP-.js.br +0 -0
- package/assets/devtools-ui/chunk.BOVFxkYC.js +0 -1
- package/assets/devtools-ui/chunk.BOVFxkYC.js.br +0 -0
- package/assets/devtools-ui/chunk.BR842zj5.js +0 -1
- package/assets/devtools-ui/chunk.BR842zj5.js.br +0 -0
- package/assets/devtools-ui/chunk.BT2IiBkZ.js.br +0 -0
- package/assets/devtools-ui/chunk.C79YouPp.js.br +0 -0
- package/assets/devtools-ui/chunk.C8mlBrjW.js +0 -9
- package/assets/devtools-ui/chunk.C8mlBrjW.js.br +0 -0
- package/assets/devtools-ui/chunk.CK0ow3AZ.js +0 -1
- package/assets/devtools-ui/chunk.CK0ow3AZ.js.br +0 -0
- package/assets/devtools-ui/chunk.CZl6J9DF.js.br +0 -0
- package/assets/devtools-ui/chunk.CdNr0YzS.js +0 -1
- package/assets/devtools-ui/chunk.CdNr0YzS.js.br +0 -0
- package/assets/devtools-ui/chunk.Ce6_6iIF.js +0 -1
- package/assets/devtools-ui/chunk.Ce6_6iIF.js.br +0 -0
- package/assets/devtools-ui/chunk.CpyDMr6O.js +0 -1
- package/assets/devtools-ui/chunk.CpyDMr6O.js.br +0 -0
- package/assets/devtools-ui/chunk.CyPmvPnY.js +0 -1
- package/assets/devtools-ui/chunk.CyPmvPnY.js.br +0 -0
- package/assets/devtools-ui/chunk.DTI_geWu.js +0 -1
- package/assets/devtools-ui/chunk.DTI_geWu.js.br +0 -0
- package/assets/devtools-ui/chunk.DbEH1oOB.js.br +0 -0
- package/assets/devtools-ui/chunk.Ddeqj5gv.js +0 -1
- package/assets/devtools-ui/chunk.Ddeqj5gv.js.br +0 -0
- package/assets/devtools-ui/chunk.DpRnB4vJ.js +0 -1
- package/assets/devtools-ui/chunk.DpRnB4vJ.js.br +0 -0
- package/assets/devtools-ui/chunk.DxPGTlsg.js +0 -1
- package/assets/devtools-ui/chunk.DxPGTlsg.js.br +0 -0
- package/assets/devtools-ui/chunk.G7_MMBJS.js +0 -1
- package/assets/devtools-ui/chunk.G7_MMBJS.js.br +0 -0
- package/assets/devtools-ui/chunk.M6wyKO_3.js.br +0 -0
- package/assets/devtools-ui/chunk.OUxNGmQ6.js +0 -1
- package/assets/devtools-ui/chunk.OUxNGmQ6.js.br +0 -0
- package/assets/devtools-ui/chunk.T1kle-fF.js +0 -1
- package/assets/devtools-ui/chunk.T1kle-fF.js.br +0 -0
- package/assets/devtools-ui/chunk.WjpsbQAv.js +0 -1
- package/assets/devtools-ui/chunk.WjpsbQAv.js.br +0 -0
- package/assets/devtools-ui/chunk.c6YgVx86.js +0 -1
- package/assets/devtools-ui/chunk.c6YgVx86.js.br +0 -0
- package/assets/devtools-ui/chunk.dwU3E_MU.js +0 -1
- package/assets/devtools-ui/chunk.dwU3E_MU.js.br +0 -0
- package/assets/devtools-ui/chunk.lJL-lgnW.js.br +0 -0
- package/assets/devtools-ui/chunk.lPWRmvA-.js +0 -7
- package/assets/devtools-ui/chunk.lPWRmvA-.js.br +0 -0
- package/assets/devtools-ui/chunk.p3HJvugM.js +0 -1
- package/assets/devtools-ui/chunk.p3HJvugM.js.br +0 -0
- package/assets/devtools-ui/chunk.r_Xoa_CI.js +0 -1
- package/assets/devtools-ui/chunk.r_Xoa_CI.js.br +0 -0
- package/assets/devtools-ui/chunk.sRNuTYXb.js +0 -1
- package/assets/devtools-ui/chunk.sRNuTYXb.js.br +0 -0
- package/assets/devtools-ui/chunk.tUjcyX5C.js +0 -1
- package/assets/devtools-ui/chunk.tUjcyX5C.js.br +0 -0
- package/assets/devtools-ui/chunk.thjBxvCA.js +0 -1
- package/assets/devtools-ui/chunk.thjBxvCA.js.br +0 -0
- package/assets/devtools-ui/entry.GYhBVRpC.js +0 -78
- package/assets/devtools-ui/entry.GYhBVRpC.js.br +0 -0
- package/src/server/links/services/DefinitionsPool.spec.ts +0 -86
- package/src/server/links/services/DefinitionsPool.ts +0 -43
package/dist/logger/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/logger/providers/LogDestinationProvider.ts","../../src/logger/providers/LogFormatterProvider.ts","../../src/logger/services/Logger.ts","../../src/logger/primitives/$logger.ts","../../src/logger/providers/ConsoleColorProvider.ts","../../src/logger/providers/ConsoleDestinationProvider.ts","../../src/logger/providers/JsonFormatterProvider.ts","../../src/logger/providers/MemoryDestinationProvider.ts","../../src/logger/providers/PrettyFormatterProvider.ts","../../src/logger/providers/RawFormatterProvider.ts","../../src/logger/schemas/logEntrySchema.ts","../../src/logger/index.ts"],"sourcesContent":["import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\n\nexport abstract class LogDestinationProvider {\n public abstract write(message: string, entry: LogEntry): void;\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\n\nexport abstract class LogFormatterProvider {\n public abstract format(entry: LogEntry): string;\n}\n","import {\n $inject,\n Alepha,\n AlephaError,\n type LoggerInterface,\n type LogLevel,\n} from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { LogDestinationProvider } from \"../providers/LogDestinationProvider.ts\";\nimport { LogFormatterProvider } from \"../providers/LogFormatterProvider.ts\";\nimport type { LogEntry } from \"../schemas/logEntrySchema.ts\";\n\nexport class Logger implements LoggerInterface {\n protected readonly alepha = $inject(Alepha);\n protected readonly formatter = $inject(LogFormatterProvider);\n protected readonly destination = $inject(LogDestinationProvider);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n\n protected readonly levels: Record<string, number> = {\n SILENT: -1,\n ERROR: 0,\n WARN: 1,\n INFO: 2,\n DEBUG: 3,\n TRACE: 4,\n };\n\n protected readonly service: string;\n protected readonly module: string;\n protected readonly app?: string;\n\n protected appLogLevel: string = \"INFO\";\n protected logLevel: LogLevel = \"INFO\";\n\n constructor(service: string, module: string) {\n this.service = service;\n this.module = module;\n this.app = this.alepha.env.APP_NAME;\n }\n\n public get context(): string | undefined {\n return this.alepha.context.get<string>(\"context\");\n }\n\n public get level(): string {\n const stateLogLevel = this.alepha.store.get(\"alepha.logger.level\");\n if (stateLogLevel && stateLogLevel !== this.appLogLevel) {\n this.appLogLevel = stateLogLevel;\n this.logLevel = this.parseLevel(this.appLogLevel, this.module);\n }\n return this.logLevel;\n }\n\n public parseLevel(level: string, app: string): LogLevel {\n const parts = level.toLowerCase().split(/[,;]/);\n\n // First pass: check for module-specific configurations\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue; // Skip empty parts\n\n if (trimmedPart.includes(\":\") || trimmedPart.includes(\"=\")) {\n const [modulePattern, levelValue] = trimmedPart.split(/[:=]/);\n const trimmedModule = modulePattern.trim();\n const trimmedLevel = levelValue?.trim();\n\n if (!trimmedLevel) continue; // Skip if no level specified\n\n if (this.matchesPattern(app, trimmedModule)) {\n try {\n return this.asLogLevel(trimmedLevel);\n } catch (error) {\n throw new AlephaError(\n `Invalid log level '${levelValue?.trim()}' for module pattern '${trimmedModule}'`,\n );\n }\n }\n }\n }\n\n // Second pass: look for global level\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue; // Skip empty parts\n\n if (!trimmedPart.includes(\":\") && !trimmedPart.includes(\"=\")) {\n try {\n return this.asLogLevel(trimmedPart);\n } catch (error) {\n throw new Error(`Invalid global log level \"${trimmedPart}\"`);\n }\n }\n }\n\n return \"INFO\";\n }\n\n private matchesPattern(moduleName: string, pattern: string): boolean {\n if (pattern.includes(\"*\")) {\n // Convert wildcard pattern to regex\n const regexPattern = pattern.replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\");\n return new RegExp(`^${regexPattern}`).test(moduleName);\n }\n\n // Exact prefix match (existing behavior)\n return moduleName.startsWith(pattern);\n }\n\n public asLogLevel(something: string): LogLevel {\n const level = something.trim().toUpperCase();\n if (this.levels[level] !== undefined) {\n return level as LogLevel;\n }\n\n throw new AlephaError(`Invalid log level: ${something}`);\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n public error(message: string, data?: unknown): void {\n this.log(\"ERROR\", message, data);\n }\n\n public warn(message: string, data?: unknown): void {\n this.log(\"WARN\", message, data);\n }\n\n public info(message: string, data?: unknown): void {\n this.log(\"INFO\", message, data);\n }\n\n public debug(message: string, data?: unknown): void {\n this.log(\"DEBUG\", message, data);\n }\n\n public trace(message: string, data?: unknown): void {\n this.log(\"TRACE\", message, data);\n }\n\n protected log(level: LogLevel, message: string, data?: unknown): void {\n let _message = \"\";\n if (typeof message === \"string\") {\n _message = message;\n } else if (typeof data === \"string\") {\n _message = data;\n }\n\n let _data: object | Error | undefined;\n if (typeof data === \"object\" && !!data) {\n _data = data;\n } else if (typeof message === \"object\" && message) {\n _data = message;\n }\n\n const logEntry: LogEntry = {\n level,\n message: _message,\n data: _data,\n context: this.context,\n service: this.service,\n module: this.module,\n app: this.app,\n timestamp: this.dateTimeProvider.nowMillis(),\n };\n\n if (this.levels[level] > this.levels[this.level]) {\n this.emit(logEntry);\n return;\n }\n\n const formatted = this.formatter.format(logEntry);\n\n this.emit(logEntry, formatted);\n\n this.destination.write(formatted, logEntry);\n }\n\n protected emit(entry: LogEntry, message?: string) {\n this.alepha.events\n .emit(\n \"log\",\n {\n message,\n entry,\n },\n {\n catch: true,\n },\n )\n .catch(() => null);\n }\n}\n","import { $context, $inject, KIND } from \"alepha\";\nimport { Logger } from \"../services/Logger.ts\";\n\n/**\n * Create a logger.\n *\n * `name` is optional, by default it will use the name of the service.\n *\n * @example\n * ```ts\n * import { $logger } from \"alepha\";\n *\n * class MyService {\n * \tlog = $logger();\n *\n * constructor() {\n * this.log.info(\"Service initialized\");\n * // print something like '[23:45:53.326] INFO <app.MyService>: Service initialized'\n * }\n * }\n * ```\n */\nexport const $logger = (options: LoggerPrimitiveOptions = {}): Logger => {\n const { alepha, service, module } = $context();\n\n return $inject(Logger, {\n lifetime: \"transient\",\n args: [\n options.name ?? service?.name ?? \"Func\",\n module?.name ?? alepha.env.MODULE_NAME ?? \"app\",\n ],\n });\n};\n\nexport interface LoggerPrimitiveOptions {\n name?: string;\n}\n\n$logger[KIND] = Logger;\n","import { $inject, Alepha } from \"alepha\";\n\nexport class ConsoleColorProvider {\n static readonly COLORS = {\n RESET: \"\\x1b[0m\",\n BLACK: \"\\x1b[30m\",\n RED: \"\\x1b[31m\",\n GREEN: \"\\x1b[32m\",\n ORANGE: \"\\x1b[33m\", // using yellow for orange-ish\n BLUE: \"\\x1b[34m\",\n PURPLE: \"\\x1b[35m\",\n CYAN: \"\\x1b[36m\",\n GREY_LIGHT: \"\\x1b[37m\",\n GREY_LIGHT_BOLD: \"\\x1b[1;37m\",\n GREY_DARK: \"\\x1b[90m\",\n GREY_DARK_BOLD: \"\\x1b[1;90m\",\n WHITE: \"\\x1b[97m\",\n WHITE_BOLD: \"\\x1b[1;97m\",\n // modifiers\n DIM: \"\\x1b[2m\",\n BOLD: \"\\x1b[1m\",\n INVERSE: \"\\x1b[7m\",\n // levels\n SILENT: \"\",\n ERROR: \"\\x1b[31m\",\n WARN: \"\\x1b[33m\",\n INFO: \"\\x1b[32m\",\n DEBUG: \"\\x1b[34m\",\n TRACE: \"\\x1b[90m\",\n };\n\n protected readonly alepha = $inject(Alepha);\n\n protected enabled = true;\n\n constructor() {\n this.enabled = this.isEnabled();\n }\n\n public isEnabled(): boolean {\n if (this.alepha.env.NO_COLOR) {\n return false;\n }\n\n if (this.alepha.env.FORCE_COLOR) {\n return true;\n }\n\n return !this.alepha.isProduction();\n }\n\n public set(\n color: keyof typeof ConsoleColorProvider.COLORS,\n text: string,\n reset: string = ConsoleColorProvider.COLORS.RESET,\n ): string {\n if (!this.enabled) {\n return text;\n }\n\n return `${ConsoleColorProvider.COLORS[color]}${text}${reset}`;\n }\n}\n","import { LogDestinationProvider } from \"./LogDestinationProvider.ts\";\n\nexport class ConsoleDestinationProvider extends LogDestinationProvider {\n public write(message: string): void {\n console.log(message);\n }\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { LogFormatterProvider } from \"./LogFormatterProvider.ts\";\n\nexport class JsonFormatterProvider extends LogFormatterProvider {\n public format(entry: LogEntry): string {\n const json: Record<string, any> = {\n level: entry.level,\n message: entry.message,\n context: entry.context,\n service: entry.service,\n module: entry.module,\n app: entry.app,\n time: entry.timestamp,\n };\n\n if (entry.data instanceof Error) {\n json.error = this.formatJsonError(entry.data);\n } else {\n json.data = entry.data;\n }\n\n return JSON.stringify(json);\n }\n\n public formatJsonError(error: Error): object {\n return {\n name: error.name,\n message: error.message,\n stack: error.stack,\n cause:\n error.cause instanceof Error\n ? this.formatJsonError(error.cause)\n : undefined,\n };\n }\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { LogDestinationProvider } from \"./LogDestinationProvider.ts\";\n\nexport class MemoryDestinationProvider extends LogDestinationProvider {\n protected entries: Array<LogEntry & { formatted: string }> = [];\n\n public readonly options = {\n maxEntries: 10_000,\n };\n\n public write(formatted: string, entry: LogEntry): void {\n this.entries.push({ ...entry, formatted });\n\n if (this.entries.length > this.options.maxEntries) {\n this.entries = this.entries.slice(\n -Math.floor(this.options.maxEntries * 0.8),\n );\n }\n }\n\n public get logs() {\n return [...this.entries];\n }\n\n public clear(): void {\n this.entries = [];\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { ConsoleColorProvider } from \"./ConsoleColorProvider.ts\";\nimport { LogFormatterProvider } from \"./LogFormatterProvider.ts\";\n\nexport class PrettyFormatterProvider extends LogFormatterProvider {\n protected color = $inject(ConsoleColorProvider);\n protected alepha = $inject(Alepha);\n\n public format(entry: LogEntry): string {\n const { data, timestamp } = entry;\n\n let output = \"\";\n let details = \"\";\n\n const isError = data instanceof Error;\n if (isError) {\n details = this.formatError(data);\n } else if (data) {\n let error = \"\";\n if (\"error\" in data && data.error instanceof Error) {\n error = this.formatError(data.error);\n delete data.error;\n }\n\n if (Object.keys(data).length > 0) {\n try {\n details = JSON.stringify(data);\n } catch {\n details = \"[Unserializable Object]\";\n }\n }\n\n if (error) {\n details += `\\n${error}`;\n }\n }\n\n output += this.color.set(\n \"GREY_DARK\",\n `[${this.formatTimestamp(timestamp)}]`,\n );\n output += \" \";\n\n output += this.color.set(entry.level, entry.level.toUpperCase());\n output += \" \";\n\n if (entry.app) {\n output += this.color.set(\"GREY_DARK\", `${entry.app}`);\n output += \" \";\n }\n\n if (entry.context) {\n output += this.color.set(\n \"GREY_DARK\",\n `(${this.formatContext(entry.context)})`,\n );\n output += \" \";\n }\n\n const module = this.color.set(\"GREY_LIGHT\", `${entry.module}.`);\n const service = this.color.set(\n this.alepha.isBrowser() ? \"RESET\" : \"WHITE\",\n entry.service,\n );\n\n output += `<${module}${service}>`;\n\n if (entry.message) {\n output += `: ${this.color.set(\"CYAN\", entry.message)}`;\n } else {\n output += \":\";\n }\n\n if (details) {\n if (isError) {\n output += ` \\n${details}`;\n } else {\n output += ` ${this.color.set(\"GREY_DARK\", details)}`;\n }\n }\n\n return output;\n }\n\n public formatTimestamp(timestamp: number): string {\n const d = new Date(timestamp);\n const h = d.getHours();\n const m = d.getMinutes();\n const s = d.getSeconds();\n const ms = d.getMilliseconds();\n\n return `${this.pad2(h)}:${this.pad2(m)}:${this.pad2(s)}.${this.pad3(ms)}`;\n }\n\n protected pad2 = (n: number) => (n < 10 ? \"0\" : \"\") + n;\n protected pad3 = (n: number) =>\n n < 10 ? `00${n}` : n < 100 ? `0${n}` : `${n}`;\n\n /**\n * Avoid to display the whole UUID in development mode\n */\n protected formatContext(context: string): string {\n if (this.alepha.isProduction()) {\n return context;\n }\n\n return context.slice(0, 8);\n }\n\n protected formatError(error: Error): string {\n // Chrome does not like stack traces with ASCII colors\n // so we remove the stack trace from log and just print with console.error\n if (this.alepha.isBrowser()) {\n // call console.error in a separate tick to avoid messing with log order\n setTimeout(() => {\n console.error(error);\n });\n return \"\";\n }\n\n // hack: use vite's stack trace formatter if available\n const vite = this.alepha.store.get(\"alepha.vite.server\") as\n | {\n ssrFixStacktrace: (error: Error) => void;\n }\n | undefined;\n\n vite?.ssrFixStacktrace(error);\n\n let str = error.stack ?? error.message;\n\n const anyError = error as any;\n while (anyError.cause && anyError.cause instanceof Error) {\n vite?.ssrFixStacktrace(anyError.cause);\n\n str += `\\nCaused by: ${anyError.cause.stack ?? anyError.cause.message}`;\n anyError.cause = anyError.cause.cause;\n }\n\n return str;\n }\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { LogFormatterProvider } from \"./LogFormatterProvider.ts\";\n\nexport class RawFormatterProvider extends LogFormatterProvider {\n public format(entry: LogEntry): string {\n let output = \"\";\n\n output += `${entry.message}`;\n\n if (entry.data instanceof Error) {\n output += `\\n${entry.data.message}`;\n let cause = entry.data.cause;\n while (cause instanceof Error) {\n output += `\\nCaused by: ${cause.message}`;\n cause = cause.cause;\n }\n }\n\n return output;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const logEntrySchema = t.object({\n level: t.enum([\"SILENT\", \"TRACE\", \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\"]),\n message: t.text({\n size: \"rich\",\n }),\n service: t.text(),\n module: t.text(),\n context: t.optional(t.text()),\n app: t.optional(t.text()),\n data: t.optional(t.any()),\n timestamp: t.number(),\n});\n\nexport type LogEntry = Static<typeof logEntrySchema>;\n","import { $module, type Static, t } from \"alepha\";\nimport { $logger } from \"./primitives/$logger.ts\";\nimport { ConsoleColorProvider } from \"./providers/ConsoleColorProvider.ts\";\nimport { ConsoleDestinationProvider } from \"./providers/ConsoleDestinationProvider.ts\";\nimport { JsonFormatterProvider } from \"./providers/JsonFormatterProvider.ts\";\nimport { LogDestinationProvider } from \"./providers/LogDestinationProvider.ts\";\nimport { LogFormatterProvider } from \"./providers/LogFormatterProvider.ts\";\nimport { MemoryDestinationProvider } from \"./providers/MemoryDestinationProvider.ts\";\nimport { PrettyFormatterProvider } from \"./providers/PrettyFormatterProvider.ts\";\nimport { RawFormatterProvider } from \"./providers/RawFormatterProvider.ts\";\nimport type { LogEntry } from \"./schemas/logEntrySchema.ts\";\nimport { Logger } from \"./services/Logger.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./primitives/$logger.ts\";\nexport * from \"./providers/ConsoleColorProvider.ts\";\nexport * from \"./providers/ConsoleDestinationProvider.ts\";\nexport * from \"./providers/JsonFormatterProvider.ts\";\nexport * from \"./providers/LogDestinationProvider.ts\";\nexport * from \"./providers/LogFormatterProvider.ts\";\nexport * from \"./providers/MemoryDestinationProvider.ts\";\nexport * from \"./providers/PrettyFormatterProvider.ts\";\nexport * from \"./schemas/logEntrySchema.ts\";\nexport * from \"./services/Logger.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Configurable logging with multiple outputs.\n *\n * **Features:**\n * - Global logger access\n * - JSON format\n * - Pretty colored output\n * - Raw text format\n * - Console destination\n * - Memory destination (for devtools)\n * - Custom handlers\n * - Configuration via `LOG_LEVEL` and `LOG_FORMAT`\n *\n * @module alepha.logger\n */\nexport const AlephaLogger = $module({\n name: \"alepha.logger\",\n primitives: [$logger],\n services: [\n Logger,\n ConsoleDestinationProvider,\n MemoryDestinationProvider,\n JsonFormatterProvider,\n PrettyFormatterProvider,\n RawFormatterProvider,\n ConsoleColorProvider,\n ],\n register: (alepha) => {\n const env = alepha.parseEnv(envSchema);\n\n const getLogDestinationProvider = () => {\n // in test mode, if no LOG_LEVEL is set, use MemoryDestinationProvider to capture logs for inspection.\n // logs will be printed to console only if the test fails.\n if (alepha.isTest() && !env.LOG_LEVEL) {\n const printOnError = (ev: any) => {\n if (ev.task?.result?.state === \"fail\") {\n const output = alepha.inject(MemoryDestinationProvider);\n for (const log of output.logs) {\n console.log(log.formatted);\n }\n }\n };\n\n try {\n alepha.store.get(\"alepha.test.afterEach\")?.(printOnError);\n alepha.store.get(\"alepha.test.onTestFinished\")?.(printOnError);\n } catch {\n // ignore\n }\n\n return MemoryDestinationProvider;\n }\n\n return ConsoleDestinationProvider;\n };\n\n const getLogFormatterProvider = () => {\n if (env.LOG_FORMAT) {\n if (env.LOG_FORMAT === \"json\") {\n return JsonFormatterProvider;\n }\n if (env.LOG_FORMAT === \"raw\") {\n return RawFormatterProvider;\n }\n return PrettyFormatterProvider;\n }\n\n if (alepha.isProduction() && !alepha.isBrowser()) {\n return JsonFormatterProvider;\n }\n\n return PrettyFormatterProvider;\n };\n\n alepha.with({\n optional: true,\n provide: LogDestinationProvider,\n use: getLogDestinationProvider(),\n });\n\n alepha.with({\n optional: true,\n provide: LogFormatterProvider,\n use: getLogFormatterProvider(),\n });\n\n alepha.store.set(\n \"alepha.logger\",\n alepha.inject(Logger, {\n lifetime: \"transient\",\n args: [\"Alepha\", \"alepha.core\"],\n }),\n );\n\n alepha.store.set(\n \"alepha.logger.level\",\n env.LOG_LEVEL ?? (alepha.isTest() ? \"trace\" : \"info\"),\n );\n },\n});\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nconst envSchema = t.object({\n /**\n * Default log level for the application.\n *\n * Default by environment:\n * - dev = info\n * - prod = info\n * - test = error\n *\n * Levels are: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\"\n *\n * Level can be set for a specific module:\n *\n * @example\n * LOG_LEVEL=my.module.name:debug,info # Set debug level for my.module.name and info for all other modules\n * LOG_LEVEL=alepha:trace, info # Set trace level for all alepha modules and info for all other modules\n */\n LOG_LEVEL: t.optional(\n t.text({\n description: `Application log level on startup.\nLevels are: trace, debug, info, warn, error, silent\nLevel can be set for a specific module:\n\"my.module.name:debug,info\" -> Set debug level for my.module.name and info for all other modules\n\"alepha:trace,info\" -> Set trace level for all alepha modules and info for all other modules`,\n lowercase: true,\n }),\n ),\n\n /**\n * Built-in log formats.\n * - \"json\" - JSON format, useful for structured logging and log aggregation. {@link JsonFormatterProvider}\n * - \"pretty\" - Simple text format, human-readable, with colors. {@link PrettyFormatterProvider}\n * - \"raw\" - Raw format, no formatting, just the message. {@link RawFormatterProvider}\n */\n LOG_FORMAT: t.optional(\n t.enum([\"json\", \"pretty\", \"raw\"], {\n description: \"Default log format for the application.\",\n lowercase: true,\n }),\n ),\n});\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n export interface Env extends Partial<Static<typeof envSchema>> {}\n\n export interface State {\n /**\n * Current log level for the application or specific modules.\n */\n \"alepha.logger.level\"?: string;\n }\n\n export interface Hooks {\n log: {\n message?: string;\n entry: LogEntry;\n };\n }\n}\n"],"mappings":";;;;AAEA,IAAsB,yBAAtB,MAA6C;;;;ACA7C,IAAsB,uBAAtB,MAA2C;;;;ACU3C,IAAa,SAAb,MAA+C;CAC7C,AAAmB,SAAS,QAAQ,OAAO;CAC3C,AAAmB,YAAY,QAAQ,qBAAqB;CAC5D,AAAmB,cAAc,QAAQ,uBAAuB;CAChE,AAAmB,mBAAmB,QAAQ,iBAAiB;CAE/D,AAAmB,SAAiC;EAClD,QAAQ;EACR,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,OAAO;EACR;CAED,AAAmB;CACnB,AAAmB;CACnB,AAAmB;CAEnB,AAAU,cAAsB;CAChC,AAAU,WAAqB;CAE/B,YAAY,SAAiB,QAAgB;AAC3C,OAAK,UAAU;AACf,OAAK,SAAS;AACd,OAAK,MAAM,KAAK,OAAO,IAAI;;CAG7B,IAAW,UAA8B;AACvC,SAAO,KAAK,OAAO,QAAQ,IAAY,UAAU;;CAGnD,IAAW,QAAgB;EACzB,MAAM,gBAAgB,KAAK,OAAO,MAAM,IAAI,sBAAsB;AAClE,MAAI,iBAAiB,kBAAkB,KAAK,aAAa;AACvD,QAAK,cAAc;AACnB,QAAK,WAAW,KAAK,WAAW,KAAK,aAAa,KAAK,OAAO;;AAEhE,SAAO,KAAK;;CAGd,AAAO,WAAW,OAAe,KAAuB;EACtD,MAAM,QAAQ,MAAM,aAAa,CAAC,MAAM,OAAO;AAG/C,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,cAAc,KAAK,MAAM;AAC/B,OAAI,CAAC,YAAa;AAElB,OAAI,YAAY,SAAS,IAAI,IAAI,YAAY,SAAS,IAAI,EAAE;IAC1D,MAAM,CAAC,eAAe,cAAc,YAAY,MAAM,OAAO;IAC7D,MAAM,gBAAgB,cAAc,MAAM;IAC1C,MAAM,eAAe,YAAY,MAAM;AAEvC,QAAI,CAAC,aAAc;AAEnB,QAAI,KAAK,eAAe,KAAK,cAAc,CACzC,KAAI;AACF,YAAO,KAAK,WAAW,aAAa;aAC7B,OAAO;AACd,WAAM,IAAI,YACR,sBAAsB,YAAY,MAAM,CAAC,wBAAwB,cAAc,GAChF;;;;AAOT,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,cAAc,KAAK,MAAM;AAC/B,OAAI,CAAC,YAAa;AAElB,OAAI,CAAC,YAAY,SAAS,IAAI,IAAI,CAAC,YAAY,SAAS,IAAI,CAC1D,KAAI;AACF,WAAO,KAAK,WAAW,YAAY;YAC5B,OAAO;AACd,UAAM,IAAI,MAAM,6BAA6B,YAAY,GAAG;;;AAKlE,SAAO;;CAGT,AAAQ,eAAe,YAAoB,SAA0B;AACnE,MAAI,QAAQ,SAAS,IAAI,EAAE;GAEzB,MAAM,eAAe,QAAQ,QAAQ,OAAO,MAAM,CAAC,QAAQ,OAAO,KAAK;AACvE,UAAO,IAAI,OAAO,IAAI,eAAe,CAAC,KAAK,WAAW;;AAIxD,SAAO,WAAW,WAAW,QAAQ;;CAGvC,AAAO,WAAW,WAA6B;EAC7C,MAAM,QAAQ,UAAU,MAAM,CAAC,aAAa;AAC5C,MAAI,KAAK,OAAO,WAAW,OACzB,QAAO;AAGT,QAAM,IAAI,YAAY,sBAAsB,YAAY;;CAK1D,AAAO,MAAM,SAAiB,MAAsB;AAClD,OAAK,IAAI,SAAS,SAAS,KAAK;;CAGlC,AAAO,KAAK,SAAiB,MAAsB;AACjD,OAAK,IAAI,QAAQ,SAAS,KAAK;;CAGjC,AAAO,KAAK,SAAiB,MAAsB;AACjD,OAAK,IAAI,QAAQ,SAAS,KAAK;;CAGjC,AAAO,MAAM,SAAiB,MAAsB;AAClD,OAAK,IAAI,SAAS,SAAS,KAAK;;CAGlC,AAAO,MAAM,SAAiB,MAAsB;AAClD,OAAK,IAAI,SAAS,SAAS,KAAK;;CAGlC,AAAU,IAAI,OAAiB,SAAiB,MAAsB;EACpE,IAAI,WAAW;AACf,MAAI,OAAO,YAAY,SACrB,YAAW;WACF,OAAO,SAAS,SACzB,YAAW;EAGb,IAAI;AACJ,MAAI,OAAO,SAAS,YAAY,CAAC,CAAC,KAChC,SAAQ;WACC,OAAO,YAAY,YAAY,QACxC,SAAQ;EAGV,MAAM,WAAqB;GACzB;GACA,SAAS;GACT,MAAM;GACN,SAAS,KAAK;GACd,SAAS,KAAK;GACd,QAAQ,KAAK;GACb,KAAK,KAAK;GACV,WAAW,KAAK,iBAAiB,WAAW;GAC7C;AAED,MAAI,KAAK,OAAO,SAAS,KAAK,OAAO,KAAK,QAAQ;AAChD,QAAK,KAAK,SAAS;AACnB;;EAGF,MAAM,YAAY,KAAK,UAAU,OAAO,SAAS;AAEjD,OAAK,KAAK,UAAU,UAAU;AAE9B,OAAK,YAAY,MAAM,WAAW,SAAS;;CAG7C,AAAU,KAAK,OAAiB,SAAkB;AAChD,OAAK,OAAO,OACT,KACC,OACA;GACE;GACA;GACD,EACD,EACE,OAAO,MACR,CACF,CACA,YAAY,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;ACvKxB,MAAa,WAAW,UAAkC,EAAE,KAAa;CACvE,MAAM,EAAE,QAAQ,SAAS,WAAW,UAAU;AAE9C,QAAO,QAAQ,QAAQ;EACrB,UAAU;EACV,MAAM,CACJ,QAAQ,QAAQ,SAAS,QAAQ,QACjC,QAAQ,QAAQ,OAAO,IAAI,eAAe,MAC3C;EACF,CAAC;;AAOJ,QAAQ,QAAQ;;;;ACpChB,IAAa,uBAAb,MAAa,qBAAqB;CAChC,OAAgB,SAAS;EACvB,OAAO;EACP,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ;EACR,MAAM;EACN,QAAQ;EACR,MAAM;EACN,YAAY;EACZ,iBAAiB;EACjB,WAAW;EACX,gBAAgB;EAChB,OAAO;EACP,YAAY;EAEZ,KAAK;EACL,MAAM;EACN,SAAS;EAET,QAAQ;EACR,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,OAAO;EACR;CAED,AAAmB,SAAS,QAAQ,OAAO;CAE3C,AAAU,UAAU;CAEpB,cAAc;AACZ,OAAK,UAAU,KAAK,WAAW;;CAGjC,AAAO,YAAqB;AAC1B,MAAI,KAAK,OAAO,IAAI,SAClB,QAAO;AAGT,MAAI,KAAK,OAAO,IAAI,YAClB,QAAO;AAGT,SAAO,CAAC,KAAK,OAAO,cAAc;;CAGpC,AAAO,IACL,OACA,MACA,QAAgB,qBAAqB,OAAO,OACpC;AACR,MAAI,CAAC,KAAK,QACR,QAAO;AAGT,SAAO,GAAG,qBAAqB,OAAO,SAAS,OAAO;;;;;;AC1D1D,IAAa,6BAAb,cAAgD,uBAAuB;CACrE,AAAO,MAAM,SAAuB;AAClC,UAAQ,IAAI,QAAQ;;;;;;ACDxB,IAAa,wBAAb,cAA2C,qBAAqB;CAC9D,AAAO,OAAO,OAAyB;EACrC,MAAM,OAA4B;GAChC,OAAO,MAAM;GACb,SAAS,MAAM;GACf,SAAS,MAAM;GACf,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,KAAK,MAAM;GACX,MAAM,MAAM;GACb;AAED,MAAI,MAAM,gBAAgB,MACxB,MAAK,QAAQ,KAAK,gBAAgB,MAAM,KAAK;MAE7C,MAAK,OAAO,MAAM;AAGpB,SAAO,KAAK,UAAU,KAAK;;CAG7B,AAAO,gBAAgB,OAAsB;AAC3C,SAAO;GACL,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,OAAO,MAAM;GACb,OACE,MAAM,iBAAiB,QACnB,KAAK,gBAAgB,MAAM,MAAM,GACjC;GACP;;;;;;AC9BL,IAAa,4BAAb,cAA+C,uBAAuB;CACpE,AAAU,UAAmD,EAAE;CAE/D,AAAgB,UAAU,EACxB,YAAY,KACb;CAED,AAAO,MAAM,WAAmB,OAAuB;AACrD,OAAK,QAAQ,KAAK;GAAE,GAAG;GAAO;GAAW,CAAC;AAE1C,MAAI,KAAK,QAAQ,SAAS,KAAK,QAAQ,WACrC,MAAK,UAAU,KAAK,QAAQ,MAC1B,CAAC,KAAK,MAAM,KAAK,QAAQ,aAAa,GAAI,CAC3C;;CAIL,IAAW,OAAO;AAChB,SAAO,CAAC,GAAG,KAAK,QAAQ;;CAG1B,AAAO,QAAc;AACnB,OAAK,UAAU,EAAE;;;;;;ACpBrB,IAAa,0BAAb,cAA6C,qBAAqB;CAChE,AAAU,QAAQ,QAAQ,qBAAqB;CAC/C,AAAU,SAAS,QAAQ,OAAO;CAElC,AAAO,OAAO,OAAyB;EACrC,MAAM,EAAE,MAAM,cAAc;EAE5B,IAAI,SAAS;EACb,IAAI,UAAU;EAEd,MAAM,UAAU,gBAAgB;AAChC,MAAI,QACF,WAAU,KAAK,YAAY,KAAK;WACvB,MAAM;GACf,IAAI,QAAQ;AACZ,OAAI,WAAW,QAAQ,KAAK,iBAAiB,OAAO;AAClD,YAAQ,KAAK,YAAY,KAAK,MAAM;AACpC,WAAO,KAAK;;AAGd,OAAI,OAAO,KAAK,KAAK,CAAC,SAAS,EAC7B,KAAI;AACF,cAAU,KAAK,UAAU,KAAK;WACxB;AACN,cAAU;;AAId,OAAI,MACF,YAAW,KAAK;;AAIpB,YAAU,KAAK,MAAM,IACnB,aACA,IAAI,KAAK,gBAAgB,UAAU,CAAC,GACrC;AACD,YAAU;AAEV,YAAU,KAAK,MAAM,IAAI,MAAM,OAAO,MAAM,MAAM,aAAa,CAAC;AAChE,YAAU;AAEV,MAAI,MAAM,KAAK;AACb,aAAU,KAAK,MAAM,IAAI,aAAa,GAAG,MAAM,MAAM;AACrD,aAAU;;AAGZ,MAAI,MAAM,SAAS;AACjB,aAAU,KAAK,MAAM,IACnB,aACA,IAAI,KAAK,cAAc,MAAM,QAAQ,CAAC,GACvC;AACD,aAAU;;EAGZ,MAAM,SAAS,KAAK,MAAM,IAAI,cAAc,GAAG,MAAM,OAAO,GAAG;EAC/D,MAAM,UAAU,KAAK,MAAM,IACzB,KAAK,OAAO,WAAW,GAAG,UAAU,SACpC,MAAM,QACP;AAED,YAAU,IAAI,SAAS,QAAQ;AAE/B,MAAI,MAAM,QACR,WAAU,KAAK,KAAK,MAAM,IAAI,QAAQ,MAAM,QAAQ;MAEpD,WAAU;AAGZ,MAAI,QACF,KAAI,QACF,WAAU,MAAM;MAEhB,WAAU,IAAI,KAAK,MAAM,IAAI,aAAa,QAAQ;AAItD,SAAO;;CAGT,AAAO,gBAAgB,WAA2B;EAChD,MAAM,IAAI,IAAI,KAAK,UAAU;EAC7B,MAAM,IAAI,EAAE,UAAU;EACtB,MAAM,IAAI,EAAE,YAAY;EACxB,MAAM,IAAI,EAAE,YAAY;EACxB,MAAM,KAAK,EAAE,iBAAiB;AAE9B,SAAO,GAAG,KAAK,KAAK,EAAE,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,GAAG,KAAK,KAAK,GAAG;;CAGzE,AAAU,QAAQ,OAAe,IAAI,KAAK,MAAM,MAAM;CACtD,AAAU,QAAQ,MAChB,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM,GAAG;;;;CAK7C,AAAU,cAAc,SAAyB;AAC/C,MAAI,KAAK,OAAO,cAAc,CAC5B,QAAO;AAGT,SAAO,QAAQ,MAAM,GAAG,EAAE;;CAG5B,AAAU,YAAY,OAAsB;AAG1C,MAAI,KAAK,OAAO,WAAW,EAAE;AAE3B,oBAAiB;AACf,YAAQ,MAAM,MAAM;KACpB;AACF,UAAO;;EAIT,MAAM,OAAO,KAAK,OAAO,MAAM,IAAI,qBAAqB;AAMxD,QAAM,iBAAiB,MAAM;EAE7B,IAAI,MAAM,MAAM,SAAS,MAAM;EAE/B,MAAM,WAAW;AACjB,SAAO,SAAS,SAAS,SAAS,iBAAiB,OAAO;AACxD,SAAM,iBAAiB,SAAS,MAAM;AAEtC,UAAO,gBAAgB,SAAS,MAAM,SAAS,SAAS,MAAM;AAC9D,YAAS,QAAQ,SAAS,MAAM;;AAGlC,SAAO;;;;;;ACzIX,IAAa,uBAAb,cAA0C,qBAAqB;CAC7D,AAAO,OAAO,OAAyB;EACrC,IAAI,SAAS;AAEb,YAAU,GAAG,MAAM;AAEnB,MAAI,MAAM,gBAAgB,OAAO;AAC/B,aAAU,KAAK,MAAM,KAAK;GAC1B,IAAI,QAAQ,MAAM,KAAK;AACvB,UAAO,iBAAiB,OAAO;AAC7B,cAAU,gBAAgB,MAAM;AAChC,YAAQ,MAAM;;;AAIlB,SAAO;;;;;;AChBX,MAAa,iBAAiB,EAAE,OAAO;CACrC,OAAO,EAAE,KAAK;EAAC;EAAU;EAAS;EAAS;EAAQ;EAAQ;EAAQ,CAAC;CACpE,SAAS,EAAE,KAAK,EACd,MAAM,QACP,CAAC;CACF,SAAS,EAAE,MAAM;CACjB,QAAQ,EAAE,MAAM;CAChB,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;CAC7B,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC;CACzB,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;CACzB,WAAW,EAAE,QAAQ;CACtB,CAAC;;;;;;;;;;;;;;;;;;;AC8BF,MAAa,eAAe,QAAQ;CAClC,MAAM;CACN,YAAY,CAAC,QAAQ;CACrB,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,WAAW,WAAW;EACpB,MAAM,MAAM,OAAO,SAAS,UAAU;EAEtC,MAAM,kCAAkC;AAGtC,OAAI,OAAO,QAAQ,IAAI,CAAC,IAAI,WAAW;IACrC,MAAM,gBAAgB,OAAY;AAChC,SAAI,GAAG,MAAM,QAAQ,UAAU,QAAQ;MACrC,MAAM,SAAS,OAAO,OAAO,0BAA0B;AACvD,WAAK,MAAM,OAAO,OAAO,KACvB,SAAQ,IAAI,IAAI,UAAU;;;AAKhC,QAAI;AACF,YAAO,MAAM,IAAI,wBAAwB,GAAG,aAAa;AACzD,YAAO,MAAM,IAAI,6BAA6B,GAAG,aAAa;YACxD;AAIR,WAAO;;AAGT,UAAO;;EAGT,MAAM,gCAAgC;AACpC,OAAI,IAAI,YAAY;AAClB,QAAI,IAAI,eAAe,OACrB,QAAO;AAET,QAAI,IAAI,eAAe,MACrB,QAAO;AAET,WAAO;;AAGT,OAAI,OAAO,cAAc,IAAI,CAAC,OAAO,WAAW,CAC9C,QAAO;AAGT,UAAO;;AAGT,SAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK,2BAA2B;GACjC,CAAC;AAEF,SAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK,yBAAyB;GAC/B,CAAC;AAEF,SAAO,MAAM,IACX,iBACA,OAAO,OAAO,QAAQ;GACpB,UAAU;GACV,MAAM,CAAC,UAAU,cAAc;GAChC,CAAC,CACH;AAED,SAAO,MAAM,IACX,uBACA,IAAI,cAAc,OAAO,QAAQ,GAAG,UAAU,QAC/C;;CAEJ,CAAC;AAIF,MAAM,YAAY,EAAE,OAAO;CAiBzB,WAAW,EAAE,SACX,EAAE,KAAK;EACL,aAAa;;;;;EAKb,WAAW;EACZ,CAAC,CACH;CAQD,YAAY,EAAE,SACZ,EAAE,KAAK;EAAC;EAAQ;EAAU;EAAM,EAAE;EAChC,aAAa;EACb,WAAW;EACZ,CAAC,CACH;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/logger/providers/LogDestinationProvider.ts","../../src/logger/providers/LogFormatterProvider.ts","../../src/logger/services/Logger.ts","../../src/logger/primitives/$logger.ts","../../src/logger/providers/ConsoleColorProvider.ts","../../src/logger/providers/ConsoleDestinationProvider.ts","../../src/logger/providers/JsonFormatterProvider.ts","../../src/logger/providers/MemoryDestinationProvider.ts","../../src/logger/providers/PrettyFormatterProvider.ts","../../src/logger/providers/RawFormatterProvider.ts","../../src/logger/schemas/logEntrySchema.ts","../../src/logger/index.ts"],"sourcesContent":["import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\n\nexport abstract class LogDestinationProvider {\n public abstract write(message: string, entry: LogEntry): void;\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\n\nexport abstract class LogFormatterProvider {\n public abstract format(entry: LogEntry): string;\n}\n","import {\n $inject,\n Alepha,\n AlephaError,\n type LoggerInterface,\n type LogLevel,\n} from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { LogDestinationProvider } from \"../providers/LogDestinationProvider.ts\";\nimport { LogFormatterProvider } from \"../providers/LogFormatterProvider.ts\";\nimport type { LogEntry } from \"../schemas/logEntrySchema.ts\";\n\nexport class Logger implements LoggerInterface {\n protected readonly alepha = $inject(Alepha);\n protected readonly formatter = $inject(LogFormatterProvider);\n protected readonly destination = $inject(LogDestinationProvider);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n\n protected readonly levels: Record<string, number> = {\n SILENT: -1,\n ERROR: 0,\n WARN: 1,\n INFO: 2,\n DEBUG: 3,\n TRACE: 4,\n };\n\n protected readonly service: string;\n protected readonly module: string;\n protected readonly app?: string;\n\n protected appLogLevel: string = \"INFO\";\n protected logLevel: LogLevel = \"INFO\";\n\n constructor(service: string, module: string) {\n this.service = service;\n this.module = module;\n this.app = this.alepha.env.APP_NAME;\n }\n\n public get context(): string | undefined {\n return this.alepha.context.get<string>(\"context\");\n }\n\n public get level(): string {\n const stateLogLevel = this.alepha.store.get(\"alepha.logger.level\");\n if (stateLogLevel && stateLogLevel !== this.appLogLevel) {\n this.appLogLevel = stateLogLevel;\n this.logLevel = this.parseLevel(this.appLogLevel, this.module);\n }\n return this.logLevel;\n }\n\n public parseLevel(level: string, app: string): LogLevel {\n const parts = level.toLowerCase().split(/[,;]/);\n\n // First pass: check for module-specific configurations\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue; // Skip empty parts\n\n if (trimmedPart.includes(\":\") || trimmedPart.includes(\"=\")) {\n const [modulePattern, levelValue] = trimmedPart.split(/[:=]/);\n const trimmedModule = modulePattern.trim();\n const trimmedLevel = levelValue?.trim();\n\n if (!trimmedLevel) continue; // Skip if no level specified\n\n if (this.matchesPattern(app, trimmedModule)) {\n try {\n return this.asLogLevel(trimmedLevel);\n } catch (error) {\n throw new AlephaError(\n `Invalid log level '${levelValue?.trim()}' for module pattern '${trimmedModule}'`,\n );\n }\n }\n }\n }\n\n // Second pass: look for global level\n for (const part of parts) {\n const trimmedPart = part.trim();\n if (!trimmedPart) continue; // Skip empty parts\n\n if (!trimmedPart.includes(\":\") && !trimmedPart.includes(\"=\")) {\n try {\n return this.asLogLevel(trimmedPart);\n } catch (error) {\n throw new Error(`Invalid global log level \"${trimmedPart}\"`);\n }\n }\n }\n\n return \"INFO\";\n }\n\n private matchesPattern(moduleName: string, pattern: string): boolean {\n if (pattern.includes(\"*\")) {\n // Convert wildcard pattern to regex\n const regexPattern = pattern.replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\");\n return new RegExp(`^${regexPattern}`).test(moduleName);\n }\n\n // Exact prefix match (existing behavior)\n return moduleName.startsWith(pattern);\n }\n\n public asLogLevel(something: string): LogLevel {\n const level = something.trim().toUpperCase();\n if (this.levels[level] !== undefined) {\n return level as LogLevel;\n }\n\n throw new AlephaError(`Invalid log level: ${something}`);\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n public error(message: string, data?: unknown): void {\n this.log(\"ERROR\", message, data);\n }\n\n public warn(message: string, data?: unknown): void {\n this.log(\"WARN\", message, data);\n }\n\n public info(message: string, data?: unknown): void {\n this.log(\"INFO\", message, data);\n }\n\n public debug(message: string, data?: unknown): void {\n this.log(\"DEBUG\", message, data);\n }\n\n public trace(message: string, data?: unknown): void {\n this.log(\"TRACE\", message, data);\n }\n\n protected log(level: LogLevel, message: string, data?: unknown): void {\n let _message = \"\";\n if (typeof message === \"string\") {\n _message = message;\n } else if (typeof data === \"string\") {\n _message = data;\n }\n\n let _data: object | Error | undefined;\n if (typeof data === \"object\" && !!data) {\n _data = data;\n } else if (typeof message === \"object\" && message) {\n _data = message;\n }\n\n const logEntry: LogEntry = {\n level,\n message: _message,\n data: _data,\n context: this.context,\n service: this.service,\n module: this.module,\n app: this.app,\n timestamp: this.dateTimeProvider.nowMillis(),\n };\n\n if (this.levels[level] > this.levels[this.level]) {\n this.emit(logEntry);\n return;\n }\n\n const formatted = this.formatter.format(logEntry);\n\n this.emit(logEntry, formatted);\n\n this.destination.write(formatted, logEntry);\n }\n\n protected emit(entry: LogEntry, message?: string) {\n this.alepha.events\n .emit(\n \"log\",\n {\n message,\n entry,\n },\n {\n catch: true,\n },\n )\n .catch(() => null);\n }\n}\n","import { $context, $inject, KIND } from \"alepha\";\nimport { Logger } from \"../services/Logger.ts\";\n\n/**\n * Create a logger.\n *\n * `name` is optional, by default it will use the name of the service.\n *\n * @example\n * ```ts\n * import { $logger } from \"alepha\";\n *\n * class MyService {\n * \tlog = $logger();\n *\n * constructor() {\n * this.log.info(\"Service initialized\");\n * // print something like '[23:45:53.326] INFO <app.MyService>: Service initialized'\n * }\n * }\n * ```\n */\nexport const $logger = (options: LoggerPrimitiveOptions = {}): Logger => {\n const { alepha, service, module } = $context();\n\n return $inject(Logger, {\n lifetime: \"transient\",\n args: [\n options.name ?? service?.name ?? \"Func\",\n module?.name ?? alepha.env.MODULE_NAME ?? \"app\",\n ],\n });\n};\n\nexport interface LoggerPrimitiveOptions {\n name?: string;\n}\n\n$logger[KIND] = Logger;\n","import { $inject, Alepha } from \"alepha\";\n\nexport class ConsoleColorProvider {\n static readonly COLORS = {\n RESET: \"\\x1b[0m\",\n BLACK: \"\\x1b[30m\",\n RED: \"\\x1b[31m\",\n GREEN: \"\\x1b[32m\",\n ORANGE: \"\\x1b[33m\", // using yellow for orange-ish\n BLUE: \"\\x1b[34m\",\n PURPLE: \"\\x1b[35m\",\n CYAN: \"\\x1b[36m\",\n GREY_LIGHT: \"\\x1b[37m\",\n GREY_LIGHT_BOLD: \"\\x1b[1;37m\",\n GREY_DARK: \"\\x1b[90m\",\n GREY_DARK_BOLD: \"\\x1b[1;90m\",\n WHITE: \"\\x1b[97m\",\n WHITE_BOLD: \"\\x1b[1;97m\",\n // modifiers\n DIM: \"\\x1b[2m\",\n BOLD: \"\\x1b[1m\",\n INVERSE: \"\\x1b[7m\",\n // levels\n SILENT: \"\",\n ERROR: \"\\x1b[31m\",\n WARN: \"\\x1b[33m\",\n INFO: \"\\x1b[32m\",\n DEBUG: \"\\x1b[34m\",\n TRACE: \"\\x1b[90m\",\n };\n\n protected readonly alepha = $inject(Alepha);\n\n protected enabled = true;\n\n constructor() {\n this.enabled = this.isEnabled();\n }\n\n public isEnabled(): boolean {\n if (this.alepha.env.NO_COLOR) {\n return false;\n }\n\n if (this.alepha.env.FORCE_COLOR) {\n return true;\n }\n\n return !this.alepha.isProduction();\n }\n\n public set(\n color: keyof typeof ConsoleColorProvider.COLORS,\n text: string,\n reset: string = ConsoleColorProvider.COLORS.RESET,\n ): string {\n if (!this.enabled) {\n return text;\n }\n\n return `${ConsoleColorProvider.COLORS[color]}${text}${reset}`;\n }\n}\n","import { LogDestinationProvider } from \"./LogDestinationProvider.ts\";\n\nexport class ConsoleDestinationProvider extends LogDestinationProvider {\n public write(message: string): void {\n console.log(message);\n }\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { LogFormatterProvider } from \"./LogFormatterProvider.ts\";\n\nexport class JsonFormatterProvider extends LogFormatterProvider {\n public format(entry: LogEntry): string {\n const json: Record<string, any> = {\n level: entry.level,\n message: entry.message,\n context: entry.context,\n service: entry.service,\n module: entry.module,\n app: entry.app,\n time: entry.timestamp,\n };\n\n if (entry.data instanceof Error) {\n json.error = this.formatJsonError(entry.data);\n } else {\n json.data = entry.data;\n }\n\n return JSON.stringify(json);\n }\n\n public formatJsonError(error: Error): object {\n return {\n name: error.name,\n message: error.message,\n stack: error.stack,\n cause:\n error.cause instanceof Error\n ? this.formatJsonError(error.cause)\n : undefined,\n };\n }\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { LogDestinationProvider } from \"./LogDestinationProvider.ts\";\n\nexport class MemoryDestinationProvider extends LogDestinationProvider {\n protected entries: Array<LogEntry & { formatted: string }> = [];\n\n public readonly options = {\n maxEntries: 10_000,\n };\n\n public write(formatted: string, entry: LogEntry): void {\n this.entries.push({ ...entry, formatted });\n\n if (this.entries.length > this.options.maxEntries) {\n this.entries = this.entries.slice(\n -Math.floor(this.options.maxEntries * 0.8),\n );\n }\n }\n\n public get logs() {\n return [...this.entries];\n }\n\n public clear(): void {\n this.entries = [];\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { ConsoleColorProvider } from \"./ConsoleColorProvider.ts\";\nimport { LogFormatterProvider } from \"./LogFormatterProvider.ts\";\n\nexport class PrettyFormatterProvider extends LogFormatterProvider {\n protected color = $inject(ConsoleColorProvider);\n protected alepha = $inject(Alepha);\n\n public format(entry: LogEntry): string {\n const { data, timestamp } = entry;\n\n let output = \"\";\n let details = \"\";\n\n const isError = data instanceof Error;\n if (isError) {\n details = this.formatError(data);\n } else if (data) {\n let error = \"\";\n let jsonData = data;\n if (\"error\" in data && data.error instanceof Error) {\n error = this.formatError(data.error);\n const { error: _, ...rest } = data;\n jsonData = rest;\n }\n\n if (Object.keys(jsonData).length > 0) {\n try {\n details = JSON.stringify(jsonData);\n } catch {\n details = \"[Unserializable Object]\";\n }\n }\n\n if (error) {\n details += `\\n${error}`;\n }\n }\n\n output += this.color.set(\n \"GREY_DARK\",\n `[${this.formatTimestamp(timestamp)}]`,\n );\n output += \" \";\n\n output += this.color.set(entry.level, entry.level.toUpperCase());\n output += \" \";\n\n if (entry.app) {\n output += this.color.set(\"GREY_DARK\", `${entry.app}`);\n output += \" \";\n }\n\n if (entry.context) {\n output += this.color.set(\n \"GREY_DARK\",\n `(${this.formatContext(entry.context)})`,\n );\n output += \" \";\n }\n\n const module = this.color.set(\"GREY_LIGHT\", `${entry.module}.`);\n const service = this.color.set(\n this.alepha.isBrowser() ? \"RESET\" : \"WHITE\",\n entry.service,\n );\n\n output += `<${module}${service}>`;\n\n if (entry.message) {\n output += `: ${this.color.set(\"CYAN\", entry.message)}`;\n } else {\n output += \":\";\n }\n\n if (details) {\n if (isError) {\n output += ` \\n${details}`;\n } else {\n output += ` ${this.color.set(\"GREY_DARK\", details)}`;\n }\n }\n\n return output;\n }\n\n public formatTimestamp(timestamp: number): string {\n const d = new Date(timestamp);\n const h = d.getHours();\n const m = d.getMinutes();\n const s = d.getSeconds();\n const ms = d.getMilliseconds();\n\n return `${this.pad2(h)}:${this.pad2(m)}:${this.pad2(s)}.${this.pad3(ms)}`;\n }\n\n protected pad2 = (n: number) => (n < 10 ? \"0\" : \"\") + n;\n protected pad3 = (n: number) =>\n n < 10 ? `00${n}` : n < 100 ? `0${n}` : `${n}`;\n\n /**\n * Avoid to display the whole UUID in development mode\n */\n protected formatContext(context: string): string {\n if (this.alepha.isProduction()) {\n return context;\n }\n\n return context.slice(0, 8);\n }\n\n protected formatError(error: Error): string {\n // Chrome does not like stack traces with ASCII colors\n // so we remove the stack trace from log and just print with console.error\n if (this.alepha.isBrowser()) {\n // call console.error in a separate tick to avoid messing with log order\n setTimeout(() => {\n console.error(error);\n });\n return \"\";\n }\n\n // hack: use vite's stack trace formatter if available\n const vite = this.alepha.store.get(\"alepha.vite.server\") as\n | {\n ssrFixStacktrace: (error: Error) => void;\n }\n | undefined;\n\n vite?.ssrFixStacktrace(error);\n\n let str = error.stack ?? error.message;\n\n const anyError = error as any;\n while (anyError.cause && anyError.cause instanceof Error) {\n vite?.ssrFixStacktrace(anyError.cause);\n\n str += `\\nCaused by: ${anyError.cause.stack ?? anyError.cause.message}`;\n anyError.cause = anyError.cause.cause;\n }\n\n return str;\n }\n}\n","import type { LogEntry } from \"../schemas/logEntrySchema.ts\";\nimport { LogFormatterProvider } from \"./LogFormatterProvider.ts\";\n\nexport class RawFormatterProvider extends LogFormatterProvider {\n public format(entry: LogEntry): string {\n let output = \"\";\n\n output += `${entry.message}`;\n\n if (entry.data instanceof Error) {\n output += `\\n${entry.data.message}`;\n let cause = entry.data.cause;\n while (cause instanceof Error) {\n output += `\\nCaused by: ${cause.message}`;\n cause = cause.cause;\n }\n }\n\n return output;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const logEntrySchema = t.object({\n level: t.enum([\"SILENT\", \"TRACE\", \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\"]),\n message: t.text({\n size: \"rich\",\n }),\n service: t.text(),\n module: t.text(),\n context: t.optional(t.text()),\n app: t.optional(t.text()),\n data: t.optional(t.any()),\n timestamp: t.number(),\n});\n\nexport type LogEntry = Static<typeof logEntrySchema>;\n","import { $module, type Static, t } from \"alepha\";\nimport { $logger } from \"./primitives/$logger.ts\";\nimport { ConsoleColorProvider } from \"./providers/ConsoleColorProvider.ts\";\nimport { ConsoleDestinationProvider } from \"./providers/ConsoleDestinationProvider.ts\";\nimport { JsonFormatterProvider } from \"./providers/JsonFormatterProvider.ts\";\nimport { LogDestinationProvider } from \"./providers/LogDestinationProvider.ts\";\nimport { LogFormatterProvider } from \"./providers/LogFormatterProvider.ts\";\nimport { MemoryDestinationProvider } from \"./providers/MemoryDestinationProvider.ts\";\nimport { PrettyFormatterProvider } from \"./providers/PrettyFormatterProvider.ts\";\nimport { RawFormatterProvider } from \"./providers/RawFormatterProvider.ts\";\nimport type { LogEntry } from \"./schemas/logEntrySchema.ts\";\nimport { Logger } from \"./services/Logger.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./primitives/$logger.ts\";\nexport * from \"./providers/ConsoleColorProvider.ts\";\nexport * from \"./providers/ConsoleDestinationProvider.ts\";\nexport * from \"./providers/JsonFormatterProvider.ts\";\nexport * from \"./providers/LogDestinationProvider.ts\";\nexport * from \"./providers/LogFormatterProvider.ts\";\nexport * from \"./providers/MemoryDestinationProvider.ts\";\nexport * from \"./providers/PrettyFormatterProvider.ts\";\nexport * from \"./schemas/logEntrySchema.ts\";\nexport * from \"./services/Logger.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Configurable logging with multiple outputs.\n *\n * **Features:**\n * - Global logger access\n * - JSON format\n * - Pretty colored output\n * - Raw text format\n * - Console destination\n * - Memory destination (for devtools)\n * - Custom handlers\n * - Configuration via `LOG_LEVEL`, `LOG_FORMAT`, and `DEBUG`\n *\n * @module alepha.logger\n */\nexport const AlephaLogger = $module({\n name: \"alepha.logger\",\n primitives: [$logger],\n services: [\n Logger,\n ConsoleDestinationProvider,\n MemoryDestinationProvider,\n JsonFormatterProvider,\n PrettyFormatterProvider,\n RawFormatterProvider,\n ConsoleColorProvider,\n ],\n register: (alepha) => {\n const env = alepha.parseEnv(envSchema);\n\n // Support DEBUG env var (debug package convention) as shorthand for LOG_LEVEL/LOG_FORMAT.\n // DEBUG=alepha:* → LOG_LEVEL=alepha.*:debug,info LOG_FORMAT=pretty\n let logLevel = env.LOG_LEVEL;\n let logFormat = env.LOG_FORMAT;\n if (env.DEBUG) {\n const patterns = env.DEBUG.split(\",\")\n .map((p) => p.trim().replaceAll(\":\", \".\"))\n .filter(Boolean);\n logLevel ??= `${patterns.map((p) => `${p}:debug`).join(\",\")},info`;\n logFormat ??= \"pretty\";\n }\n\n const getLogDestinationProvider = () => {\n // in test mode, if no LOG_LEVEL is set, use MemoryDestinationProvider to capture logs for inspection.\n // logs will be printed to console only if the test fails.\n if (alepha.isTest() && !logLevel) {\n const printOnError = (ev: any) => {\n if (ev.task?.result?.state === \"fail\") {\n const output = alepha.inject(MemoryDestinationProvider);\n for (const log of output.logs) {\n console.log(log.formatted);\n }\n }\n };\n\n try {\n alepha.store.get(\"alepha.test.afterEach\")?.(printOnError);\n alepha.store.get(\"alepha.test.onTestFinished\")?.(printOnError);\n } catch {\n // ignore\n }\n\n return MemoryDestinationProvider;\n }\n\n return ConsoleDestinationProvider;\n };\n\n const getLogFormatterProvider = () => {\n if (logFormat) {\n if (logFormat === \"json\") {\n return JsonFormatterProvider;\n }\n if (logFormat === \"raw\") {\n return RawFormatterProvider;\n }\n return PrettyFormatterProvider;\n }\n\n if (alepha.isProduction() && !alepha.isBrowser()) {\n return JsonFormatterProvider;\n }\n\n return PrettyFormatterProvider;\n };\n\n alepha.with({\n optional: true,\n provide: LogDestinationProvider,\n use: getLogDestinationProvider(),\n });\n\n alepha.with({\n optional: true,\n provide: LogFormatterProvider,\n use: getLogFormatterProvider(),\n });\n\n alepha.store.set(\n \"alepha.logger\",\n alepha.inject(Logger, {\n lifetime: \"transient\",\n args: [\"Alepha\", \"alepha.core\"],\n }),\n );\n\n alepha.store.set(\n \"alepha.logger.level\",\n logLevel ?? (alepha.isTest() ? \"trace\" : \"info\"),\n );\n },\n});\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nconst envSchema = t.object({\n /**\n * Enable debug logging for specific modules using the `debug` package convention.\n *\n * @example\n * DEBUG=alepha:* # Enable debug logging for all alepha modules\n * DEBUG=alepha:orm:* # Enable debug logging for alepha.orm modules\n * DEBUG=* # Enable debug logging for all modules\n */\n DEBUG: t.optional(\n t.text({\n description:\n \"Enable debug logging for specific modules using the debug package convention. Example: DEBUG=alepha:*\",\n }),\n ),\n\n /**\n * Default log level for the application.\n *\n * Default by environment:\n * - dev = info\n * - prod = info\n * - test = error\n *\n * Levels are: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\"\n *\n * Level can be set for a specific module:\n *\n * @example\n * LOG_LEVEL=my.module.name:debug,info # Set debug level for my.module.name and info for all other modules\n * LOG_LEVEL=alepha:trace, info # Set trace level for all alepha modules and info for all other modules\n */\n LOG_LEVEL: t.optional(\n t.text({\n description: `Application log level on startup.\nLevels are: trace, debug, info, warn, error, silent\nLevel can be set for a specific module:\n\"my.module.name:debug,info\" -> Set debug level for my.module.name and info for all other modules\n\"alepha:trace,info\" -> Set trace level for all alepha modules and info for all other modules`,\n lowercase: true,\n }),\n ),\n\n /**\n * Built-in log formats.\n * - \"json\" - JSON format, useful for structured logging and log aggregation. {@link JsonFormatterProvider}\n * - \"pretty\" - Simple text format, human-readable, with colors. {@link PrettyFormatterProvider}\n * - \"raw\" - Raw format, no formatting, just the message. {@link RawFormatterProvider}\n */\n LOG_FORMAT: t.optional(\n t.enum([\"json\", \"pretty\", \"raw\"], {\n description: \"Default log format for the application.\",\n lowercase: true,\n }),\n ),\n});\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n export interface Env extends Partial<Static<typeof envSchema>> {}\n\n export interface State {\n /**\n * Current log level for the application or specific modules.\n */\n \"alepha.logger.level\"?: string;\n }\n\n export interface Hooks {\n log: {\n message?: string;\n entry: LogEntry;\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -656,6 +656,7 @@ const PG_VERSION = Symbol.for("Alepha.Postgres.Version");
|
|
|
656
656
|
const PG_IDENTITY = Symbol.for("Alepha.Postgres.Identity");
|
|
657
657
|
const PG_ENUM = Symbol.for("Alepha.Postgres.Enum");
|
|
658
658
|
const PG_REF = Symbol.for("Alepha.Postgres.Ref");
|
|
659
|
+
const PG_GENERATED = Symbol.for("Alepha.Postgres.Generated");
|
|
659
660
|
/**
|
|
660
661
|
* @deprecated Use `PG_IDENTITY` instead.
|
|
661
662
|
*/
|
|
@@ -678,6 +679,7 @@ const insertSchema = (obj) => {
|
|
|
678
679
|
const newProperties = {};
|
|
679
680
|
for (const key in obj.properties) {
|
|
680
681
|
const prop = obj.properties[key];
|
|
682
|
+
if (PG_GENERATED in prop) continue;
|
|
681
683
|
if (PG_DEFAULT in prop) newProperties[key] = t.optional(prop);
|
|
682
684
|
else newProperties[key] = prop;
|
|
683
685
|
}
|
|
@@ -690,6 +692,7 @@ const updateSchema = (schema) => {
|
|
|
690
692
|
const newProperties = {};
|
|
691
693
|
for (const key in schema.properties) {
|
|
692
694
|
const prop = schema.properties[key];
|
|
695
|
+
if (PG_GENERATED in prop) continue;
|
|
693
696
|
if (t.schema.isOptional(prop)) newProperties[key] = t.optional(t.union([prop, t.raw.Null()]));
|
|
694
697
|
else newProperties[key] = prop;
|
|
695
698
|
}
|
|
@@ -754,6 +757,59 @@ var EntityPrimitive = class EntityPrimitive {
|
|
|
754
757
|
};
|
|
755
758
|
$entity[KIND] = EntityPrimitive;
|
|
756
759
|
|
|
760
|
+
//#endregion
|
|
761
|
+
//#region ../../src/orm/core/primitives/$view.ts
|
|
762
|
+
/**
|
|
763
|
+
* Creates a database view primitive from a TypeBox schema and SQL query.
|
|
764
|
+
*
|
|
765
|
+
* Views are read-only: Repository blocks all write operations.
|
|
766
|
+
*
|
|
767
|
+
* @example
|
|
768
|
+
* ```ts
|
|
769
|
+
* import { t } from "alepha";
|
|
770
|
+
* import { $view } from "alepha/orm";
|
|
771
|
+
* import { sql } from "drizzle-orm";
|
|
772
|
+
*
|
|
773
|
+
* const userSummary = $view({
|
|
774
|
+
* name: "user_summary",
|
|
775
|
+
* schema: t.object({
|
|
776
|
+
* id: t.uuid(),
|
|
777
|
+
* fullName: t.text(),
|
|
778
|
+
* orderCount: t.integer(),
|
|
779
|
+
* }),
|
|
780
|
+
* query: sql`SELECT u.id, u.first_name || ' ' || u.last_name AS full_name, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id`,
|
|
781
|
+
* });
|
|
782
|
+
*
|
|
783
|
+
* // Materialized view (PostgreSQL only)
|
|
784
|
+
* const monthlyStats = $view({
|
|
785
|
+
* name: "monthly_stats",
|
|
786
|
+
* schema: t.object({ ... }),
|
|
787
|
+
* query: sql`...`,
|
|
788
|
+
* materialized: true,
|
|
789
|
+
* });
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
792
|
+
const $view = (options) => {
|
|
793
|
+
return new ViewPrimitive(options);
|
|
794
|
+
};
|
|
795
|
+
var ViewPrimitive = class {
|
|
796
|
+
options;
|
|
797
|
+
isView = true;
|
|
798
|
+
constructor(options) {
|
|
799
|
+
this.options = options;
|
|
800
|
+
}
|
|
801
|
+
get name() {
|
|
802
|
+
return this.options.name;
|
|
803
|
+
}
|
|
804
|
+
get schema() {
|
|
805
|
+
return this.options.schema;
|
|
806
|
+
}
|
|
807
|
+
get materialized() {
|
|
808
|
+
return this.options.materialized ?? false;
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
$view[KIND] = ViewPrimitive;
|
|
812
|
+
|
|
757
813
|
//#endregion
|
|
758
814
|
//#region ../../src/orm/core/providers/DatabaseTypeProvider.ts
|
|
759
815
|
var DatabaseTypeProvider = class {
|
|
@@ -880,5 +936,5 @@ const AlephaOrm = $module({
|
|
|
880
936
|
});
|
|
881
937
|
|
|
882
938
|
//#endregion
|
|
883
|
-
export { $entity, AlephaOrm, DatabaseTypeProvider, DbColumnNotFoundError, DbConnectionError, DbDeadlockError, DbEntityNotFoundError, DbForeignKeyError, DbNotNullError, DbTableNotFoundError, EntityPrimitive, buildQueryString, db, getAttrFields, legacyIdSchema, pageQuerySchema, pageSchema, parseQueryString, pgAttr };
|
|
939
|
+
export { $entity, $view, AlephaOrm, DatabaseTypeProvider, DbColumnNotFoundError, DbConnectionError, DbDeadlockError, DbEntityNotFoundError, DbForeignKeyError, DbNotNullError, DbTableNotFoundError, EntityPrimitive, ViewPrimitive, buildQueryString, db, getAttrFields, legacyIdSchema, pageQuerySchema, pageSchema, parseQueryString, pgAttr };
|
|
884
940
|
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":["pageSchema"],"sources":["../../../src/orm/core/errors/DbError.ts","../../../src/orm/core/errors/DbColumnNotFoundError.ts","../../../src/orm/core/errors/DbConnectionError.ts","../../../src/orm/core/errors/DbDeadlockError.ts","../../../src/orm/core/errors/DbEntityNotFoundError.ts","../../../src/orm/core/errors/DbForeignKeyError.ts","../../../src/orm/core/errors/DbNotNullError.ts","../../../src/orm/core/errors/DbTableNotFoundError.ts","../../../src/orm/core/helpers/parseQueryString.ts","../../../src/orm/core/helpers/pgAttr.ts","../../../src/orm/core/constants/PG_SYMBOLS.ts","../../../src/orm/core/types/schema.ts","../../../src/orm/core/schemas/insertSchema.ts","../../../src/orm/core/schemas/updateSchema.ts","../../../src/orm/core/primitives/$entity.ts","../../../src/orm/core/providers/DatabaseTypeProvider.ts","../../../src/orm/core/schemas/legacyIdSchema.ts","../../../src/orm/core/index.browser.ts"],"sourcesContent":["import { AlephaError } from \"alepha\";\n\nexport class DbError extends AlephaError {\n name = \"DbError\";\n\n constructor(message: string, cause?: unknown) {\n super(message, { cause });\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a column does not exist.\n *\n * This typically happens when:\n * - Column name is misspelled\n * - Migrations haven't been run\n * - Using wrong schema version\n */\nexport class DbColumnNotFoundError extends DbError {\n readonly name = \"DbColumnNotFoundError\";\n readonly status = 500;\n\n /**\n * The column that was not found.\n */\n readonly column?: string;\n\n /**\n * The table where the column was expected.\n */\n readonly table?: string;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: { column?: string; table?: string },\n ) {\n super(message, cause);\n this.column = options?.column;\n this.table = options?.table;\n }\n\n /**\n * Parse a database column not found error and create a DbColumnNotFoundError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error): DbColumnNotFoundError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'column \"foo\" does not exist'\n // 'column \"foo\" of relation \"users\" does not exist'\n const pgMatch = message.match(\n /column \"([^\"]+)\"(?: of relation \"([^\"]+)\")? does not exist/,\n );\n\n if (pgMatch) {\n const column = pgMatch[1];\n const table = pgMatch[2];\n const msg = table\n ? `Column '${column}' does not exist in table '${table}'`\n : `Column '${column}' does not exist`;\n return new DbColumnNotFoundError(msg, error, { column, table });\n }\n\n // SQLite format:\n // 'no such column: foo'\n // 'no such column: users.foo'\n const sqliteMatch = message.match(/no such column: (?:(\\S+)\\.)?(\\S+)/);\n\n if (sqliteMatch) {\n const table = sqliteMatch[1];\n const column = sqliteMatch[2];\n const msg = table\n ? `Column '${column}' does not exist in table '${table}'`\n : `Column '${column}' does not exist`;\n return new DbColumnNotFoundError(msg, error, { column, table });\n }\n\n return new DbColumnNotFoundError(\"Column does not exist\", error);\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a database connection fails.\n *\n * This can happen due to:\n * - Connection refused (server not running)\n * - Connection timeout\n * - Authentication failure\n * - Network issues\n * - Database file not found (SQLite)\n */\nexport class DbConnectionError extends DbError {\n readonly name = \"DbConnectionError\";\n readonly status = 503;\n\n /**\n * The type of connection error.\n */\n readonly errorType?:\n | \"refused\"\n | \"timeout\"\n | \"auth\"\n | \"not_found\"\n | \"locked\"\n | \"unknown\";\n\n /**\n * Whether this error is retryable.\n * Connection errors are often transient and can be retried.\n */\n readonly retryable: boolean;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: {\n errorType?: DbConnectionError[\"errorType\"];\n retryable?: boolean;\n },\n ) {\n super(message, cause);\n this.errorType = options?.errorType;\n this.retryable = options?.retryable ?? true;\n }\n\n /**\n * Parse a database connection error message and create a DbConnectionError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error): DbConnectionError {\n const message = error.message.toLowerCase();\n\n // Connection refused\n if (\n message.includes(\"connection refused\") ||\n message.includes(\"econnrefused\") ||\n message.includes(\"could not connect\")\n ) {\n return new DbConnectionError(\n \"Database connection refused. Is the server running?\",\n error,\n { errorType: \"refused\", retryable: true },\n );\n }\n\n // Timeout\n if (\n message.includes(\"timeout\") ||\n message.includes(\"timed out\") ||\n message.includes(\"etimedout\")\n ) {\n return new DbConnectionError(\"Database connection timed out\", error, {\n errorType: \"timeout\",\n retryable: true,\n });\n }\n\n // Authentication\n if (\n message.includes(\"password authentication failed\") ||\n message.includes(\"authentication failed\") ||\n message.includes(\"access denied\")\n ) {\n return new DbConnectionError(\n \"Database authentication failed. Check credentials.\",\n error,\n { errorType: \"auth\", retryable: false },\n );\n }\n\n // SQLite file not found\n if (\n message.includes(\"unable to open database\") ||\n message.includes(\"no such file\") ||\n message.includes(\"enoent\")\n ) {\n return new DbConnectionError(\"Database file not found\", error, {\n errorType: \"not_found\",\n retryable: false,\n });\n }\n\n // SQLite database locked\n if (message.includes(\"database is locked\")) {\n return new DbConnectionError(\n \"Database is locked by another process\",\n error,\n { errorType: \"locked\", retryable: true },\n );\n }\n\n return new DbConnectionError(\"Failed to connect to database\", error, {\n errorType: \"unknown\",\n retryable: true,\n });\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a deadlock is detected.\n *\n * This happens when two or more transactions are waiting for each other\n * to release locks. The database automatically aborts one transaction\n * to resolve the deadlock.\n *\n * This error is useful for implementing retry logic.\n */\nexport class DbDeadlockError extends DbError {\n readonly name = \"DbDeadlockError\";\n readonly status = 409;\n\n /**\n * Whether this error is retryable.\n * Deadlocks are typically safe to retry.\n */\n readonly retryable = true;\n\n /**\n * Parse a database deadlock error message and create a DbDeadlockError.\n * Supports PostgreSQL. SQLite doesn't have true deadlocks (uses SQLITE_BUSY instead).\n */\n static fromDatabaseError(error: Error): DbDeadlockError {\n return new DbDeadlockError(\n \"Transaction deadlock detected. Please retry the operation.\",\n error,\n );\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\nexport class DbEntityNotFoundError extends DbError {\n readonly name = \"DbEntityNotFoundError\";\n readonly status = 404;\n\n constructor(entityName: string) {\n super(`Entity from '${entityName}' was not found`);\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a foreign key constraint is violated.\n *\n * This typically happens when trying to delete an entity that is\n * referenced by another entity.\n */\nexport class DbForeignKeyError extends DbError {\n readonly name = \"DbForeignKeyError\";\n readonly status = 409;\n\n /**\n * The table that references the entity being deleted.\n */\n readonly referencingTable?: string;\n\n /**\n * The constraint name that was violated.\n */\n readonly constraintName?: string;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: { referencingTable?: string; constraintName?: string },\n ) {\n super(message, cause);\n this.referencingTable = options?.referencingTable;\n this.constraintName = options?.constraintName;\n }\n\n /**\n * Parse a database foreign key error message and create a DbForeignKeyError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error, tableName: string): DbForeignKeyError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'violates foreign key constraint \"reporting_alert_query_id_fk\" on table \"reporting_alert\"'\n const pgMatch = message.match(\n /violates foreign key constraint \"([^\"]+)\" on table \"([^\"]+)\"/,\n );\n\n if (pgMatch) {\n const constraintName = pgMatch[1];\n const referencingTable = pgMatch[2];\n\n return new DbForeignKeyError(\n `Cannot delete ${tableName}: it is referenced by ${referencingTable}`,\n error,\n { referencingTable, constraintName },\n );\n }\n\n // SQLite format:\n // 'FOREIGN KEY constraint failed' (no table name available)\n return new DbForeignKeyError(\n `Cannot delete ${tableName}: it is referenced by another entity`,\n error,\n );\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a NOT NULL constraint is violated.\n *\n * This happens when inserting or updating a NULL value into a column\n * that has a NOT NULL constraint.\n */\nexport class DbNotNullError extends DbError {\n readonly name = \"DbNotNullError\";\n readonly status = 400;\n\n /**\n * The column that violated the NOT NULL constraint.\n */\n readonly column?: string;\n\n /**\n * The table containing the column.\n */\n readonly table?: string;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: { column?: string; table?: string },\n ) {\n super(message, cause);\n this.column = options?.column;\n this.table = options?.table;\n }\n\n /**\n * Parse a database NOT NULL error message and create a DbNotNullError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error, tableName: string): DbNotNullError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'null value in column \"email\" of relation \"users\" violates not-null constraint'\n const pgMatch = message.match(\n /null value in column \"([^\"]+)\" of relation \"([^\"]+)\" violates not-null constraint/,\n );\n\n if (pgMatch) {\n const column = pgMatch[1];\n const table = pgMatch[2];\n return new DbNotNullError(\n `Column '${column}' in '${table}' cannot be null`,\n error,\n { column, table },\n );\n }\n\n // SQLite format:\n // 'NOT NULL constraint failed: users.email'\n const sqliteMatch = message.match(\n /NOT NULL constraint failed: ([^.]+)\\.(\\S+)/,\n );\n\n if (sqliteMatch) {\n const table = sqliteMatch[1];\n const column = sqliteMatch[2];\n return new DbNotNullError(\n `Column '${column}' in '${table}' cannot be null`,\n error,\n { column, table },\n );\n }\n\n return new DbNotNullError(\n `A required field in '${tableName}' cannot be null`,\n error,\n );\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a table does not exist.\n *\n * This typically happens when:\n * - Migrations haven't been run\n * - Table name is misspelled\n * - Wrong database/schema is being used\n */\nexport class DbTableNotFoundError extends DbError {\n readonly name = \"DbTableNotFoundError\";\n readonly status = 500;\n\n /**\n * The table that was not found.\n */\n readonly table?: string;\n\n constructor(message: string, cause?: unknown, options?: { table?: string }) {\n super(message, cause);\n this.table = options?.table;\n }\n\n /**\n * Parse a database table not found error and create a DbTableNotFoundError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error): DbTableNotFoundError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'relation \"users\" does not exist'\n const pgMatch = message.match(/relation \"([^\"]+)\" does not exist/);\n\n if (pgMatch) {\n const table = pgMatch[1];\n return new DbTableNotFoundError(\n `Table '${table}' does not exist. Have you run migrations?`,\n error,\n { table },\n );\n }\n\n // SQLite format:\n // 'no such table: users'\n const sqliteMatch = message.match(/no such table: (\\S+)/);\n\n if (sqliteMatch) {\n const table = sqliteMatch[1];\n return new DbTableNotFoundError(\n `Table '${table}' does not exist. Have you run migrations?`,\n error,\n { table },\n );\n }\n\n return new DbTableNotFoundError(\n \"Table does not exist. Have you run migrations?\",\n error,\n );\n }\n}\n","import { AlephaError, type TObject } from \"alepha\";\nimport type { PgQueryWhere } from \"../interfaces/PgQueryWhere.ts\";\n\n/**\n * Parse a string query into a PgQueryWhere object.\n *\n * Supported syntax:\n * - Simple equality: \"name=John\"\n * - Wildcard patterns: \"name=John*\" (startsWith), \"name=*John\" (endsWith), \"name=*John*\" (contains)\n * - Operators: \"age>18\", \"age>=18\", \"age<65\", \"age<=65\", \"status!=active\"\n * - NULL checks: \"deletedAt=null\", \"email!=null\"\n * - IN arrays: \"status=[pending,active]\"\n * - AND conditions: \"name=John&age>18\"\n * - OR conditions: \"name=John|email=john@example.com\"\n * - Nested AND/OR: \"(name=John|name=Jane)&age>18\"\n * - JSONB nested: \"profile.city=Paris\"\n *\n * @example\n * ```ts\n * // Simple equality\n * parseQueryString(\"name=John\")\n * // => { name: { eq: \"John\" } }\n *\n * // Wildcard patterns\n * parseQueryString(\"name=John*\") // startsWith\n * // => { name: { startsWith: \"John\" } }\n * parseQueryString(\"name=*Smith\") // endsWith\n * // => { name: { endsWith: \"Smith\" } }\n * parseQueryString(\"name=*oh*\") // contains\n * // => { name: { contains: \"oh\" } }\n *\n * // Multiple conditions\n * parseQueryString(\"name=John&age>18\")\n * // => { and: [{ name: { eq: \"John\" } }, { age: { gt: 18 } }] }\n *\n * // OR conditions\n * parseQueryString(\"status=active|status=pending\")\n * // => { or: [{ status: { eq: \"active\" } }, { status: { eq: \"pending\" } }] }\n *\n * // Complex nested\n * parseQueryString(\"(name=John|name=Jane)&age>18&status!=archived\")\n * // => { and: [\n * // { or: [{ name: { eq: \"John\" } }, { name: { eq: \"Jane\" } }] },\n * // { age: { gt: 18 } },\n * // { status: { ne: \"archived\" } }\n * // ] }\n *\n * // JSONB nested query\n * parseQueryString(\"profile.city=Paris&profile.age>25\")\n * // => { profile: { city: { eq: \"Paris\" }, age: { gt: 25 } } }\n * ```\n */\nexport function parseQueryString<T extends TObject>(\n query: string,\n): PgQueryWhere<T> {\n if (!query || query.trim() === \"\") {\n return {};\n }\n\n const parser = new QueryStringParser(query);\n return parser.parse() as PgQueryWhere<T>;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nclass QueryStringParser {\n private pos = 0;\n private readonly query: string;\n\n constructor(query: string) {\n this.query = query.trim();\n }\n\n parse(): PgQueryWhere<any> {\n return this.parseExpression();\n }\n\n private parseExpression(): PgQueryWhere<any> {\n return this.parseOr();\n }\n\n private parseOr(): any {\n const left = this.parseAnd();\n\n // Check for OR operator (|)\n if (this.peek() === \"|\") {\n const conditions = [left];\n\n while (this.peek() === \"|\") {\n this.consume(\"|\");\n conditions.push(this.parseAnd());\n }\n\n return { or: conditions };\n }\n\n return left;\n }\n\n private parseAnd(): any {\n const left = this.parsePrimary();\n\n // Check for AND operator (&)\n if (this.peek() === \"&\") {\n const conditions = [left];\n\n while (this.peek() === \"&\") {\n this.consume(\"&\");\n conditions.push(this.parsePrimary());\n }\n\n return { and: conditions };\n }\n\n return left;\n }\n\n private parsePrimary(): any {\n this.skipWhitespace();\n\n // Handle parentheses\n if (this.peek() === \"(\") {\n this.consume(\"(\");\n const expr = this.parseExpression();\n this.consume(\")\");\n return expr;\n }\n\n // Parse field condition\n return this.parseCondition();\n }\n\n private parseCondition(): any {\n const field = this.parseFieldPath();\n this.skipWhitespace();\n\n // Get operator\n const operator = this.parseOperator();\n this.skipWhitespace();\n\n // Get value\n const value = this.parseValue();\n\n if (value === \"\") {\n throw new AlephaError(`Expected value for field '${field.join(\".\")}'`);\n }\n\n // Build the condition object\n return this.buildCondition(field, operator, value);\n }\n\n private parseFieldPath(): string[] {\n const path: string[] = [];\n let current = \"\";\n\n while (this.pos < this.query.length) {\n const ch = this.query[this.pos];\n\n if (ch === \".\" && current) {\n path.push(current);\n current = \"\";\n this.pos++;\n continue;\n }\n\n if (ch === \"=\" || ch === \"!\" || ch === \">\" || ch === \"<\" || ch === \" \") {\n break;\n }\n\n current += ch;\n this.pos++;\n }\n\n if (current) {\n path.push(current);\n }\n\n return path;\n }\n\n private parseOperator(): string {\n this.skipWhitespace();\n\n const remaining = this.query.slice(this.pos);\n\n // Two-character operators\n if (remaining.startsWith(\">=\")) {\n this.pos += 2;\n return \">=\";\n }\n if (remaining.startsWith(\"<=\")) {\n this.pos += 2;\n return \"<=\";\n }\n if (remaining.startsWith(\"!=\")) {\n this.pos += 2;\n return \"!=\";\n }\n\n // Single-character operators\n const ch = this.query[this.pos];\n if (ch === \"=\" || ch === \">\" || ch === \"<\") {\n this.pos++;\n return ch;\n }\n\n throw new Error(`Expected operator at position ${this.pos}`);\n }\n\n private parseValue(): any {\n this.skipWhitespace();\n\n // Handle null\n if (this.query.slice(this.pos, this.pos + 4).toLowerCase() === \"null\") {\n this.pos += 4;\n return null;\n }\n\n // Handle arrays [value1,value2,...]\n if (this.query[this.pos] === \"[\") {\n return this.parseArray();\n }\n\n // Handle quoted strings\n if (this.query[this.pos] === '\"' || this.query[this.pos] === \"'\") {\n return this.parseQuotedString();\n }\n\n // Parse unquoted value (until &, |, or ))\n let value = \"\";\n while (this.pos < this.query.length) {\n const ch = this.query[this.pos];\n if (ch === \"&\" || ch === \"|\" || ch === \")\") {\n break;\n }\n value += ch;\n this.pos++;\n }\n\n return this.coerceValue(value.trim());\n }\n\n private parseArray(): any[] {\n this.consume(\"[\");\n const values: any[] = [];\n\n while (this.pos < this.query.length && this.query[this.pos] !== \"]\") {\n this.skipWhitespace();\n\n // Handle quoted values\n if (this.query[this.pos] === '\"' || this.query[this.pos] === \"'\") {\n values.push(this.parseQuotedString());\n } else {\n // Parse until comma or ]\n let value = \"\";\n while (\n this.pos < this.query.length &&\n this.query[this.pos] !== \",\" &&\n this.query[this.pos] !== \"]\"\n ) {\n value += this.query[this.pos];\n this.pos++;\n }\n values.push(this.coerceValue(value.trim()));\n }\n\n this.skipWhitespace();\n if (this.query[this.pos] === \",\") {\n this.pos++;\n }\n }\n\n this.consume(\"]\");\n return values;\n }\n\n private parseQuotedString(): string {\n const quote = this.query[this.pos];\n this.pos++; // Skip opening quote\n\n let value = \"\";\n let escaped = false;\n\n while (this.pos < this.query.length) {\n const ch = this.query[this.pos];\n\n if (escaped) {\n value += ch;\n escaped = false;\n this.pos++;\n continue;\n }\n\n if (ch === \"\\\\\") {\n escaped = true;\n this.pos++;\n continue;\n }\n\n if (ch === quote) {\n this.pos++; // Skip closing quote\n break;\n }\n\n value += ch;\n this.pos++;\n }\n\n return value;\n }\n\n private coerceValue(value: string): any {\n // Try to parse as number\n if (/^-?\\d+$/.test(value)) {\n return parseInt(value, 10);\n }\n\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return parseFloat(value);\n }\n\n // Try to parse as boolean\n if (value.toLowerCase() === \"true\") {\n return true;\n }\n if (value.toLowerCase() === \"false\") {\n return false;\n }\n\n return value;\n }\n\n private buildCondition(path: string[], operator: string, value: any): any {\n // Map operator to filter operator\n let filterOp: any;\n\n if (operator === \"=\") {\n if (value === null) {\n filterOp = { isNull: true };\n } else if (Array.isArray(value)) {\n // Arrays should be treated as inArray regardless of content\n filterOp = { inArray: value };\n } else if (typeof value === \"string\" && value.includes(\"*\")) {\n // Handle wildcard patterns\n const startsWithAsterisk = value.startsWith(\"*\");\n const endsWithAsterisk = value.endsWith(\"*\");\n const cleanValue = value.replace(/^\\*|\\*$/g, \"\"); // Remove leading/trailing asterisks\n\n if (startsWithAsterisk && endsWithAsterisk) {\n // *text* -> contains\n filterOp = { contains: cleanValue };\n } else if (startsWithAsterisk) {\n // *text -> endsWith\n filterOp = { endsWith: cleanValue };\n } else if (endsWithAsterisk) {\n // text* -> startsWith\n filterOp = { startsWith: cleanValue };\n } else {\n // Has asterisk in the middle, treat as literal\n filterOp = { eq: value };\n }\n } else {\n filterOp = { eq: value };\n }\n } else if (operator === \"!=\") {\n if (value === null) {\n filterOp = { isNotNull: true };\n } else {\n filterOp = { ne: value };\n }\n } else if (operator === \">\") {\n filterOp = { gt: value };\n } else if (operator === \">=\") {\n filterOp = { gte: value };\n } else if (operator === \"<\") {\n filterOp = { lt: value };\n } else if (operator === \"<=\") {\n filterOp = { lte: value };\n } else {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n // Build nested object for path\n if (path.length === 1) {\n return { [path[0]]: filterOp };\n }\n\n // Handle nested paths (JSONB)\n let result: any = filterOp;\n for (let i = path.length - 1; i >= 0; i--) {\n result = { [path[i]]: result };\n }\n\n return result;\n }\n\n private peek(): string {\n this.skipWhitespace();\n return this.query[this.pos] || \"\";\n }\n\n private consume(expected: string): void {\n this.skipWhitespace();\n if (this.query[this.pos] !== expected) {\n throw new Error(\n `Expected '${expected}' at position ${this.pos}, got '${this.query[this.pos]}'`,\n );\n }\n this.pos++;\n }\n\n private skipWhitespace(): void {\n while (this.pos < this.query.length && /\\s/.test(this.query[this.pos])) {\n this.pos++;\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Helper function to build query strings programmatically\n *\n * @example\n * ```ts\n * buildQueryString({\n * and: [\n * { name: \"eq:John\" },\n * { age: \"gt:18\" }\n * ]\n * })\n * // => \"name=John&age>18\"\n * ```\n */\nexport function buildQueryString(where: any): string {\n if (!where || typeof where !== \"object\") {\n return \"\";\n }\n\n // Handle logical operators\n if (\"and\" in where && Array.isArray(where.and)) {\n return where.and.map((w: any) => buildQueryString(w)).join(\"&\");\n }\n\n if (\"or\" in where && Array.isArray(where.or)) {\n const parts = where.or.map((w: any) => buildQueryString(w));\n return parts.length > 1 ? `(${parts.join(\"|\")})` : parts[0];\n }\n\n if (\"not\" in where) {\n // Not operator is harder to represent in string form\n // For now, we'll skip it or you could add a syntax like \"!field=value\"\n return \"\";\n }\n\n // Handle field conditions\n const parts: string[] = [];\n\n for (const [field, condition] of Object.entries(where)) {\n if (typeof condition !== \"object\" || condition === null) {\n parts.push(`${field}=${condition}`);\n continue;\n }\n\n if (\"eq\" in condition) {\n parts.push(`${field}=${condition.eq}`);\n } else if (\"ne\" in condition) {\n parts.push(`${field}!=${condition.ne}`);\n } else if (\"gt\" in condition) {\n parts.push(`${field}>${condition.gt}`);\n } else if (\"gte\" in condition) {\n parts.push(`${field}>=${condition.gte}`);\n } else if (\"lt\" in condition) {\n parts.push(`${field}<${condition.lt}`);\n } else if (\"lte\" in condition) {\n parts.push(`${field}<=${condition.lte}`);\n } else if (\"contains\" in condition) {\n parts.push(`${field}=*${condition.contains}*`);\n } else if (\"startsWith\" in condition) {\n parts.push(`${field}=${condition.startsWith}*`);\n } else if (\"endsWith\" in condition) {\n parts.push(`${field}=*${condition.endsWith}`);\n } else if (\"isNull\" in condition && condition.isNull) {\n parts.push(`${field}=null`);\n } else if (\"isNotNull\" in condition && condition.isNotNull) {\n parts.push(`${field}!=null`);\n } else if (\"inArray\" in condition && Array.isArray(condition.inArray)) {\n const values = condition.inArray.map((v: any) =>\n typeof v === \"string\" ? `\"${v}\"` : v,\n );\n parts.push(`${field}=[${values.join(\",\")}]`);\n } else {\n // Nested object (JSONB)\n const nested = buildQueryString(condition);\n if (nested) {\n parts.push(`${field}.${nested}`);\n }\n }\n }\n\n return parts.join(\"&\");\n}\n","import type { TObject, TSchema } from \"alepha\";\nimport type { PgSymbolKeys, PgSymbols } from \"../constants/PG_SYMBOLS.ts\";\n\n/**\n * Decorates a typebox schema with a Postgres attribute.\n *\n * > It's just a fancy way to add Symbols to a field.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { PG_UPDATED_AT } from \"../constants/PG_SYMBOLS\";\n *\n * export const updatedAtSchema = pgAttr(\n * t.datetime(), PG_UPDATED_AT,\n * );\n * ```\n */\nexport const pgAttr = <T extends TSchema, Attr extends PgSymbolKeys>(\n type: T,\n attr: Attr,\n value?: PgSymbols[Attr],\n): PgAttr<T, Attr> => {\n Object.assign(type, { [attr]: value ?? {} });\n return type as PgAttr<T, Attr>;\n};\n\n/**\n * Retrieves the fields of a schema that have a specific attribute.\n */\nexport const getAttrFields = (\n schema: TObject,\n name: PgSymbolKeys,\n): PgAttrField[] => {\n const fields: Array<PgAttrField> = [];\n\n for (const key of Object.keys(schema.properties)) {\n const value = schema.properties[key];\n if (name in value) {\n fields.push({\n type: value as TSchema,\n key: key,\n data: (value as any)[name],\n });\n }\n }\n\n return fields;\n};\n\n/**\n * Type representation.\n */\nexport type PgAttr<T extends TSchema, TAttr extends PgSymbolKeys> = T & {\n [K in TAttr]: PgSymbols[K];\n};\n\nexport interface PgAttrField {\n key: string;\n type: TSchema;\n data: any;\n nested?: any[];\n one?: boolean;\n}\n","import type {\n PgSequenceOptions,\n UpdateDeleteAction,\n} from \"drizzle-orm/pg-core\";\nimport type { EntityPrimitive } from \"../primitives/$entity.ts\";\n\nexport const PG_DEFAULT = Symbol.for(\"Alepha.Postgres.Default\");\nexport const PG_PRIMARY_KEY = Symbol.for(\"Alepha.Postgres.PrimaryKey\");\nexport const PG_CREATED_AT = Symbol.for(\"Alepha.Postgres.CreatedAt\");\nexport const PG_UPDATED_AT = Symbol.for(\"Alepha.Postgres.UpdatedAt\");\nexport const PG_DELETED_AT = Symbol.for(\"Alepha.Postgres.DeletedAt\");\nexport const PG_VERSION = Symbol.for(\"Alepha.Postgres.Version\");\nexport const PG_IDENTITY = Symbol.for(\"Alepha.Postgres.Identity\");\nexport const PG_ENUM = Symbol.for(\"Alepha.Postgres.Enum\");\nexport const PG_REF = Symbol.for(\"Alepha.Postgres.Ref\");\n\n/**\n * @deprecated Use `PG_IDENTITY` instead.\n */\nexport const PG_SERIAL = Symbol.for(\"Alepha.Postgres.Serial\");\n\nexport type PgDefault = typeof PG_DEFAULT;\nexport type PgRef = typeof PG_REF;\nexport type PgPrimaryKey = typeof PG_PRIMARY_KEY;\n\nexport type PgSymbols = {\n [PG_DEFAULT]: {};\n [PG_PRIMARY_KEY]: {};\n [PG_CREATED_AT]: {};\n [PG_UPDATED_AT]: {};\n [PG_DELETED_AT]: {};\n [PG_VERSION]: {};\n [PG_IDENTITY]: PgIdentityOptions;\n [PG_REF]: PgRefOptions;\n [PG_ENUM]: PgEnumOptions;\n\n /**\n * @deprecated Use `PG_IDENTITY` instead.\n */\n [PG_SERIAL]: {};\n};\n\nexport type PgSymbolKeys = keyof PgSymbols;\n\nexport type PgIdentityOptions = {\n mode: \"always\" | \"byDefault\";\n} & PgSequenceOptions & {\n name?: string;\n };\n\nexport interface PgEnumOptions {\n name?: string;\n description?: string;\n}\n\nexport interface PgRefOptions {\n ref: () => {\n name: string;\n entity: EntityPrimitive;\n };\n actions?: {\n onUpdate?: UpdateDeleteAction;\n onDelete?: UpdateDeleteAction;\n };\n}\n","import type { Static, TSchema } from \"alepha\";\nimport { customType } from \"drizzle-orm/pg-core\";\n\n/**\n * Postgres schema type.\n */\nexport const schema = <TDocument extends TSchema>(\n name: string,\n document: TDocument,\n) =>\n customType<{\n data: Static<TDocument>;\n driverData: string;\n config: { document: TDocument };\n configRequired: true;\n }>({\n dataType: () => \"jsonb\",\n toDriver: (value) => JSON.stringify(value),\n fromDriver: (value: TDocument | string) =>\n value && typeof value === \"string\" ? JSON.parse(value) : value,\n })(name, { document }).$type<Static<TDocument>>();\n","import type { TObject, TOptional } from \"alepha\";\nimport { t } from \"alepha\";\nimport { PG_DEFAULT } from \"../constants/PG_SYMBOLS.ts\";\nimport { schema } from \"../types/schema.ts\";\n\n/**\n * Transforms a TObject schema for insert operations.\n * All default properties at the root level are made optional.\n *\n * @example\n * Before: { name: string; age: number(default=0); }\n * After: { name: string; age?: number; }\n */\nexport type TObjectInsert<T extends TObject> = TObject<{\n [K in keyof T[\"properties\"]]: T[\"properties\"][K] extends\n | { [PG_DEFAULT]: any }\n | { \"~optional\": true }\n ? TOptional<T[\"properties\"][K]>\n : T[\"properties\"][K];\n}>;\n\nexport const insertSchema = <T extends TObject>(obj: T): TObjectInsert<T> => {\n const newProperties: Record<string, any> = {};\n\n for (const key in obj.properties) {\n const prop = obj.properties[key];\n\n if (PG_DEFAULT in prop) {\n newProperties[key] = t.optional(prop);\n } else {\n newProperties[key] = prop;\n }\n }\n\n return t.object(\n newProperties,\n \"options\" in schema && typeof schema.options === \"object\"\n ? { ...schema.options }\n : {},\n ) as TObjectInsert<T>;\n};\n","import {\n type TNull,\n type TObject,\n type TOptional,\n type TUnion,\n t,\n} from \"alepha\";\n\n/**\n * Transforms a TObject schema for update operations.\n * All optional properties at the root level are made nullable (i.e., `T | null`).\n * This allows an API endpoint to explicitly accept `null` to clear an optional field in the database.\n *\n * @example\n * Before: { name?: string; age: number; }\n * After: { name?: string | null; age: number; }\n */\nexport type TObjectUpdate<T extends TObject> = TObject<{\n [K in keyof T[\"properties\"]]: T[\"properties\"][K] extends TOptional<infer U>\n ? TOptional<TUnion<[U, TNull]>>\n : T[\"properties\"][K];\n}>;\n\nexport const updateSchema = <T extends TObject>(\n schema: T,\n): TObjectUpdate<T> => {\n const newProperties: Record<string, any> = {};\n\n for (const key in schema.properties) {\n const prop = schema.properties[key];\n if (t.schema.isOptional(prop)) {\n newProperties[key] = t.optional(t.union([prop, t.raw.Null()]));\n } else {\n newProperties[key] = prop;\n }\n }\n\n return t.object(\n newProperties,\n \"options\" in schema && typeof schema.options === \"object\"\n ? { ...schema.options }\n : {},\n ) as TObjectUpdate<T>;\n};\n","import { KIND, type Static, type TObject } from \"alepha\";\nimport type { BuildExtraConfigColumns, SQL } from \"drizzle-orm\";\nimport type {\n PgColumn,\n PgColumnBuilderBase,\n PgTableExtraConfigValue,\n} from \"drizzle-orm/pg-core\";\nimport { insertSchema, type TObjectInsert } from \"../schemas/insertSchema.ts\";\nimport { type TObjectUpdate, updateSchema } from \"../schemas/updateSchema.ts\";\n\n/**\n * Creates a database entity primitive that defines table structure using TypeBox schemas.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { $entity } from \"alepha/orm\";\n *\n * const userEntity = $entity({\n * name: \"users\",\n * schema: t.object({\n * id: pg.primaryKey(),\n * name: t.text(),\n * email: t.email(),\n * }),\n * });\n * ```\n */\nexport const $entity = <TSchema extends TObject>(\n options: EntityPrimitiveOptions<TSchema>,\n): EntityPrimitive<TSchema> => {\n return new EntityPrimitive<TSchema>(options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface EntityPrimitiveOptions<\n T extends TObject,\n Keys = keyof Static<T>,\n> {\n /**\n * The database table name that will be created for this entity.\n * If not provided, name will be inferred from the $repository variable name.\n */\n name: string;\n\n /**\n * TypeBox schema defining the table structure and column types.\n */\n schema: T;\n\n /**\n * Database indexes to create for query optimization.\n */\n indexes?: (\n | Keys\n | {\n /**\n * Single column to index.\n */\n column: Keys;\n /**\n * Whether this should be a unique index (enforces uniqueness constraint).\n */\n unique?: boolean;\n /**\n * Custom name for the index. If not provided, generates name automatically.\n */\n name?: string;\n }\n | {\n /**\n * Multiple columns for composite index (order matters for query optimization).\n */\n columns: Keys[];\n /**\n * Whether this should be a unique index (enforces uniqueness constraint).\n */\n unique?: boolean;\n /**\n * Custom name for the index. If not provided, generates name automatically.\n */\n name?: string;\n }\n )[];\n\n /**\n * Foreign key constraints to maintain referential integrity.\n */\n foreignKeys?: Array<{\n /**\n * Optional name for the foreign key constraint.\n */\n name?: string;\n /**\n * Local columns that reference the foreign table.\n */\n columns: Array<keyof Static<T>>;\n /**\n * Referenced columns in the foreign table.\n * Must be EntityColumn references from other entities.\n */\n foreignColumns: Array<() => EntityColumn<any>>;\n }>;\n\n /**\n * Additional table constraints for data validation.\n *\n * Constraints enforce business rules at the database level, providing\n * an additional layer of data integrity beyond application validation.\n *\n * **Constraint Types**:\n * - **Unique constraints**: Prevent duplicate values across columns\n * - **Check constraints**: Enforce custom validation rules with SQL expressions\n *\n * @example\n * ```ts\n * constraints: [\n * {\n * name: \"unique_user_email\",\n * columns: [\"email\"],\n * unique: true\n * },\n * {\n * name: \"valid_age_range\",\n * columns: [\"age\"],\n * check: sql`age >= 0 AND age <= 150`\n * },\n * {\n * name: \"unique_user_username_per_tenant\",\n * columns: [\"tenantId\", \"username\"],\n * unique: true\n * }\n * ]\n * ```\n */\n constraints?: Array<{\n /**\n * Columns involved in this constraint.\n */\n columns: Array<keyof Static<T>>;\n /**\n * Optional name for the constraint.\n */\n name?: string;\n /**\n * Whether this is a unique constraint.\n */\n unique?: boolean | {} /* options */;\n /**\n * SQL expression for check constraint validation.\n */\n check?: SQL;\n }>;\n\n /**\n * Advanced Drizzle ORM configuration for complex table setups.\n */\n config?: (\n self: BuildExtraConfigColumns<string, FromSchema<T>, \"pg\">,\n ) => PgTableExtraConfigValue[];\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class EntityPrimitive<T extends TObject = TObject> {\n public readonly options: EntityPrimitiveOptions<T>;\n\n constructor(options: EntityPrimitiveOptions<T>) {\n this.options = options;\n }\n\n alias(alias: string): this {\n const aliased = new EntityPrimitive<T>(this.options);\n return new Proxy(aliased, {\n get(target, prop, receiver) {\n if (prop === \"$alias\") {\n return alias;\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as this;\n }\n\n get cols(): EntityColumns<T> {\n const cols: Partial<EntityColumns<T>> = {};\n for (const key of Object.keys(this.schema.properties) as Array<\n keyof T[\"properties\"]\n >) {\n cols[key] = {\n name: key as string,\n entity: this,\n };\n }\n\n return cols as EntityColumns<T>;\n }\n\n get name(): string {\n return this.options.name;\n }\n\n get schema(): T {\n return this.options.schema;\n }\n\n get insertSchema(): TObjectInsert<T> {\n return insertSchema(this.options.schema);\n }\n\n get updateSchema(): TObjectUpdate<T> {\n return updateSchema(this.options.schema);\n }\n}\n\n$entity[KIND] = EntityPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Convert a schema to columns.\n */\nexport type FromSchema<T extends TObject> = {\n [key in keyof T[\"properties\"]]: PgColumnBuilderBase;\n};\n\nexport type SchemaToTableConfig<T extends TObject> = {\n name: string;\n schema: string | undefined;\n columns: {\n [key in keyof T[\"properties\"]]: PgColumn;\n };\n dialect: string;\n};\n\nexport type EntityColumn<T extends TObject> = {\n name: string;\n entity: EntityPrimitive<T>;\n};\n\nexport type EntityColumns<T extends TObject> = {\n [key in keyof T[\"properties\"]]: EntityColumn<T>;\n};\n","import {\n AlephaError,\n pageSchema,\n type Static,\n type TBigInt,\n type TInteger,\n type TNumber,\n type TNumberOptions,\n type TObject,\n type TObjectOptions,\n type TPage,\n type TSchema,\n type TString,\n type TStringOptions,\n type TUnsafe,\n t,\n} from \"alepha\";\nimport type { UpdateDeleteAction } from \"drizzle-orm/pg-core/foreign-keys\";\nimport {\n PG_CREATED_AT,\n PG_DEFAULT,\n PG_DELETED_AT,\n PG_ENUM,\n PG_IDENTITY,\n PG_PRIMARY_KEY,\n PG_REF,\n PG_UPDATED_AT,\n PG_VERSION,\n type PgDefault,\n type PgEnumOptions,\n type PgIdentityOptions,\n type PgPrimaryKey,\n type PgRef,\n} from \"../constants/PG_SYMBOLS.ts\";\nimport type { PgAttr } from \"../helpers/pgAttr.ts\";\nimport { pgAttr } from \"../helpers/pgAttr.ts\";\n\nexport class DatabaseTypeProvider {\n public readonly attr = pgAttr;\n\n /**\n * Creates a primary key with an identity column.\n */\n public readonly identityPrimaryKey = (\n identity?: PgIdentityOptions,\n options?: TNumberOptions,\n ) =>\n pgAttr(\n pgAttr(pgAttr(t.integer(options), PG_PRIMARY_KEY), PG_IDENTITY, identity),\n PG_DEFAULT,\n );\n\n /**\n * Creates a primary key with a big identity column. (default)\n */\n public readonly bigIdentityPrimaryKey = (\n identity?: PgIdentityOptions,\n options?: TNumberOptions,\n ) =>\n pgAttr(\n pgAttr(pgAttr(t.int64(options), PG_PRIMARY_KEY), PG_IDENTITY, identity),\n PG_DEFAULT,\n );\n\n /**\n * Creates a primary key with a UUID column.\n */\n public readonly uuidPrimaryKey = () =>\n pgAttr(pgAttr(t.uuid(), PG_PRIMARY_KEY), PG_DEFAULT);\n\n /**\n * Creates a primary key for a given type. Supports:\n * - `t.integer()` -> PG INT (default)\n * - `t.bigint()` -> PG BIGINT\n * - `t.uuid()` -> PG UUID\n */\n public primaryKey(): PgAttr<PgAttr<TInteger, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TString,\n options?: TStringOptions,\n ): PgAttr<PgAttr<TString, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TInteger,\n options?: TNumberOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TInteger, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TNumber,\n options?: TNumberOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TNumber, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TBigInt,\n options?: TNumberOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TBigInt, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type?: TSchema,\n options?: TNumberOptions | TStringOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TSchema, PgPrimaryKey>, PgDefault> {\n if (!type || t.schema.isInteger(type)) {\n return pgAttr(\n pgAttr(\n pgAttr(t.integer(options), PG_PRIMARY_KEY),\n PG_IDENTITY,\n identity,\n ),\n PG_DEFAULT,\n );\n }\n\n if (t.schema.isString(type) && type.format === \"uuid\") {\n return pgAttr(pgAttr(t.uuid(), PG_PRIMARY_KEY), PG_DEFAULT);\n }\n\n if (t.schema.isNumber(type) && type.format === \"int64\") {\n return pgAttr(\n pgAttr(\n pgAttr(t.number(options), PG_PRIMARY_KEY),\n PG_IDENTITY,\n identity,\n ),\n PG_DEFAULT,\n );\n }\n\n if (t.schema.isBigInt(type)) {\n return pgAttr(\n pgAttr(\n pgAttr(t.bigint(options), PG_PRIMARY_KEY),\n PG_IDENTITY,\n identity,\n ),\n PG_DEFAULT,\n );\n }\n\n throw new AlephaError(`Unsupported type for primary key: ${type}`);\n }\n\n /**\n * Wrap a schema with \"default\" attribute.\n * This is used to set a default value for a column in the database.\n */\n public readonly default = <T extends TSchema>(\n type: T,\n value?: Static<T>,\n ): PgAttr<T, PgDefault> => {\n if (value != null) {\n Object.assign(type, { default: value });\n }\n\n return this.attr(type, PG_DEFAULT);\n };\n\n /**\n * Creates a column 'version'.\n *\n * This is used to track the version of a row in the database.\n *\n * You can use it for optimistic concurrency control (OCC) with {@link RepositoryPrimitive#save}.\n *\n * @see {@link RepositoryPrimitive#save}\n * @see {@link PgVersionMismatchError}\n */\n public readonly version = (options: TNumberOptions = {}) =>\n this.default(pgAttr(t.integer(options), PG_VERSION), 0);\n\n /**\n * Creates a column Created At. So just a datetime column with a default value of the current timestamp.\n */\n public readonly createdAt = (options?: TStringOptions) =>\n pgAttr(pgAttr(t.datetime(options), PG_CREATED_AT), PG_DEFAULT);\n\n /**\n * Creates a column Updated At. Like createdAt, but it is updated on every update of the row.\n */\n public readonly updatedAt = (options?: TStringOptions) =>\n pgAttr(pgAttr(t.datetime(options), PG_UPDATED_AT), PG_DEFAULT);\n\n /**\n * Creates a column Deleted At for soft delete functionality.\n * This is used to mark rows as deleted without actually removing them from the database.\n * The column is nullable - NULL means not deleted, timestamp means deleted.\n */\n public readonly deletedAt = (options?: TStringOptions) =>\n pgAttr(t.optional(t.datetime(options)), PG_DELETED_AT);\n\n /**\n * Creates a Postgres ENUM type.\n *\n * > By default, `t.enum()` is mapped to a TEXT column in Postgres.\n * > Using this method, you can create a real ENUM type in the database.\n *\n * @example\n * ```ts\n * const statusEnum = pg.enum([\"pending\", \"active\", \"archived\"], { name: \"status_enum\" });\n * ```\n */\n public readonly enum = <T extends string[]>(\n values: [...T],\n pgEnumOptions?: PgEnumOptions,\n typeOptions?: TStringOptions,\n ): PgAttr<TUnsafe<T[number]>, typeof PG_ENUM> => {\n return pgAttr(\n t.enum(values, {\n description: pgEnumOptions?.description,\n ...typeOptions,\n }),\n PG_ENUM,\n pgEnumOptions,\n );\n };\n\n /**\n * Creates a reference to another table or schema. Basically a foreign key.\n */\n public readonly ref = <T extends TSchema>(\n type: T,\n ref: () => any,\n actions?: {\n onUpdate?: UpdateDeleteAction;\n onDelete?: UpdateDeleteAction;\n },\n ): PgAttr<T, PgRef> => {\n // If actions are not provided, set default onDelete based on type\n const finalActions = actions ?? {\n onDelete: t.schema.isOptional(type) ? \"set null\" : \"cascade\",\n };\n\n return this.attr(type, PG_REF, {\n ref,\n actions: finalActions,\n });\n };\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Creates a page schema for a given object schema.\n * It's used by {@link Repository#paginate} method.\n */\n public readonly page = <T extends TObject>(\n resource: T,\n options?: TObjectOptions,\n ): TPage<T> => {\n return pageSchema(resource, options);\n };\n}\n\n/**\n * Wrapper of TypeProvider (`t`) for database types.\n *\n * Use `db` for improve TypeBox schema definitions with database-specific attributes.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { db } from \"alepha/orm\";\n *\n * const userSchema = t.object({\n * id: db.primaryKey(t.uuid()),\n * email: t.email(),\n * createdAt: db.createdAt(),\n * });\n * ```\n */\nexport const db = new DatabaseTypeProvider();\n","import { t } from \"alepha\";\nimport {\n PG_DEFAULT,\n PG_PRIMARY_KEY,\n PG_SERIAL,\n} from \"../constants/PG_SYMBOLS.ts\";\nimport { pgAttr } from \"../helpers/pgAttr.ts\";\n\n/**\n * @deprecated Use `pg.primaryKey()` instead.\n */\nexport const legacyIdSchema = pgAttr(\n pgAttr(pgAttr(t.integer(), PG_PRIMARY_KEY), PG_SERIAL),\n PG_DEFAULT,\n);\n","import { $module } from \"alepha\";\nimport { AlephaDateTime } from \"alepha/datetime\";\n\nexport * from \"./index.shared.ts\";\n\nexport const AlephaOrm = $module({\n name: \"alepha.orm\",\n primitives: [],\n services: [AlephaDateTime],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.browser.js","names":["pageSchema"],"sources":["../../../src/orm/core/errors/DbError.ts","../../../src/orm/core/errors/DbColumnNotFoundError.ts","../../../src/orm/core/errors/DbConnectionError.ts","../../../src/orm/core/errors/DbDeadlockError.ts","../../../src/orm/core/errors/DbEntityNotFoundError.ts","../../../src/orm/core/errors/DbForeignKeyError.ts","../../../src/orm/core/errors/DbNotNullError.ts","../../../src/orm/core/errors/DbTableNotFoundError.ts","../../../src/orm/core/helpers/parseQueryString.ts","../../../src/orm/core/helpers/pgAttr.ts","../../../src/orm/core/constants/PG_SYMBOLS.ts","../../../src/orm/core/types/schema.ts","../../../src/orm/core/schemas/insertSchema.ts","../../../src/orm/core/schemas/updateSchema.ts","../../../src/orm/core/primitives/$entity.ts","../../../src/orm/core/primitives/$view.ts","../../../src/orm/core/providers/DatabaseTypeProvider.ts","../../../src/orm/core/schemas/legacyIdSchema.ts","../../../src/orm/core/index.browser.ts"],"sourcesContent":["import { AlephaError } from \"alepha\";\n\nexport class DbError extends AlephaError {\n name = \"DbError\";\n\n constructor(message: string, cause?: unknown) {\n super(message, { cause });\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a column does not exist.\n *\n * This typically happens when:\n * - Column name is misspelled\n * - Migrations haven't been run\n * - Using wrong schema version\n */\nexport class DbColumnNotFoundError extends DbError {\n readonly name = \"DbColumnNotFoundError\";\n readonly status = 500;\n\n /**\n * The column that was not found.\n */\n readonly column?: string;\n\n /**\n * The table where the column was expected.\n */\n readonly table?: string;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: { column?: string; table?: string },\n ) {\n super(message, cause);\n this.column = options?.column;\n this.table = options?.table;\n }\n\n /**\n * Parse a database column not found error and create a DbColumnNotFoundError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error): DbColumnNotFoundError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'column \"foo\" does not exist'\n // 'column \"foo\" of relation \"users\" does not exist'\n const pgMatch = message.match(\n /column \"([^\"]+)\"(?: of relation \"([^\"]+)\")? does not exist/,\n );\n\n if (pgMatch) {\n const column = pgMatch[1];\n const table = pgMatch[2];\n const msg = table\n ? `Column '${column}' does not exist in table '${table}'`\n : `Column '${column}' does not exist`;\n return new DbColumnNotFoundError(msg, error, { column, table });\n }\n\n // SQLite format:\n // 'no such column: foo'\n // 'no such column: users.foo'\n const sqliteMatch = message.match(/no such column: (?:(\\S+)\\.)?(\\S+)/);\n\n if (sqliteMatch) {\n const table = sqliteMatch[1];\n const column = sqliteMatch[2];\n const msg = table\n ? `Column '${column}' does not exist in table '${table}'`\n : `Column '${column}' does not exist`;\n return new DbColumnNotFoundError(msg, error, { column, table });\n }\n\n return new DbColumnNotFoundError(\"Column does not exist\", error);\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a database connection fails.\n *\n * This can happen due to:\n * - Connection refused (server not running)\n * - Connection timeout\n * - Authentication failure\n * - Network issues\n * - Database file not found (SQLite)\n */\nexport class DbConnectionError extends DbError {\n readonly name = \"DbConnectionError\";\n readonly status = 503;\n\n /**\n * The type of connection error.\n */\n readonly errorType?:\n | \"refused\"\n | \"timeout\"\n | \"auth\"\n | \"not_found\"\n | \"locked\"\n | \"unknown\";\n\n /**\n * Whether this error is retryable.\n * Connection errors are often transient and can be retried.\n */\n readonly retryable: boolean;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: {\n errorType?: DbConnectionError[\"errorType\"];\n retryable?: boolean;\n },\n ) {\n super(message, cause);\n this.errorType = options?.errorType;\n this.retryable = options?.retryable ?? true;\n }\n\n /**\n * Parse a database connection error message and create a DbConnectionError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error): DbConnectionError {\n const message = error.message.toLowerCase();\n\n // Connection refused\n if (\n message.includes(\"connection refused\") ||\n message.includes(\"econnrefused\") ||\n message.includes(\"could not connect\")\n ) {\n return new DbConnectionError(\n \"Database connection refused. Is the server running?\",\n error,\n { errorType: \"refused\", retryable: true },\n );\n }\n\n // Timeout\n if (\n message.includes(\"timeout\") ||\n message.includes(\"timed out\") ||\n message.includes(\"etimedout\")\n ) {\n return new DbConnectionError(\"Database connection timed out\", error, {\n errorType: \"timeout\",\n retryable: true,\n });\n }\n\n // Authentication\n if (\n message.includes(\"password authentication failed\") ||\n message.includes(\"authentication failed\") ||\n message.includes(\"access denied\")\n ) {\n return new DbConnectionError(\n \"Database authentication failed. Check credentials.\",\n error,\n { errorType: \"auth\", retryable: false },\n );\n }\n\n // SQLite file not found\n if (\n message.includes(\"unable to open database\") ||\n message.includes(\"no such file\") ||\n message.includes(\"enoent\")\n ) {\n return new DbConnectionError(\"Database file not found\", error, {\n errorType: \"not_found\",\n retryable: false,\n });\n }\n\n // SQLite database locked\n if (message.includes(\"database is locked\")) {\n return new DbConnectionError(\n \"Database is locked by another process\",\n error,\n { errorType: \"locked\", retryable: true },\n );\n }\n\n return new DbConnectionError(\"Failed to connect to database\", error, {\n errorType: \"unknown\",\n retryable: true,\n });\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a deadlock is detected.\n *\n * This happens when two or more transactions are waiting for each other\n * to release locks. The database automatically aborts one transaction\n * to resolve the deadlock.\n *\n * This error is useful for implementing retry logic.\n */\nexport class DbDeadlockError extends DbError {\n readonly name = \"DbDeadlockError\";\n readonly status = 409;\n\n /**\n * Whether this error is retryable.\n * Deadlocks are typically safe to retry.\n */\n readonly retryable = true;\n\n /**\n * Parse a database deadlock error message and create a DbDeadlockError.\n * Supports PostgreSQL. SQLite doesn't have true deadlocks (uses SQLITE_BUSY instead).\n */\n static fromDatabaseError(error: Error): DbDeadlockError {\n return new DbDeadlockError(\n \"Transaction deadlock detected. Please retry the operation.\",\n error,\n );\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\nexport class DbEntityNotFoundError extends DbError {\n readonly name = \"DbEntityNotFoundError\";\n readonly status = 404;\n\n constructor(entityName: string) {\n super(`Entity from '${entityName}' was not found`);\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a foreign key constraint is violated.\n *\n * This typically happens when trying to delete an entity that is\n * referenced by another entity.\n */\nexport class DbForeignKeyError extends DbError {\n readonly name = \"DbForeignKeyError\";\n readonly status = 409;\n\n /**\n * The table that references the entity being deleted.\n */\n readonly referencingTable?: string;\n\n /**\n * The constraint name that was violated.\n */\n readonly constraintName?: string;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: { referencingTable?: string; constraintName?: string },\n ) {\n super(message, cause);\n this.referencingTable = options?.referencingTable;\n this.constraintName = options?.constraintName;\n }\n\n /**\n * Parse a database foreign key error message and create a DbForeignKeyError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error, tableName: string): DbForeignKeyError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'violates foreign key constraint \"reporting_alert_query_id_fk\" on table \"reporting_alert\"'\n const pgMatch = message.match(\n /violates foreign key constraint \"([^\"]+)\" on table \"([^\"]+)\"/,\n );\n\n if (pgMatch) {\n const constraintName = pgMatch[1];\n const referencingTable = pgMatch[2];\n\n return new DbForeignKeyError(\n `Cannot delete ${tableName}: it is referenced by ${referencingTable}`,\n error,\n { referencingTable, constraintName },\n );\n }\n\n // SQLite format:\n // 'FOREIGN KEY constraint failed' (no table name available)\n return new DbForeignKeyError(\n `Cannot delete ${tableName}: it is referenced by another entity`,\n error,\n );\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a NOT NULL constraint is violated.\n *\n * This happens when inserting or updating a NULL value into a column\n * that has a NOT NULL constraint.\n */\nexport class DbNotNullError extends DbError {\n readonly name = \"DbNotNullError\";\n readonly status = 400;\n\n /**\n * The column that violated the NOT NULL constraint.\n */\n readonly column?: string;\n\n /**\n * The table containing the column.\n */\n readonly table?: string;\n\n constructor(\n message: string,\n cause?: unknown,\n options?: { column?: string; table?: string },\n ) {\n super(message, cause);\n this.column = options?.column;\n this.table = options?.table;\n }\n\n /**\n * Parse a database NOT NULL error message and create a DbNotNullError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error, tableName: string): DbNotNullError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'null value in column \"email\" of relation \"users\" violates not-null constraint'\n const pgMatch = message.match(\n /null value in column \"([^\"]+)\" of relation \"([^\"]+)\" violates not-null constraint/,\n );\n\n if (pgMatch) {\n const column = pgMatch[1];\n const table = pgMatch[2];\n return new DbNotNullError(\n `Column '${column}' in '${table}' cannot be null`,\n error,\n { column, table },\n );\n }\n\n // SQLite format:\n // 'NOT NULL constraint failed: users.email'\n const sqliteMatch = message.match(\n /NOT NULL constraint failed: ([^.]+)\\.(\\S+)/,\n );\n\n if (sqliteMatch) {\n const table = sqliteMatch[1];\n const column = sqliteMatch[2];\n return new DbNotNullError(\n `Column '${column}' in '${table}' cannot be null`,\n error,\n { column, table },\n );\n }\n\n return new DbNotNullError(\n `A required field in '${tableName}' cannot be null`,\n error,\n );\n }\n}\n","import { DbError } from \"./DbError.ts\";\n\n/**\n * Error thrown when a table does not exist.\n *\n * This typically happens when:\n * - Migrations haven't been run\n * - Table name is misspelled\n * - Wrong database/schema is being used\n */\nexport class DbTableNotFoundError extends DbError {\n readonly name = \"DbTableNotFoundError\";\n readonly status = 500;\n\n /**\n * The table that was not found.\n */\n readonly table?: string;\n\n constructor(message: string, cause?: unknown, options?: { table?: string }) {\n super(message, cause);\n this.table = options?.table;\n }\n\n /**\n * Parse a database table not found error and create a DbTableNotFoundError.\n * Supports both PostgreSQL and SQLite error formats.\n */\n static fromDatabaseError(error: Error): DbTableNotFoundError {\n const message = error.message;\n\n // PostgreSQL format:\n // 'relation \"users\" does not exist'\n const pgMatch = message.match(/relation \"([^\"]+)\" does not exist/);\n\n if (pgMatch) {\n const table = pgMatch[1];\n return new DbTableNotFoundError(\n `Table '${table}' does not exist. Have you run migrations?`,\n error,\n { table },\n );\n }\n\n // SQLite format:\n // 'no such table: users'\n const sqliteMatch = message.match(/no such table: (\\S+)/);\n\n if (sqliteMatch) {\n const table = sqliteMatch[1];\n return new DbTableNotFoundError(\n `Table '${table}' does not exist. Have you run migrations?`,\n error,\n { table },\n );\n }\n\n return new DbTableNotFoundError(\n \"Table does not exist. Have you run migrations?\",\n error,\n );\n }\n}\n","import { AlephaError, type TObject } from \"alepha\";\nimport type { PgQueryWhere } from \"../interfaces/PgQueryWhere.ts\";\n\n/**\n * Parse a string query into a PgQueryWhere object.\n *\n * Supported syntax:\n * - Simple equality: \"name=John\"\n * - Wildcard patterns: \"name=John*\" (startsWith), \"name=*John\" (endsWith), \"name=*John*\" (contains)\n * - Operators: \"age>18\", \"age>=18\", \"age<65\", \"age<=65\", \"status!=active\"\n * - NULL checks: \"deletedAt=null\", \"email!=null\"\n * - IN arrays: \"status=[pending,active]\"\n * - AND conditions: \"name=John&age>18\"\n * - OR conditions: \"name=John|email=john@example.com\"\n * - Nested AND/OR: \"(name=John|name=Jane)&age>18\"\n * - JSONB nested: \"profile.city=Paris\"\n *\n * @example\n * ```ts\n * // Simple equality\n * parseQueryString(\"name=John\")\n * // => { name: { eq: \"John\" } }\n *\n * // Wildcard patterns\n * parseQueryString(\"name=John*\") // startsWith\n * // => { name: { startsWith: \"John\" } }\n * parseQueryString(\"name=*Smith\") // endsWith\n * // => { name: { endsWith: \"Smith\" } }\n * parseQueryString(\"name=*oh*\") // contains\n * // => { name: { contains: \"oh\" } }\n *\n * // Multiple conditions\n * parseQueryString(\"name=John&age>18\")\n * // => { and: [{ name: { eq: \"John\" } }, { age: { gt: 18 } }] }\n *\n * // OR conditions\n * parseQueryString(\"status=active|status=pending\")\n * // => { or: [{ status: { eq: \"active\" } }, { status: { eq: \"pending\" } }] }\n *\n * // Complex nested\n * parseQueryString(\"(name=John|name=Jane)&age>18&status!=archived\")\n * // => { and: [\n * // { or: [{ name: { eq: \"John\" } }, { name: { eq: \"Jane\" } }] },\n * // { age: { gt: 18 } },\n * // { status: { ne: \"archived\" } }\n * // ] }\n *\n * // JSONB nested query\n * parseQueryString(\"profile.city=Paris&profile.age>25\")\n * // => { profile: { city: { eq: \"Paris\" }, age: { gt: 25 } } }\n * ```\n */\nexport function parseQueryString<T extends TObject>(\n query: string,\n): PgQueryWhere<T> {\n if (!query || query.trim() === \"\") {\n return {};\n }\n\n const parser = new QueryStringParser(query);\n return parser.parse() as PgQueryWhere<T>;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nclass QueryStringParser {\n private pos = 0;\n private readonly query: string;\n\n constructor(query: string) {\n this.query = query.trim();\n }\n\n parse(): PgQueryWhere<any> {\n return this.parseExpression();\n }\n\n private parseExpression(): PgQueryWhere<any> {\n return this.parseOr();\n }\n\n private parseOr(): any {\n const left = this.parseAnd();\n\n // Check for OR operator (|)\n if (this.peek() === \"|\") {\n const conditions = [left];\n\n while (this.peek() === \"|\") {\n this.consume(\"|\");\n conditions.push(this.parseAnd());\n }\n\n return { or: conditions };\n }\n\n return left;\n }\n\n private parseAnd(): any {\n const left = this.parsePrimary();\n\n // Check for AND operator (&)\n if (this.peek() === \"&\") {\n const conditions = [left];\n\n while (this.peek() === \"&\") {\n this.consume(\"&\");\n conditions.push(this.parsePrimary());\n }\n\n return { and: conditions };\n }\n\n return left;\n }\n\n private parsePrimary(): any {\n this.skipWhitespace();\n\n // Handle parentheses\n if (this.peek() === \"(\") {\n this.consume(\"(\");\n const expr = this.parseExpression();\n this.consume(\")\");\n return expr;\n }\n\n // Parse field condition\n return this.parseCondition();\n }\n\n private parseCondition(): any {\n const field = this.parseFieldPath();\n this.skipWhitespace();\n\n // Get operator\n const operator = this.parseOperator();\n this.skipWhitespace();\n\n // Get value\n const value = this.parseValue();\n\n if (value === \"\") {\n throw new AlephaError(`Expected value for field '${field.join(\".\")}'`);\n }\n\n // Build the condition object\n return this.buildCondition(field, operator, value);\n }\n\n private parseFieldPath(): string[] {\n const path: string[] = [];\n let current = \"\";\n\n while (this.pos < this.query.length) {\n const ch = this.query[this.pos];\n\n if (ch === \".\" && current) {\n path.push(current);\n current = \"\";\n this.pos++;\n continue;\n }\n\n if (ch === \"=\" || ch === \"!\" || ch === \">\" || ch === \"<\" || ch === \" \") {\n break;\n }\n\n current += ch;\n this.pos++;\n }\n\n if (current) {\n path.push(current);\n }\n\n return path;\n }\n\n private parseOperator(): string {\n this.skipWhitespace();\n\n const remaining = this.query.slice(this.pos);\n\n // Two-character operators\n if (remaining.startsWith(\">=\")) {\n this.pos += 2;\n return \">=\";\n }\n if (remaining.startsWith(\"<=\")) {\n this.pos += 2;\n return \"<=\";\n }\n if (remaining.startsWith(\"!=\")) {\n this.pos += 2;\n return \"!=\";\n }\n\n // Single-character operators\n const ch = this.query[this.pos];\n if (ch === \"=\" || ch === \">\" || ch === \"<\") {\n this.pos++;\n return ch;\n }\n\n throw new Error(`Expected operator at position ${this.pos}`);\n }\n\n private parseValue(): any {\n this.skipWhitespace();\n\n // Handle null\n if (this.query.slice(this.pos, this.pos + 4).toLowerCase() === \"null\") {\n this.pos += 4;\n return null;\n }\n\n // Handle arrays [value1,value2,...]\n if (this.query[this.pos] === \"[\") {\n return this.parseArray();\n }\n\n // Handle quoted strings\n if (this.query[this.pos] === '\"' || this.query[this.pos] === \"'\") {\n return this.parseQuotedString();\n }\n\n // Parse unquoted value (until &, |, or ))\n let value = \"\";\n while (this.pos < this.query.length) {\n const ch = this.query[this.pos];\n if (ch === \"&\" || ch === \"|\" || ch === \")\") {\n break;\n }\n value += ch;\n this.pos++;\n }\n\n return this.coerceValue(value.trim());\n }\n\n private parseArray(): any[] {\n this.consume(\"[\");\n const values: any[] = [];\n\n while (this.pos < this.query.length && this.query[this.pos] !== \"]\") {\n this.skipWhitespace();\n\n // Handle quoted values\n if (this.query[this.pos] === '\"' || this.query[this.pos] === \"'\") {\n values.push(this.parseQuotedString());\n } else {\n // Parse until comma or ]\n let value = \"\";\n while (\n this.pos < this.query.length &&\n this.query[this.pos] !== \",\" &&\n this.query[this.pos] !== \"]\"\n ) {\n value += this.query[this.pos];\n this.pos++;\n }\n values.push(this.coerceValue(value.trim()));\n }\n\n this.skipWhitespace();\n if (this.query[this.pos] === \",\") {\n this.pos++;\n }\n }\n\n this.consume(\"]\");\n return values;\n }\n\n private parseQuotedString(): string {\n const quote = this.query[this.pos];\n this.pos++; // Skip opening quote\n\n let value = \"\";\n let escaped = false;\n\n while (this.pos < this.query.length) {\n const ch = this.query[this.pos];\n\n if (escaped) {\n value += ch;\n escaped = false;\n this.pos++;\n continue;\n }\n\n if (ch === \"\\\\\") {\n escaped = true;\n this.pos++;\n continue;\n }\n\n if (ch === quote) {\n this.pos++; // Skip closing quote\n break;\n }\n\n value += ch;\n this.pos++;\n }\n\n return value;\n }\n\n private coerceValue(value: string): any {\n // Try to parse as number\n if (/^-?\\d+$/.test(value)) {\n return parseInt(value, 10);\n }\n\n if (/^-?\\d+\\.\\d+$/.test(value)) {\n return parseFloat(value);\n }\n\n // Try to parse as boolean\n if (value.toLowerCase() === \"true\") {\n return true;\n }\n if (value.toLowerCase() === \"false\") {\n return false;\n }\n\n return value;\n }\n\n private buildCondition(path: string[], operator: string, value: any): any {\n // Map operator to filter operator\n let filterOp: any;\n\n if (operator === \"=\") {\n if (value === null) {\n filterOp = { isNull: true };\n } else if (Array.isArray(value)) {\n // Arrays should be treated as inArray regardless of content\n filterOp = { inArray: value };\n } else if (typeof value === \"string\" && value.includes(\"*\")) {\n // Handle wildcard patterns\n const startsWithAsterisk = value.startsWith(\"*\");\n const endsWithAsterisk = value.endsWith(\"*\");\n const cleanValue = value.replace(/^\\*|\\*$/g, \"\"); // Remove leading/trailing asterisks\n\n if (startsWithAsterisk && endsWithAsterisk) {\n // *text* -> contains\n filterOp = { contains: cleanValue };\n } else if (startsWithAsterisk) {\n // *text -> endsWith\n filterOp = { endsWith: cleanValue };\n } else if (endsWithAsterisk) {\n // text* -> startsWith\n filterOp = { startsWith: cleanValue };\n } else {\n // Has asterisk in the middle, treat as literal\n filterOp = { eq: value };\n }\n } else {\n filterOp = { eq: value };\n }\n } else if (operator === \"!=\") {\n if (value === null) {\n filterOp = { isNotNull: true };\n } else {\n filterOp = { ne: value };\n }\n } else if (operator === \">\") {\n filterOp = { gt: value };\n } else if (operator === \">=\") {\n filterOp = { gte: value };\n } else if (operator === \"<\") {\n filterOp = { lt: value };\n } else if (operator === \"<=\") {\n filterOp = { lte: value };\n } else {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n // Build nested object for path\n if (path.length === 1) {\n return { [path[0]]: filterOp };\n }\n\n // Handle nested paths (JSONB)\n let result: any = filterOp;\n for (let i = path.length - 1; i >= 0; i--) {\n result = { [path[i]]: result };\n }\n\n return result;\n }\n\n private peek(): string {\n this.skipWhitespace();\n return this.query[this.pos] || \"\";\n }\n\n private consume(expected: string): void {\n this.skipWhitespace();\n if (this.query[this.pos] !== expected) {\n throw new Error(\n `Expected '${expected}' at position ${this.pos}, got '${this.query[this.pos]}'`,\n );\n }\n this.pos++;\n }\n\n private skipWhitespace(): void {\n while (this.pos < this.query.length && /\\s/.test(this.query[this.pos])) {\n this.pos++;\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Helper function to build query strings programmatically\n *\n * @example\n * ```ts\n * buildQueryString({\n * and: [\n * { name: \"eq:John\" },\n * { age: \"gt:18\" }\n * ]\n * })\n * // => \"name=John&age>18\"\n * ```\n */\nexport function buildQueryString(where: any): string {\n if (!where || typeof where !== \"object\") {\n return \"\";\n }\n\n // Handle logical operators\n if (\"and\" in where && Array.isArray(where.and)) {\n return where.and.map((w: any) => buildQueryString(w)).join(\"&\");\n }\n\n if (\"or\" in where && Array.isArray(where.or)) {\n const parts = where.or.map((w: any) => buildQueryString(w));\n return parts.length > 1 ? `(${parts.join(\"|\")})` : parts[0];\n }\n\n if (\"not\" in where) {\n // Not operator is harder to represent in string form\n // For now, we'll skip it or you could add a syntax like \"!field=value\"\n return \"\";\n }\n\n // Handle field conditions\n const parts: string[] = [];\n\n for (const [field, condition] of Object.entries(where)) {\n if (typeof condition !== \"object\" || condition === null) {\n parts.push(`${field}=${condition}`);\n continue;\n }\n\n if (\"eq\" in condition) {\n parts.push(`${field}=${condition.eq}`);\n } else if (\"ne\" in condition) {\n parts.push(`${field}!=${condition.ne}`);\n } else if (\"gt\" in condition) {\n parts.push(`${field}>${condition.gt}`);\n } else if (\"gte\" in condition) {\n parts.push(`${field}>=${condition.gte}`);\n } else if (\"lt\" in condition) {\n parts.push(`${field}<${condition.lt}`);\n } else if (\"lte\" in condition) {\n parts.push(`${field}<=${condition.lte}`);\n } else if (\"contains\" in condition) {\n parts.push(`${field}=*${condition.contains}*`);\n } else if (\"startsWith\" in condition) {\n parts.push(`${field}=${condition.startsWith}*`);\n } else if (\"endsWith\" in condition) {\n parts.push(`${field}=*${condition.endsWith}`);\n } else if (\"isNull\" in condition && condition.isNull) {\n parts.push(`${field}=null`);\n } else if (\"isNotNull\" in condition && condition.isNotNull) {\n parts.push(`${field}!=null`);\n } else if (\"inArray\" in condition && Array.isArray(condition.inArray)) {\n const values = condition.inArray.map((v: any) =>\n typeof v === \"string\" ? `\"${v}\"` : v,\n );\n parts.push(`${field}=[${values.join(\",\")}]`);\n } else {\n // Nested object (JSONB)\n const nested = buildQueryString(condition);\n if (nested) {\n parts.push(`${field}.${nested}`);\n }\n }\n }\n\n return parts.join(\"&\");\n}\n","import type { TObject, TSchema } from \"alepha\";\nimport type { PgSymbolKeys, PgSymbols } from \"../constants/PG_SYMBOLS.ts\";\n\n/**\n * Decorates a typebox schema with a Postgres attribute.\n *\n * > It's just a fancy way to add Symbols to a field.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { PG_UPDATED_AT } from \"../constants/PG_SYMBOLS\";\n *\n * export const updatedAtSchema = pgAttr(\n * t.datetime(), PG_UPDATED_AT,\n * );\n * ```\n */\nexport const pgAttr = <T extends TSchema, Attr extends PgSymbolKeys>(\n type: T,\n attr: Attr,\n value?: PgSymbols[Attr],\n): PgAttr<T, Attr> => {\n Object.assign(type, { [attr]: value ?? {} });\n return type as PgAttr<T, Attr>;\n};\n\n/**\n * Retrieves the fields of a schema that have a specific attribute.\n */\nexport const getAttrFields = (\n schema: TObject,\n name: PgSymbolKeys,\n): PgAttrField[] => {\n const fields: Array<PgAttrField> = [];\n\n for (const key of Object.keys(schema.properties)) {\n const value = schema.properties[key];\n if (name in value) {\n fields.push({\n type: value as TSchema,\n key: key,\n data: (value as any)[name],\n });\n }\n }\n\n return fields;\n};\n\n/**\n * Type representation.\n */\nexport type PgAttr<T extends TSchema, TAttr extends PgSymbolKeys> = T & {\n [K in TAttr]: PgSymbols[K];\n};\n\nexport interface PgAttrField {\n key: string;\n type: TSchema;\n data: any;\n nested?: any[];\n one?: boolean;\n}\n","import type { SQL } from \"drizzle-orm\";\nimport type {\n PgSequenceOptions,\n UpdateDeleteAction,\n} from \"drizzle-orm/pg-core\";\nimport type { EntityPrimitive } from \"../primitives/$entity.ts\";\n\nexport const PG_DEFAULT = Symbol.for(\"Alepha.Postgres.Default\");\nexport const PG_PRIMARY_KEY = Symbol.for(\"Alepha.Postgres.PrimaryKey\");\nexport const PG_CREATED_AT = Symbol.for(\"Alepha.Postgres.CreatedAt\");\nexport const PG_UPDATED_AT = Symbol.for(\"Alepha.Postgres.UpdatedAt\");\nexport const PG_DELETED_AT = Symbol.for(\"Alepha.Postgres.DeletedAt\");\nexport const PG_VERSION = Symbol.for(\"Alepha.Postgres.Version\");\nexport const PG_IDENTITY = Symbol.for(\"Alepha.Postgres.Identity\");\nexport const PG_ENUM = Symbol.for(\"Alepha.Postgres.Enum\");\nexport const PG_REF = Symbol.for(\"Alepha.Postgres.Ref\");\nexport const PG_GENERATED = Symbol.for(\"Alepha.Postgres.Generated\");\n\n/**\n * @deprecated Use `PG_IDENTITY` instead.\n */\nexport const PG_SERIAL = Symbol.for(\"Alepha.Postgres.Serial\");\n\nexport type PgDefault = typeof PG_DEFAULT;\nexport type PgRef = typeof PG_REF;\nexport type PgPrimaryKey = typeof PG_PRIMARY_KEY;\n\nexport type PgSymbols = {\n [PG_DEFAULT]: {};\n [PG_PRIMARY_KEY]: {};\n [PG_CREATED_AT]: {};\n [PG_UPDATED_AT]: {};\n [PG_DELETED_AT]: {};\n [PG_VERSION]: {};\n [PG_IDENTITY]: PgIdentityOptions;\n [PG_REF]: PgRefOptions;\n [PG_ENUM]: PgEnumOptions;\n [PG_GENERATED]: PgGeneratedOptions;\n\n /**\n * @deprecated Use `PG_IDENTITY` instead.\n */\n [PG_SERIAL]: {};\n};\n\nexport type PgSymbolKeys = keyof PgSymbols;\n\nexport type PgIdentityOptions = {\n mode: \"always\" | \"byDefault\";\n} & PgSequenceOptions & {\n name?: string;\n };\n\nexport interface PgEnumOptions {\n name?: string;\n description?: string;\n}\n\nexport interface PgGeneratedOptions {\n /**\n * SQL expression for the generated column.\n */\n expression: SQL;\n\n /**\n * Storage mode for the generated column.\n * - `\"stored\"` — value is computed on write and stored on disk (default for PostgreSQL).\n * - `\"virtual\"` — value is computed on read (default for SQLite).\n */\n mode?: \"stored\" | \"virtual\";\n}\n\nexport interface PgRefOptions {\n ref: () => {\n name: string;\n entity: EntityPrimitive;\n };\n actions?: {\n onUpdate?: UpdateDeleteAction;\n onDelete?: UpdateDeleteAction;\n };\n}\n","import type { Static, TSchema } from \"alepha\";\nimport { customType } from \"drizzle-orm/pg-core\";\n\n/**\n * Postgres schema type.\n */\nexport const schema = <TDocument extends TSchema>(\n name: string,\n document: TDocument,\n) =>\n customType<{\n data: Static<TDocument>;\n driverData: string;\n config: { document: TDocument };\n configRequired: true;\n }>({\n dataType: () => \"jsonb\",\n toDriver: (value) => JSON.stringify(value),\n fromDriver: (value: TDocument | string) =>\n value && typeof value === \"string\" ? JSON.parse(value) : value,\n })(name, { document }).$type<Static<TDocument>>();\n","import type { TObject, TOptional } from \"alepha\";\nimport { t } from \"alepha\";\nimport { PG_DEFAULT, PG_GENERATED } from \"../constants/PG_SYMBOLS.ts\";\nimport { schema } from \"../types/schema.ts\";\n\n/**\n * Transforms a TObject schema for insert operations.\n * All default properties at the root level are made optional.\n * Generated columns are excluded entirely.\n *\n * @example\n * Before: { name: string; age: number(default=0); fullName: generated }\n * After: { name: string; age?: number; }\n */\nexport type TObjectInsert<T extends TObject> = TObject<{\n [K in keyof T[\"properties\"] as T[\"properties\"][K] extends {\n [PG_GENERATED]: any;\n }\n ? never\n : K]: T[\"properties\"][K] extends\n | { [PG_DEFAULT]: any }\n | { \"~optional\": true }\n ? TOptional<T[\"properties\"][K]>\n : T[\"properties\"][K];\n}>;\n\nexport const insertSchema = <T extends TObject>(obj: T): TObjectInsert<T> => {\n const newProperties: Record<string, any> = {};\n\n for (const key in obj.properties) {\n const prop = obj.properties[key];\n\n // Skip generated columns — they are computed by the database\n if (PG_GENERATED in prop) {\n continue;\n }\n\n if (PG_DEFAULT in prop) {\n newProperties[key] = t.optional(prop);\n } else {\n newProperties[key] = prop;\n }\n }\n\n return t.object(\n newProperties,\n \"options\" in schema && typeof schema.options === \"object\"\n ? { ...schema.options }\n : {},\n ) as TObjectInsert<T>;\n};\n","import {\n type TNull,\n type TObject,\n type TOptional,\n type TUnion,\n t,\n} from \"alepha\";\nimport { PG_GENERATED } from \"../constants/PG_SYMBOLS.ts\";\n\n/**\n * Transforms a TObject schema for update operations.\n * All optional properties at the root level are made nullable (i.e., `T | null`).\n * Generated columns are excluded entirely.\n *\n * @example\n * Before: { name?: string; age: number; fullName: generated }\n * After: { name?: string | null; age: number; }\n */\nexport type TObjectUpdate<T extends TObject> = TObject<{\n [K in keyof T[\"properties\"] as T[\"properties\"][K] extends {\n [PG_GENERATED]: any;\n }\n ? never\n : K]: T[\"properties\"][K] extends TOptional<infer U>\n ? TOptional<TUnion<[U, TNull]>>\n : T[\"properties\"][K];\n}>;\n\nexport const updateSchema = <T extends TObject>(\n schema: T,\n): TObjectUpdate<T> => {\n const newProperties: Record<string, any> = {};\n\n for (const key in schema.properties) {\n const prop = schema.properties[key];\n\n // Skip generated columns — they are computed by the database\n if (PG_GENERATED in prop) {\n continue;\n }\n\n if (t.schema.isOptional(prop)) {\n newProperties[key] = t.optional(t.union([prop, t.raw.Null()]));\n } else {\n newProperties[key] = prop;\n }\n }\n\n return t.object(\n newProperties,\n \"options\" in schema && typeof schema.options === \"object\"\n ? { ...schema.options }\n : {},\n ) as TObjectUpdate<T>;\n};\n","import { KIND, type Static, type TObject } from \"alepha\";\nimport type { BuildExtraConfigColumns, SQL } from \"drizzle-orm\";\nimport type {\n PgColumn,\n PgColumnBuilderBase,\n PgTableExtraConfigValue,\n} from \"drizzle-orm/pg-core\";\nimport { insertSchema, type TObjectInsert } from \"../schemas/insertSchema.ts\";\nimport { type TObjectUpdate, updateSchema } from \"../schemas/updateSchema.ts\";\n\n/**\n * Creates a database entity primitive that defines table structure using TypeBox schemas.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { $entity } from \"alepha/orm\";\n *\n * const userEntity = $entity({\n * name: \"users\",\n * schema: t.object({\n * id: pg.primaryKey(),\n * name: t.text(),\n * email: t.email(),\n * }),\n * });\n * ```\n */\nexport const $entity = <TSchema extends TObject>(\n options: EntityPrimitiveOptions<TSchema>,\n): EntityPrimitive<TSchema> => {\n return new EntityPrimitive<TSchema>(options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface EntityPrimitiveOptions<\n T extends TObject,\n Keys = keyof Static<T>,\n> {\n /**\n * The database table name that will be created for this entity.\n * If not provided, name will be inferred from the $repository variable name.\n */\n name: string;\n\n /**\n * TypeBox schema defining the table structure and column types.\n */\n schema: T;\n\n /**\n * Database indexes to create for query optimization.\n */\n indexes?: (\n | Keys\n | {\n /**\n * Single column to index.\n */\n column: Keys;\n /**\n * Whether this should be a unique index (enforces uniqueness constraint).\n */\n unique?: boolean;\n /**\n * Custom name for the index. If not provided, generates name automatically.\n */\n name?: string;\n /**\n * Partial index condition. Only rows matching this SQL expression are indexed.\n */\n where?: SQL;\n }\n | {\n /**\n * Multiple columns for composite index (order matters for query optimization).\n */\n columns: Keys[];\n /**\n * Whether this should be a unique index (enforces uniqueness constraint).\n */\n unique?: boolean;\n /**\n * Custom name for the index. If not provided, generates name automatically.\n */\n name?: string;\n /**\n * Partial index condition. Only rows matching this SQL expression are indexed.\n */\n where?: SQL;\n }\n )[];\n\n /**\n * Foreign key constraints to maintain referential integrity.\n */\n foreignKeys?: Array<{\n /**\n * Optional name for the foreign key constraint.\n */\n name?: string;\n /**\n * Local columns that reference the foreign table.\n */\n columns: Array<keyof Static<T>>;\n /**\n * Referenced columns in the foreign table.\n * Must be EntityColumn references from other entities.\n */\n foreignColumns: Array<() => EntityColumn<any>>;\n }>;\n\n /**\n * Additional table constraints for data validation.\n *\n * Constraints enforce business rules at the database level, providing\n * an additional layer of data integrity beyond application validation.\n *\n * **Constraint Types**:\n * - **Unique constraints**: Prevent duplicate values across columns\n * - **Check constraints**: Enforce custom validation rules with SQL expressions\n *\n * @example\n * ```ts\n * constraints: [\n * {\n * name: \"unique_user_email\",\n * columns: [\"email\"],\n * unique: true\n * },\n * {\n * name: \"valid_age_range\",\n * columns: [\"age\"],\n * check: sql`age >= 0 AND age <= 150`\n * },\n * {\n * name: \"unique_user_username_per_tenant\",\n * columns: [\"tenantId\", \"username\"],\n * unique: true\n * }\n * ]\n * ```\n */\n constraints?: Array<{\n /**\n * Columns involved in this constraint.\n */\n columns: Array<keyof Static<T>>;\n /**\n * Optional name for the constraint.\n */\n name?: string;\n /**\n * Whether this is a unique constraint.\n */\n unique?: boolean | {} /* options */;\n /**\n * SQL expression for check constraint validation.\n */\n check?: SQL;\n }>;\n\n /**\n * Advanced Drizzle ORM configuration for complex table setups.\n */\n config?: (\n self: BuildExtraConfigColumns<string, FromSchema<T>, \"pg\">,\n ) => PgTableExtraConfigValue[];\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class EntityPrimitive<T extends TObject = TObject> {\n public readonly options: EntityPrimitiveOptions<T>;\n\n constructor(options: EntityPrimitiveOptions<T>) {\n this.options = options;\n }\n\n alias(alias: string): this {\n const aliased = new EntityPrimitive<T>(this.options);\n return new Proxy(aliased, {\n get(target, prop, receiver) {\n if (prop === \"$alias\") {\n return alias;\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as this;\n }\n\n get cols(): EntityColumns<T> {\n const cols: Partial<EntityColumns<T>> = {};\n for (const key of Object.keys(this.schema.properties) as Array<\n keyof T[\"properties\"]\n >) {\n cols[key] = {\n name: key as string,\n entity: this,\n };\n }\n\n return cols as EntityColumns<T>;\n }\n\n get name(): string {\n return this.options.name;\n }\n\n get schema(): T {\n return this.options.schema;\n }\n\n get insertSchema(): TObjectInsert<T> {\n return insertSchema(this.options.schema);\n }\n\n get updateSchema(): TObjectUpdate<T> {\n return updateSchema(this.options.schema);\n }\n}\n\n$entity[KIND] = EntityPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Convert a schema to columns.\n */\nexport type FromSchema<T extends TObject> = {\n [key in keyof T[\"properties\"]]: PgColumnBuilderBase;\n};\n\nexport type SchemaToTableConfig<T extends TObject> = {\n name: string;\n schema: string | undefined;\n columns: {\n [key in keyof T[\"properties\"]]: PgColumn;\n };\n dialect: string;\n};\n\nexport type EntityColumn<T extends TObject> = {\n name: string;\n entity: EntityPrimitive<T>;\n};\n\nexport type EntityColumns<T extends TObject> = {\n [key in keyof T[\"properties\"]]: EntityColumn<T>;\n};\n","import { KIND, type TObject } from \"alepha\";\nimport type { SQL } from \"drizzle-orm\";\n\n/**\n * Creates a database view primitive from a TypeBox schema and SQL query.\n *\n * Views are read-only: Repository blocks all write operations.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { $view } from \"alepha/orm\";\n * import { sql } from \"drizzle-orm\";\n *\n * const userSummary = $view({\n * name: \"user_summary\",\n * schema: t.object({\n * id: t.uuid(),\n * fullName: t.text(),\n * orderCount: t.integer(),\n * }),\n * query: sql`SELECT u.id, u.first_name || ' ' || u.last_name AS full_name, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id`,\n * });\n *\n * // Materialized view (PostgreSQL only)\n * const monthlyStats = $view({\n * name: \"monthly_stats\",\n * schema: t.object({ ... }),\n * query: sql`...`,\n * materialized: true,\n * });\n * ```\n */\nexport const $view = <TSchema extends TObject>(\n options: ViewPrimitiveOptions<TSchema>,\n): ViewPrimitive<TSchema> => {\n return new ViewPrimitive<TSchema>(options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface ViewPrimitiveOptions<T extends TObject> {\n /**\n * The database view name.\n */\n name: string;\n\n /**\n * TypeBox schema defining the view's columns.\n */\n schema: T;\n\n /**\n * SQL query that defines the view.\n */\n query: SQL;\n\n /**\n * Whether this is a materialized view (PostgreSQL only).\n * Materialized views store results on disk and can be refreshed.\n */\n materialized?: boolean;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class ViewPrimitive<T extends TObject = TObject> {\n public readonly options: ViewPrimitiveOptions<T>;\n public readonly isView = true;\n\n constructor(options: ViewPrimitiveOptions<T>) {\n this.options = options;\n }\n\n get name(): string {\n return this.options.name;\n }\n\n get schema(): T {\n return this.options.schema;\n }\n\n get materialized(): boolean {\n return this.options.materialized ?? false;\n }\n}\n\n$view[KIND] = ViewPrimitive;\n","import {\n AlephaError,\n pageSchema,\n type Static,\n type TBigInt,\n type TInteger,\n type TNumber,\n type TNumberOptions,\n type TObject,\n type TObjectOptions,\n type TPage,\n type TSchema,\n type TString,\n type TStringOptions,\n type TUnsafe,\n t,\n} from \"alepha\";\nimport type { UpdateDeleteAction } from \"drizzle-orm/pg-core/foreign-keys\";\nimport {\n PG_CREATED_AT,\n PG_DEFAULT,\n PG_DELETED_AT,\n PG_ENUM,\n PG_IDENTITY,\n PG_PRIMARY_KEY,\n PG_REF,\n PG_UPDATED_AT,\n PG_VERSION,\n type PgDefault,\n type PgEnumOptions,\n type PgIdentityOptions,\n type PgPrimaryKey,\n type PgRef,\n} from \"../constants/PG_SYMBOLS.ts\";\nimport type { PgAttr } from \"../helpers/pgAttr.ts\";\nimport { pgAttr } from \"../helpers/pgAttr.ts\";\n\nexport class DatabaseTypeProvider {\n public readonly attr = pgAttr;\n\n /**\n * Creates a primary key with an identity column.\n */\n public readonly identityPrimaryKey = (\n identity?: PgIdentityOptions,\n options?: TNumberOptions,\n ) =>\n pgAttr(\n pgAttr(pgAttr(t.integer(options), PG_PRIMARY_KEY), PG_IDENTITY, identity),\n PG_DEFAULT,\n );\n\n /**\n * Creates a primary key with a big identity column. (default)\n */\n public readonly bigIdentityPrimaryKey = (\n identity?: PgIdentityOptions,\n options?: TNumberOptions,\n ) =>\n pgAttr(\n pgAttr(pgAttr(t.int64(options), PG_PRIMARY_KEY), PG_IDENTITY, identity),\n PG_DEFAULT,\n );\n\n /**\n * Creates a primary key with a UUID column.\n */\n public readonly uuidPrimaryKey = () =>\n pgAttr(pgAttr(t.uuid(), PG_PRIMARY_KEY), PG_DEFAULT);\n\n /**\n * Creates a primary key for a given type. Supports:\n * - `t.integer()` -> PG INT (default)\n * - `t.bigint()` -> PG BIGINT\n * - `t.uuid()` -> PG UUID\n */\n public primaryKey(): PgAttr<PgAttr<TInteger, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TString,\n options?: TStringOptions,\n ): PgAttr<PgAttr<TString, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TInteger,\n options?: TNumberOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TInteger, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TNumber,\n options?: TNumberOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TNumber, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type: TBigInt,\n options?: TNumberOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TBigInt, PgPrimaryKey>, PgDefault>;\n public primaryKey(\n type?: TSchema,\n options?: TNumberOptions | TStringOptions,\n identity?: PgIdentityOptions,\n ): PgAttr<PgAttr<TSchema, PgPrimaryKey>, PgDefault> {\n if (!type || t.schema.isInteger(type)) {\n return pgAttr(\n pgAttr(\n pgAttr(t.integer(options), PG_PRIMARY_KEY),\n PG_IDENTITY,\n identity,\n ),\n PG_DEFAULT,\n );\n }\n\n if (t.schema.isString(type) && type.format === \"uuid\") {\n return pgAttr(pgAttr(t.uuid(), PG_PRIMARY_KEY), PG_DEFAULT);\n }\n\n if (t.schema.isNumber(type) && type.format === \"int64\") {\n return pgAttr(\n pgAttr(\n pgAttr(t.number(options), PG_PRIMARY_KEY),\n PG_IDENTITY,\n identity,\n ),\n PG_DEFAULT,\n );\n }\n\n if (t.schema.isBigInt(type)) {\n return pgAttr(\n pgAttr(\n pgAttr(t.bigint(options), PG_PRIMARY_KEY),\n PG_IDENTITY,\n identity,\n ),\n PG_DEFAULT,\n );\n }\n\n throw new AlephaError(`Unsupported type for primary key: ${type}`);\n }\n\n /**\n * Wrap a schema with \"default\" attribute.\n * This is used to set a default value for a column in the database.\n */\n public readonly default = <T extends TSchema>(\n type: T,\n value?: Static<T>,\n ): PgAttr<T, PgDefault> => {\n if (value != null) {\n Object.assign(type, { default: value });\n }\n\n return this.attr(type, PG_DEFAULT);\n };\n\n /**\n * Creates a column 'version'.\n *\n * This is used to track the version of a row in the database.\n *\n * You can use it for optimistic concurrency control (OCC) with {@link RepositoryPrimitive#save}.\n *\n * @see {@link RepositoryPrimitive#save}\n * @see {@link PgVersionMismatchError}\n */\n public readonly version = (options: TNumberOptions = {}) =>\n this.default(pgAttr(t.integer(options), PG_VERSION), 0);\n\n /**\n * Creates a column Created At. So just a datetime column with a default value of the current timestamp.\n */\n public readonly createdAt = (options?: TStringOptions) =>\n pgAttr(pgAttr(t.datetime(options), PG_CREATED_AT), PG_DEFAULT);\n\n /**\n * Creates a column Updated At. Like createdAt, but it is updated on every update of the row.\n */\n public readonly updatedAt = (options?: TStringOptions) =>\n pgAttr(pgAttr(t.datetime(options), PG_UPDATED_AT), PG_DEFAULT);\n\n /**\n * Creates a column Deleted At for soft delete functionality.\n * This is used to mark rows as deleted without actually removing them from the database.\n * The column is nullable - NULL means not deleted, timestamp means deleted.\n */\n public readonly deletedAt = (options?: TStringOptions) =>\n pgAttr(t.optional(t.datetime(options)), PG_DELETED_AT);\n\n /**\n * Creates a Postgres ENUM type.\n *\n * > By default, `t.enum()` is mapped to a TEXT column in Postgres.\n * > Using this method, you can create a real ENUM type in the database.\n *\n * @example\n * ```ts\n * const statusEnum = pg.enum([\"pending\", \"active\", \"archived\"], { name: \"status_enum\" });\n * ```\n */\n public readonly enum = <T extends string[]>(\n values: [...T],\n pgEnumOptions?: PgEnumOptions,\n typeOptions?: TStringOptions,\n ): PgAttr<TUnsafe<T[number]>, typeof PG_ENUM> => {\n return pgAttr(\n t.enum(values, {\n description: pgEnumOptions?.description,\n ...typeOptions,\n }),\n PG_ENUM,\n pgEnumOptions,\n );\n };\n\n /**\n * Creates a reference to another table or schema. Basically a foreign key.\n */\n public readonly ref = <T extends TSchema>(\n type: T,\n ref: () => any,\n actions?: {\n onUpdate?: UpdateDeleteAction;\n onDelete?: UpdateDeleteAction;\n },\n ): PgAttr<T, PgRef> => {\n // If actions are not provided, set default onDelete based on type\n const finalActions = actions ?? {\n onDelete: t.schema.isOptional(type) ? \"set null\" : \"cascade\",\n };\n\n return this.attr(type, PG_REF, {\n ref,\n actions: finalActions,\n });\n };\n\n // -------------------------------------------------------------------------------------------------------------------\n\n /**\n * Creates a page schema for a given object schema.\n * It's used by {@link Repository#paginate} method.\n */\n public readonly page = <T extends TObject>(\n resource: T,\n options?: TObjectOptions,\n ): TPage<T> => {\n return pageSchema(resource, options);\n };\n}\n\n/**\n * Wrapper of TypeProvider (`t`) for database types.\n *\n * Use `db` for improve TypeBox schema definitions with database-specific attributes.\n *\n * @example\n * ```ts\n * import { t } from \"alepha\";\n * import { db } from \"alepha/orm\";\n *\n * const userSchema = t.object({\n * id: db.primaryKey(t.uuid()),\n * email: t.email(),\n * createdAt: db.createdAt(),\n * });\n * ```\n */\nexport const db = new DatabaseTypeProvider();\n","import { t } from \"alepha\";\nimport {\n PG_DEFAULT,\n PG_PRIMARY_KEY,\n PG_SERIAL,\n} from \"../constants/PG_SYMBOLS.ts\";\nimport { pgAttr } from \"../helpers/pgAttr.ts\";\n\n/**\n * @deprecated Use `pg.primaryKey()` instead.\n */\nexport const legacyIdSchema = pgAttr(\n pgAttr(pgAttr(t.integer(), PG_PRIMARY_KEY), PG_SERIAL),\n PG_DEFAULT,\n);\n","import { $module } from \"alepha\";\nimport { AlephaDateTime } from \"alepha/datetime\";\n\nexport * from \"./index.shared.ts\";\n\nexport const AlephaOrm = $module({\n name: \"alepha.orm\",\n primitives: [],\n services: [AlephaDateTime],\n});\n"],"mappings":";;;;;AAEA,IAAa,UAAb,cAA6B,YAAY;CACvC,OAAO;CAEP,YAAY,SAAiB,OAAiB;AAC5C,QAAM,SAAS,EAAE,OAAO,CAAC;;;;;;;;;;;;;;ACI7B,IAAa,wBAAb,MAAa,8BAA8B,QAAQ;CACjD,AAAS,OAAO;CAChB,AAAS,SAAS;;;;CAKlB,AAAS;;;;CAKT,AAAS;CAET,YACE,SACA,OACA,SACA;AACA,QAAM,SAAS,MAAM;AACrB,OAAK,SAAS,SAAS;AACvB,OAAK,QAAQ,SAAS;;;;;;CAOxB,OAAO,kBAAkB,OAAqC;EAC5D,MAAM,UAAU,MAAM;EAKtB,MAAM,UAAU,QAAQ,MACtB,6DACD;AAED,MAAI,SAAS;GACX,MAAM,SAAS,QAAQ;GACvB,MAAM,QAAQ,QAAQ;AAItB,UAAO,IAAI,sBAHC,QACR,WAAW,OAAO,6BAA6B,MAAM,KACrD,WAAW,OAAO,mBACgB,OAAO;IAAE;IAAQ;IAAO,CAAC;;EAMjE,MAAM,cAAc,QAAQ,MAAM,oCAAoC;AAEtE,MAAI,aAAa;GACf,MAAM,QAAQ,YAAY;GAC1B,MAAM,SAAS,YAAY;AAI3B,UAAO,IAAI,sBAHC,QACR,WAAW,OAAO,6BAA6B,MAAM,KACrD,WAAW,OAAO,mBACgB,OAAO;IAAE;IAAQ;IAAO,CAAC;;AAGjE,SAAO,IAAI,sBAAsB,yBAAyB,MAAM;;;;;;;;;;;;;;;;AC3DpE,IAAa,oBAAb,MAAa,0BAA0B,QAAQ;CAC7C,AAAS,OAAO;CAChB,AAAS,SAAS;;;;CAKlB,AAAS;;;;;CAYT,AAAS;CAET,YACE,SACA,OACA,SAIA;AACA,QAAM,SAAS,MAAM;AACrB,OAAK,YAAY,SAAS;AAC1B,OAAK,YAAY,SAAS,aAAa;;;;;;CAOzC,OAAO,kBAAkB,OAAiC;EACxD,MAAM,UAAU,MAAM,QAAQ,aAAa;AAG3C,MACE,QAAQ,SAAS,qBAAqB,IACtC,QAAQ,SAAS,eAAe,IAChC,QAAQ,SAAS,oBAAoB,CAErC,QAAO,IAAI,kBACT,uDACA,OACA;GAAE,WAAW;GAAW,WAAW;GAAM,CAC1C;AAIH,MACE,QAAQ,SAAS,UAAU,IAC3B,QAAQ,SAAS,YAAY,IAC7B,QAAQ,SAAS,YAAY,CAE7B,QAAO,IAAI,kBAAkB,iCAAiC,OAAO;GACnE,WAAW;GACX,WAAW;GACZ,CAAC;AAIJ,MACE,QAAQ,SAAS,iCAAiC,IAClD,QAAQ,SAAS,wBAAwB,IACzC,QAAQ,SAAS,gBAAgB,CAEjC,QAAO,IAAI,kBACT,sDACA,OACA;GAAE,WAAW;GAAQ,WAAW;GAAO,CACxC;AAIH,MACE,QAAQ,SAAS,0BAA0B,IAC3C,QAAQ,SAAS,eAAe,IAChC,QAAQ,SAAS,SAAS,CAE1B,QAAO,IAAI,kBAAkB,2BAA2B,OAAO;GAC7D,WAAW;GACX,WAAW;GACZ,CAAC;AAIJ,MAAI,QAAQ,SAAS,qBAAqB,CACxC,QAAO,IAAI,kBACT,yCACA,OACA;GAAE,WAAW;GAAU,WAAW;GAAM,CACzC;AAGH,SAAO,IAAI,kBAAkB,iCAAiC,OAAO;GACnE,WAAW;GACX,WAAW;GACZ,CAAC;;;;;;;;;;;;;;;ACxGN,IAAa,kBAAb,MAAa,wBAAwB,QAAQ;CAC3C,AAAS,OAAO;CAChB,AAAS,SAAS;;;;;CAMlB,AAAS,YAAY;;;;;CAMrB,OAAO,kBAAkB,OAA+B;AACtD,SAAO,IAAI,gBACT,8DACA,MACD;;;;;;AC3BL,IAAa,wBAAb,cAA2C,QAAQ;CACjD,AAAS,OAAO;CAChB,AAAS,SAAS;CAElB,YAAY,YAAoB;AAC9B,QAAM,gBAAgB,WAAW,iBAAiB;;;;;;;;;;;;ACCtD,IAAa,oBAAb,MAAa,0BAA0B,QAAQ;CAC7C,AAAS,OAAO;CAChB,AAAS,SAAS;;;;CAKlB,AAAS;;;;CAKT,AAAS;CAET,YACE,SACA,OACA,SACA;AACA,QAAM,SAAS,MAAM;AACrB,OAAK,mBAAmB,SAAS;AACjC,OAAK,iBAAiB,SAAS;;;;;;CAOjC,OAAO,kBAAkB,OAAc,WAAsC;EAK3E,MAAM,UAJU,MAAM,QAIE,MACtB,+DACD;AAED,MAAI,SAAS;GACX,MAAM,iBAAiB,QAAQ;GAC/B,MAAM,mBAAmB,QAAQ;AAEjC,UAAO,IAAI,kBACT,iBAAiB,UAAU,wBAAwB,oBACnD,OACA;IAAE;IAAkB;IAAgB,CACrC;;AAKH,SAAO,IAAI,kBACT,iBAAiB,UAAU,uCAC3B,MACD;;;;;;;;;;;;ACrDL,IAAa,iBAAb,MAAa,uBAAuB,QAAQ;CAC1C,AAAS,OAAO;CAChB,AAAS,SAAS;;;;CAKlB,AAAS;;;;CAKT,AAAS;CAET,YACE,SACA,OACA,SACA;AACA,QAAM,SAAS,MAAM;AACrB,OAAK,SAAS,SAAS;AACvB,OAAK,QAAQ,SAAS;;;;;;CAOxB,OAAO,kBAAkB,OAAc,WAAmC;EACxE,MAAM,UAAU,MAAM;EAItB,MAAM,UAAU,QAAQ,MACtB,oFACD;AAED,MAAI,SAAS;GACX,MAAM,SAAS,QAAQ;GACvB,MAAM,QAAQ,QAAQ;AACtB,UAAO,IAAI,eACT,WAAW,OAAO,QAAQ,MAAM,mBAChC,OACA;IAAE;IAAQ;IAAO,CAClB;;EAKH,MAAM,cAAc,QAAQ,MAC1B,6CACD;AAED,MAAI,aAAa;GACf,MAAM,QAAQ,YAAY;GAC1B,MAAM,SAAS,YAAY;AAC3B,UAAO,IAAI,eACT,WAAW,OAAO,QAAQ,MAAM,mBAChC,OACA;IAAE;IAAQ;IAAO,CAClB;;AAGH,SAAO,IAAI,eACT,wBAAwB,UAAU,mBAClC,MACD;;;;;;;;;;;;;;AChEL,IAAa,uBAAb,MAAa,6BAA6B,QAAQ;CAChD,AAAS,OAAO;CAChB,AAAS,SAAS;;;;CAKlB,AAAS;CAET,YAAY,SAAiB,OAAiB,SAA8B;AAC1E,QAAM,SAAS,MAAM;AACrB,OAAK,QAAQ,SAAS;;;;;;CAOxB,OAAO,kBAAkB,OAAoC;EAC3D,MAAM,UAAU,MAAM;EAItB,MAAM,UAAU,QAAQ,MAAM,oCAAoC;AAElE,MAAI,SAAS;GACX,MAAM,QAAQ,QAAQ;AACtB,UAAO,IAAI,qBACT,UAAU,MAAM,6CAChB,OACA,EAAE,OAAO,CACV;;EAKH,MAAM,cAAc,QAAQ,MAAM,uBAAuB;AAEzD,MAAI,aAAa;GACf,MAAM,QAAQ,YAAY;AAC1B,UAAO,IAAI,qBACT,UAAU,MAAM,6CAChB,OACA,EAAE,OAAO,CACV;;AAGH,SAAO,IAAI,qBACT,kDACA,MACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACRL,SAAgB,iBACd,OACiB;AACjB,KAAI,CAAC,SAAS,MAAM,MAAM,KAAK,GAC7B,QAAO,EAAE;AAIX,QADe,IAAI,kBAAkB,MAAM,CAC7B,OAAO;;AAKvB,IAAM,oBAAN,MAAwB;CACtB,AAAQ,MAAM;CACd,AAAiB;CAEjB,YAAY,OAAe;AACzB,OAAK,QAAQ,MAAM,MAAM;;CAG3B,QAA2B;AACzB,SAAO,KAAK,iBAAiB;;CAG/B,AAAQ,kBAAqC;AAC3C,SAAO,KAAK,SAAS;;CAGvB,AAAQ,UAAe;EACrB,MAAM,OAAO,KAAK,UAAU;AAG5B,MAAI,KAAK,MAAM,KAAK,KAAK;GACvB,MAAM,aAAa,CAAC,KAAK;AAEzB,UAAO,KAAK,MAAM,KAAK,KAAK;AAC1B,SAAK,QAAQ,IAAI;AACjB,eAAW,KAAK,KAAK,UAAU,CAAC;;AAGlC,UAAO,EAAE,IAAI,YAAY;;AAG3B,SAAO;;CAGT,AAAQ,WAAgB;EACtB,MAAM,OAAO,KAAK,cAAc;AAGhC,MAAI,KAAK,MAAM,KAAK,KAAK;GACvB,MAAM,aAAa,CAAC,KAAK;AAEzB,UAAO,KAAK,MAAM,KAAK,KAAK;AAC1B,SAAK,QAAQ,IAAI;AACjB,eAAW,KAAK,KAAK,cAAc,CAAC;;AAGtC,UAAO,EAAE,KAAK,YAAY;;AAG5B,SAAO;;CAGT,AAAQ,eAAoB;AAC1B,OAAK,gBAAgB;AAGrB,MAAI,KAAK,MAAM,KAAK,KAAK;AACvB,QAAK,QAAQ,IAAI;GACjB,MAAM,OAAO,KAAK,iBAAiB;AACnC,QAAK,QAAQ,IAAI;AACjB,UAAO;;AAIT,SAAO,KAAK,gBAAgB;;CAG9B,AAAQ,iBAAsB;EAC5B,MAAM,QAAQ,KAAK,gBAAgB;AACnC,OAAK,gBAAgB;EAGrB,MAAM,WAAW,KAAK,eAAe;AACrC,OAAK,gBAAgB;EAGrB,MAAM,QAAQ,KAAK,YAAY;AAE/B,MAAI,UAAU,GACZ,OAAM,IAAI,YAAY,6BAA6B,MAAM,KAAK,IAAI,CAAC,GAAG;AAIxE,SAAO,KAAK,eAAe,OAAO,UAAU,MAAM;;CAGpD,AAAQ,iBAA2B;EACjC,MAAM,OAAiB,EAAE;EACzB,IAAI,UAAU;AAEd,SAAO,KAAK,MAAM,KAAK,MAAM,QAAQ;GACnC,MAAM,KAAK,KAAK,MAAM,KAAK;AAE3B,OAAI,OAAO,OAAO,SAAS;AACzB,SAAK,KAAK,QAAQ;AAClB,cAAU;AACV,SAAK;AACL;;AAGF,OAAI,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,IACjE;AAGF,cAAW;AACX,QAAK;;AAGP,MAAI,QACF,MAAK,KAAK,QAAQ;AAGpB,SAAO;;CAGT,AAAQ,gBAAwB;AAC9B,OAAK,gBAAgB;EAErB,MAAM,YAAY,KAAK,MAAM,MAAM,KAAK,IAAI;AAG5C,MAAI,UAAU,WAAW,KAAK,EAAE;AAC9B,QAAK,OAAO;AACZ,UAAO;;AAET,MAAI,UAAU,WAAW,KAAK,EAAE;AAC9B,QAAK,OAAO;AACZ,UAAO;;AAET,MAAI,UAAU,WAAW,KAAK,EAAE;AAC9B,QAAK,OAAO;AACZ,UAAO;;EAIT,MAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,MAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC1C,QAAK;AACL,UAAO;;AAGT,QAAM,IAAI,MAAM,iCAAiC,KAAK,MAAM;;CAG9D,AAAQ,aAAkB;AACxB,OAAK,gBAAgB;AAGrB,MAAI,KAAK,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,EAAE,CAAC,aAAa,KAAK,QAAQ;AACrE,QAAK,OAAO;AACZ,UAAO;;AAIT,MAAI,KAAK,MAAM,KAAK,SAAS,IAC3B,QAAO,KAAK,YAAY;AAI1B,MAAI,KAAK,MAAM,KAAK,SAAS,QAAO,KAAK,MAAM,KAAK,SAAS,IAC3D,QAAO,KAAK,mBAAmB;EAIjC,IAAI,QAAQ;AACZ,SAAO,KAAK,MAAM,KAAK,MAAM,QAAQ;GACnC,MAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,OAAI,OAAO,OAAO,OAAO,OAAO,OAAO,IACrC;AAEF,YAAS;AACT,QAAK;;AAGP,SAAO,KAAK,YAAY,MAAM,MAAM,CAAC;;CAGvC,AAAQ,aAAoB;AAC1B,OAAK,QAAQ,IAAI;EACjB,MAAM,SAAgB,EAAE;AAExB,SAAO,KAAK,MAAM,KAAK,MAAM,UAAU,KAAK,MAAM,KAAK,SAAS,KAAK;AACnE,QAAK,gBAAgB;AAGrB,OAAI,KAAK,MAAM,KAAK,SAAS,QAAO,KAAK,MAAM,KAAK,SAAS,IAC3D,QAAO,KAAK,KAAK,mBAAmB,CAAC;QAChC;IAEL,IAAI,QAAQ;AACZ,WACE,KAAK,MAAM,KAAK,MAAM,UACtB,KAAK,MAAM,KAAK,SAAS,OACzB,KAAK,MAAM,KAAK,SAAS,KACzB;AACA,cAAS,KAAK,MAAM,KAAK;AACzB,UAAK;;AAEP,WAAO,KAAK,KAAK,YAAY,MAAM,MAAM,CAAC,CAAC;;AAG7C,QAAK,gBAAgB;AACrB,OAAI,KAAK,MAAM,KAAK,SAAS,IAC3B,MAAK;;AAIT,OAAK,QAAQ,IAAI;AACjB,SAAO;;CAGT,AAAQ,oBAA4B;EAClC,MAAM,QAAQ,KAAK,MAAM,KAAK;AAC9B,OAAK;EAEL,IAAI,QAAQ;EACZ,IAAI,UAAU;AAEd,SAAO,KAAK,MAAM,KAAK,MAAM,QAAQ;GACnC,MAAM,KAAK,KAAK,MAAM,KAAK;AAE3B,OAAI,SAAS;AACX,aAAS;AACT,cAAU;AACV,SAAK;AACL;;AAGF,OAAI,OAAO,MAAM;AACf,cAAU;AACV,SAAK;AACL;;AAGF,OAAI,OAAO,OAAO;AAChB,SAAK;AACL;;AAGF,YAAS;AACT,QAAK;;AAGP,SAAO;;CAGT,AAAQ,YAAY,OAAoB;AAEtC,MAAI,UAAU,KAAK,MAAM,CACvB,QAAO,SAAS,OAAO,GAAG;AAG5B,MAAI,eAAe,KAAK,MAAM,CAC5B,QAAO,WAAW,MAAM;AAI1B,MAAI,MAAM,aAAa,KAAK,OAC1B,QAAO;AAET,MAAI,MAAM,aAAa,KAAK,QAC1B,QAAO;AAGT,SAAO;;CAGT,AAAQ,eAAe,MAAgB,UAAkB,OAAiB;EAExE,IAAI;AAEJ,MAAI,aAAa,IACf,KAAI,UAAU,KACZ,YAAW,EAAE,QAAQ,MAAM;WAClB,MAAM,QAAQ,MAAM,CAE7B,YAAW,EAAE,SAAS,OAAO;WACpB,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,EAAE;GAE3D,MAAM,qBAAqB,MAAM,WAAW,IAAI;GAChD,MAAM,mBAAmB,MAAM,SAAS,IAAI;GAC5C,MAAM,aAAa,MAAM,QAAQ,YAAY,GAAG;AAEhD,OAAI,sBAAsB,iBAExB,YAAW,EAAE,UAAU,YAAY;YAC1B,mBAET,YAAW,EAAE,UAAU,YAAY;YAC1B,iBAET,YAAW,EAAE,YAAY,YAAY;OAGrC,YAAW,EAAE,IAAI,OAAO;QAG1B,YAAW,EAAE,IAAI,OAAO;WAEjB,aAAa,KACtB,KAAI,UAAU,KACZ,YAAW,EAAE,WAAW,MAAM;MAE9B,YAAW,EAAE,IAAI,OAAO;WAEjB,aAAa,IACtB,YAAW,EAAE,IAAI,OAAO;WACf,aAAa,KACtB,YAAW,EAAE,KAAK,OAAO;WAChB,aAAa,IACtB,YAAW,EAAE,IAAI,OAAO;WACf,aAAa,KACtB,YAAW,EAAE,KAAK,OAAO;MAEzB,OAAM,IAAI,MAAM,yBAAyB,WAAW;AAItD,MAAI,KAAK,WAAW,EAClB,QAAO,GAAG,KAAK,KAAK,UAAU;EAIhC,IAAI,SAAc;AAClB,OAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,IACpC,UAAS,GAAG,KAAK,KAAK,QAAQ;AAGhC,SAAO;;CAGT,AAAQ,OAAe;AACrB,OAAK,gBAAgB;AACrB,SAAO,KAAK,MAAM,KAAK,QAAQ;;CAGjC,AAAQ,QAAQ,UAAwB;AACtC,OAAK,gBAAgB;AACrB,MAAI,KAAK,MAAM,KAAK,SAAS,SAC3B,OAAM,IAAI,MACR,aAAa,SAAS,gBAAgB,KAAK,IAAI,SAAS,KAAK,MAAM,KAAK,KAAK,GAC9E;AAEH,OAAK;;CAGP,AAAQ,iBAAuB;AAC7B,SAAO,KAAK,MAAM,KAAK,MAAM,UAAU,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,CACpE,MAAK;;;;;;;;;;;;;;;;;AAqBX,SAAgB,iBAAiB,OAAoB;AACnD,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAIT,KAAI,SAAS,SAAS,MAAM,QAAQ,MAAM,IAAI,CAC5C,QAAO,MAAM,IAAI,KAAK,MAAW,iBAAiB,EAAE,CAAC,CAAC,KAAK,IAAI;AAGjE,KAAI,QAAQ,SAAS,MAAM,QAAQ,MAAM,GAAG,EAAE;EAC5C,MAAM,QAAQ,MAAM,GAAG,KAAK,MAAW,iBAAiB,EAAE,CAAC;AAC3D,SAAO,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,MAAM;;AAG3D,KAAI,SAAS,MAGX,QAAO;CAIT,MAAM,QAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,OAAO,cAAc,OAAO,QAAQ,MAAM,EAAE;AACtD,MAAI,OAAO,cAAc,YAAY,cAAc,MAAM;AACvD,SAAM,KAAK,GAAG,MAAM,GAAG,YAAY;AACnC;;AAGF,MAAI,QAAQ,UACV,OAAM,KAAK,GAAG,MAAM,GAAG,UAAU,KAAK;WAC7B,QAAQ,UACjB,OAAM,KAAK,GAAG,MAAM,IAAI,UAAU,KAAK;WAC9B,QAAQ,UACjB,OAAM,KAAK,GAAG,MAAM,GAAG,UAAU,KAAK;WAC7B,SAAS,UAClB,OAAM,KAAK,GAAG,MAAM,IAAI,UAAU,MAAM;WAC/B,QAAQ,UACjB,OAAM,KAAK,GAAG,MAAM,GAAG,UAAU,KAAK;WAC7B,SAAS,UAClB,OAAM,KAAK,GAAG,MAAM,IAAI,UAAU,MAAM;WAC/B,cAAc,UACvB,OAAM,KAAK,GAAG,MAAM,IAAI,UAAU,SAAS,GAAG;WACrC,gBAAgB,UACzB,OAAM,KAAK,GAAG,MAAM,GAAG,UAAU,WAAW,GAAG;WACtC,cAAc,UACvB,OAAM,KAAK,GAAG,MAAM,IAAI,UAAU,WAAW;WACpC,YAAY,aAAa,UAAU,OAC5C,OAAM,KAAK,GAAG,MAAM,OAAO;WAClB,eAAe,aAAa,UAAU,UAC/C,OAAM,KAAK,GAAG,MAAM,QAAQ;WACnB,aAAa,aAAa,MAAM,QAAQ,UAAU,QAAQ,EAAE;GACrE,MAAM,SAAS,UAAU,QAAQ,KAAK,MACpC,OAAO,MAAM,WAAW,IAAI,EAAE,KAAK,EACpC;AACD,SAAM,KAAK,GAAG,MAAM,IAAI,OAAO,KAAK,IAAI,CAAC,GAAG;SACvC;GAEL,MAAM,SAAS,iBAAiB,UAAU;AAC1C,OAAI,OACF,OAAM,KAAK,GAAG,MAAM,GAAG,SAAS;;;AAKtC,QAAO,MAAM,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;AClexB,MAAa,UACX,MACA,MACA,UACoB;AACpB,QAAO,OAAO,MAAM,GAAG,OAAO,SAAS,EAAE,EAAE,CAAC;AAC5C,QAAO;;;;;AAMT,MAAa,iBACX,QACA,SACkB;CAClB,MAAM,SAA6B,EAAE;AAErC,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,WAAW,EAAE;EAChD,MAAM,QAAQ,OAAO,WAAW;AAChC,MAAI,QAAQ,MACV,QAAO,KAAK;GACV,MAAM;GACD;GACL,MAAO,MAAc;GACtB,CAAC;;AAIN,QAAO;;;;;ACxCT,MAAa,aAAa,OAAO,IAAI,0BAA0B;AAC/D,MAAa,iBAAiB,OAAO,IAAI,6BAA6B;AACtE,MAAa,gBAAgB,OAAO,IAAI,4BAA4B;AACpE,MAAa,gBAAgB,OAAO,IAAI,4BAA4B;AACpE,MAAa,gBAAgB,OAAO,IAAI,4BAA4B;AACpE,MAAa,aAAa,OAAO,IAAI,0BAA0B;AAC/D,MAAa,cAAc,OAAO,IAAI,2BAA2B;AACjE,MAAa,UAAU,OAAO,IAAI,uBAAuB;AACzD,MAAa,SAAS,OAAO,IAAI,sBAAsB;AACvD,MAAa,eAAe,OAAO,IAAI,4BAA4B;;;;AAKnE,MAAa,YAAY,OAAO,IAAI,yBAAyB;;;;;;;ACf7D,MAAa,UACX,MACA,aAEA,WAKG;CACD,gBAAgB;CAChB,WAAW,UAAU,KAAK,UAAU,MAAM;CAC1C,aAAa,UACX,SAAS,OAAO,UAAU,WAAW,KAAK,MAAM,MAAM,GAAG;CAC5D,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,OAA0B;;;;ACMnD,MAAa,gBAAmC,QAA6B;CAC3E,MAAM,gBAAqC,EAAE;AAE7C,MAAK,MAAM,OAAO,IAAI,YAAY;EAChC,MAAM,OAAO,IAAI,WAAW;AAG5B,MAAI,gBAAgB,KAClB;AAGF,MAAI,cAAc,KAChB,eAAc,OAAO,EAAE,SAAS,KAAK;MAErC,eAAc,OAAO;;AAIzB,QAAO,EAAE,OACP,eACA,aAAa,UAAU,OAAO,OAAO,YAAY,WAC7C,EAAE,GAAG,OAAO,SAAS,GACrB,EAAE,CACP;;;;;ACrBH,MAAa,gBACX,WACqB;CACrB,MAAM,gBAAqC,EAAE;AAE7C,MAAK,MAAM,OAAO,OAAO,YAAY;EACnC,MAAM,OAAO,OAAO,WAAW;AAG/B,MAAI,gBAAgB,KAClB;AAGF,MAAI,EAAE,OAAO,WAAW,KAAK,CAC3B,eAAc,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC;MAE9D,eAAc,OAAO;;AAIzB,QAAO,EAAE,OACP,eACA,aAAa,UAAU,OAAO,OAAO,YAAY,WAC7C,EAAE,GAAG,OAAO,SAAS,GACrB,EAAE,CACP;;;;;;;;;;;;;;;;;;;;;;;ACzBH,MAAa,WACX,YAC6B;AAC7B,QAAO,IAAI,gBAAyB,QAAQ;;AA8I9C,IAAa,kBAAb,MAAa,gBAA6C;CACxD,AAAgB;CAEhB,YAAY,SAAoC;AAC9C,OAAK,UAAU;;CAGjB,MAAM,OAAqB;EACzB,MAAM,UAAU,IAAI,gBAAmB,KAAK,QAAQ;AACpD,SAAO,IAAI,MAAM,SAAS,EACxB,IAAI,QAAQ,MAAM,UAAU;AAC1B,OAAI,SAAS,SACX,QAAO;AAET,UAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;KAE7C,CAAC;;CAGJ,IAAI,OAAyB;EAC3B,MAAM,OAAkC,EAAE;AAC1C,OAAK,MAAM,OAAO,OAAO,KAAK,KAAK,OAAO,WAAW,CAGnD,MAAK,OAAO;GACV,MAAM;GACN,QAAQ;GACT;AAGH,SAAO;;CAGT,IAAI,OAAe;AACjB,SAAO,KAAK,QAAQ;;CAGtB,IAAI,SAAY;AACd,SAAO,KAAK,QAAQ;;CAGtB,IAAI,eAAiC;AACnC,SAAO,aAAa,KAAK,QAAQ,OAAO;;CAG1C,IAAI,eAAiC;AACnC,SAAO,aAAa,KAAK,QAAQ,OAAO;;;AAI5C,QAAQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9LhB,MAAa,SACX,YAC2B;AAC3B,QAAO,IAAI,cAAuB,QAAQ;;AA8B5C,IAAa,gBAAb,MAAwD;CACtD,AAAgB;CAChB,AAAgB,SAAS;CAEzB,YAAY,SAAkC;AAC5C,OAAK,UAAU;;CAGjB,IAAI,OAAe;AACjB,SAAO,KAAK,QAAQ;;CAGtB,IAAI,SAAY;AACd,SAAO,KAAK,QAAQ;;CAGtB,IAAI,eAAwB;AAC1B,SAAO,KAAK,QAAQ,gBAAgB;;;AAIxC,MAAM,QAAQ;;;;AClDd,IAAa,uBAAb,MAAkC;CAChC,AAAgB,OAAO;;;;CAKvB,AAAgB,sBACd,UACA,YAEA,OACE,OAAO,OAAO,EAAE,QAAQ,QAAQ,EAAE,eAAe,EAAE,aAAa,SAAS,EACzE,WACD;;;;CAKH,AAAgB,yBACd,UACA,YAEA,OACE,OAAO,OAAO,EAAE,MAAM,QAAQ,EAAE,eAAe,EAAE,aAAa,SAAS,EACvE,WACD;;;;CAKH,AAAgB,uBACd,OAAO,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW;CA4BtD,AAAO,WACL,MACA,SACA,UACkD;AAClD,MAAI,CAAC,QAAQ,EAAE,OAAO,UAAU,KAAK,CACnC,QAAO,OACL,OACE,OAAO,EAAE,QAAQ,QAAQ,EAAE,eAAe,EAC1C,aACA,SACD,EACD,WACD;AAGH,MAAI,EAAE,OAAO,SAAS,KAAK,IAAI,KAAK,WAAW,OAC7C,QAAO,OAAO,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW;AAG7D,MAAI,EAAE,OAAO,SAAS,KAAK,IAAI,KAAK,WAAW,QAC7C,QAAO,OACL,OACE,OAAO,EAAE,OAAO,QAAQ,EAAE,eAAe,EACzC,aACA,SACD,EACD,WACD;AAGH,MAAI,EAAE,OAAO,SAAS,KAAK,CACzB,QAAO,OACL,OACE,OAAO,EAAE,OAAO,QAAQ,EAAE,eAAe,EACzC,aACA,SACD,EACD,WACD;AAGH,QAAM,IAAI,YAAY,qCAAqC,OAAO;;;;;;CAOpE,AAAgB,WACd,MACA,UACyB;AACzB,MAAI,SAAS,KACX,QAAO,OAAO,MAAM,EAAE,SAAS,OAAO,CAAC;AAGzC,SAAO,KAAK,KAAK,MAAM,WAAW;;;;;;;;;;;;CAapC,AAAgB,WAAW,UAA0B,EAAE,KACrD,KAAK,QAAQ,OAAO,EAAE,QAAQ,QAAQ,EAAE,WAAW,EAAE,EAAE;;;;CAKzD,AAAgB,aAAa,YAC3B,OAAO,OAAO,EAAE,SAAS,QAAQ,EAAE,cAAc,EAAE,WAAW;;;;CAKhE,AAAgB,aAAa,YAC3B,OAAO,OAAO,EAAE,SAAS,QAAQ,EAAE,cAAc,EAAE,WAAW;;;;;;CAOhE,AAAgB,aAAa,YAC3B,OAAO,EAAE,SAAS,EAAE,SAAS,QAAQ,CAAC,EAAE,cAAc;;;;;;;;;;;;CAaxD,AAAgB,QACd,QACA,eACA,gBAC+C;AAC/C,SAAO,OACL,EAAE,KAAK,QAAQ;GACb,aAAa,eAAe;GAC5B,GAAG;GACJ,CAAC,EACF,SACA,cACD;;;;;CAMH,AAAgB,OACd,MACA,KACA,YAIqB;EAErB,MAAM,eAAe,WAAW,EAC9B,UAAU,EAAE,OAAO,WAAW,KAAK,GAAG,aAAa,WACpD;AAED,SAAO,KAAK,KAAK,MAAM,QAAQ;GAC7B;GACA,SAAS;GACV,CAAC;;;;;;CASJ,AAAgB,QACd,UACA,YACa;AACb,SAAOA,aAAW,UAAU,QAAQ;;;;;;;;;;;;;;;;;;;;AAqBxC,MAAa,KAAK,IAAI,sBAAsB;;;;;;;ACjQ5C,MAAa,iBAAiB,OAC5B,OAAO,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EACtD,WACD;;;;ACTD,MAAa,YAAY,QAAQ;CAC/B,MAAM;CACN,YAAY,EAAE;CACd,UAAU,CAAC,eAAe;CAC3B,CAAC"}
|