alepha 0.15.1 → 0.15.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 +68 -80
- package/dist/api/audits/index.d.ts +10 -33
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +10 -33
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +10 -3
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +10 -3
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +162 -155
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +10 -3
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +413 -0
- package/dist/api/keys/index.d.ts.map +1 -0
- package/dist/api/keys/index.js +476 -0
- package/dist/api/keys/index.js.map +1 -0
- package/dist/api/notifications/index.d.ts +10 -4
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +10 -4
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +43 -50
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +30 -37
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +1081 -760
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +2539 -218
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +138 -132
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +12 -4
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.d.ts +20 -40
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js +31 -44
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +440 -8
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +1861 -12
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/core/index.d.ts +179 -7
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +213 -7
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/redis/index.d.ts +1 -0
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js +4 -0
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/cli/index.d.ts +638 -5645
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2550 -368
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +203 -45
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +2060 -71
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +70 -40
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +34 -13
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +90 -40
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +70 -40
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +15 -0
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +15 -0
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +323 -20
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +1857 -7
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +90 -8
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +91 -20
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +11 -4
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +11 -4
- package/dist/lock/core/index.js.map +1 -1
- package/dist/logger/index.d.ts +17 -66
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +14 -63
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +10 -30
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +12 -35
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.browser.js +3 -3
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +39 -20
- package/dist/orm/index.bun.js.map +1 -1
- package/dist/orm/index.d.ts +517 -540
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +58 -71
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +18 -10
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/core/index.js +14 -6
- package/dist/queue/core/index.js.map +1 -1
- package/dist/react/auth/index.browser.js +108 -0
- package/dist/react/auth/index.browser.js.map +1 -0
- package/dist/react/auth/index.d.ts +100 -0
- package/dist/react/auth/index.d.ts.map +1 -0
- package/dist/react/auth/index.js +145 -0
- package/dist/react/auth/index.js.map +1 -0
- package/dist/react/core/index.d.ts +469 -0
- package/dist/react/core/index.d.ts.map +1 -0
- package/dist/react/core/index.js +464 -0
- package/dist/react/core/index.js.map +1 -0
- package/dist/react/form/index.d.ts +232 -0
- package/dist/react/form/index.d.ts.map +1 -0
- package/dist/react/form/index.js +432 -0
- package/dist/react/form/index.js.map +1 -0
- package/dist/react/head/index.browser.js +423 -0
- package/dist/react/head/index.browser.js.map +1 -0
- package/dist/react/head/index.d.ts +288 -0
- package/dist/react/head/index.d.ts.map +1 -0
- package/dist/react/head/index.js +465 -0
- package/dist/react/head/index.js.map +1 -0
- package/dist/react/i18n/index.d.ts +175 -0
- package/dist/react/i18n/index.d.ts.map +1 -0
- package/dist/react/i18n/index.js +224 -0
- package/dist/react/i18n/index.js.map +1 -0
- package/dist/react/router/index.browser.js +1974 -0
- package/dist/react/router/index.browser.js.map +1 -0
- package/dist/react/router/index.d.ts +1956 -0
- package/dist/react/router/index.d.ts.map +1 -0
- package/dist/react/router/index.js +4722 -0
- package/dist/react/router/index.js.map +1 -0
- package/dist/react/websocket/index.d.ts +117 -0
- package/dist/react/websocket/index.d.ts.map +1 -0
- package/dist/react/websocket/index.js +107 -0
- package/dist/react/websocket/index.js.map +1 -0
- package/dist/redis/index.bun.js +4 -0
- package/dist/redis/index.bun.js.map +1 -1
- package/dist/redis/index.d.ts +41 -44
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +16 -25
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +11 -2
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/retry/index.js +11 -2
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +11 -2
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +11 -2
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +140 -49
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +164 -32
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +12 -7
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +12 -7
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +7 -22
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +7 -22
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +10 -2
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +10 -2
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +40 -16
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +7 -5
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +124 -23
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +231 -14
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +13 -23
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/cors/index.js +7 -21
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/health/index.d.ts +8 -2
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/health/index.js +8 -2
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/helmet/index.d.ts +11 -3
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/helmet/index.js +11 -3
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.d.ts +11 -6
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +11 -6
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +10 -3
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +10 -3
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts +9 -3
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/multipart/index.js +9 -3
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts +8 -2
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/proxy/index.js +8 -2
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts +30 -35
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.js +18 -55
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +137 -4
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/static/index.js +1853 -5
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +309 -6
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +1854 -6
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +309 -7
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +1856 -7
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.browser.js +1218 -0
- package/dist/system/index.browser.js.map +1 -0
- package/dist/{file → system}/index.d.ts +343 -16
- package/dist/system/index.d.ts.map +1 -0
- package/dist/{file → system}/index.js +419 -22
- package/dist/system/index.js.map +1 -0
- package/dist/thread/index.d.ts +11 -2
- package/dist/thread/index.d.ts.map +1 -1
- package/dist/thread/index.js +11 -2
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts +12 -5
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/core/index.js +12 -5
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.d.ts +5 -6272
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +23 -10
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts +12 -8
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +12 -8
- package/dist/websocket/index.js.map +1 -1
- package/package.json +82 -11
- package/src/api/audits/index.ts +10 -33
- package/src/api/files/__tests__/$bucket.spec.ts +1 -1
- package/src/api/files/controllers/AdminFileStatsController.spec.ts +1 -1
- package/src/api/files/controllers/FileController.spec.ts +1 -1
- package/src/api/files/index.ts +10 -3
- package/src/api/files/jobs/FileJobs.spec.ts +1 -1
- package/src/api/files/services/FileService.spec.ts +1 -1
- package/src/api/jobs/index.ts +10 -3
- package/src/api/keys/controllers/AdminApiKeyController.ts +75 -0
- package/src/api/keys/controllers/ApiKeyController.ts +103 -0
- package/src/api/keys/entities/apiKeyEntity.ts +41 -0
- package/src/api/keys/index.ts +49 -0
- package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +7 -0
- package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +17 -0
- package/src/api/keys/schemas/createApiKeyBodySchema.ts +7 -0
- package/src/api/keys/schemas/createApiKeyResponseSchema.ts +11 -0
- package/src/api/keys/schemas/listApiKeyResponseSchema.ts +15 -0
- package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +5 -0
- package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +5 -0
- package/src/api/keys/services/ApiKeyService.spec.ts +553 -0
- package/src/api/keys/services/ApiKeyService.ts +306 -0
- package/src/api/logs/TODO.md +55 -0
- package/src/api/notifications/index.ts +10 -4
- package/src/api/parameters/index.ts +9 -30
- package/src/api/parameters/primitives/$config.ts +12 -4
- package/src/api/parameters/services/ConfigStore.ts +9 -3
- package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1035 -0
- package/src/api/users/__tests__/ApiKeys.spec.ts +401 -0
- package/src/api/users/index.ts +14 -3
- package/src/api/users/primitives/$realm.ts +33 -5
- package/src/api/users/providers/RealmProvider.ts +1 -12
- package/src/api/users/services/SessionService.ts +1 -1
- package/src/api/verifications/controllers/VerificationController.ts +2 -0
- package/src/api/verifications/index.ts +10 -4
- package/src/batch/index.ts +9 -36
- package/src/batch/primitives/$batch.ts +0 -8
- package/src/batch/providers/BatchProvider.ts +29 -2
- package/src/bucket/__tests__/shared.ts +1 -1
- package/src/bucket/index.ts +13 -6
- package/src/bucket/primitives/$bucket.ts +1 -1
- package/src/bucket/providers/LocalFileStorageProvider.ts +1 -1
- package/src/bucket/providers/MemoryFileStorageProvider.ts +1 -1
- package/src/cache/core/__tests__/shared.ts +30 -0
- package/src/cache/core/index.ts +11 -6
- package/src/cache/core/primitives/$cache.spec.ts +5 -0
- package/src/cache/core/providers/CacheProvider.ts +17 -0
- package/src/cache/core/providers/MemoryCacheProvider.ts +300 -1
- package/src/cache/redis/__tests__/cache-redis.spec.ts +5 -0
- package/src/cache/redis/providers/RedisCacheProvider.ts +9 -0
- package/src/cli/apps/AlephaCli.ts +1 -14
- package/src/cli/apps/AlephaPackageBuilderCli.ts +10 -1
- package/src/cli/atoms/buildOptions.ts +99 -9
- package/src/cli/commands/build.ts +150 -37
- package/src/cli/commands/db.ts +22 -18
- package/src/cli/commands/deploy.ts +1 -1
- package/src/cli/commands/dev.ts +1 -20
- package/src/cli/commands/gen/env.ts +5 -2
- package/src/cli/commands/gen/openapi.ts +5 -2
- package/src/cli/commands/init.spec.ts +588 -0
- package/src/cli/commands/init.ts +115 -58
- package/src/cli/commands/lint.ts +7 -1
- package/src/cli/commands/typecheck.ts +11 -0
- package/src/cli/providers/AppEntryProvider.ts +1 -1
- package/src/cli/providers/ViteBuildProvider.ts +8 -50
- package/src/cli/providers/ViteDevServerProvider.ts +35 -16
- package/src/cli/services/AlephaCliUtils.ts +52 -121
- package/src/cli/services/PackageManagerUtils.ts +129 -11
- package/src/cli/services/ProjectScaffolder.spec.ts +97 -0
- package/src/cli/services/ProjectScaffolder.ts +148 -81
- package/src/cli/services/ViteUtils.ts +82 -0
- package/src/cli/{assets/claudeMd.ts → templates/agentMd.ts} +37 -24
- package/src/cli/templates/apiAppSecurityTs.ts +11 -0
- package/src/cli/templates/apiIndexTs.ts +30 -0
- package/src/cli/templates/gitignore.ts +39 -0
- package/src/cli/{assets → templates}/mainCss.ts +11 -2
- package/src/cli/templates/mainServerTs.ts +33 -0
- package/src/cli/templates/webAppRouterTs.ts +74 -0
- package/src/cli/templates/webHelloComponentTsx.ts +30 -0
- package/src/command/helpers/Runner.spec.ts +139 -0
- package/src/command/helpers/Runner.ts +7 -22
- package/src/command/index.ts +12 -4
- package/src/command/providers/CliProvider.spec.ts +1392 -0
- package/src/command/providers/CliProvider.ts +320 -47
- package/src/core/Alepha.ts +34 -27
- package/src/core/__tests__/Alepha-start.spec.ts +4 -4
- package/src/core/helpers/jsonSchemaToTypeBox.spec.ts +771 -0
- package/src/core/helpers/jsonSchemaToTypeBox.ts +62 -10
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +20 -0
- package/src/core/providers/EventManager.spec.ts +0 -71
- package/src/core/providers/EventManager.ts +3 -15
- package/src/core/providers/Json.ts +2 -14
- package/src/datetime/index.ts +15 -0
- package/src/email/index.ts +10 -5
- package/src/email/providers/LocalEmailProvider.spec.ts +1 -1
- package/src/email/providers/LocalEmailProvider.ts +1 -1
- package/src/fake/__tests__/keyName.example.ts +1 -1
- package/src/fake/__tests__/keyName.spec.ts +5 -5
- package/src/fake/index.ts +9 -6
- package/src/fake/providers/FakeProvider.spec.ts +258 -40
- package/src/fake/providers/FakeProvider.ts +133 -19
- package/src/lock/core/index.ts +11 -4
- package/src/logger/index.ts +17 -66
- package/src/mcp/index.ts +10 -27
- package/src/mcp/transports/SseMcpTransport.ts +0 -11
- package/src/orm/__tests__/PostgresProvider.spec.ts +2 -2
- package/src/orm/index.browser.ts +2 -2
- package/src/orm/index.bun.ts +5 -3
- package/src/orm/index.ts +23 -53
- package/src/orm/providers/drivers/BunSqliteProvider.ts +5 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +57 -30
- package/src/orm/providers/drivers/DatabaseProvider.ts +9 -1
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +4 -1
- package/src/orm/services/Repository.ts +7 -3
- package/src/queue/core/index.ts +14 -6
- package/src/react/auth/__tests__/$auth.spec.ts +202 -0
- package/src/react/auth/hooks/useAuth.ts +32 -0
- package/src/react/auth/index.browser.ts +13 -0
- package/src/react/auth/index.shared.ts +2 -0
- package/src/react/auth/index.ts +48 -0
- package/src/react/auth/providers/ReactAuthProvider.ts +16 -0
- package/src/react/auth/services/ReactAuth.ts +135 -0
- package/src/react/core/__tests__/Router.spec.tsx +169 -0
- package/src/react/core/components/ClientOnly.tsx +49 -0
- package/src/react/core/components/ErrorBoundary.tsx +73 -0
- package/src/react/core/contexts/AlephaContext.ts +7 -0
- package/src/react/core/contexts/AlephaProvider.tsx +42 -0
- package/src/react/core/hooks/useAction.browser.spec.tsx +569 -0
- package/src/react/core/hooks/useAction.ts +480 -0
- package/src/react/core/hooks/useAlepha.ts +26 -0
- package/src/react/core/hooks/useClient.ts +17 -0
- package/src/react/core/hooks/useEvents.ts +51 -0
- package/src/react/core/hooks/useInject.ts +12 -0
- package/src/react/core/hooks/useStore.ts +52 -0
- package/src/react/core/index.ts +90 -0
- package/src/react/form/components/FormState.tsx +17 -0
- package/src/react/form/errors/FormValidationError.ts +18 -0
- package/src/react/form/hooks/useForm.browser.spec.tsx +366 -0
- package/src/react/form/hooks/useForm.ts +47 -0
- package/src/react/form/hooks/useFormState.ts +130 -0
- package/src/react/form/index.ts +44 -0
- package/src/react/form/services/FormModel.ts +614 -0
- package/src/react/head/helpers/SeoExpander.spec.ts +203 -0
- package/src/react/head/helpers/SeoExpander.ts +142 -0
- package/src/react/head/hooks/useHead.spec.tsx +288 -0
- package/src/react/head/hooks/useHead.ts +62 -0
- package/src/react/head/index.browser.ts +26 -0
- package/src/react/head/index.ts +44 -0
- package/src/react/head/interfaces/Head.ts +105 -0
- package/src/react/head/primitives/$head.ts +25 -0
- package/src/react/head/providers/BrowserHeadProvider.browser.spec.ts +196 -0
- package/src/react/head/providers/BrowserHeadProvider.ts +212 -0
- package/src/react/head/providers/HeadProvider.ts +168 -0
- package/src/react/head/providers/ServerHeadProvider.ts +31 -0
- package/src/react/i18n/__tests__/integration.spec.tsx +239 -0
- package/src/react/i18n/components/Localize.spec.tsx +357 -0
- package/src/react/i18n/components/Localize.tsx +35 -0
- package/src/react/i18n/hooks/useI18n.browser.spec.tsx +438 -0
- package/src/react/i18n/hooks/useI18n.ts +18 -0
- package/src/react/i18n/index.ts +41 -0
- package/src/react/i18n/primitives/$dictionary.ts +69 -0
- package/src/react/i18n/providers/I18nProvider.spec.ts +389 -0
- package/src/react/i18n/providers/I18nProvider.ts +278 -0
- package/src/react/router/__tests__/page-head-browser.browser.spec.ts +95 -0
- package/src/react/router/__tests__/page-head.spec.ts +48 -0
- package/src/react/router/__tests__/seo-head.spec.ts +125 -0
- package/src/react/router/atoms/ssrManifestAtom.ts +58 -0
- package/src/react/router/components/ErrorViewer.tsx +872 -0
- package/src/react/router/components/Link.tsx +23 -0
- package/src/react/router/components/NestedView.tsx +223 -0
- package/src/react/router/components/NotFound.tsx +30 -0
- package/src/react/router/constants/PAGE_PRELOAD_KEY.ts +6 -0
- package/src/react/router/contexts/RouterLayerContext.ts +12 -0
- package/src/react/router/errors/Redirection.ts +28 -0
- package/src/react/router/hooks/useActive.ts +52 -0
- package/src/react/router/hooks/useQueryParams.ts +63 -0
- package/src/react/router/hooks/useRouter.ts +20 -0
- package/src/react/router/hooks/useRouterState.ts +11 -0
- package/src/react/router/index.browser.ts +45 -0
- package/src/react/router/index.shared.ts +19 -0
- package/src/react/router/index.ts +146 -0
- package/src/react/router/primitives/$page.browser.spec.tsx +851 -0
- package/src/react/router/primitives/$page.spec.tsx +676 -0
- package/src/react/router/primitives/$page.ts +489 -0
- package/src/react/router/providers/ReactBrowserProvider.ts +312 -0
- package/src/react/router/providers/ReactBrowserRendererProvider.ts +25 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +168 -0
- package/src/react/router/providers/ReactPageProvider.ts +726 -0
- package/src/react/router/providers/ReactPreloadProvider.spec.ts +142 -0
- package/src/react/router/providers/ReactPreloadProvider.ts +85 -0
- package/src/react/router/providers/ReactServerProvider.spec.tsx +316 -0
- package/src/react/router/providers/ReactServerProvider.ts +487 -0
- package/src/react/router/providers/ReactServerTemplateProvider.spec.ts +210 -0
- package/src/react/router/providers/ReactServerTemplateProvider.ts +542 -0
- package/src/react/router/providers/SSRManifestProvider.ts +334 -0
- package/src/react/router/services/ReactPageServerService.ts +48 -0
- package/src/react/router/services/ReactPageService.ts +27 -0
- package/src/react/router/services/ReactRouter.ts +262 -0
- package/src/react/websocket/hooks/useRoom.tsx +242 -0
- package/src/react/websocket/index.ts +7 -0
- package/src/redis/__tests__/redis.spec.ts +13 -0
- package/src/redis/index.ts +9 -25
- package/src/redis/providers/BunRedisProvider.ts +9 -0
- package/src/redis/providers/NodeRedisProvider.ts +8 -0
- package/src/redis/providers/RedisProvider.ts +16 -0
- package/src/retry/index.ts +11 -2
- package/src/router/index.ts +15 -0
- package/src/scheduler/index.ts +11 -2
- package/src/security/__tests__/BasicAuth.spec.ts +2 -0
- package/src/security/__tests__/ServerSecurityProvider.spec.ts +90 -5
- package/src/security/index.ts +15 -10
- package/src/security/interfaces/IssuerResolver.ts +27 -0
- package/src/security/primitives/$issuer.ts +55 -0
- package/src/security/providers/SecurityProvider.ts +179 -0
- package/src/security/providers/ServerBasicAuthProvider.ts +6 -2
- package/src/security/providers/ServerSecurityProvider.ts +63 -41
- package/src/server/auth/index.ts +12 -7
- package/src/server/cache/index.ts +7 -22
- package/src/server/compress/index.ts +10 -2
- package/src/server/cookies/index.ts +7 -5
- package/src/server/cookies/primitives/$cookie.ts +33 -11
- package/src/server/core/index.ts +16 -6
- package/src/server/core/interfaces/ServerRequest.ts +83 -1
- package/src/server/core/primitives/$action.spec.ts +1 -1
- package/src/server/core/primitives/$action.ts +8 -3
- package/src/server/core/providers/NodeHttpServerProvider.spec.ts +9 -3
- package/src/server/core/providers/NodeHttpServerProvider.ts +9 -3
- package/src/server/core/services/ServerRequestParser.spec.ts +520 -0
- package/src/server/core/services/ServerRequestParser.ts +306 -13
- package/src/server/cors/index.ts +7 -21
- package/src/server/cors/primitives/$cors.ts +6 -2
- package/src/server/health/index.ts +8 -2
- package/src/server/helmet/index.ts +11 -3
- package/src/server/links/index.ts +11 -6
- package/src/server/metrics/index.ts +10 -3
- package/src/server/multipart/index.ts +9 -3
- package/src/server/proxy/index.ts +8 -2
- package/src/server/rate-limit/index.ts +21 -25
- package/src/server/rate-limit/primitives/$rateLimit.ts +6 -2
- package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +38 -14
- package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +22 -56
- package/src/server/static/index.ts +8 -2
- package/src/server/static/providers/ServerStaticProvider.ts +1 -1
- package/src/server/swagger/index.ts +9 -4
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
- package/src/sms/index.ts +9 -5
- package/src/sms/providers/LocalSmsProvider.spec.ts +1 -1
- package/src/sms/providers/LocalSmsProvider.ts +1 -1
- package/src/system/index.browser.ts +36 -0
- package/src/system/index.ts +62 -0
- package/src/system/index.workerd.ts +1 -0
- package/src/{file → system}/providers/FileSystemProvider.ts +24 -0
- package/src/{file → system}/providers/MemoryFileSystemProvider.ts +116 -3
- package/src/system/providers/MemoryShellProvider.ts +164 -0
- package/src/{file → system}/providers/NodeFileSystemProvider.spec.ts +2 -2
- package/src/{file → system}/providers/NodeFileSystemProvider.ts +47 -2
- package/src/system/providers/NodeShellProvider.ts +184 -0
- package/src/system/providers/ShellProvider.ts +74 -0
- package/src/{file → system}/services/FileDetector.spec.ts +2 -2
- package/src/thread/index.ts +11 -2
- package/src/topic/core/index.ts +12 -5
- package/src/vite/tasks/buildClient.ts +2 -7
- package/src/vite/tasks/buildServer.ts +19 -13
- package/src/vite/tasks/generateCloudflare.ts +10 -7
- package/src/vite/tasks/generateDocker.ts +4 -0
- package/src/websocket/index.ts +12 -8
- package/dist/file/index.d.ts.map +0 -1
- package/dist/file/index.js.map +0 -1
- package/src/cli/assets/apiIndexTs.ts +0 -16
- package/src/cli/assets/mainServerTs.ts +0 -24
- package/src/cli/assets/webAppRouterTs.ts +0 -16
- package/src/cli/assets/webHelloComponentTsx.ts +0 -20
- package/src/cli/providers/ViteTemplateProvider.ts +0 -27
- package/src/file/index.ts +0 -43
- /package/src/cli/{assets → templates}/apiHelloControllerTs.ts +0 -0
- /package/src/cli/{assets → templates}/biomeJson.ts +0 -0
- /package/src/cli/{assets → templates}/dummySpecTs.ts +0 -0
- /package/src/cli/{assets → templates}/editorconfig.ts +0 -0
- /package/src/cli/{assets → templates}/mainBrowserTs.ts +0 -0
- /package/src/cli/{assets → templates}/tsconfigJson.ts +0 -0
- /package/src/cli/{assets → templates}/webIndexTs.ts +0 -0
- /package/src/{file → system}/errors/FileError.ts +0 -0
- /package/src/{file → system}/services/FileDetector.ts +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { ShellProvider, ShellRunOptions } from "./ShellProvider.ts";
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export interface MemoryShellCall {
|
|
6
|
+
command: string;
|
|
7
|
+
options: ShellRunOptions;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface MemoryShellProviderOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Simulated outputs for specific commands.
|
|
13
|
+
* Key is the command string, value is the stdout to return.
|
|
14
|
+
*/
|
|
15
|
+
outputs?: Record<string, string>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Commands that should throw an error.
|
|
19
|
+
* Key is the command string, value is the error message.
|
|
20
|
+
*/
|
|
21
|
+
errors?: Record<string, string>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Commands that are considered "installed" in the system PATH.
|
|
25
|
+
*/
|
|
26
|
+
installedCommands?: string[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* In-memory implementation of ShellProvider for testing.
|
|
33
|
+
*
|
|
34
|
+
* Records all commands that would be executed without actually running them.
|
|
35
|
+
* Can be configured to return specific outputs or throw errors for testing.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // In tests, substitute the real ShellProvider with MemoryShellProvider
|
|
40
|
+
* const alepha = Alepha.create().with({
|
|
41
|
+
* provide: ShellProvider,
|
|
42
|
+
* use: MemoryShellProvider,
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Configure mock behavior
|
|
46
|
+
* const shell = alepha.inject(MemoryShellProvider);
|
|
47
|
+
* shell.configure({
|
|
48
|
+
* outputs: { "echo hello": "hello\n" },
|
|
49
|
+
* errors: { "failing-cmd": "Command failed" },
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* // Or use the fluent API
|
|
53
|
+
* shell.outputs.set("another-cmd", "output");
|
|
54
|
+
* shell.errors.set("another-error", "Error message");
|
|
55
|
+
*
|
|
56
|
+
* // Run code that uses ShellProvider
|
|
57
|
+
* const service = alepha.inject(MyService);
|
|
58
|
+
* await service.doSomething();
|
|
59
|
+
*
|
|
60
|
+
* // Verify commands were called
|
|
61
|
+
* expect(shell.calls).toHaveLength(2);
|
|
62
|
+
* expect(shell.calls[0].command).toBe("yarn install");
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export class MemoryShellProvider implements ShellProvider {
|
|
66
|
+
/**
|
|
67
|
+
* All recorded shell calls.
|
|
68
|
+
*/
|
|
69
|
+
public calls: MemoryShellCall[] = [];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Simulated outputs for specific commands.
|
|
73
|
+
*/
|
|
74
|
+
public outputs = new Map<string, string>();
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Commands that should throw an error.
|
|
78
|
+
*/
|
|
79
|
+
public errors = new Map<string, string>();
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Commands considered installed in the system PATH.
|
|
83
|
+
*/
|
|
84
|
+
public installedCommands = new Set<string>();
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Configure the mock with predefined outputs, errors, and installed commands.
|
|
88
|
+
*/
|
|
89
|
+
public configure(options: MemoryShellProviderOptions): this {
|
|
90
|
+
if (options.outputs) {
|
|
91
|
+
for (const [cmd, output] of Object.entries(options.outputs)) {
|
|
92
|
+
this.outputs.set(cmd, output);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (options.errors) {
|
|
96
|
+
for (const [cmd, error] of Object.entries(options.errors)) {
|
|
97
|
+
this.errors.set(cmd, error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (options.installedCommands) {
|
|
101
|
+
for (const cmd of options.installedCommands) {
|
|
102
|
+
this.installedCommands.add(cmd);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Record command and return simulated output.
|
|
110
|
+
*/
|
|
111
|
+
public async run(
|
|
112
|
+
command: string,
|
|
113
|
+
options: ShellRunOptions = {},
|
|
114
|
+
): Promise<string> {
|
|
115
|
+
this.calls.push({ command, options });
|
|
116
|
+
|
|
117
|
+
// Check for configured error
|
|
118
|
+
const errorMsg = this.errors.get(command);
|
|
119
|
+
if (errorMsg) {
|
|
120
|
+
throw new Error(errorMsg);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Return configured output or empty string
|
|
124
|
+
return this.outputs.get(command) ?? "";
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if a specific command was called.
|
|
129
|
+
*/
|
|
130
|
+
public wasCalled(command: string): boolean {
|
|
131
|
+
return this.calls.some((call) => call.command === command);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Check if a command matching a pattern was called.
|
|
136
|
+
*/
|
|
137
|
+
public wasCalledMatching(pattern: RegExp): boolean {
|
|
138
|
+
return this.calls.some((call) => pattern.test(call.command));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get all calls matching a pattern.
|
|
143
|
+
*/
|
|
144
|
+
public getCallsMatching(pattern: RegExp): MemoryShellCall[] {
|
|
145
|
+
return this.calls.filter((call) => pattern.test(call.command));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Check if a command is installed.
|
|
150
|
+
*/
|
|
151
|
+
public async isInstalled(command: string): Promise<boolean> {
|
|
152
|
+
return this.installedCommands.has(command);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Reset all recorded state.
|
|
157
|
+
*/
|
|
158
|
+
public reset(): void {
|
|
159
|
+
this.calls = [];
|
|
160
|
+
this.outputs.clear();
|
|
161
|
+
this.errors.clear();
|
|
162
|
+
this.installedCommands.clear();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Readable } from "node:stream";
|
|
2
2
|
import { Alepha } from "alepha";
|
|
3
3
|
import { beforeEach, describe, it } from "vitest";
|
|
4
|
-
import {
|
|
4
|
+
import { AlephaSystem } from "../index.ts";
|
|
5
5
|
import { NodeFileSystemProvider } from "../providers/NodeFileSystemProvider.ts";
|
|
6
6
|
|
|
7
7
|
describe("NodeFileSystem", () => {
|
|
8
8
|
let fs: NodeFileSystemProvider;
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
11
|
-
const alepha = Alepha.create().with(
|
|
11
|
+
const alepha = Alepha.create().with(AlephaSystem);
|
|
12
12
|
fs = alepha.inject(NodeFileSystemProvider);
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
AlephaError,
|
|
21
21
|
type FileLike,
|
|
22
22
|
isFileLike,
|
|
23
|
+
Json,
|
|
23
24
|
type StreamLike,
|
|
24
25
|
} from "alepha";
|
|
25
26
|
import { FileDetector } from "../services/FileDetector.ts";
|
|
@@ -58,6 +59,7 @@ import type {
|
|
|
58
59
|
*/
|
|
59
60
|
export class NodeFileSystemProvider implements FileSystemProvider {
|
|
60
61
|
protected detector = $inject(FileDetector);
|
|
62
|
+
protected json = $inject(Json);
|
|
61
63
|
|
|
62
64
|
public join(...paths: string[]): string {
|
|
63
65
|
return join(...paths);
|
|
@@ -289,8 +291,17 @@ export class NodeFileSystemProvider implements FileSystemProvider {
|
|
|
289
291
|
* await fs.mkdir("/tmp/mydir", { mode: 0o755 });
|
|
290
292
|
* ```
|
|
291
293
|
*/
|
|
292
|
-
async mkdir(path: string, options
|
|
293
|
-
|
|
294
|
+
async mkdir(path: string, options: MkdirOptions = {}): Promise<void> {
|
|
295
|
+
const p = fsMkdir(path, {
|
|
296
|
+
recursive: options.recursive ?? true,
|
|
297
|
+
mode: options.mode,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
if (options.force === false) {
|
|
301
|
+
await p;
|
|
302
|
+
} else {
|
|
303
|
+
await p.catch(() => {});
|
|
304
|
+
}
|
|
294
305
|
}
|
|
295
306
|
|
|
296
307
|
/**
|
|
@@ -418,6 +429,40 @@ export class NodeFileSystemProvider implements FileSystemProvider {
|
|
|
418
429
|
await fsWriteFile(path, data);
|
|
419
430
|
}
|
|
420
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Reads the content of a file as a string.
|
|
434
|
+
*
|
|
435
|
+
* @param path - The file path to read
|
|
436
|
+
* @returns The file content as a string
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```typescript
|
|
440
|
+
* const fs = alepha.inject(NodeFileSystemProvider);
|
|
441
|
+
* const content = await fs.readTextFile("/tmp/file.txt");
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
async readTextFile(path: string): Promise<string> {
|
|
445
|
+
const buffer = await this.readFile(path);
|
|
446
|
+
return buffer.toString("utf-8");
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Reads the content of a file as JSON.
|
|
451
|
+
*
|
|
452
|
+
* @param path - The file path to read
|
|
453
|
+
* @returns The parsed JSON content
|
|
454
|
+
*
|
|
455
|
+
* @example
|
|
456
|
+
* ```typescript
|
|
457
|
+
* const fs = alepha.inject(NodeFileSystemProvider);
|
|
458
|
+
* const config = await fs.readJsonFile<{ name: string }>("/tmp/config.json");
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
async readJsonFile<T = unknown>(path: string): Promise<T> {
|
|
462
|
+
const text = await this.readTextFile(path);
|
|
463
|
+
return this.json.parse(text) as T;
|
|
464
|
+
}
|
|
465
|
+
|
|
421
466
|
/**
|
|
422
467
|
* Creates a FileLike object from a Web File.
|
|
423
468
|
*
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { exec, spawn } from "node:child_process";
|
|
2
|
+
import { $inject, AlephaError } from "alepha";
|
|
3
|
+
import { $logger } from "alepha/logger";
|
|
4
|
+
import { FileSystemProvider } from "./FileSystemProvider.ts";
|
|
5
|
+
import type { ShellProvider, ShellRunOptions } from "./ShellProvider.ts";
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Node.js implementation of ShellProvider.
|
|
11
|
+
*
|
|
12
|
+
* Executes shell commands using Node.js child_process module.
|
|
13
|
+
* Supports binary resolution from node_modules/.bin for local packages.
|
|
14
|
+
*/
|
|
15
|
+
export class NodeShellProvider implements ShellProvider {
|
|
16
|
+
protected readonly log = $logger();
|
|
17
|
+
protected readonly fs = $inject(FileSystemProvider);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Run a shell command or binary.
|
|
21
|
+
*/
|
|
22
|
+
public async run(
|
|
23
|
+
command: string,
|
|
24
|
+
options: ShellRunOptions = {},
|
|
25
|
+
): Promise<string> {
|
|
26
|
+
const { resolve = false, capture = false, root, env } = options;
|
|
27
|
+
const cwd = root ?? process.cwd();
|
|
28
|
+
|
|
29
|
+
this.log.debug(`Shell: ${command}`, { cwd, resolve, capture });
|
|
30
|
+
|
|
31
|
+
let executable: string;
|
|
32
|
+
let args: string[];
|
|
33
|
+
|
|
34
|
+
if (resolve) {
|
|
35
|
+
const [bin, ...rest] = command.split(" ");
|
|
36
|
+
executable = await this.resolveExecutable(bin, cwd);
|
|
37
|
+
args = rest;
|
|
38
|
+
} else {
|
|
39
|
+
[executable, ...args] = command.split(" ");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (capture) {
|
|
43
|
+
return this.execCapture(command, { cwd, env });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return this.execInherit(executable, args, { cwd, env });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Execute command with inherited stdio (streams to terminal).
|
|
51
|
+
*/
|
|
52
|
+
protected async execInherit(
|
|
53
|
+
executable: string,
|
|
54
|
+
args: string[],
|
|
55
|
+
options: { cwd: string; env?: Record<string, string> },
|
|
56
|
+
): Promise<string> {
|
|
57
|
+
const proc = spawn(executable, args, {
|
|
58
|
+
stdio: "inherit",
|
|
59
|
+
cwd: options.cwd,
|
|
60
|
+
env: {
|
|
61
|
+
...process.env,
|
|
62
|
+
...options.env,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return new Promise<string>((resolve, reject) => {
|
|
67
|
+
proc.on("exit", (code) => {
|
|
68
|
+
if (code === 0 || code === null) {
|
|
69
|
+
resolve("");
|
|
70
|
+
} else {
|
|
71
|
+
reject(new AlephaError(`Command exited with code ${code}`));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
proc.on("error", reject);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Execute command and capture stdout.
|
|
80
|
+
*/
|
|
81
|
+
protected execCapture(
|
|
82
|
+
command: string,
|
|
83
|
+
options: { cwd: string; env?: Record<string, string> },
|
|
84
|
+
): Promise<string> {
|
|
85
|
+
return new Promise<string>((resolve, reject) => {
|
|
86
|
+
exec(
|
|
87
|
+
command,
|
|
88
|
+
{
|
|
89
|
+
cwd: options.cwd,
|
|
90
|
+
env: {
|
|
91
|
+
...process.env,
|
|
92
|
+
LOG_FORMAT: "pretty",
|
|
93
|
+
...options.env,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
(err, stdout) => {
|
|
97
|
+
if (err) {
|
|
98
|
+
(err as any).stdout = stdout;
|
|
99
|
+
reject(err);
|
|
100
|
+
} else {
|
|
101
|
+
resolve(stdout);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Resolve executable path from node_modules/.bin.
|
|
110
|
+
*
|
|
111
|
+
* Search order:
|
|
112
|
+
* 1. Local: node_modules/.bin/
|
|
113
|
+
* 2. Pnpm nested: node_modules/alepha/node_modules/.bin/
|
|
114
|
+
* 3. Monorepo: Walk up to 3 parent directories
|
|
115
|
+
*/
|
|
116
|
+
protected async resolveExecutable(
|
|
117
|
+
name: string,
|
|
118
|
+
root: string,
|
|
119
|
+
): Promise<string> {
|
|
120
|
+
const suffix = process.platform === "win32" ? ".cmd" : "";
|
|
121
|
+
|
|
122
|
+
// 1. Local node_modules
|
|
123
|
+
let execPath = await this.findExecutable(
|
|
124
|
+
root,
|
|
125
|
+
`node_modules/.bin/${name}${suffix}`,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// 2. Pnpm nested (alepha's own node_modules)
|
|
129
|
+
if (!execPath) {
|
|
130
|
+
execPath = await this.findExecutable(
|
|
131
|
+
root,
|
|
132
|
+
`node_modules/alepha/node_modules/.bin/${name}${suffix}`,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 3. Monorepo: check parent directories (up to 3 levels)
|
|
137
|
+
if (!execPath) {
|
|
138
|
+
let parentDir = this.fs.join(root, "..");
|
|
139
|
+
for (let i = 0; i < 3; i++) {
|
|
140
|
+
execPath = await this.findExecutable(
|
|
141
|
+
parentDir,
|
|
142
|
+
`node_modules/.bin/${name}${suffix}`,
|
|
143
|
+
);
|
|
144
|
+
if (execPath) break;
|
|
145
|
+
parentDir = this.fs.join(parentDir, "..");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!execPath) {
|
|
150
|
+
throw new AlephaError(
|
|
151
|
+
`Could not find executable for '${name}'. Make sure the package is installed.`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return execPath;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if executable exists at path.
|
|
160
|
+
*/
|
|
161
|
+
protected async findExecutable(
|
|
162
|
+
root: string,
|
|
163
|
+
relativePath: string,
|
|
164
|
+
): Promise<string | undefined> {
|
|
165
|
+
const fullPath = this.fs.join(root, relativePath);
|
|
166
|
+
if (await this.fs.exists(fullPath)) {
|
|
167
|
+
return fullPath;
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Check if a command is installed and available in the system PATH.
|
|
174
|
+
*/
|
|
175
|
+
public isInstalled(command: string): Promise<boolean> {
|
|
176
|
+
return new Promise((resolve) => {
|
|
177
|
+
const check =
|
|
178
|
+
process.platform === "win32"
|
|
179
|
+
? `where ${command}`
|
|
180
|
+
: `command -v ${command}`;
|
|
181
|
+
exec(check, (error) => resolve(!error));
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
export interface ShellRunOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Working directory for the command.
|
|
6
|
+
*/
|
|
7
|
+
root?: string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Additional environment variables.
|
|
11
|
+
*/
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the executable from node_modules/.bin.
|
|
16
|
+
* Supports local project, pnpm nested, and monorepo structures.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
resolve?: boolean;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Capture stdout instead of inheriting stdio.
|
|
23
|
+
* When true, returns stdout as string.
|
|
24
|
+
* When false, streams output to terminal.
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
capture?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Abstract provider for executing shell commands and binaries.
|
|
34
|
+
*
|
|
35
|
+
* Implementations:
|
|
36
|
+
* - `NodeShellProvider` - Real shell execution using Node.js child_process
|
|
37
|
+
* - `MemoryShellProvider` - In-memory mock for testing
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* class MyService {
|
|
42
|
+
* protected readonly shell = $inject(ShellProvider);
|
|
43
|
+
*
|
|
44
|
+
* async build() {
|
|
45
|
+
* // Run shell command directly
|
|
46
|
+
* await this.shell.run("yarn install");
|
|
47
|
+
*
|
|
48
|
+
* // Run local binary with resolution
|
|
49
|
+
* await this.shell.run("vite build", { resolve: true });
|
|
50
|
+
*
|
|
51
|
+
* // Capture output
|
|
52
|
+
* const output = await this.shell.run("echo hello", { capture: true });
|
|
53
|
+
* }
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export abstract class ShellProvider {
|
|
58
|
+
/**
|
|
59
|
+
* Run a shell command or binary.
|
|
60
|
+
*
|
|
61
|
+
* @param command - The command to run
|
|
62
|
+
* @param options - Execution options
|
|
63
|
+
* @returns stdout if capture is true, empty string otherwise
|
|
64
|
+
*/
|
|
65
|
+
abstract run(command: string, options?: ShellRunOptions): Promise<string>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Check if a command is installed and available in the system PATH.
|
|
69
|
+
*
|
|
70
|
+
* @param command - The command name to check
|
|
71
|
+
* @returns true if the command is available
|
|
72
|
+
*/
|
|
73
|
+
abstract isInstalled(command: string): Promise<boolean>;
|
|
74
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Readable } from "node:stream";
|
|
2
2
|
import { Alepha } from "alepha";
|
|
3
3
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
4
|
-
import {
|
|
4
|
+
import { AlephaSystem } from "../index.ts";
|
|
5
5
|
import { FileDetector } from "../services/FileDetector.ts";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -26,7 +26,7 @@ describe("FileDetector", () => {
|
|
|
26
26
|
let detector: FileDetector;
|
|
27
27
|
|
|
28
28
|
beforeEach(() => {
|
|
29
|
-
const alepha = Alepha.create().with(
|
|
29
|
+
const alepha = Alepha.create().with(AlephaSystem);
|
|
30
30
|
detector = alepha.inject(FileDetector);
|
|
31
31
|
});
|
|
32
32
|
|
package/src/thread/index.ts
CHANGED
|
@@ -22,9 +22,18 @@ Alepha.prototype.isWorkerThread = function (this: Alepha): boolean {
|
|
|
22
22
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* | type | quality | stability |
|
|
26
|
+
* |------|---------|-----------|
|
|
27
|
+
* | backend | standard | experimental |
|
|
28
|
+
*
|
|
29
|
+
* Multi-threading support.
|
|
30
|
+
*
|
|
31
|
+
* **Features:**
|
|
32
|
+
* - Worker thread definitions
|
|
33
|
+
* - Worker thread management
|
|
34
|
+
* - Message passing
|
|
35
|
+
* - Worker pools
|
|
26
36
|
*
|
|
27
|
-
* @see {@link $thread}
|
|
28
37
|
* @module alepha.thread
|
|
29
38
|
*/
|
|
30
39
|
export const AlephaThread = $module({
|
package/src/topic/core/index.ts
CHANGED
|
@@ -15,12 +15,19 @@ export * from "./providers/TopicProvider.ts";
|
|
|
15
15
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* | type | quality | stability |
|
|
19
|
+
* |------|---------|-----------|
|
|
20
|
+
* | backend | rare | stable |
|
|
21
|
+
*
|
|
22
|
+
* Publish/subscribe messaging for event-driven architectures.
|
|
23
|
+
*
|
|
24
|
+
* **Features:**
|
|
25
|
+
* - Pub/sub topics with type-safe messages
|
|
26
|
+
* - Topic subscription handlers
|
|
27
|
+
* - Multiple subscriber support
|
|
28
|
+
* - Message filtering and routing
|
|
29
|
+
* - Providers: Memory (dev), Redis (production)
|
|
21
30
|
*
|
|
22
|
-
* @see {@link $topic}
|
|
23
|
-
* @see {@link $subscriber}
|
|
24
31
|
* @module alepha.topic
|
|
25
32
|
*/
|
|
26
33
|
export const AlephaTopic = $module({
|
|
@@ -36,11 +36,6 @@ export interface BuildClientOptions {
|
|
|
36
36
|
hostname: string;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
/**
|
|
40
|
-
* Override Vite config options.
|
|
41
|
-
*/
|
|
42
|
-
config?: UserConfig;
|
|
43
|
-
|
|
44
39
|
/**
|
|
45
40
|
* If true, generate build stats report.
|
|
46
41
|
*/
|
|
@@ -61,7 +56,7 @@ export interface BuildClientOptions {
|
|
|
61
56
|
* including code splitting, minification, and optional compression.
|
|
62
57
|
*/
|
|
63
58
|
export async function buildClient(opts: BuildClientOptions): Promise<void> {
|
|
64
|
-
const { build: viteBuild
|
|
59
|
+
const { build: viteBuild } = await importVite();
|
|
65
60
|
const plugins: any[] = [];
|
|
66
61
|
|
|
67
62
|
const viteReact = await importViteReact();
|
|
@@ -117,7 +112,7 @@ export async function buildClient(opts: BuildClientOptions): Promise<void> {
|
|
|
117
112
|
};
|
|
118
113
|
|
|
119
114
|
try {
|
|
120
|
-
await viteBuild(
|
|
115
|
+
await viteBuild(viteBuildClientConfig);
|
|
121
116
|
} catch (error) {
|
|
122
117
|
// Flush buffered logs on failure so user can see what happened
|
|
123
118
|
logger?.flush();
|
|
@@ -23,7 +23,7 @@ export interface BuildServerOptions {
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Optional client directory name (relative to distDir).
|
|
26
|
-
* If provided, the
|
|
26
|
+
* If provided, the SSR manifest will be embedded in the server output.
|
|
27
27
|
*/
|
|
28
28
|
clientDir?: string;
|
|
29
29
|
|
|
@@ -61,6 +61,7 @@ export interface BuildServerResult {
|
|
|
61
61
|
* Can be used to set in alepha store for pre-rendering.
|
|
62
62
|
*/
|
|
63
63
|
manifest?: {
|
|
64
|
+
base?: string;
|
|
64
65
|
client?: Record<string, any>;
|
|
65
66
|
preload?: Record<string, string>;
|
|
66
67
|
};
|
|
@@ -166,21 +167,15 @@ export async function buildServer(
|
|
|
166
167
|
|
|
167
168
|
const entryFile = extractEntryFromBundle(opts.entry, result);
|
|
168
169
|
|
|
169
|
-
// Embed client template if client was built
|
|
170
|
-
let template = "";
|
|
171
|
-
if (opts.clientDir) {
|
|
172
|
-
const index = await readFile(
|
|
173
|
-
`${opts.distDir}/${opts.clientDir}/index.html`,
|
|
174
|
-
"utf-8",
|
|
175
|
-
);
|
|
176
|
-
template = `__alepha.set("alepha.react.server.template", \`${index.replace(/>\s*</g, "><").trim()}\`);\n`;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
170
|
// Embed SSR manifests if client was built
|
|
180
171
|
// This bundles all manifest data into index.js for serverless deployments
|
|
181
172
|
let manifest = "";
|
|
182
173
|
let manifestData:
|
|
183
|
-
| {
|
|
174
|
+
| {
|
|
175
|
+
base?: string;
|
|
176
|
+
client?: Record<string, any>;
|
|
177
|
+
preload?: Record<string, string>;
|
|
178
|
+
}
|
|
184
179
|
| undefined;
|
|
185
180
|
|
|
186
181
|
if (opts.clientDir) {
|
|
@@ -193,7 +188,18 @@ export async function buildServer(
|
|
|
193
188
|
// Strip unused fields from client manifest to reduce bundle size
|
|
194
189
|
const strippedClientManifest = stripClientManifest(clientManifest);
|
|
195
190
|
|
|
191
|
+
// Get base path from resolved config (defaults to "/" if not set)
|
|
192
|
+
// Normalize: ensure it starts with "/" and doesn't end with "/" (unless it's just "/")
|
|
193
|
+
let base = resolvedConfig.base || "/";
|
|
194
|
+
if (!base.startsWith("/")) {
|
|
195
|
+
base = `/${base}`;
|
|
196
|
+
}
|
|
197
|
+
if (base.length > 1 && base.endsWith("/")) {
|
|
198
|
+
base = base.slice(0, -1);
|
|
199
|
+
}
|
|
200
|
+
|
|
196
201
|
manifestData = {
|
|
202
|
+
base: base !== "/" ? base : undefined, // Only include if not default
|
|
197
203
|
client: strippedClientManifest,
|
|
198
204
|
preload: preloadManifest,
|
|
199
205
|
};
|
|
@@ -214,7 +220,7 @@ export async function buildServer(
|
|
|
214
220
|
|
|
215
221
|
await writeFile(
|
|
216
222
|
`${opts.distDir}/index.js`,
|
|
217
|
-
`${warning}\n${
|
|
223
|
+
`${warning}\n${manifest}import './server/${entryFile}';\n`.trim(),
|
|
218
224
|
);
|
|
219
225
|
|
|
220
226
|
return { entryFile, manifest: manifestData };
|