alepha 0.14.1 → 0.14.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/README.md +3 -3
- package/dist/api/audits/index.browser.js +5 -5
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.d.ts +784 -784
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +13 -13
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.browser.js +5 -5
- package/dist/api/files/index.browser.js.map +1 -1
- package/dist/api/files/index.d.ts +57 -57
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +71 -71
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +5 -5
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +165 -165
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +10 -10
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/notifications/index.browser.js +10 -10
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +583 -171
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +12 -12
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.browser.js +163 -10
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +281 -276
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +196 -91
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.browser.js +19 -19
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +778 -764
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +831 -596
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.browser.js +6 -6
- package/dist/api/verifications/index.browser.js.map +1 -1
- package/dist/api/verifications/index.d.ts +125 -125
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +6 -6
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/bin/index.d.ts +1 -2
- package/dist/bin/index.js +0 -1
- package/dist/bin/index.js.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +249 -218
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +951 -821
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +40 -0
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +97 -17
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +14 -18
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +29 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +21 -24
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +21 -24
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/fake/index.js +195 -168
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.d.ts +8 -0
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +3 -0
- package/dist/file/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.browser.js +26 -5
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.d.ts +146 -121
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +49 -24
- package/dist/orm/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +29 -29
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +171 -155
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +0 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +2 -0
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.browser.js +22 -6
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +46 -44
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +24 -41
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/security/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +2 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +8 -3
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +12 -4
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.js.map +1 -1
- package/package.json +7 -7
- package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
- package/src/api/audits/entities/audits.ts +5 -5
- package/src/api/audits/index.browser.ts +1 -1
- package/src/api/audits/index.ts +3 -3
- package/src/api/audits/primitives/$audit.spec.ts +276 -0
- package/src/api/audits/services/AuditService.spec.ts +495 -0
- package/src/api/files/__tests__/$bucket.spec.ts +91 -0
- package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
- package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
- package/src/api/files/controllers/FileController.spec.ts +558 -0
- package/src/api/files/controllers/FileController.ts +4 -5
- package/src/api/files/entities/files.ts +5 -5
- package/src/api/files/index.browser.ts +1 -1
- package/src/api/files/index.ts +4 -4
- package/src/api/files/jobs/FileJobs.spec.ts +52 -0
- package/src/api/files/services/FileService.spec.ts +109 -0
- package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
- package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
- package/src/api/jobs/entities/jobExecutions.ts +5 -5
- package/src/api/jobs/index.ts +3 -3
- package/src/api/jobs/primitives/$job.spec.ts +476 -0
- package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
- package/src/api/notifications/entities/notifications.ts +5 -5
- package/src/api/notifications/index.browser.ts +1 -1
- package/src/api/notifications/index.ts +4 -4
- package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
- package/src/api/parameters/entities/parameters.ts +7 -17
- package/src/api/parameters/index.ts +3 -3
- package/src/api/parameters/primitives/$config.spec.ts +356 -0
- package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
- package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
- package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
- package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
- package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
- package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
- package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
- package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
- package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
- package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
- package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
- package/src/api/parameters/schemas/index.ts +15 -0
- package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
- package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
- package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
- package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
- package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
- package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
- package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
- package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
- package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
- package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
- package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
- package/src/api/users/controllers/AdminUserController.ts +116 -0
- package/src/api/users/controllers/UserController.ts +4 -107
- package/src/api/users/controllers/UserRealmController.ts +3 -0
- package/src/api/users/entities/identities.ts +6 -6
- package/src/api/users/entities/sessions.ts +6 -6
- package/src/api/users/entities/users.ts +9 -9
- package/src/api/users/index.ts +13 -6
- package/src/api/users/primitives/$userRealm.ts +13 -8
- package/src/api/users/services/CredentialService.spec.ts +509 -0
- package/src/api/users/services/CredentialService.ts +46 -0
- package/src/api/users/services/IdentityService.ts +15 -0
- package/src/api/users/services/RegistrationService.spec.ts +630 -0
- package/src/api/users/services/RegistrationService.ts +18 -0
- package/src/api/users/services/SessionService.spec.ts +301 -0
- package/src/api/users/services/SessionService.ts +110 -1
- package/src/api/users/services/UserService.ts +67 -2
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
- package/src/api/verifications/entities/verifications.ts +6 -6
- package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
- package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
- package/src/batch/primitives/$batch.spec.ts +766 -0
- package/src/batch/providers/BatchProvider.spec.ts +786 -0
- package/src/bin/index.ts +0 -1
- package/src/bucket/__tests__/shared.ts +194 -0
- package/src/bucket/primitives/$bucket.spec.ts +104 -0
- package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
- package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
- package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
- package/src/cache/core/__tests__/shared.ts +377 -0
- package/src/cache/core/primitives/$cache.spec.ts +111 -0
- package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
- package/src/cli/apps/AlephaCli.ts +54 -16
- package/src/cli/apps/AlephaPackageBuilderCli.ts +2 -1
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/commands/{ViteCommands.ts → build.ts} +2 -105
- package/src/cli/commands/clean.ts +14 -0
- package/src/cli/commands/{DrizzleCommands.ts → db.ts} +10 -117
- package/src/cli/commands/{DeployCommands.ts → deploy.ts} +1 -1
- package/src/cli/commands/dev.ts +69 -0
- package/src/cli/commands/format.ts +17 -0
- package/src/cli/commands/gen/changelog.spec.ts +315 -0
- package/src/cli/commands/{ChangelogCommands.ts → gen/changelog.ts} +16 -31
- package/src/cli/commands/gen/openapi.ts +71 -0
- package/src/cli/commands/gen.ts +18 -0
- package/src/cli/commands/{CoreCommands.ts → init.ts} +4 -40
- package/src/cli/commands/lint.ts +17 -0
- package/src/cli/commands/root.ts +41 -0
- package/src/cli/commands/run.ts +24 -0
- package/src/cli/commands/test.ts +42 -0
- package/src/cli/commands/typecheck.ts +24 -0
- package/src/cli/commands/{VerifyCommands.ts → verify.ts} +1 -13
- package/src/cli/defineConfig.ts +10 -1
- package/src/cli/index.ts +17 -7
- package/src/cli/services/AlephaCliUtils.ts +71 -32
- package/src/cli/services/GitMessageParser.ts +1 -1
- package/src/command/helpers/Asker.spec.ts +127 -0
- package/src/command/helpers/Runner.spec.ts +126 -0
- package/src/command/primitives/$command.spec.ts +1588 -0
- package/src/command/providers/CliProvider.ts +74 -24
- package/src/core/Alepha.ts +52 -4
- package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
- package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
- package/src/core/__tests__/Alepha-has.spec.ts +41 -0
- package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
- package/src/core/__tests__/Alepha-register.spec.ts +81 -0
- package/src/core/__tests__/Alepha-start.spec.ts +176 -0
- package/src/core/__tests__/Alepha-with.spec.ts +14 -0
- package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
- package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
- package/src/core/__tests__/descriptor.spec.ts +34 -0
- package/src/core/__tests__/fixtures/A.ts +5 -0
- package/src/core/__tests__/pagination.spec.ts +77 -0
- package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
- package/src/core/primitives/$atom.spec.ts +43 -0
- package/src/core/primitives/$hook.spec.ts +130 -0
- package/src/core/primitives/$inject.spec.ts +175 -0
- package/src/core/primitives/$module.spec.ts +115 -0
- package/src/core/providers/CodecManager.spec.ts +740 -0
- package/src/core/providers/EventManager.spec.ts +762 -0
- package/src/core/providers/EventManager.ts +4 -0
- package/src/core/providers/StateManager.spec.ts +365 -0
- package/src/core/providers/TypeProvider.spec.ts +1607 -0
- package/src/core/providers/TypeProvider.ts +20 -26
- package/src/datetime/primitives/$interval.spec.ts +103 -0
- package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
- package/src/email/primitives/$email.spec.ts +175 -0
- package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
- package/src/fake/__tests__/keyName.example.ts +40 -0
- package/src/fake/__tests__/keyName.spec.ts +152 -0
- package/src/fake/__tests__/module.example.ts +32 -0
- package/src/fake/providers/FakeProvider.spec.ts +438 -0
- package/src/file/providers/FileSystemProvider.ts +8 -0
- package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
- package/src/file/providers/NodeFileSystemProvider.ts +5 -0
- package/src/file/services/FileDetector.spec.ts +591 -0
- package/src/lock/core/__tests__/shared.ts +190 -0
- package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
- package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
- package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
- package/src/logger/primitives/$logger.spec.ts +108 -0
- package/src/logger/services/Logger.spec.ts +295 -0
- package/src/mcp/__tests__/errors.spec.ts +175 -0
- package/src/mcp/__tests__/integration.spec.ts +450 -0
- package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
- package/src/mcp/primitives/$prompt.spec.ts +468 -0
- package/src/mcp/primitives/$resource.spec.ts +390 -0
- package/src/mcp/primitives/$tool.spec.ts +406 -0
- package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
- package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
- package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
- package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
- package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
- package/src/orm/__tests__/$repository-save.spec.ts +37 -0
- package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
- package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
- package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
- package/src/orm/__tests__/delete-returning.spec.ts +256 -0
- package/src/orm/__tests__/deletedAt.spec.ts +80 -0
- package/src/orm/__tests__/enums.spec.ts +315 -0
- package/src/orm/__tests__/execute.spec.ts +72 -0
- package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
- package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
- package/src/orm/__tests__/joins.spec.ts +1114 -0
- package/src/orm/__tests__/page.spec.ts +287 -0
- package/src/orm/__tests__/primaryKey.spec.ts +87 -0
- package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
- package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
- package/src/orm/__tests__/references.spec.ts +102 -0
- package/src/orm/__tests__/security.spec.ts +710 -0
- package/src/orm/__tests__/sqlite.spec.ts +111 -0
- package/src/orm/__tests__/string-operators.spec.ts +429 -0
- package/src/orm/__tests__/timestamps.spec.ts +388 -0
- package/src/orm/__tests__/validation.spec.ts +183 -0
- package/src/orm/__tests__/version.spec.ts +64 -0
- package/src/orm/helpers/parseQueryString.spec.ts +196 -0
- package/src/orm/index.browser.ts +1 -1
- package/src/orm/index.ts +10 -6
- package/src/orm/primitives/$repository.spec.ts +137 -0
- package/src/orm/primitives/$sequence.spec.ts +29 -0
- package/src/orm/primitives/$transaction.spec.ts +82 -0
- package/src/orm/providers/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
- package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
- package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
- package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
- package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
- package/src/orm/services/ModelBuilder.spec.ts +575 -0
- package/src/orm/services/Repository.spec.ts +137 -0
- package/src/queue/core/__tests__/shared.ts +143 -0
- package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
- package/src/queue/core/providers/WorkerProvider.spec.ts +378 -0
- package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
- package/src/redis/__tests__/redis.spec.ts +58 -0
- package/src/retry/primitives/$retry.spec.ts +234 -0
- package/src/retry/providers/RetryProvider.spec.ts +438 -0
- package/src/router/__tests__/match.spec.ts +252 -0
- package/src/router/providers/RouterProvider.spec.ts +197 -0
- package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
- package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
- package/src/scheduler/__tests__/shared.ts +77 -0
- package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
- package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
- package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
- package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
- package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
- package/src/security/primitives/$permission.spec.ts +30 -0
- package/src/security/primitives/$permission.ts +2 -2
- package/src/security/primitives/$realm.spec.ts +101 -0
- package/src/security/primitives/$role.spec.ts +52 -0
- package/src/security/primitives/$serviceAccount.spec.ts +61 -0
- package/src/security/providers/SecurityProvider.spec.ts +350 -0
- package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
- package/src/server/cache/providers/ServerCacheProvider.spec.ts +942 -0
- package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
- package/src/server/compress/providers/ServerCompressProvider.ts +2 -0
- package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
- package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
- package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
- package/src/server/core/primitives/$action.spec.ts +191 -0
- package/src/server/core/primitives/$route.spec.ts +65 -0
- package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
- package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
- package/src/server/core/providers/ServerProvider.ts +3 -1
- package/src/server/core/services/HttpClient.spec.ts +123 -0
- package/src/server/core/services/UserAgentParser.spec.ts +111 -0
- package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
- package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
- package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
- package/src/server/links/__tests__/$action.spec.ts +238 -0
- package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
- package/src/server/links/__tests__/requestId.spec.ts +120 -0
- package/src/server/links/primitives/$remote.spec.ts +228 -0
- package/src/server/links/providers/LinkProvider.spec.ts +54 -0
- package/src/server/links/providers/LinkProvider.ts +49 -3
- package/src/server/links/providers/ServerLinksProvider.ts +1 -53
- package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
- package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
- package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
- package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
- package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
- package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
- package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
- package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
- package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
- package/src/server/static/primitives/$serve.spec.ts +193 -0
- package/src/server/swagger/__tests__/ui.spec.ts +52 -0
- package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +18 -8
- package/src/sms/primitives/$sms.spec.ts +165 -0
- package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
- package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
- package/src/thread/primitives/$thread.spec.ts +186 -0
- package/src/topic/core/__tests__/shared.ts +144 -0
- package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
- package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
- package/src/vite/plugins/viteAlephaDev.ts +16 -4
- package/src/vite/tasks/runAlepha.ts +7 -1
- package/src/websocket/__tests__/$websocket-new.spec.ts +195 -0
- package/src/websocket/primitives/$channel.spec.ts +30 -0
- package/src/cli/commands/BiomeCommands.ts +0 -29
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Alepha, t } from "alepha";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { $entity, $repository, DatabaseProvider, pg } from "../index.ts";
|
|
4
|
+
import {
|
|
5
|
+
NodeSqliteProvider,
|
|
6
|
+
nodeSqliteOptions,
|
|
7
|
+
} from "../providers/drivers/NodeSqliteProvider.ts";
|
|
8
|
+
|
|
9
|
+
describe("sqlite", () => {
|
|
10
|
+
it("should create and query entities using SQLite", async () => {
|
|
11
|
+
const users = $entity({
|
|
12
|
+
name: "users",
|
|
13
|
+
schema: t.object({
|
|
14
|
+
id: pg.primaryKey(t.integer()),
|
|
15
|
+
name: t.text(),
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const alepha = Alepha.create().with({
|
|
20
|
+
provide: DatabaseProvider,
|
|
21
|
+
use: NodeSqliteProvider,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
alepha.store.mut(nodeSqliteOptions, (old) => ({
|
|
25
|
+
...old,
|
|
26
|
+
path: "sqlite://:memory:",
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
class TestApp {
|
|
30
|
+
userRepository = $repository(users);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const repository = alepha.inject(TestApp).userRepository;
|
|
34
|
+
|
|
35
|
+
await alepha.start();
|
|
36
|
+
|
|
37
|
+
await repository.create({
|
|
38
|
+
name: "John Doe",
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const user = await repository.findOne({
|
|
42
|
+
where: {
|
|
43
|
+
name: { eq: "John Doe" },
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(user).toStrictEqual({
|
|
48
|
+
id: 1,
|
|
49
|
+
name: "John Doe",
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("should create and query entities with bigint primary key", async () => {
|
|
54
|
+
const posts = $entity({
|
|
55
|
+
name: "posts",
|
|
56
|
+
schema: t.object({
|
|
57
|
+
id: pg.primaryKey(t.bigint()),
|
|
58
|
+
title: t.text(),
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const alepha = Alepha.create().with({
|
|
63
|
+
provide: DatabaseProvider,
|
|
64
|
+
use: NodeSqliteProvider,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
alepha.store.mut(nodeSqliteOptions, (old) => ({
|
|
68
|
+
...old,
|
|
69
|
+
path: "sqlite://:memory:",
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
class TestApp {
|
|
73
|
+
postRepository = $repository(posts);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const repository = alepha.inject(TestApp).postRepository;
|
|
77
|
+
|
|
78
|
+
await alepha.start();
|
|
79
|
+
|
|
80
|
+
await repository.create({
|
|
81
|
+
title: "Hello World",
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
await repository.create({
|
|
85
|
+
title: "Second Post",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const post = await repository.findOne({
|
|
89
|
+
where: {
|
|
90
|
+
title: { eq: "Hello World" },
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// bigint returns as string (for int64 safety)
|
|
95
|
+
expect(post).toStrictEqual({
|
|
96
|
+
id: "1",
|
|
97
|
+
title: "Hello World",
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const secondPost = await repository.findOne({
|
|
101
|
+
where: {
|
|
102
|
+
title: { eq: "Second Post" },
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(secondPost).toStrictEqual({
|
|
107
|
+
id: "2",
|
|
108
|
+
title: "Second Post",
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { Alepha, t } from "alepha";
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
import { $entity, $repository, pg } from "../index.ts";
|
|
4
|
+
|
|
5
|
+
const User = $entity({
|
|
6
|
+
name: "users",
|
|
7
|
+
schema: t.object({
|
|
8
|
+
id: pg.primaryKey(),
|
|
9
|
+
createdAt: pg.createdAt(),
|
|
10
|
+
updatedAt: pg.updatedAt(),
|
|
11
|
+
name: t.text(),
|
|
12
|
+
email: t.text(),
|
|
13
|
+
bio: t.optional(t.text()),
|
|
14
|
+
}),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
class App {
|
|
18
|
+
users = $repository(User);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
test("contains operator - case insensitive substring matching", async ({
|
|
22
|
+
expect,
|
|
23
|
+
}) => {
|
|
24
|
+
const alepha = Alepha.create();
|
|
25
|
+
const app = alepha.inject(App);
|
|
26
|
+
await alepha.start();
|
|
27
|
+
|
|
28
|
+
const repository = app.users;
|
|
29
|
+
|
|
30
|
+
// Insert test data
|
|
31
|
+
await repository.create({ name: "Alice Smith", email: "alice@example.com" });
|
|
32
|
+
await repository.create({ name: "Bob Johnson", email: "bob@test.com" });
|
|
33
|
+
await repository.create({
|
|
34
|
+
name: "Charlie Brown",
|
|
35
|
+
email: "charlie@example.com",
|
|
36
|
+
});
|
|
37
|
+
await repository.create({ name: "David Wilson", email: "david@sample.org" });
|
|
38
|
+
|
|
39
|
+
// Test contains with exact case
|
|
40
|
+
const result1 = await repository.findMany({
|
|
41
|
+
where: { name: { contains: "Smith" } },
|
|
42
|
+
});
|
|
43
|
+
expect(result1).toHaveLength(1);
|
|
44
|
+
expect(result1[0].name).toBe("Alice Smith");
|
|
45
|
+
|
|
46
|
+
// Test contains with different case (should be case insensitive)
|
|
47
|
+
const result2 = await repository.findMany({
|
|
48
|
+
where: { name: { contains: "smith" } },
|
|
49
|
+
});
|
|
50
|
+
expect(result2).toHaveLength(1);
|
|
51
|
+
expect(result2[0].name).toBe("Alice Smith");
|
|
52
|
+
|
|
53
|
+
// Test contains in email
|
|
54
|
+
const result3 = await repository.findMany({
|
|
55
|
+
where: { email: { contains: "example" } },
|
|
56
|
+
});
|
|
57
|
+
expect(result3).toHaveLength(2);
|
|
58
|
+
expect(result3.map((u: any) => u.name).sort()).toEqual([
|
|
59
|
+
"Alice Smith",
|
|
60
|
+
"Charlie Brown",
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
// Test contains with no matches
|
|
64
|
+
const result4 = await repository.findMany({
|
|
65
|
+
where: { name: { contains: "XYZ" } },
|
|
66
|
+
});
|
|
67
|
+
expect(result4).toHaveLength(0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("startsWith operator - case insensitive prefix matching", async ({
|
|
71
|
+
expect,
|
|
72
|
+
}) => {
|
|
73
|
+
const alepha = Alepha.create();
|
|
74
|
+
const app = alepha.inject(App);
|
|
75
|
+
await alepha.start();
|
|
76
|
+
|
|
77
|
+
const repository = app.users;
|
|
78
|
+
|
|
79
|
+
// Insert test data
|
|
80
|
+
await repository.create({ name: "Alice Smith", email: "alice@example.com" });
|
|
81
|
+
await repository.create({ name: "Bob Johnson", email: "bob@test.com" });
|
|
82
|
+
await repository.create({
|
|
83
|
+
name: "Charlie Brown",
|
|
84
|
+
email: "charlie@example.com",
|
|
85
|
+
});
|
|
86
|
+
await repository.create({ name: "Alan Turing", email: "alan@sample.org" });
|
|
87
|
+
|
|
88
|
+
// Test startsWith with exact case
|
|
89
|
+
const result1 = await repository.findMany({
|
|
90
|
+
where: { name: { startsWith: "Alice" } },
|
|
91
|
+
});
|
|
92
|
+
expect(result1).toHaveLength(1);
|
|
93
|
+
expect(result1[0].name).toBe("Alice Smith");
|
|
94
|
+
|
|
95
|
+
// Test startsWith with different case (should be case insensitive)
|
|
96
|
+
const result2 = await repository.findMany({
|
|
97
|
+
where: { name: { startsWith: "alice" } },
|
|
98
|
+
});
|
|
99
|
+
expect(result2).toHaveLength(1);
|
|
100
|
+
expect(result2[0].name).toBe("Alice Smith");
|
|
101
|
+
|
|
102
|
+
// Test startsWith matching multiple records
|
|
103
|
+
const result3 = await repository.findMany({
|
|
104
|
+
where: { name: { startsWith: "A" } },
|
|
105
|
+
orderBy: { column: "name", direction: "asc" },
|
|
106
|
+
});
|
|
107
|
+
expect(result3).toHaveLength(2);
|
|
108
|
+
expect(result3.map((u: any) => u.name)).toEqual([
|
|
109
|
+
"Alan Turing",
|
|
110
|
+
"Alice Smith",
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
// Test startsWith with email
|
|
114
|
+
const result4 = await repository.findMany({
|
|
115
|
+
where: { email: { startsWith: "bob" } },
|
|
116
|
+
});
|
|
117
|
+
expect(result4).toHaveLength(1);
|
|
118
|
+
expect(result4[0].email).toBe("bob@test.com");
|
|
119
|
+
|
|
120
|
+
// Test startsWith with no matches
|
|
121
|
+
const result5 = await repository.findMany({
|
|
122
|
+
where: { name: { startsWith: "XYZ" } },
|
|
123
|
+
});
|
|
124
|
+
expect(result5).toHaveLength(0);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("endsWith operator - case insensitive suffix matching", async ({
|
|
128
|
+
expect,
|
|
129
|
+
}) => {
|
|
130
|
+
const alepha = Alepha.create();
|
|
131
|
+
const app = alepha.inject(App);
|
|
132
|
+
await alepha.start();
|
|
133
|
+
|
|
134
|
+
const repository = app.users;
|
|
135
|
+
|
|
136
|
+
// Insert test data
|
|
137
|
+
await repository.create({ name: "Alice Smith", email: "alice@example.com" });
|
|
138
|
+
await repository.create({ name: "Bob Johnson", email: "bob@example.com" });
|
|
139
|
+
await repository.create({ name: "Charlie Brown", email: "charlie@test.com" });
|
|
140
|
+
await repository.create({ name: "David Wilson", email: "david@example.org" });
|
|
141
|
+
|
|
142
|
+
// Test endsWith with exact case
|
|
143
|
+
const result1 = await repository.findMany({
|
|
144
|
+
where: { name: { endsWith: "Smith" } },
|
|
145
|
+
});
|
|
146
|
+
expect(result1).toHaveLength(1);
|
|
147
|
+
expect(result1[0].name).toBe("Alice Smith");
|
|
148
|
+
|
|
149
|
+
// Test endsWith with different case (should be case insensitive)
|
|
150
|
+
const result2 = await repository.findMany({
|
|
151
|
+
where: { name: { endsWith: "smith" } },
|
|
152
|
+
});
|
|
153
|
+
expect(result2).toHaveLength(1);
|
|
154
|
+
expect(result2[0].name).toBe("Alice Smith");
|
|
155
|
+
|
|
156
|
+
// Test endsWith matching multiple records
|
|
157
|
+
const result3 = await repository.findMany({
|
|
158
|
+
where: { name: { endsWith: "son" } },
|
|
159
|
+
orderBy: { column: "name", direction: "asc" },
|
|
160
|
+
});
|
|
161
|
+
expect(result3).toHaveLength(2);
|
|
162
|
+
expect(result3.map((u: any) => u.name)).toEqual([
|
|
163
|
+
"Bob Johnson",
|
|
164
|
+
"David Wilson",
|
|
165
|
+
]);
|
|
166
|
+
|
|
167
|
+
// Test endsWith with email domain
|
|
168
|
+
const result4 = await repository.findMany({
|
|
169
|
+
where: { email: { endsWith: "example.com" } },
|
|
170
|
+
orderBy: { column: "name", direction: "asc" },
|
|
171
|
+
});
|
|
172
|
+
expect(result4).toHaveLength(2);
|
|
173
|
+
expect(result4.map((u) => u.name)).toEqual(["Alice Smith", "Bob Johnson"]);
|
|
174
|
+
|
|
175
|
+
// Test endsWith with no matches
|
|
176
|
+
const result5 = await repository.findMany({
|
|
177
|
+
where: { name: { endsWith: "XYZ" } },
|
|
178
|
+
});
|
|
179
|
+
expect(result5).toHaveLength(0);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test("combining string operators with other filters", async ({ expect }) => {
|
|
183
|
+
const alepha = Alepha.create();
|
|
184
|
+
const app = alepha.inject(App);
|
|
185
|
+
await alepha.start();
|
|
186
|
+
|
|
187
|
+
const repository = app.users;
|
|
188
|
+
|
|
189
|
+
// Insert test data
|
|
190
|
+
await repository.create({
|
|
191
|
+
name: "Alice Smith",
|
|
192
|
+
email: "alice@example.com",
|
|
193
|
+
bio: "Software Engineer",
|
|
194
|
+
});
|
|
195
|
+
await repository.create({
|
|
196
|
+
name: "Bob Johnson",
|
|
197
|
+
email: "bob@example.com",
|
|
198
|
+
bio: "Product Manager",
|
|
199
|
+
});
|
|
200
|
+
await repository.create({
|
|
201
|
+
name: "Charlie Brown",
|
|
202
|
+
email: "charlie@test.com",
|
|
203
|
+
bio: "Software Developer",
|
|
204
|
+
});
|
|
205
|
+
await repository.create({
|
|
206
|
+
name: "David Wilson",
|
|
207
|
+
email: "david@example.org",
|
|
208
|
+
bio: "Designer",
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Combine contains with other operators
|
|
212
|
+
const result1 = await repository.findMany({
|
|
213
|
+
where: {
|
|
214
|
+
and: [
|
|
215
|
+
{ email: { contains: "example" } },
|
|
216
|
+
{ bio: { contains: "Software" } },
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
expect(result1).toHaveLength(1);
|
|
221
|
+
expect(result1[0].name).toBe("Alice Smith");
|
|
222
|
+
|
|
223
|
+
// Combine startsWith and endsWith
|
|
224
|
+
const result2 = await repository.findMany({
|
|
225
|
+
where: {
|
|
226
|
+
and: [{ name: { startsWith: "B" } }, { name: { endsWith: "son" } }],
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
expect(result2).toHaveLength(1);
|
|
230
|
+
expect(result2[0].name).toBe("Bob Johnson");
|
|
231
|
+
|
|
232
|
+
// Combine with OR
|
|
233
|
+
const result3 = await repository.findMany({
|
|
234
|
+
where: {
|
|
235
|
+
or: [
|
|
236
|
+
{ name: { contains: "Alice" } },
|
|
237
|
+
{ email: { endsWith: "test.com" } },
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
orderBy: { column: "name", direction: "asc" },
|
|
241
|
+
});
|
|
242
|
+
expect(result3).toHaveLength(2);
|
|
243
|
+
expect(result3.map((u: any) => u.name)).toEqual([
|
|
244
|
+
"Alice Smith",
|
|
245
|
+
"Charlie Brown",
|
|
246
|
+
]);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test("string operators with special characters", async ({ expect }) => {
|
|
250
|
+
const alepha = Alepha.create();
|
|
251
|
+
const app = alepha.inject(App);
|
|
252
|
+
await alepha.start();
|
|
253
|
+
|
|
254
|
+
const repository = app.users;
|
|
255
|
+
|
|
256
|
+
// Insert test data with special characters
|
|
257
|
+
await repository.create({ name: "O'Brien", email: "obrien@example.com" });
|
|
258
|
+
await repository.create({
|
|
259
|
+
name: "Smith & Jones",
|
|
260
|
+
email: "smith-jones@test.com",
|
|
261
|
+
});
|
|
262
|
+
await repository.create({ name: "50% Off", email: "discount@shop.com" });
|
|
263
|
+
|
|
264
|
+
// Test contains with apostrophe
|
|
265
|
+
const result1 = await repository.findMany({
|
|
266
|
+
where: { name: { contains: "O'Brien" } },
|
|
267
|
+
});
|
|
268
|
+
expect(result1).toHaveLength(1);
|
|
269
|
+
expect(result1[0].name).toBe("O'Brien");
|
|
270
|
+
|
|
271
|
+
// Test contains with ampersand
|
|
272
|
+
const result2 = await repository.findMany({
|
|
273
|
+
where: { name: { contains: "&" } },
|
|
274
|
+
});
|
|
275
|
+
expect(result2).toHaveLength(1);
|
|
276
|
+
expect(result2[0].name).toBe("Smith & Jones");
|
|
277
|
+
|
|
278
|
+
// Test startsWith with percent sign
|
|
279
|
+
const result3 = await repository.findMany({
|
|
280
|
+
where: { name: { startsWith: "50%" } },
|
|
281
|
+
});
|
|
282
|
+
expect(result3).toHaveLength(1);
|
|
283
|
+
expect(result3[0].name).toBe("50% Off");
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test("string operators on optional fields", async ({ expect }) => {
|
|
287
|
+
const alepha = Alepha.create();
|
|
288
|
+
const app = alepha.inject(App);
|
|
289
|
+
await alepha.start();
|
|
290
|
+
|
|
291
|
+
const repository = app.users;
|
|
292
|
+
|
|
293
|
+
// Insert test data with some null bio fields
|
|
294
|
+
await repository.create({
|
|
295
|
+
name: "Alice",
|
|
296
|
+
email: "alice@example.com",
|
|
297
|
+
bio: "Engineer at Tech Co",
|
|
298
|
+
});
|
|
299
|
+
await repository.create({ name: "Bob", email: "bob@example.com" });
|
|
300
|
+
await repository.create({
|
|
301
|
+
name: "Charlie",
|
|
302
|
+
email: "charlie@test.com",
|
|
303
|
+
bio: "Designer",
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Test contains on optional field
|
|
307
|
+
const result1 = await repository.findMany({
|
|
308
|
+
where: { bio: { contains: "Engineer" } },
|
|
309
|
+
});
|
|
310
|
+
expect(result1).toHaveLength(1);
|
|
311
|
+
expect(result1[0].name).toBe("Alice");
|
|
312
|
+
|
|
313
|
+
// Test that null values don't match
|
|
314
|
+
const result2 = await repository.findMany({
|
|
315
|
+
where: { bio: { contains: "Bob" } },
|
|
316
|
+
});
|
|
317
|
+
expect(result2).toHaveLength(0);
|
|
318
|
+
|
|
319
|
+
// Combine with isNotNull
|
|
320
|
+
const result3 = await repository.findMany({
|
|
321
|
+
where: {
|
|
322
|
+
and: [{ bio: { isNotNull: true } }, { bio: { startsWith: "Des" } }],
|
|
323
|
+
},
|
|
324
|
+
});
|
|
325
|
+
expect(result3).toHaveLength(1);
|
|
326
|
+
expect(result3[0].name).toBe("Charlie");
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test("string operators properly escape SQL wildcards", async ({ expect }) => {
|
|
330
|
+
const alepha = Alepha.create();
|
|
331
|
+
const app = alepha.inject(App);
|
|
332
|
+
await alepha.start();
|
|
333
|
+
|
|
334
|
+
const repository = app.users;
|
|
335
|
+
|
|
336
|
+
// Insert test data with wildcard characters
|
|
337
|
+
await repository.create({ name: "admin", email: "admin@example.com" });
|
|
338
|
+
await repository.create({ name: "user123", email: "user@example.com" });
|
|
339
|
+
await repository.create({ name: "test_admin", email: "test@example.com" });
|
|
340
|
+
await repository.create({ name: "superuser", email: "super@example.com" });
|
|
341
|
+
await repository.create({ name: "%special%", email: "special@example.com" });
|
|
342
|
+
await repository.create({ name: "under_score", email: "under@example.com" });
|
|
343
|
+
|
|
344
|
+
// Test 1: Percent sign should be treated as literal, not wildcard
|
|
345
|
+
const result1 = await repository.findMany({
|
|
346
|
+
where: { name: { contains: "%special%" } },
|
|
347
|
+
});
|
|
348
|
+
expect(result1).toHaveLength(1);
|
|
349
|
+
expect(result1[0].name).toBe("%special%");
|
|
350
|
+
|
|
351
|
+
// Test 2: Underscore should be treated as literal, not single-char wildcard
|
|
352
|
+
const result2 = await repository.findMany({
|
|
353
|
+
where: { name: { contains: "_" } },
|
|
354
|
+
});
|
|
355
|
+
// Should match "test_admin" and "under_score" only (literal underscore)
|
|
356
|
+
expect(result2).toHaveLength(2);
|
|
357
|
+
expect(result2.map((u: any) => u.name).sort()).toEqual([
|
|
358
|
+
"test_admin",
|
|
359
|
+
"under_score",
|
|
360
|
+
]);
|
|
361
|
+
|
|
362
|
+
// Test 3: startsWith with underscore should match literal
|
|
363
|
+
const result3 = await repository.findMany({
|
|
364
|
+
where: { name: { startsWith: "test_" } },
|
|
365
|
+
});
|
|
366
|
+
expect(result3).toHaveLength(1);
|
|
367
|
+
expect(result3[0].name).toBe("test_admin");
|
|
368
|
+
|
|
369
|
+
// Test 4: endsWith with percent should match literal
|
|
370
|
+
const result4 = await repository.findMany({
|
|
371
|
+
where: { name: { endsWith: "%" } },
|
|
372
|
+
});
|
|
373
|
+
expect(result4).toHaveLength(1);
|
|
374
|
+
expect(result4[0].name).toBe("%special%");
|
|
375
|
+
|
|
376
|
+
// Test 5: Multiple wildcards should be escaped
|
|
377
|
+
const result5 = await repository.findMany({
|
|
378
|
+
where: { name: { contains: "%spe" } },
|
|
379
|
+
});
|
|
380
|
+
expect(result5).toHaveLength(1);
|
|
381
|
+
expect(result5[0].name).toBe("%special%");
|
|
382
|
+
|
|
383
|
+
// Test 6: Backslash escaping
|
|
384
|
+
await repository.create({ name: "back\\slash", email: "back@example.com" });
|
|
385
|
+
const result6 = await repository.findMany({
|
|
386
|
+
where: { name: { contains: "back\\" } },
|
|
387
|
+
});
|
|
388
|
+
expect(result6).toHaveLength(1);
|
|
389
|
+
expect(result6[0].name).toBe("back\\slash");
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
test("wildcard injection prevention", async ({ expect }) => {
|
|
393
|
+
const alepha = Alepha.create();
|
|
394
|
+
const app = alepha.inject(App);
|
|
395
|
+
await alepha.start();
|
|
396
|
+
|
|
397
|
+
const repository = app.users;
|
|
398
|
+
|
|
399
|
+
// Insert test data
|
|
400
|
+
await repository.create({ name: "admin", email: "admin@example.com" });
|
|
401
|
+
await repository.create({ name: "user123", email: "user@example.com" });
|
|
402
|
+
await repository.create({ name: "superuser", email: "super@example.com" });
|
|
403
|
+
|
|
404
|
+
// Attempt wildcard injection with %
|
|
405
|
+
// If not escaped, "%user%" would match "user123" and "superuser"
|
|
406
|
+
// With proper escaping, it should match nothing (no literal "%user%" exists)
|
|
407
|
+
const result1 = await repository.findMany({
|
|
408
|
+
where: { name: { contains: "%user%" } },
|
|
409
|
+
});
|
|
410
|
+
expect(result1).toHaveLength(0);
|
|
411
|
+
|
|
412
|
+
// Attempt wildcard injection with _
|
|
413
|
+
// If not escaped, "user_" would match "user1", "user2", etc.
|
|
414
|
+
// With proper escaping, it should match nothing
|
|
415
|
+
const result2 = await repository.findMany({
|
|
416
|
+
where: { name: { contains: "user_" } },
|
|
417
|
+
});
|
|
418
|
+
expect(result2).toHaveLength(0);
|
|
419
|
+
|
|
420
|
+
// Verify normal search still works
|
|
421
|
+
const result3 = await repository.findMany({
|
|
422
|
+
where: { name: { contains: "user" } },
|
|
423
|
+
});
|
|
424
|
+
expect(result3).toHaveLength(2); // user123 and superuser
|
|
425
|
+
expect(result3.map((u: any) => u.name).sort()).toEqual([
|
|
426
|
+
"superuser",
|
|
427
|
+
"user123",
|
|
428
|
+
]);
|
|
429
|
+
});
|