alepha 0.19.0 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +6 -9
- package/dist/api/audits/index.d.ts +378 -346
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +216 -184
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +5 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +528 -496
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +3 -3
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +202 -202
- package/dist/api/keys/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +152 -152
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/organizations/index.browser.js +48 -0
- package/dist/api/organizations/index.browser.js.map +1 -0
- package/dist/api/organizations/index.d.ts +516 -0
- package/dist/api/organizations/index.d.ts.map +1 -0
- package/dist/api/organizations/index.js +202 -0
- package/dist/api/organizations/index.js.map +1 -0
- package/dist/api/parameters/index.d.ts +391 -358
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +5 -1
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.browser.js +7 -5
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +989 -931
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +292 -146
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +132 -132
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +2 -2
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.d.ts +6 -6
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/billing/index.d.ts +1048 -0
- package/dist/billing/index.d.ts.map +1 -0
- package/dist/billing/index.js +713 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/bin/index.js +0 -2
- package/dist/bin/index.js.map +1 -1
- package/dist/bucket/index.d.ts +10 -10
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +2 -2
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/core/index.d.ts +9 -9
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +2 -2
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +2 -2
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cache/redis/index.d.ts +6 -6
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/cli/config/index.d.ts +12 -2
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +4 -0
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +183 -139
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +283 -86
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +45 -0
- package/dist/cli/devtools/index.d.ts.map +1 -0
- package/dist/cli/devtools/index.js +170 -0
- package/dist/cli/devtools/index.js.map +1 -0
- package/dist/cli/platform/index.d.ts +383 -492
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +42 -511
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +196 -0
- package/dist/cli/vendor/index.d.ts.map +1 -0
- package/dist/cli/vendor/index.js +384 -0
- package/dist/cli/vendor/index.js.map +1 -0
- package/dist/command/index.d.ts +18 -18
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +2 -2
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +4 -4
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +10 -10
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +4 -4
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +4 -4
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.d.ts +7 -7
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/datetime/index.d.ts +4 -4
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/email/brevo/index.d.ts +4 -4
- package/dist/email/brevo/index.d.ts.map +1 -1
- package/dist/email/core/index.d.ts +15 -11
- package/dist/email/core/index.d.ts.map +1 -1
- package/dist/email/core/index.js +12 -35
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/smtp/index.d.ts +12 -12
- package/dist/email/smtp/index.d.ts.map +1 -1
- package/dist/email/smtp/index.js +7 -4
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +4 -8
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +55 -889
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +13 -13
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +2 -2
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.d.ts +4 -4
- package/dist/lock/redis/index.d.ts.map +1 -1
- package/dist/logger/index.d.ts +16 -15
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +5 -2
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +11 -11
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +11 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +53 -16
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +95 -51
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +55 -14
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +17 -11
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +21 -15
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +19 -13
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +14 -14
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/core/index.js +2 -2
- package/dist/queue/core/index.js.map +1 -1
- package/dist/queue/core/index.workerd.js +2 -2
- package/dist/queue/core/index.workerd.js.map +1 -1
- package/dist/queue/redis/index.d.ts +4 -4
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/queue/redis/index.js +2 -2
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/react/auth/index.d.ts +9 -9
- package/dist/react/auth/index.d.ts.map +1 -1
- package/dist/react/core/index.d.ts +6 -6
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +5 -4
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +4 -4
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/head/index.d.ts +4 -4
- package/dist/react/head/index.d.ts.map +1 -1
- package/dist/react/i18n/index.d.ts +9 -9
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/intro/index.d.ts +2 -2
- package/dist/react/intro/index.d.ts.map +1 -1
- package/dist/react/intro/index.js +3 -4
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +4 -5
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +215 -215
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +6 -7
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/index.d.ts +2 -2
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +2 -4
- package/dist/react/testing/index.js.map +1 -1
- package/dist/redis/index.d.ts +19 -19
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/retry/index.d.ts +4 -4
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +13 -13
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +2 -2
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +2 -2
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +47 -47
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +9 -12
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +170 -169
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +16 -2
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +7 -7
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/core/index.d.ts +76 -76
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +23 -17
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +13 -13
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/cors/index.js +2 -2
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/etag/index.d.ts +9 -9
- package/dist/server/etag/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts +20 -20
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/links/index.browser.js +2 -2
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +66 -66
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +4 -4
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +7 -7
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +5 -5
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts +12 -12
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.js +2 -2
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +5 -5
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +7 -7
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +2 -2
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +11 -7
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +9 -15
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.d.ts +4 -4
- package/dist/system/index.d.ts.map +1 -1
- package/dist/topic/core/index.d.ts +6 -6
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts +7 -7
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/topic/redis/index.js +2 -2
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/websocket/index.d.ts +36 -36
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +2 -2
- package/dist/websocket/index.js.map +1 -1
- package/package.json +37 -32
- package/src/api/files/{controllers → __tests__}/FileController.spec.ts +189 -143
- package/src/api/files/{services → __tests__}/FileService.spec.ts +50 -30
- package/src/api/files/controllers/FileController.ts +6 -0
- package/src/api/jobs/{services → __tests__}/JobService.spec.ts +1 -1
- package/src/api/jobs/providers/JobProvider.ts +3 -3
- package/src/api/keys/{services → __tests__}/ApiKeyService.spec.ts +1 -1
- package/src/api/organizations/__tests__/OrganizationService.spec.ts +193 -0
- package/src/api/organizations/controllers/AdminOrganizationController.ts +103 -0
- package/src/api/organizations/entities/organizations.ts +20 -0
- package/src/api/organizations/index.browser.ts +10 -0
- package/src/api/organizations/index.ts +31 -0
- package/src/api/organizations/schemas/createOrganizationSchema.ts +10 -0
- package/src/api/organizations/schemas/organizationQuerySchema.ts +10 -0
- package/src/api/organizations/schemas/organizationResourceSchema.ts +6 -0
- package/src/api/organizations/schemas/updateOrganizationSchema.ts +7 -0
- package/src/api/organizations/services/OrganizationService.ts +75 -0
- package/src/api/parameters/services/ParameterProvider.ts +6 -1
- package/src/api/users/__tests__/$realm.spec.ts +191 -0
- package/src/api/users/__tests__/RealmProvider.spec.ts +53 -0
- package/src/api/users/__tests__/SessionService.spec.ts +778 -0
- package/src/api/users/{jobs → __tests__}/UserJobs.spec.ts +1 -1
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +24 -0
- package/src/api/users/controllers/RealmController.ts +5 -11
- package/src/api/users/entities/users.ts +9 -3
- package/src/api/users/index.ts +23 -3
- package/src/api/users/primitives/$realm.ts +23 -11
- package/src/api/users/providers/RealmProvider.ts +23 -3
- package/src/api/users/services/RegistrationService.ts +3 -2
- package/src/api/users/services/SessionService.ts +249 -8
- package/src/api/users/services/UserService.ts +1 -1
- package/src/api/verifications/{jobs → __tests__}/VerificationJobs.spec.ts +4 -2
- package/src/api/verifications/parameters/VerificationParameters.ts +2 -2
- package/src/billing/__tests__/BillingService.spec.ts +136 -0
- package/src/billing/__tests__/PaymentMethodService.spec.ts +78 -0
- package/src/billing/controllers/AdminBillingController.ts +149 -0
- package/src/billing/controllers/BillingController.ts +108 -0
- package/src/billing/entities/paymentIntents.ts +34 -0
- package/src/billing/entities/paymentMethods.ts +24 -0
- package/src/billing/entities/refunds.ts +22 -0
- package/src/billing/errors/BillingError.ts +5 -0
- package/src/billing/index.ts +76 -0
- package/src/billing/providers/BillingProvider.ts +79 -0
- package/src/billing/providers/MemoryBillingProvider.ts +139 -0
- package/src/billing/schemas/intentSchemas.ts +60 -0
- package/src/billing/schemas/paymentMethodSchemas.ts +13 -0
- package/src/billing/schemas/refundSchemas.ts +6 -0
- package/src/billing/services/BillingService.ts +325 -0
- package/src/billing/services/PaymentMethodService.ts +82 -0
- package/src/bin/index.ts +0 -2
- package/src/bucket/providers/LocalFileStorageProvider.ts +2 -2
- package/src/cache/core/{primitives → __tests__}/$cache.middleware.spec.ts +1 -1
- package/src/cache/core/{providers → __tests__}/MemoryCacheProvider.spec.ts +1 -1
- package/src/cache/core/primitives/$cache.ts +2 -2
- package/src/cache/redis/providers/RedisCacheProvider.ts +2 -2
- package/src/cli/config/defineConfig.ts +20 -0
- package/src/cli/core/{services → __tests__}/ProjectScaffolder.spec.ts +1 -1
- package/src/cli/core/{commands/gen → __tests__}/changelog.spec.ts +1 -1
- package/src/cli/core/{commands → __tests__}/init.spec.ts +4 -12
- package/src/cli/core/assets.ts +0 -1
- package/src/cli/core/atoms/devOptions.ts +0 -5
- package/src/cli/core/commands/build.ts +2 -2
- package/src/cli/core/commands/dev.ts +165 -30
- package/src/cli/core/commands/gen/changelog.ts +2 -2
- package/src/cli/core/commands/init.ts +2 -7
- package/src/cli/core/commands/verify.ts +0 -1
- package/src/cli/core/providers/AppEntryProvider.ts +2 -2
- package/src/cli/core/providers/ViteDevServerProvider.ts +53 -46
- package/src/cli/core/services/PackageManagerUtils.ts +8 -3
- package/src/cli/core/services/ProjectScaffolder.ts +20 -20
- package/src/cli/core/tasks/BuildClientTask.ts +8 -0
- package/src/cli/core/tasks/BuildServerTask.ts +17 -4
- package/src/cli/core/templates/alephaConfigTs.ts +0 -6
- package/src/cli/core/templates/webAdminDashboardTsx.ts +17 -0
- package/src/cli/core/templates/webAppRouterTs.ts +85 -2
- package/src/cli/devtools/atoms/devtoolsOptions.ts +26 -0
- package/src/cli/devtools/index.ts +194 -0
- package/src/cli/platform/{adapters → __tests__}/CloudflareAdapter.spec.ts +2 -2
- package/src/cli/platform/{providers → __tests__}/GitHubSecretStore.spec.ts +1 -1
- package/src/cli/platform/{services → __tests__}/NamingService.spec.ts +1 -1
- package/src/cli/platform/{providers → __tests__}/PlatformCacheProvider.spec.ts +1 -1
- package/src/cli/platform/{services → __tests__}/PlatformInspector.spec.ts +1 -1
- package/src/cli/platform/{services → __tests__}/PlatformOrchestrator.spec.ts +3 -3
- package/src/cli/platform/{services → __tests__}/SecretFilterService.spec.ts +1 -1
- package/src/cli/platform/{commands → __tests__}/SecretsCommand.spec.ts +1 -1
- package/src/cli/platform/{adapters → __tests__}/VercelAdapter.spec.ts +2 -2
- package/src/cli/platform/atoms/platformOptions.ts +2 -10
- package/src/cli/platform/commands/SecretsCommand.ts +2 -2
- package/src/cli/platform/commands/platform.ts +2 -11
- package/src/cli/platform/index.ts +34 -11
- package/src/cli/platform/services/PlatformInspector.ts +2 -2
- package/src/cli/platform/services/PlatformOrchestrator.ts +0 -9
- package/src/cli/vendor/__tests__/VendorService.spec.ts +407 -0
- package/src/cli/vendor/atoms/vendorOptions.ts +41 -0
- package/src/cli/vendor/commands/VendorCommand.ts +204 -0
- package/src/cli/vendor/index.ts +43 -0
- package/src/cli/vendor/services/VendorService.ts +338 -0
- package/src/command/{providers → __tests__}/CliProvider.spec.ts +1 -1
- package/src/command/{helpers → __tests__}/EnvUtils.spec.ts +1 -1
- package/src/command/providers/CliProvider.ts +2 -2
- package/src/core/{primitives → __tests__}/$atom.spec.ts +2 -2
- package/src/core/{primitives → __tests__}/$memoize.spec.ts +1 -1
- package/src/core/{primitives → __tests__}/$mode.spec.ts +1 -1
- package/src/core/{primitives → __tests__}/$pipeline.spec.ts +1 -1
- package/src/core/{primitives → __tests__}/$scope.spec.ts +2 -2
- package/src/core/{providers → __tests__}/KeylessJsonSchemaCodec.spec.ts +1 -1
- package/src/core/{providers → __tests__}/SchemaValidator.spec.ts +1 -1
- package/src/core/{helpers → __tests__}/jsonSchemaToTypeBox.spec.ts +1 -1
- package/src/core/index.shared.ts +1 -1
- package/src/core/primitives/{$use.ts → $state.ts} +4 -4
- package/src/crypto/{providers → __tests__}/BrowserCryptoProvider.browser.spec.ts +1 -1
- package/src/crypto/{providers → __tests__}/CryptoProvider.spec.ts +1 -1
- package/src/datetime/{primitives → __tests__}/$debounce.spec.ts +1 -1
- package/src/datetime/{primitives → __tests__}/$throttle.spec.ts +1 -1
- package/src/datetime/{primitives → __tests__}/$timeout.spec.ts +1 -1
- package/src/email/brevo/{providers → __tests__}/BrevoEmailProvider.spec.ts +1 -1
- package/src/email/core/{providers → __tests__}/LocalEmailProvider.spec.ts +39 -150
- package/src/email/core/providers/LocalEmailProvider.ts +13 -51
- package/src/email/smtp/providers/NodemailerEmailProvider.ts +2 -2
- package/src/lock/core/{primitives → __tests__}/$lock.middleware.spec.ts +1 -1
- package/src/lock/core/primitives/$lock.ts +2 -2
- package/src/logger/index.ts +10 -4
- package/src/mcp/transports/SseMcpTransport.ts +2 -2
- package/src/orm/__tests__/ModelBuilder-tests.ts +53 -0
- package/src/orm/__tests__/ModelBuilder.spec.ts +80 -0
- package/src/orm/__tests__/organization-tests.ts +200 -0
- package/src/orm/__tests__/organization.spec.ts +103 -0
- package/src/orm/core/{providers/drivers → __tests__}/BunSqliteProvider.bun.spec.ts +5 -2
- package/src/orm/core/constants/PG_SYMBOLS.ts +2 -0
- package/src/orm/core/index.shared.ts +1 -0
- package/src/orm/core/primitives/$entity.ts +31 -0
- package/src/orm/core/providers/DatabaseTypeProvider.ts +11 -0
- package/src/orm/core/providers/DrizzleKitProvider.ts +1 -1
- package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -2
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +3 -3
- package/src/orm/core/services/ModelBuilder.ts +11 -0
- package/src/orm/core/services/QueryManager.ts +16 -2
- package/src/orm/core/services/Repository.ts +70 -10
- package/src/orm/postgres/{providers → __tests__}/BunPostgresProvider.bun.spec.ts +1 -1
- package/src/orm/postgres/services/PostgresModelBuilder.ts +9 -1
- package/src/queue/core/providers/WorkerProvider.ts +2 -2
- package/src/queue/redis/providers/RedisQueueProvider.ts +2 -2
- package/src/react/core/{hooks → __tests__}/useAction.browser.spec.tsx +1 -1
- package/src/react/core/hooks/useAction.ts +7 -6
- package/src/react/head/{providers → __tests__}/BrowserHeadProvider.browser.spec.ts +1 -1
- package/src/react/head/{helpers → __tests__}/SeoExpander.spec.ts +1 -1
- package/src/react/i18n/{providers → __tests__}/I18nProvider.spec.ts +1 -1
- package/src/react/i18n/{hooks → __tests__}/useI18n.browser.spec.tsx +1 -1
- package/src/react/intro/components/GettingStartedDevtoolsSlide.tsx +3 -6
- package/src/react/router/{providers → __tests__}/ReactBrowserProvider.browser.spec.ts +1 -1
- package/src/react/router/providers/ReactBrowserProvider.ts +2 -2
- package/src/react/router/providers/ReactPageProvider.ts +2 -2
- package/src/react/router/providers/ReactServerProvider.ts +3 -3
- package/src/redis/{providers → __tests__}/BunRedisProvider.bun.spec.ts +4 -4
- package/src/retry/{primitives → __tests__}/$retry.middleware.spec.ts +1 -1
- package/src/router/{TemplatedPathParser.spec.ts → __tests__/TemplatedPathParser.spec.ts} +1 -1
- package/src/scheduler/primitives/$scheduler.ts +2 -2
- package/src/security/{primitives → __tests__}/$secure-browser.spec.ts +1 -1
- package/src/security/{primitives → __tests__}/$secure.spec.ts +1 -1
- package/src/security/primitives/$issuer.ts +1 -1
- package/src/security/providers/JwtProvider.ts +6 -10
- package/src/security/providers/SecurityProvider.ts +6 -11
- package/src/security/schemas/userAccountInfoSchema.ts +3 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +24 -2
- package/src/server/cookies/{services → __tests__}/CookieParser.spec.ts +1 -1
- package/src/server/core/{primitives → __tests__}/$circuit.spec.ts +1 -1
- package/src/server/core/{providers → __tests__}/NodeHttpServerProvider.spec.ts +1 -1
- package/src/server/core/{providers → __tests__}/ServerBodyParserProvider.spec.ts +31 -1
- package/src/server/core/{providers → __tests__}/ServerCompressProvider.spec.ts +1 -1
- package/src/server/core/{providers → __tests__}/ServerHelmetProvider.spec.ts +4 -1
- package/src/server/core/{providers → __tests__}/ServerMultipartProvider.spec.ts +1 -1
- package/src/server/core/{services → __tests__}/ServerRequestParser.spec.ts +1 -1
- package/src/server/core/primitives/$action.ts +2 -2
- package/src/server/core/primitives/$sse.ts +2 -2
- package/src/server/core/providers/ServerBodyParserProvider.ts +21 -12
- package/src/server/core/providers/ServerCompressProvider.ts +2 -2
- package/src/server/core/providers/ServerHelmetProvider.ts +2 -2
- package/src/server/core/providers/ServerMultipartProvider.ts +2 -2
- package/src/server/core/providers/ServerRouterProvider.ts +1 -5
- package/src/server/cors/{primitives → __tests__}/$cors.spec.ts +1 -1
- package/src/server/cors/providers/ServerCorsProvider.ts +2 -2
- package/src/server/links/{services → __tests__}/BatchCollector.spec.ts +1 -1
- package/src/server/links/providers/LinkProvider.ts +2 -2
- package/src/server/links/providers/RemotePrimitiveProvider.ts +2 -2
- package/src/server/links/providers/ServerLinksProvider.ts +2 -2
- package/src/server/rate-limit/{primitives → __tests__}/$rateLimit.spec.ts +1 -1
- package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +2 -2
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +2 -2
- package/src/sms/{providers → __tests__}/LocalSmsProvider.spec.ts +35 -29
- package/src/sms/providers/LocalSmsProvider.ts +13 -24
- package/src/system/{providers → __tests__}/MemoryFileSystemProvider.spec.ts +1 -1
- package/src/system/{providers → __tests__}/MemoryShellProvider.spec.ts +1 -1
- package/src/topic/redis/providers/RedisTopicProvider.ts +2 -2
- package/src/websocket/{services → __tests__}/RoomManager.spec.ts +1 -1
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +2 -2
- package/tsconfig.base.json +1 -0
- package/assets/devtools-ui/200.html +0 -10
- package/assets/devtools-ui/200.html.br +0 -0
- package/assets/devtools-ui/404.html +0 -10
- package/assets/devtools-ui/404.html.br +0 -0
- package/assets/devtools-ui/CNAME +0 -1
- package/assets/devtools-ui/asset.CHpVij2M.css +0 -1
- package/assets/devtools-ui/asset.CHpVij2M.css.br +0 -0
- package/assets/devtools-ui/asset.DJ-i0UDz.css +0 -1
- package/assets/devtools-ui/asset.DJ-i0UDz.css.br +0 -0
- package/assets/devtools-ui/chunk.1jwpJORo.js +0 -1
- package/assets/devtools-ui/chunk.1jwpJORo.js.br +0 -0
- package/assets/devtools-ui/chunk.B0r2wfUL.js +0 -1
- package/assets/devtools-ui/chunk.B0r2wfUL.js.br +0 -0
- package/assets/devtools-ui/chunk.BScN4dVR.js +0 -84
- package/assets/devtools-ui/chunk.BScN4dVR.js.br +0 -0
- package/assets/devtools-ui/chunk.BispuoY4.js +0 -1
- package/assets/devtools-ui/chunk.BispuoY4.js.br +0 -0
- package/assets/devtools-ui/chunk.BtrPUUd7.js +0 -2
- package/assets/devtools-ui/chunk.BtrPUUd7.js.br +0 -0
- package/assets/devtools-ui/chunk.C-KMHgqf.js +0 -1
- package/assets/devtools-ui/chunk.C-KMHgqf.js.br +0 -0
- package/assets/devtools-ui/chunk.C2zQ3CF6.js +0 -7
- package/assets/devtools-ui/chunk.C2zQ3CF6.js.br +0 -0
- package/assets/devtools-ui/chunk.C619McpO.js +0 -1
- package/assets/devtools-ui/chunk.C619McpO.js.br +0 -0
- package/assets/devtools-ui/chunk.C9OsYsVl.js +0 -1
- package/assets/devtools-ui/chunk.C9OsYsVl.js.br +0 -3
- package/assets/devtools-ui/chunk.CAC_-151.js +0 -1
- package/assets/devtools-ui/chunk.CAC_-151.js.br +0 -0
- package/assets/devtools-ui/chunk.CCmesWfx.js +0 -1
- package/assets/devtools-ui/chunk.CCmesWfx.js.br +0 -0
- package/assets/devtools-ui/chunk.CFQDmrcV.js +0 -1
- package/assets/devtools-ui/chunk.CFQDmrcV.js.br +0 -0
- package/assets/devtools-ui/chunk.CgM71Zau.js +0 -1
- package/assets/devtools-ui/chunk.CgM71Zau.js.br +0 -0
- package/assets/devtools-ui/chunk.CmHq336a.js +0 -1
- package/assets/devtools-ui/chunk.CmHq336a.js.br +0 -0
- package/assets/devtools-ui/chunk.CthNMCar.js +0 -1
- package/assets/devtools-ui/chunk.CthNMCar.js.br +0 -0
- package/assets/devtools-ui/chunk.D2brVJP1.js +0 -1
- package/assets/devtools-ui/chunk.D2brVJP1.js.br +0 -0
- package/assets/devtools-ui/chunk.DgBKGkiw.js +0 -1
- package/assets/devtools-ui/chunk.DgBKGkiw.js.br +0 -0
- package/assets/devtools-ui/chunk.NNHHCQsa.js +0 -1
- package/assets/devtools-ui/chunk.NNHHCQsa.js.br +0 -0
- package/assets/devtools-ui/chunk._CDKKWMo.js +0 -1
- package/assets/devtools-ui/chunk._CDKKWMo.js.br +0 -0
- package/assets/devtools-ui/entry.B_nOjAod.js +0 -2
- package/assets/devtools-ui/entry.B_nOjAod.js.br +0 -0
- package/assets/devtools-ui/index.html +0 -10
- package/assets/devtools-ui/index.html.br +0 -0
- package/dist/devtools/index.browser.js +0 -224
- package/dist/devtools/index.browser.js.map +0 -1
- package/dist/devtools/index.d.ts +0 -499
- package/dist/devtools/index.d.ts.map +0 -1
- package/dist/devtools/index.js +0 -782
- package/dist/devtools/index.js.map +0 -1
- package/dist/mqtt/index.d.ts +0 -164
- package/dist/mqtt/index.d.ts.map +0 -1
- package/dist/mqtt/index.js +0 -214
- package/dist/mqtt/index.js.map +0 -1
- package/dist/topic/mqtt/index.d.ts +0 -87
- package/dist/topic/mqtt/index.d.ts.map +0 -1
- package/dist/topic/mqtt/index.js +0 -88
- package/dist/topic/mqtt/index.js.map +0 -1
- package/src/api/users/parameters/UserParameters.ts +0 -23
- package/src/api/users/services/SessionService.spec.ts +0 -303
- package/src/cli/platform/adapters/DockerAdapter.spec.ts +0 -378
- package/src/cli/platform/adapters/DockerAdapter.ts +0 -417
- package/src/cli/platform/services/DockerComposeGenerator.spec.ts +0 -490
- package/src/cli/platform/services/DockerComposeGenerator.ts +0 -353
- package/src/cli/platform/services/DockerSshService.spec.ts +0 -47
- package/src/cli/platform/services/DockerSshService.ts +0 -61
- package/src/devtools/__tests__/DevCollectorProvider.spec.ts +0 -7
- package/src/devtools/assets.ts +0 -6
- package/src/devtools/entities/logs.ts +0 -21
- package/src/devtools/index.browser.ts +0 -11
- package/src/devtools/index.shared.ts +0 -15
- package/src/devtools/index.ts +0 -39
- package/src/devtools/providers/DevToolsMetadataProvider.ts +0 -459
- package/src/devtools/providers/DevToolsProvider.ts +0 -280
- package/src/devtools/schemas/DevActionMetadata.ts +0 -30
- package/src/devtools/schemas/DevAtomMetadata.ts +0 -26
- package/src/devtools/schemas/DevBucketMetadata.ts +0 -11
- package/src/devtools/schemas/DevCacheMetadata.ts +0 -10
- package/src/devtools/schemas/DevEntityMetadata.ts +0 -60
- package/src/devtools/schemas/DevEnvMetadata.ts +0 -22
- package/src/devtools/schemas/DevMetadata.ts +0 -47
- package/src/devtools/schemas/DevModuleMetadata.ts +0 -8
- package/src/devtools/schemas/DevPageMetadata.ts +0 -24
- package/src/devtools/schemas/DevProviderMetadata.ts +0 -10
- package/src/devtools/schemas/DevQueueMetadata.ts +0 -10
- package/src/devtools/schemas/DevRealmMetadata.ts +0 -19
- package/src/devtools/schemas/DevRouteMetadata.ts +0 -8
- package/src/devtools/schemas/DevSchedulerMetadata.ts +0 -11
- package/src/devtools/schemas/DevTopicMetadata.ts +0 -11
- package/src/mqtt/index.ts +0 -32
- package/src/mqtt/providers/MqttClientProvider.ts +0 -63
- package/src/mqtt/providers/MqttJsClientProvider.spec.ts +0 -165
- package/src/mqtt/providers/MqttJsClientProvider.ts +0 -309
- package/src/topic/mqtt/index.ts +0 -30
- package/src/topic/mqtt/providers/MqttTopicProvider.spec.ts +0 -160
- package/src/topic/mqtt/providers/MqttTopicProvider.ts +0 -146
- /package/src/api/audits/{primitives → __tests__}/$audit.spec.ts +0 -0
- /package/src/api/audits/{services → __tests__}/AuditService.spec.ts +0 -0
- /package/src/api/files/{controllers → __tests__}/AdminFileStatsController.spec.ts +0 -0
- /package/src/api/files/{jobs → __tests__}/FileJobs.spec.ts +0 -0
- /package/src/api/jobs/{primitives → __tests__}/$job-middleware.spec.ts +0 -0
- /package/src/api/parameters/{primitives → __tests__}/$parameter.spec.ts +0 -0
- /package/src/api/users/{controllers → __tests__}/AdminIdentityController.spec.ts +0 -0
- /package/src/api/users/{controllers → __tests__}/AdminSessionController.spec.ts +0 -0
- /package/src/api/users/{controllers → __tests__}/AdminUserController.spec.ts +0 -0
- /package/src/api/users/{services → __tests__}/CredentialService.spec.ts +0 -0
- /package/src/api/users/{services → __tests__}/RegistrationService.spec.ts +0 -0
- /package/src/batch/{primitives → __tests__}/$batch.spec.ts +0 -0
- /package/src/batch/{providers → __tests__}/BatchProvider.spec.ts +0 -0
- /package/src/bucket/{primitives → __tests__}/$bucket.spec.ts +0 -0
- /package/src/bucket/{providers → __tests__}/FileStorageProvider.spec.ts +0 -0
- /package/src/bucket/{providers → __tests__}/LocalFileStorageProvider.spec.ts +0 -0
- /package/src/bucket/{providers → __tests__}/MemoryFileStorageProvider.spec.ts +0 -0
- /package/src/cache/core/{primitives → __tests__}/$cache.spec.ts +0 -0
- /package/src/cache/redis/{providers → __tests__}/RedisCacheProvider.spec.ts +0 -0
- /package/src/command/{primitives → __tests__}/$command.spec.ts +0 -0
- /package/src/command/{helpers → __tests__}/Asker.spec.ts +0 -0
- /package/src/command/{helpers → __tests__}/Runner.spec.ts +0 -0
- /package/src/core/{primitives → __tests__}/$context.spec.ts +0 -0
- /package/src/core/{primitives → __tests__}/$env.spec.ts +0 -0
- /package/src/core/{primitives → __tests__}/$hook.spec.ts +0 -0
- /package/src/core/{primitives → __tests__}/$inject.spec.ts +0 -0
- /package/src/core/{primitives → __tests__}/$module.spec.ts +0 -0
- /package/src/core/{providers → __tests__}/CodecManager.spec.ts +0 -0
- /package/src/core/{providers → __tests__}/EventManager.spec.ts +0 -0
- /package/src/core/{providers → __tests__}/StateManager.spec.ts +0 -0
- /package/src/core/{providers → __tests__}/TypeProvider.spec.ts +0 -0
- /package/src/datetime/{primitives → __tests__}/$interval.spec.ts +0 -0
- /package/src/datetime/{providers → __tests__}/DateTimeProvider.spec.ts +0 -0
- /package/src/email/core/{primitives → __tests__}/$email.spec.ts +0 -0
- /package/src/fake/{providers → __tests__}/FakeProvider.spec.ts +0 -0
- /package/src/lock/core/{providers → __tests__}/MemoryLockProvider.spec.ts +0 -0
- /package/src/lock/redis/{providers → __tests__}/RedisLockProvider.spec.ts +0 -0
- /package/src/logger/{primitives → __tests__}/$logger.spec.ts +0 -0
- /package/src/logger/{services → __tests__}/Logger.spec.ts +0 -0
- /package/src/mcp/{primitives → __tests__}/$prompt.spec.ts +0 -0
- /package/src/mcp/{primitives → __tests__}/$resource.spec.ts +0 -0
- /package/src/mcp/{primitives → __tests__}/$tool.spec.ts +0 -0
- /package/src/mcp/{providers → __tests__}/McpServerProvider.spec.ts +0 -0
- /package/src/mcp/{helpers → __tests__}/jsonrpc.spec.ts +0 -0
- /package/src/orm/core/{helpers → __tests__}/parseQueryString.spec.ts +0 -0
- /package/src/queue/core/{primitives → __tests__}/$consumer.spec.ts +0 -0
- /package/src/queue/core/{providers → __tests__}/MemoryQueueProvider.spec.ts +0 -0
- /package/src/queue/core/{providers → __tests__}/WorkerProvider.spec.ts +0 -0
- /package/src/queue/redis/{providers → __tests__}/RedisQueueProvider.spec.ts +0 -0
- /package/src/react/form/{hooks → __tests__}/useForm.browser.spec.tsx +0 -0
- /package/src/react/head/{hooks → __tests__}/useHead.spec.tsx +0 -0
- /package/src/react/i18n/{components → __tests__}/Localize.spec.tsx +0 -0
- /package/src/react/router/{primitives → __tests__}/$page.browser.spec.tsx +0 -0
- /package/src/react/router/{primitives → __tests__}/$page.middleware.spec.tsx +0 -0
- /package/src/react/router/{primitives → __tests__}/$page.spec.tsx +0 -0
- /package/src/react/router/{providers → __tests__}/ReactPreloadProvider.spec.ts +0 -0
- /package/src/react/router/{providers → __tests__}/ReactServerProvider.spec.tsx +0 -0
- /package/src/react/router/{providers → __tests__}/ReactServerTemplateProvider.spec.ts +0 -0
- /package/src/retry/{primitives → __tests__}/$retry.spec.ts +0 -0
- /package/src/retry/{providers → __tests__}/RetryProvider.spec.ts +0 -0
- /package/src/router/{providers → __tests__}/RouterProvider.spec.ts +0 -0
- /package/src/security/{primitives → __tests__}/$issuer.spec.ts +0 -0
- /package/src/security/{primitives → __tests__}/$permission.spec.ts +0 -0
- /package/src/security/{primitives → __tests__}/$role.spec.ts +0 -0
- /package/src/security/{primitives → __tests__}/$serviceAccount.spec.ts +0 -0
- /package/src/security/{providers → __tests__}/SecurityProvider.spec.ts +0 -0
- /package/src/server/cookies/{providers → __tests__}/ServerCookiesProvider.spec.ts +0 -0
- /package/src/server/core/{primitives → __tests__}/$action.spec.ts +0 -0
- /package/src/server/core/{primitives → __tests__}/$middleware.spec.ts +0 -0
- /package/src/server/core/{primitives → __tests__}/$route.spec.ts +0 -0
- /package/src/server/core/{primitives → __tests__}/$sse.spec.ts +0 -0
- /package/src/server/core/{providers → __tests__}/BunHttpServerProvider.bun.spec.ts +0 -0
- /package/src/server/core/{services → __tests__}/HttpClient.spec.ts +0 -0
- /package/src/server/core/{providers → __tests__}/ServerLoggerProvider.spec.ts +0 -0
- /package/src/server/core/{services → __tests__}/UserAgentParser.spec.ts +0 -0
- /package/src/server/cors/{providers → __tests__}/ServerCorsProvider.spec.ts +0 -0
- /package/src/server/etag/{providers → __tests__}/ServerEtagProvider.spec.ts +0 -0
- /package/src/server/health/{providers → __tests__}/ServerHealthProvider.spec.ts +0 -0
- /package/src/server/links/{primitives → __tests__}/$remote.spec.ts +0 -0
- /package/src/server/links/{services → __tests__}/BatchEndpoint.spec.ts +0 -0
- /package/src/server/links/{providers → __tests__}/LinkProvider.spec.ts +0 -0
- /package/src/server/links/{providers → __tests__}/ServerLinksProvider.spec.ts +0 -0
- /package/src/server/metrics/{providers → __tests__}/ServerMetricsProvider.spec.ts +0 -0
- /package/src/server/proxy/{primitives → __tests__}/$proxy.spec.ts +0 -0
- /package/src/server/rate-limit/{providers → __tests__}/ServerRateLimitProvider.spec.ts +0 -0
- /package/src/server/static/{primitives → __tests__}/$serve.spec.ts +0 -0
- /package/src/server/swagger/{primitives → __tests__}/$swagger.spec.ts +0 -0
- /package/src/sms/{primitives → __tests__}/$sms.spec.ts +0 -0
- /package/src/sms/{providers → __tests__}/MemorySmsProvider.spec.ts +0 -0
- /package/src/system/{services → __tests__}/FileDetector.spec.ts +0 -0
- /package/src/system/{providers → __tests__}/NodeFileSystemProvider.spec.ts +0 -0
- /package/src/topic/core/{primitives → __tests__}/$subscriber.spec.ts +0 -0
- /package/src/topic/core/{providers → __tests__}/MemoryTopicProvider.spec.ts +0 -0
- /package/src/topic/redis/{providers → __tests__}/RedisTopicProvider.spec.ts +0 -0
- /package/src/websocket/{primitives → __tests__}/$channel.spec.ts +0 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { type Alepha, t } from "alepha";
|
|
2
|
+
import { currentUserAtom } from "alepha/security";
|
|
3
|
+
import { expect } from "vitest";
|
|
4
|
+
import { $entity, $repository, db } from "../core/index.ts";
|
|
5
|
+
|
|
6
|
+
const entity = $entity({
|
|
7
|
+
name: "test_org_entity",
|
|
8
|
+
schema: t.object({
|
|
9
|
+
id: db.primaryKey(),
|
|
10
|
+
organization: db.organization(),
|
|
11
|
+
name: t.optional(t.text()),
|
|
12
|
+
}),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
class App {
|
|
16
|
+
repository = $repository(entity);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const setup = async (alepha: Alepha) => {
|
|
20
|
+
const app = alepha.inject(App);
|
|
21
|
+
await alepha.start();
|
|
22
|
+
return { repository: app.repository, alepha };
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const testOrgUserSeesOwnAndGlobalRows = async (alepha: Alepha) => {
|
|
26
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
27
|
+
|
|
28
|
+
// Create rows for org-a, org-b, and global (null)
|
|
29
|
+
await repository.create({
|
|
30
|
+
name: "org-a-row",
|
|
31
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
32
|
+
});
|
|
33
|
+
await repository.create({
|
|
34
|
+
name: "org-b-row",
|
|
35
|
+
organization: "b0000000-0000-0000-0000-000000000002",
|
|
36
|
+
});
|
|
37
|
+
await repository.create({ name: "global-row" });
|
|
38
|
+
|
|
39
|
+
// User in org-a should see org-a + global
|
|
40
|
+
app.store.set(currentUserAtom, {
|
|
41
|
+
id: "user-1",
|
|
42
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const results = await repository.findMany();
|
|
46
|
+
expect(results).toHaveLength(2);
|
|
47
|
+
expect(results.map((r: any) => r.name).sort()).toEqual([
|
|
48
|
+
"global-row",
|
|
49
|
+
"org-a-row",
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
// Count should also be filtered
|
|
53
|
+
expect(await repository.count()).toEqual(2);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const testMasterUserSeesEverything = async (alepha: Alepha) => {
|
|
57
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
58
|
+
|
|
59
|
+
await repository.create({
|
|
60
|
+
name: "org-a-row",
|
|
61
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
62
|
+
});
|
|
63
|
+
await repository.create({
|
|
64
|
+
name: "org-b-row",
|
|
65
|
+
organization: "b0000000-0000-0000-0000-000000000002",
|
|
66
|
+
});
|
|
67
|
+
await repository.create({ name: "global-row" });
|
|
68
|
+
|
|
69
|
+
// Master user (no org) sees everything
|
|
70
|
+
app.store.set(currentUserAtom, {
|
|
71
|
+
id: "master-user",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const results = await repository.findMany();
|
|
75
|
+
expect(results).toHaveLength(3);
|
|
76
|
+
expect(await repository.count()).toEqual(3);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const testNoUserSeesEverything = async (alepha: Alepha) => {
|
|
80
|
+
const { repository } = await setup(alepha);
|
|
81
|
+
|
|
82
|
+
await repository.create({
|
|
83
|
+
name: "org-a-row",
|
|
84
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
85
|
+
});
|
|
86
|
+
await repository.create({ name: "global-row" });
|
|
87
|
+
|
|
88
|
+
// No user in context = no filter
|
|
89
|
+
const results = await repository.findMany();
|
|
90
|
+
expect(results).toHaveLength(2);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const testAutoStampOnCreate = async (alepha: Alepha) => {
|
|
94
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
95
|
+
|
|
96
|
+
app.store.set(currentUserAtom, {
|
|
97
|
+
id: "user-1",
|
|
98
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Create without specifying organization — should be auto-stamped
|
|
102
|
+
const entity = await repository.create({ name: "auto-stamped" });
|
|
103
|
+
expect(entity.organization).toEqual("a0000000-0000-0000-0000-000000000001");
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const testAutoStampNullForMasterUser = async (alepha: Alepha) => {
|
|
107
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
108
|
+
|
|
109
|
+
app.store.set(currentUserAtom, {
|
|
110
|
+
id: "master-user",
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Master user creates a row — org stays null (global)
|
|
114
|
+
const entity = await repository.create({ name: "master-row" });
|
|
115
|
+
expect(entity.organization).toBeUndefined();
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const testAutoStampDoesNotOverrideExplicit = async (alepha: Alepha) => {
|
|
119
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
120
|
+
|
|
121
|
+
app.store.set(currentUserAtom, {
|
|
122
|
+
id: "user-1",
|
|
123
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Explicitly set organization — should not be overridden
|
|
127
|
+
const entity = await repository.create({
|
|
128
|
+
name: "explicit-org",
|
|
129
|
+
organization: "b0000000-0000-0000-0000-000000000002",
|
|
130
|
+
});
|
|
131
|
+
expect(entity.organization).toEqual("b0000000-0000-0000-0000-000000000002");
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const testAutoStampOnCreateMany = async (alepha: Alepha) => {
|
|
135
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
136
|
+
|
|
137
|
+
app.store.set(currentUserAtom, {
|
|
138
|
+
id: "user-1",
|
|
139
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const entities = await repository.createMany([
|
|
143
|
+
{ name: "row-1" },
|
|
144
|
+
{ name: "row-2" },
|
|
145
|
+
]);
|
|
146
|
+
expect(entities[0].organization).toEqual(
|
|
147
|
+
"a0000000-0000-0000-0000-000000000001",
|
|
148
|
+
);
|
|
149
|
+
expect(entities[1].organization).toEqual(
|
|
150
|
+
"a0000000-0000-0000-0000-000000000001",
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const testOrgFilterOnUpdateOne = async (alepha: Alepha) => {
|
|
155
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
156
|
+
|
|
157
|
+
const row = await repository.create({
|
|
158
|
+
name: "org-b-row",
|
|
159
|
+
organization: "b0000000-0000-0000-0000-000000000002",
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// User in org-a cannot update org-b row
|
|
163
|
+
app.store.set(currentUserAtom, {
|
|
164
|
+
id: "user-1",
|
|
165
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const updated = await repository.updateMany(
|
|
169
|
+
{ id: { eq: row.id } },
|
|
170
|
+
{ name: "hacked" },
|
|
171
|
+
);
|
|
172
|
+
expect(updated).toHaveLength(0);
|
|
173
|
+
|
|
174
|
+
// Verify row is unchanged (read as master)
|
|
175
|
+
app.store.set(currentUserAtom, { id: "master" });
|
|
176
|
+
const check = await repository.getById(row.id);
|
|
177
|
+
expect(check.name).toEqual("org-b-row");
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const testOrgFilterOnDelete = async (alepha: Alepha) => {
|
|
181
|
+
const { repository, alepha: app } = await setup(alepha);
|
|
182
|
+
|
|
183
|
+
const row = await repository.create({
|
|
184
|
+
name: "org-b-row",
|
|
185
|
+
organization: "b0000000-0000-0000-0000-000000000002",
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// User in org-a cannot delete org-b row
|
|
189
|
+
app.store.set(currentUserAtom, {
|
|
190
|
+
id: "user-1",
|
|
191
|
+
organization: "a0000000-0000-0000-0000-000000000001",
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const deleted = await repository.deleteMany({ id: { eq: row.id } });
|
|
195
|
+
expect(deleted).toHaveLength(0);
|
|
196
|
+
|
|
197
|
+
// Verify row still exists
|
|
198
|
+
app.store.set(currentUserAtom, { id: "master" });
|
|
199
|
+
expect(await repository.count()).toEqual(1);
|
|
200
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Alepha } from "alepha";
|
|
2
|
+
import { describe, it } from "vitest";
|
|
3
|
+
import { AlephaOrmPostgres } from "../postgres/index.ts";
|
|
4
|
+
import {
|
|
5
|
+
testAutoStampDoesNotOverrideExplicit,
|
|
6
|
+
testAutoStampNullForMasterUser,
|
|
7
|
+
testAutoStampOnCreate,
|
|
8
|
+
testAutoStampOnCreateMany,
|
|
9
|
+
testMasterUserSeesEverything,
|
|
10
|
+
testNoUserSeesEverything,
|
|
11
|
+
testOrgFilterOnDelete,
|
|
12
|
+
testOrgFilterOnUpdateOne,
|
|
13
|
+
testOrgUserSeesOwnAndGlobalRows,
|
|
14
|
+
} from "./organization-tests.ts";
|
|
15
|
+
|
|
16
|
+
describe("organization", () => {
|
|
17
|
+
it("org user sees own + global rows (sqlite)", async () => {
|
|
18
|
+
await testOrgUserSeesOwnAndGlobalRows(
|
|
19
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
it("org user sees own + global rows (postgres)", async () => {
|
|
23
|
+
await testOrgUserSeesOwnAndGlobalRows(
|
|
24
|
+
Alepha.create().with(AlephaOrmPostgres),
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("master user sees everything (sqlite)", async () => {
|
|
29
|
+
await testMasterUserSeesEverything(
|
|
30
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
it("master user sees everything (postgres)", async () => {
|
|
34
|
+
await testMasterUserSeesEverything(Alepha.create().with(AlephaOrmPostgres));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("no user sees everything (sqlite)", async () => {
|
|
38
|
+
await testNoUserSeesEverything(
|
|
39
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
it("no user sees everything (postgres)", async () => {
|
|
43
|
+
await testNoUserSeesEverything(Alepha.create().with(AlephaOrmPostgres));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("auto-stamps organization on create (sqlite)", async () => {
|
|
47
|
+
await testAutoStampOnCreate(
|
|
48
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
it("auto-stamps organization on create (postgres)", async () => {
|
|
52
|
+
await testAutoStampOnCreate(Alepha.create().with(AlephaOrmPostgres));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("auto-stamps null for master user (sqlite)", async () => {
|
|
56
|
+
await testAutoStampNullForMasterUser(
|
|
57
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
it("auto-stamps null for master user (postgres)", async () => {
|
|
61
|
+
await testAutoStampNullForMasterUser(
|
|
62
|
+
Alepha.create().with(AlephaOrmPostgres),
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("does not override explicit organization (sqlite)", async () => {
|
|
67
|
+
await testAutoStampDoesNotOverrideExplicit(
|
|
68
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
it("does not override explicit organization (postgres)", async () => {
|
|
72
|
+
await testAutoStampDoesNotOverrideExplicit(
|
|
73
|
+
Alepha.create().with(AlephaOrmPostgres),
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("auto-stamps on createMany (sqlite)", async () => {
|
|
78
|
+
await testAutoStampOnCreateMany(
|
|
79
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
it("auto-stamps on createMany (postgres)", async () => {
|
|
83
|
+
await testAutoStampOnCreateMany(Alepha.create().with(AlephaOrmPostgres));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("org filter on updateMany (sqlite)", async () => {
|
|
87
|
+
await testOrgFilterOnUpdateOne(
|
|
88
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
it("org filter on updateMany (postgres)", async () => {
|
|
92
|
+
await testOrgFilterOnUpdateOne(Alepha.create().with(AlephaOrmPostgres));
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("org filter on delete (sqlite)", async () => {
|
|
96
|
+
await testOrgFilterOnDelete(
|
|
97
|
+
Alepha.create({ env: { DATABASE_URL: "sqlite://:memory:" } }),
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
it("org filter on delete (postgres)", async () => {
|
|
101
|
+
await testOrgFilterOnDelete(Alepha.create().with(AlephaOrmPostgres));
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it } from "bun:test";
|
|
2
2
|
import { Alepha, t } from "alepha";
|
|
3
|
-
import { $entity, $repository, DatabaseProvider, db } from "
|
|
4
|
-
import {
|
|
3
|
+
import { $entity, $repository, DatabaseProvider, db } from "../index.ts";
|
|
4
|
+
import {
|
|
5
|
+
BunSqliteProvider,
|
|
6
|
+
bunSqliteOptions,
|
|
7
|
+
} from "../providers/drivers/BunSqliteProvider.ts";
|
|
5
8
|
|
|
6
9
|
// -------------------------------------------------------------------------------------------------------------------
|
|
7
10
|
|
|
@@ -15,6 +15,7 @@ export const PG_IDENTITY = Symbol.for("Alepha.Postgres.Identity");
|
|
|
15
15
|
export const PG_ENUM = Symbol.for("Alepha.Postgres.Enum");
|
|
16
16
|
export const PG_REF = Symbol.for("Alepha.Postgres.Ref");
|
|
17
17
|
export const PG_GENERATED = Symbol.for("Alepha.Postgres.Generated");
|
|
18
|
+
export const PG_ORGANIZATION = Symbol.for("Alepha.Postgres.Organization");
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* @deprecated Use `PG_IDENTITY` instead.
|
|
@@ -36,6 +37,7 @@ export type PgSymbols = {
|
|
|
36
37
|
[PG_REF]: PgRefOptions;
|
|
37
38
|
[PG_ENUM]: PgEnumOptions;
|
|
38
39
|
[PG_GENERATED]: PgGeneratedOptions;
|
|
40
|
+
[PG_ORGANIZATION]: {};
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
* @deprecated Use `PG_IDENTITY` instead.
|
|
@@ -90,6 +90,37 @@ export interface EntityPrimitiveOptions<
|
|
|
90
90
|
*/
|
|
91
91
|
where?: SQL;
|
|
92
92
|
}
|
|
93
|
+
| {
|
|
94
|
+
/**
|
|
95
|
+
* SQL expressions for expression-based indexes.
|
|
96
|
+
*
|
|
97
|
+
* Can include column references and SQL functions like `LOWER()`, `UPPER()`, etc.
|
|
98
|
+
* Columns and expressions can be mixed together.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* // Case-insensitive unique username per realm
|
|
103
|
+
* indexes: [{
|
|
104
|
+
* expressions: (self) => [self.realm, sql`LOWER(${self.username})`],
|
|
105
|
+
* unique: true,
|
|
106
|
+
* name: "users_realm_username_lower_idx",
|
|
107
|
+
* }]
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
expressions: (self: Record<Keys & string, any>) => (SQL | any)[];
|
|
111
|
+
/**
|
|
112
|
+
* Whether this should be a unique index (enforces uniqueness constraint).
|
|
113
|
+
*/
|
|
114
|
+
unique?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Custom name for the index. If not provided, generates name automatically.
|
|
117
|
+
*/
|
|
118
|
+
name: string;
|
|
119
|
+
/**
|
|
120
|
+
* Partial index condition. Only rows matching this SQL expression are indexed.
|
|
121
|
+
*/
|
|
122
|
+
where?: SQL;
|
|
123
|
+
}
|
|
93
124
|
)[];
|
|
94
125
|
|
|
95
126
|
/**
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
PG_DELETED_AT,
|
|
23
23
|
PG_ENUM,
|
|
24
24
|
PG_IDENTITY,
|
|
25
|
+
PG_ORGANIZATION,
|
|
25
26
|
PG_PRIMARY_KEY,
|
|
26
27
|
PG_REF,
|
|
27
28
|
PG_UPDATED_AT,
|
|
@@ -187,6 +188,16 @@ export class DatabaseTypeProvider {
|
|
|
187
188
|
public readonly deletedAt = (options?: TStringOptions) =>
|
|
188
189
|
pgAttr(t.optional(t.datetime(options)), PG_DELETED_AT);
|
|
189
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Creates an organization column for multi-tenant row scoping.
|
|
193
|
+
*
|
|
194
|
+
* When present, queries are automatically filtered by the current user's organization.
|
|
195
|
+
* Rows with `null` organization are considered global and visible to everyone.
|
|
196
|
+
* On create, the column is auto-stamped with the current user's organization.
|
|
197
|
+
*/
|
|
198
|
+
public readonly organization = () =>
|
|
199
|
+
pgAttr(t.optional(t.uuid()), PG_ORGANIZATION);
|
|
200
|
+
|
|
190
201
|
/**
|
|
191
202
|
* Creates a Postgres ENUM type.
|
|
192
203
|
*
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
$env,
|
|
7
7
|
$hook,
|
|
8
8
|
$inject,
|
|
9
|
-
$
|
|
9
|
+
$state,
|
|
10
10
|
AlephaError,
|
|
11
11
|
type Static,
|
|
12
12
|
t,
|
|
@@ -74,7 +74,7 @@ declare module "alepha" {
|
|
|
74
74
|
export class BunSqliteProvider extends DatabaseProvider {
|
|
75
75
|
protected readonly env = $env(envSchema);
|
|
76
76
|
protected readonly builder = $inject(SqliteModelBuilder);
|
|
77
|
-
protected readonly options = $
|
|
77
|
+
protected readonly options = $state(bunSqliteOptions);
|
|
78
78
|
|
|
79
79
|
protected sqlite?: Database;
|
|
80
80
|
protected bunDb?: BunSQLiteDatabase;
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
$env,
|
|
8
8
|
$hook,
|
|
9
9
|
$inject,
|
|
10
|
-
$
|
|
10
|
+
$state,
|
|
11
11
|
AlephaError,
|
|
12
12
|
type Static,
|
|
13
13
|
t,
|
|
@@ -81,7 +81,7 @@ declare module "alepha" {
|
|
|
81
81
|
export class NodeSqliteProvider extends DatabaseProvider {
|
|
82
82
|
protected readonly env = $env(envSchema);
|
|
83
83
|
protected readonly builder = $inject(SqliteModelBuilder);
|
|
84
|
-
protected readonly options = $
|
|
84
|
+
protected readonly options = $state(nodeSqliteOptions);
|
|
85
85
|
|
|
86
86
|
protected sqlite!: DatabaseSync;
|
|
87
87
|
protected drizzleDb!: any;
|
|
@@ -182,7 +182,7 @@ export class NodeSqliteProvider extends DatabaseProvider {
|
|
|
182
182
|
await this.migrate();
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
this.log.info(`
|
|
185
|
+
this.log.info(`Sqlite connection OK`, { at: filepath });
|
|
186
186
|
},
|
|
187
187
|
});
|
|
188
188
|
|
|
@@ -136,6 +136,17 @@ export abstract class ModelBuilder {
|
|
|
136
136
|
}
|
|
137
137
|
configs.push(idx);
|
|
138
138
|
}
|
|
139
|
+
} else if ("expressions" in indexDef) {
|
|
140
|
+
const parts = indexDef.expressions(self as any);
|
|
141
|
+
if (parts.length > 0) {
|
|
142
|
+
let idx = indexDef.unique
|
|
143
|
+
? builders.uniqueIndex(indexDef.name).on(...parts)
|
|
144
|
+
: builders.index(indexDef.name).on(...parts);
|
|
145
|
+
if ("where" in indexDef && indexDef.where) {
|
|
146
|
+
idx = (idx as any).where(indexDef.where);
|
|
147
|
+
}
|
|
148
|
+
configs.push(idx);
|
|
149
|
+
}
|
|
139
150
|
} else if ("columns" in indexDef) {
|
|
140
151
|
const columnNames = indexDef.columns.map((col: any) =>
|
|
141
152
|
this.toColumnName(col as string),
|
|
@@ -338,11 +338,25 @@ export class QueryManager {
|
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
if (operator?.ilike != null) {
|
|
341
|
-
|
|
341
|
+
if (dialect === "sqlite") {
|
|
342
|
+
// SQLite doesn't have ilike, use LOWER() for case-insensitive matching
|
|
343
|
+
conditions.push(
|
|
344
|
+
sql`LOWER(${column}) LIKE LOWER(${encodeValue(operator.ilike)})`,
|
|
345
|
+
);
|
|
346
|
+
} else {
|
|
347
|
+
conditions.push(ilike(column, encodeValue(operator.ilike)));
|
|
348
|
+
}
|
|
342
349
|
}
|
|
343
350
|
|
|
344
351
|
if (operator?.notIlike != null) {
|
|
345
|
-
|
|
352
|
+
if (dialect === "sqlite") {
|
|
353
|
+
// SQLite doesn't have ilike, use LOWER() for case-insensitive matching
|
|
354
|
+
conditions.push(
|
|
355
|
+
sql`LOWER(${column}) NOT LIKE LOWER(${encodeValue(operator.notIlike)})`,
|
|
356
|
+
);
|
|
357
|
+
} else {
|
|
358
|
+
conditions.push(notIlike(column, encodeValue(operator.notIlike)));
|
|
359
|
+
}
|
|
346
360
|
}
|
|
347
361
|
|
|
348
362
|
if (operator?.contains != null) {
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from "alepha";
|
|
13
13
|
import { type DateTime, DateTimeProvider } from "alepha/datetime";
|
|
14
14
|
import { $logger } from "alepha/logger";
|
|
15
|
+
import { currentUserAtom } from "alepha/security";
|
|
15
16
|
import {
|
|
16
17
|
asc,
|
|
17
18
|
avg,
|
|
@@ -43,6 +44,7 @@ import type {
|
|
|
43
44
|
import type { PgTransactionConfig } from "drizzle-orm/pg-core/session";
|
|
44
45
|
import {
|
|
45
46
|
PG_DELETED_AT,
|
|
47
|
+
PG_ORGANIZATION,
|
|
46
48
|
PG_PRIMARY_KEY,
|
|
47
49
|
PG_UPDATED_AT,
|
|
48
50
|
PG_VERSION,
|
|
@@ -388,9 +390,8 @@ export abstract class Repository<T extends TObject> {
|
|
|
388
390
|
);
|
|
389
391
|
}
|
|
390
392
|
|
|
391
|
-
const where = this.
|
|
392
|
-
(query.where ?? {}) as PgQueryWhere<T>,
|
|
393
|
-
opts,
|
|
393
|
+
const where = this.withOrganization(
|
|
394
|
+
this.withDeletedAt((query.where ?? {}) as PgQueryWhere<T>, opts),
|
|
394
395
|
);
|
|
395
396
|
|
|
396
397
|
builder.where(() => this.toSQL(where, joins));
|
|
@@ -565,9 +566,8 @@ export abstract class Repository<T extends TObject> {
|
|
|
565
566
|
);
|
|
566
567
|
|
|
567
568
|
if (opts.count) {
|
|
568
|
-
const countWhere = this.
|
|
569
|
-
(query.where ?? {}) as PgQueryWhere<T>,
|
|
570
|
-
opts,
|
|
569
|
+
const countWhere = this.withOrganization(
|
|
570
|
+
this.withDeletedAt((query.where ?? {}) as PgQueryWhere<T>, opts),
|
|
571
571
|
);
|
|
572
572
|
|
|
573
573
|
tasks.push(
|
|
@@ -662,6 +662,7 @@ export abstract class Repository<T extends TObject> {
|
|
|
662
662
|
opts: StatementOptions = {},
|
|
663
663
|
): Promise<Static<T>> {
|
|
664
664
|
this.assertWritable();
|
|
665
|
+
this.stampOrganization(data);
|
|
665
666
|
await this.alepha.events.emit("repository:create:before", {
|
|
666
667
|
tableName: this.tableName,
|
|
667
668
|
data,
|
|
@@ -705,6 +706,10 @@ export abstract class Repository<T extends TObject> {
|
|
|
705
706
|
return [];
|
|
706
707
|
}
|
|
707
708
|
|
|
709
|
+
for (const value of values) {
|
|
710
|
+
this.stampOrganization(value);
|
|
711
|
+
}
|
|
712
|
+
|
|
708
713
|
await this.alepha.events.emit("repository:create:before", {
|
|
709
714
|
tableName: this.tableName,
|
|
710
715
|
data: values,
|
|
@@ -774,6 +779,7 @@ export abstract class Repository<T extends TObject> {
|
|
|
774
779
|
} = {},
|
|
775
780
|
): Promise<Static<T>> {
|
|
776
781
|
this.assertWritable();
|
|
782
|
+
this.stampOrganization(data);
|
|
777
783
|
await this.alepha.events.emit("repository:create:before", {
|
|
778
784
|
tableName: this.tableName,
|
|
779
785
|
data,
|
|
@@ -862,7 +868,7 @@ export abstract class Repository<T extends TObject> {
|
|
|
862
868
|
opts.now ?? this.dateTimeProvider.nowISOString();
|
|
863
869
|
}
|
|
864
870
|
|
|
865
|
-
where = this.withDeletedAt(where, opts);
|
|
871
|
+
where = this.withOrganization(this.withDeletedAt(where, opts));
|
|
866
872
|
row = this.cast(row, false) as any;
|
|
867
873
|
|
|
868
874
|
// do not update the ID field
|
|
@@ -1025,7 +1031,7 @@ export abstract class Repository<T extends TObject> {
|
|
|
1025
1031
|
opts.now ?? this.dateTimeProvider.nowISOString();
|
|
1026
1032
|
}
|
|
1027
1033
|
|
|
1028
|
-
where = this.withDeletedAt(where, opts);
|
|
1034
|
+
where = this.withOrganization(this.withDeletedAt(where, opts));
|
|
1029
1035
|
data = this.cast(data, false) as any;
|
|
1030
1036
|
try {
|
|
1031
1037
|
const entities = await this.rawUpdate(opts)
|
|
@@ -1070,6 +1076,8 @@ export abstract class Repository<T extends TObject> {
|
|
|
1070
1076
|
);
|
|
1071
1077
|
}
|
|
1072
1078
|
|
|
1079
|
+
where = this.withOrganization(where);
|
|
1080
|
+
|
|
1073
1081
|
await this.alepha.events.emit("repository:delete:before", {
|
|
1074
1082
|
tableName: this.tableName,
|
|
1075
1083
|
where,
|
|
@@ -1170,7 +1178,7 @@ export abstract class Repository<T extends TObject> {
|
|
|
1170
1178
|
where: PgQueryWhereOrSQL<T> = {},
|
|
1171
1179
|
opts: StatementOptions = {},
|
|
1172
1180
|
): Promise<number> {
|
|
1173
|
-
where = this.withDeletedAt(where, opts);
|
|
1181
|
+
where = this.withOrganization(this.withDeletedAt(where, opts));
|
|
1174
1182
|
const db = opts.tx === null ? this.provider.db : (opts.tx ?? this.db);
|
|
1175
1183
|
return db.$count(this.table, this.toSQL(where));
|
|
1176
1184
|
}
|
|
@@ -1234,7 +1242,9 @@ export abstract class Repository<T extends TObject> {
|
|
|
1234
1242
|
|
|
1235
1243
|
// WHERE
|
|
1236
1244
|
if (query.where) {
|
|
1237
|
-
const where = this.
|
|
1245
|
+
const where = this.withOrganization(
|
|
1246
|
+
this.withDeletedAt(query.where as any, opts),
|
|
1247
|
+
);
|
|
1238
1248
|
builder = builder.where(this.toSQL(where)) as any;
|
|
1239
1249
|
}
|
|
1240
1250
|
|
|
@@ -1458,6 +1468,56 @@ export abstract class Repository<T extends TObject> {
|
|
|
1458
1468
|
return undefined;
|
|
1459
1469
|
}
|
|
1460
1470
|
|
|
1471
|
+
protected withOrganization(
|
|
1472
|
+
where: PgQueryWhereOrSQL<T>,
|
|
1473
|
+
): PgQueryWhereOrSQL<T> {
|
|
1474
|
+
const orgField = this.organizationField();
|
|
1475
|
+
if (!orgField) {
|
|
1476
|
+
return where;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
const user = this.alepha.store.get(currentUserAtom);
|
|
1480
|
+
if (!user?.organization) {
|
|
1481
|
+
return where;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
return {
|
|
1485
|
+
and: [
|
|
1486
|
+
where,
|
|
1487
|
+
{
|
|
1488
|
+
or: [
|
|
1489
|
+
{ [orgField.key]: { eq: user.organization } },
|
|
1490
|
+
{ [orgField.key]: { isNull: true } },
|
|
1491
|
+
],
|
|
1492
|
+
} as any,
|
|
1493
|
+
],
|
|
1494
|
+
} as PgQueryWhereOrSQL<T>;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
protected stampOrganization(data: any): void {
|
|
1498
|
+
const orgField = this.organizationField();
|
|
1499
|
+
if (!orgField) {
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
if (data[orgField.key] != null) {
|
|
1504
|
+
return;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
const user = this.alepha.store.get(currentUserAtom);
|
|
1508
|
+
if (user?.organization) {
|
|
1509
|
+
data[orgField.key] = user.organization;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
protected organizationField(): PgAttrField | undefined {
|
|
1514
|
+
const fields = getAttrFields(this.entity.schema, PG_ORGANIZATION);
|
|
1515
|
+
if (fields.length > 0) {
|
|
1516
|
+
return fields[0];
|
|
1517
|
+
}
|
|
1518
|
+
return undefined;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1461
1521
|
/**
|
|
1462
1522
|
* Convert something to valid Pg Insert Value.
|
|
1463
1523
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it } from "bun:test";
|
|
2
2
|
import { Alepha, t } from "alepha";
|
|
3
3
|
import { $entity, $repository, DatabaseProvider, db } from "alepha/orm";
|
|
4
|
-
import { BunPostgresProvider } from "
|
|
4
|
+
import { BunPostgresProvider } from "../providers/BunPostgresProvider.ts";
|
|
5
5
|
|
|
6
6
|
// -------------------------------------------------------------------------------------------------------------------
|
|
7
7
|
|