alepha 0.14.2 → 0.14.4
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 +1 -1
- 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 +706 -785
- 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 +58 -137
- 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 +29 -108
- 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 +504 -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 +277 -351
- 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 +787 -852
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +827 -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 +128 -128
- 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/bin/index.d.ts +1 -2
- package/dist/bin/index.js +0 -1
- package/dist/bin/index.js.map +1 -1
- package/dist/cli/index.d.ts +252 -131
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +595 -395
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +46 -11
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +99 -19
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +40 -22
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +45 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +40 -22
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +40 -22
- package/dist/core/index.native.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/logger/index.d.ts +1 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +12 -2
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.d.ts +59 -195
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +201 -430
- package/dist/orm/index.js.map +1 -1
- package/dist/security/index.d.ts +1 -1
- 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.d.ts +12 -0
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +55 -2
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +6 -0
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +38 -1
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/core/index.browser.js +2 -2
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +10 -10
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +7 -4
- package/dist/server/core/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/static/index.d.ts.map +1 -1
- package/dist/server/static/index.js +4 -0
- package/dist/server/static/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 +9 -5
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/vite/index.d.ts +101 -106
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +574 -503
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts +7 -7
- 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 +9 -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 +25 -6
- package/src/cli/atoms/buildOptions.ts +88 -0
- package/src/cli/commands/build.ts +32 -69
- package/src/cli/commands/db.ts +0 -4
- package/src/cli/commands/dev.ts +34 -10
- package/src/cli/commands/gen/changelog.spec.ts +315 -0
- package/src/cli/commands/{changelog.ts → gen/changelog.ts} +9 -9
- package/src/cli/commands/gen/env.ts +53 -0
- package/src/cli/commands/gen/openapi.ts +71 -0
- package/src/cli/commands/gen/resource.ts +15 -0
- package/src/cli/commands/gen.ts +24 -0
- package/src/cli/commands/init.ts +2 -1
- package/src/cli/commands/root.ts +12 -3
- package/src/cli/commands/test.ts +0 -1
- package/src/cli/commands/typecheck.ts +5 -0
- package/src/cli/commands/verify.ts +1 -1
- package/src/cli/defineConfig.ts +49 -7
- package/src/cli/index.ts +2 -2
- package/src/cli/services/AlephaCliUtils.ts +105 -55
- 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/helpers/Runner.ts +1 -1
- package/src/command/primitives/$command.spec.ts +1588 -0
- package/src/command/primitives/$command.ts +0 -6
- package/src/command/providers/CliProvider.ts +75 -27
- package/src/core/Alepha.ts +87 -0
- 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/index.ts +15 -3
- 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/mcp/transports/StdioMcpTransport.ts +1 -1
- 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.ts +2 -8
- 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/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 +394 -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 +1125 -0
- package/src/server/cache/providers/ServerCacheProvider.ts +94 -9
- package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
- package/src/server/compress/providers/ServerCompressProvider.ts +63 -2
- 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/helpers/ServerReply.ts +2 -2
- 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 +14 -2
- 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/static/providers/ServerStaticProvider.ts +10 -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 +19 -12
- 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/helpers/importViteReact.ts +13 -0
- package/src/vite/index.ts +1 -21
- package/src/vite/plugins/viteAlephaDev.ts +32 -5
- package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
- package/src/vite/tasks/buildClient.ts +11 -0
- package/src/vite/tasks/buildServer.ts +47 -3
- package/src/vite/tasks/devServer.ts +69 -0
- package/src/vite/tasks/index.ts +2 -1
- 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/assets/viteConfigTs.ts +0 -14
- package/src/cli/commands/run.ts +0 -24
- package/src/vite/plugins/viteAlepha.ts +0 -37
- package/src/vite/plugins/viteAlephaBuild.ts +0 -281
package/dist/vite/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import m, { createRequire } from "node:module";
|
|
2
|
-
import { access, cp, mkdir, readFile,
|
|
3
|
-
import path, { basename, dirname, join, resolve } from "node:path";
|
|
4
|
-
import { AlephaError
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { access, cp, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
4
|
+
import { AlephaError } from "alepha";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { existsSync, mkdirSync, promises, writeFileSync } from "node:fs";
|
|
7
8
|
import { promisify } from "node:util";
|
|
8
9
|
import { brotliCompress, gzip } from "node:zlib";
|
|
9
|
-
import {
|
|
10
|
+
import { analyzer } from "vite-bundle-analyzer";
|
|
10
11
|
|
|
11
12
|
//#region ../../src/vite/helpers/boot.ts
|
|
12
13
|
/**
|
|
@@ -159,12 +160,6 @@ function createBufferedLogger() {
|
|
|
159
160
|
};
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region ../../src/vite/helpers/fileExists.ts
|
|
164
|
-
const fileExists = async (path$1) => {
|
|
165
|
-
return await access(join(process.cwd(), path$1)).then(() => true).catch(() => false);
|
|
166
|
-
};
|
|
167
|
-
|
|
168
163
|
//#endregion
|
|
169
164
|
//#region ../../src/vite/helpers/importVite.ts
|
|
170
165
|
const importVite = async () => {
|
|
@@ -180,102 +175,519 @@ const importVite = async () => {
|
|
|
180
175
|
};
|
|
181
176
|
|
|
182
177
|
//#endregion
|
|
183
|
-
//#region ../../src/vite/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
178
|
+
//#region ../../src/vite/tasks/runAlepha.ts
|
|
179
|
+
/**
|
|
180
|
+
* Create an Alepha runner for development.
|
|
181
|
+
*
|
|
182
|
+
* The runner manages the lifecycle of an Alepha application during
|
|
183
|
+
* Vite dev server operation, handling start/stop/restart and HMR.
|
|
184
|
+
*/
|
|
185
|
+
function createAlephaRunner(opts) {
|
|
186
|
+
return new AlephaRunner({
|
|
187
|
+
root: process.cwd().replace(/\\/g, "/"),
|
|
188
|
+
started: false,
|
|
189
|
+
log: opts.debug ? (...msg) => console.log(...msg) : () => {},
|
|
190
|
+
entry: opts.entry,
|
|
191
|
+
onReload: () => {}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
var AlephaRunner = class {
|
|
195
|
+
state;
|
|
196
|
+
constructor(state) {
|
|
197
|
+
this.state = state;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Set resolved Vite config.
|
|
201
|
+
*/
|
|
202
|
+
setConfig(config) {
|
|
203
|
+
this.state.config = config;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if SSR is enabled for the running app.
|
|
207
|
+
*/
|
|
208
|
+
isSsrEnabled() {
|
|
209
|
+
if (!this.state.app) return false;
|
|
210
|
+
return this.state.app.store.get("alepha.react.server.ssr") ?? false;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if app is started.
|
|
214
|
+
*/
|
|
215
|
+
get isStarted() {
|
|
216
|
+
return this.state.started;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get the running Alepha app instance.
|
|
220
|
+
*/
|
|
221
|
+
get app() {
|
|
222
|
+
return this.state.app;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Start the Alepha application.
|
|
226
|
+
*/
|
|
227
|
+
async start(server) {
|
|
228
|
+
const { loadEnv } = await importVite();
|
|
229
|
+
global.ssrFixStacktrace = (e) => {
|
|
230
|
+
server.ssrFixStacktrace(e);
|
|
231
|
+
let it = e;
|
|
232
|
+
do {
|
|
233
|
+
server.ssrFixStacktrace(it);
|
|
234
|
+
it = it.cause;
|
|
235
|
+
} while (it instanceof Error);
|
|
236
|
+
};
|
|
237
|
+
if (this.state.started) {
|
|
238
|
+
await this.restart(server, true);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (!this.state.config) {
|
|
242
|
+
this.state.log("[DEBUG] No config - skip starting");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
this.state.onReload?.();
|
|
246
|
+
this.state.log("[DEBUG] Starting Alepha app...");
|
|
247
|
+
this.state.started = false;
|
|
248
|
+
this.state.app = void 0;
|
|
249
|
+
const fileUrl = pathToFileURL(`${path.resolve(this.state.config.root, this.state.entry)}`).href;
|
|
250
|
+
const env = loadEnv("development", this.state.config.root, "");
|
|
251
|
+
const before = { ...process.env };
|
|
252
|
+
for (const key in env) process.env[key] = env[key];
|
|
253
|
+
let port = 5173;
|
|
254
|
+
const address = server.httpServer?.address();
|
|
255
|
+
if (typeof address === "object" && address?.port) port = address.port;
|
|
256
|
+
process.env.NODE_ENV ??= "development";
|
|
257
|
+
process.env.VITE_ALEPHA_DEV = "true";
|
|
258
|
+
process.env.SERVER_HOST ??= typeof server.config.server.host === "string" ? server.config.server.host : "localhost";
|
|
259
|
+
process.env.SERVER_PORT ??= String(port);
|
|
260
|
+
try {
|
|
193
261
|
const now = Date.now();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
await
|
|
205
|
-
this.
|
|
262
|
+
await server.ssrLoadModule(fileUrl, { fixStacktrace: true });
|
|
263
|
+
this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);
|
|
264
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
265
|
+
this.state.app = globalThis.__alepha;
|
|
266
|
+
if (!this.state.app) {
|
|
267
|
+
this.state.log("[DEBUG] No app found - skip starting");
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.state.app.store.set("alepha.node.server", server.httpServer);
|
|
271
|
+
console.log("");
|
|
272
|
+
await this.state.app.start();
|
|
273
|
+
this.state.started = true;
|
|
274
|
+
process.env = { ...before };
|
|
275
|
+
this.state.log("[DEBUG] Starting Done!");
|
|
276
|
+
} catch (e) {
|
|
277
|
+
if (e instanceof Error) {
|
|
278
|
+
let it = e;
|
|
279
|
+
do {
|
|
280
|
+
server.ssrFixStacktrace(it);
|
|
281
|
+
it = it.cause;
|
|
282
|
+
} while (it instanceof Error);
|
|
283
|
+
server.ssrFixStacktrace(e);
|
|
284
|
+
if (e.cause instanceof Error) server.ssrFixStacktrace(e.cause);
|
|
285
|
+
this.state.app?.log?.error("App failed to start:", e);
|
|
286
|
+
this.state.app?.log?.info("Waiting for changes to restart...");
|
|
287
|
+
}
|
|
288
|
+
this.state.log("[DEBUG] Alepha app start error");
|
|
289
|
+
this.state.started = false;
|
|
206
290
|
}
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
async function compressFile(options = {}, filePath) {
|
|
210
|
-
const { brotli = true, gzip: gzip$1 = true } = options;
|
|
211
|
-
const compressionTasks = [];
|
|
212
|
-
const fileContentPromise = promises.readFile(filePath);
|
|
213
|
-
if (gzip$1) {
|
|
214
|
-
const gzipOptions = typeof gzip$1 === "object" ? gzip$1 : { level: 9 };
|
|
215
|
-
compressionTasks.push(fileContentPromise.then(async (content) => {
|
|
216
|
-
const compressed = await gzipCompress(content, gzipOptions);
|
|
217
|
-
await promises.writeFile(`${filePath}.gz`, compressed);
|
|
218
|
-
}));
|
|
219
291
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Stop the Alepha application.
|
|
294
|
+
*/
|
|
295
|
+
async stop() {
|
|
296
|
+
if (this.state.app?.stop && this.state.started) {
|
|
297
|
+
this.state.log("[DEBUG] Stopping Alepha app...");
|
|
298
|
+
await this.state.app.stop();
|
|
299
|
+
this.state.started = false;
|
|
300
|
+
this.state.log("[DEBUG] Stopping Done!");
|
|
301
|
+
} else this.state.log("[DEBUG] Alepha app not started - skip stop");
|
|
226
302
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
303
|
+
/**
|
|
304
|
+
* Restart the Alepha application.
|
|
305
|
+
*
|
|
306
|
+
* @returns true if the restart was skipped due to locking
|
|
307
|
+
*/
|
|
308
|
+
async restart(server, invalidate) {
|
|
309
|
+
if (this.state.lock) {
|
|
310
|
+
this.state.log("[DEBUG] STILL LOCKING");
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
this.state.log("[DEBUG] LOCK RESTART");
|
|
314
|
+
this.state.lock = Promise.withResolvers();
|
|
315
|
+
const now = Date.now();
|
|
316
|
+
this.state.log("[DEBUG] RESTART");
|
|
317
|
+
await this.stop();
|
|
318
|
+
this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);
|
|
319
|
+
if (invalidate) server.moduleGraph.invalidateAll();
|
|
320
|
+
await this.start(server);
|
|
321
|
+
this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);
|
|
322
|
+
setTimeout(() => {
|
|
323
|
+
this.state.log("[DEBUG] UNLOCK RESTART");
|
|
324
|
+
this.state.lock?.resolve();
|
|
325
|
+
this.state.lock = void 0;
|
|
326
|
+
}, 500);
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Send reload event to client.
|
|
331
|
+
*/
|
|
332
|
+
sendReload(server) {
|
|
333
|
+
server.ws.send({
|
|
334
|
+
type: "custom",
|
|
335
|
+
event: "alepha:reload",
|
|
336
|
+
data: {}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
};
|
|
232
340
|
/**
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
* This task compiles the browser/client code for production,
|
|
236
|
-
* including code splitting, minification, and optional compression.
|
|
341
|
+
* Check if a URL path is a Vite internal file.
|
|
237
342
|
*/
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (opts.stats) plugins.push(analyzer({ analyzerMode: "static" }));
|
|
243
|
-
if (opts.precompress && compress) plugins.push(viteCompress(compress));
|
|
244
|
-
const logger = opts.silent ? createBufferedLogger() : void 0;
|
|
245
|
-
const viteBuildClientConfig = {
|
|
246
|
-
mode: "production",
|
|
247
|
-
logLevel: opts.silent ? "silent" : void 0,
|
|
248
|
-
define: { "process.env.NODE_ENV": "\"production\"" },
|
|
249
|
-
publicDir: "public",
|
|
250
|
-
build: {
|
|
251
|
-
chunkSizeWarningLimit: 1e3,
|
|
252
|
-
outDir: opts.dist,
|
|
253
|
-
rollupOptions: { output: {
|
|
254
|
-
entryFileNames: "entry.[hash].js",
|
|
255
|
-
chunkFileNames: "chunk.[hash].js",
|
|
256
|
-
assetFileNames: "asset.[hash][extname]"
|
|
257
|
-
} }
|
|
258
|
-
},
|
|
259
|
-
esbuild: { legalComments: "none" },
|
|
260
|
-
customLogger: logger,
|
|
261
|
-
plugins
|
|
262
|
-
};
|
|
263
|
-
try {
|
|
264
|
-
await viteBuild(mergeConfig(viteBuildClientConfig, opts.config ?? {}));
|
|
265
|
-
} catch (error) {
|
|
266
|
-
logger?.flush();
|
|
267
|
-
throw error;
|
|
268
|
-
}
|
|
343
|
+
function isViteInternalPath(pathname) {
|
|
344
|
+
const [path$1] = pathname.split("?");
|
|
345
|
+
if (path$1.startsWith("/@") || path$1.startsWith("/src") || path$1.includes("/node_modules/")) return true;
|
|
346
|
+
return false;
|
|
269
347
|
}
|
|
270
348
|
|
|
271
349
|
//#endregion
|
|
272
|
-
//#region ../../src/vite/
|
|
350
|
+
//#region ../../src/vite/plugins/viteAlephaDev.ts
|
|
273
351
|
/**
|
|
274
|
-
*
|
|
352
|
+
* Plug Alepha into Vite development server.
|
|
275
353
|
*
|
|
276
|
-
* This
|
|
277
|
-
*
|
|
278
|
-
|
|
354
|
+
* This plugin manages the Alepha application lifecycle during development,
|
|
355
|
+
* handling hot module replacement and request forwarding.
|
|
356
|
+
*/
|
|
357
|
+
async function viteAlephaDev(options = {}) {
|
|
358
|
+
let entry = options.serverEntry;
|
|
359
|
+
if (!entry) {
|
|
360
|
+
entry = await boot.getServerEntry();
|
|
361
|
+
if (!entry) return {
|
|
362
|
+
name: "alepha-dev",
|
|
363
|
+
apply: "serve",
|
|
364
|
+
config() {}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
const runner = createAlephaRunner({
|
|
368
|
+
entry,
|
|
369
|
+
debug: options.debug
|
|
370
|
+
});
|
|
371
|
+
const { loadEnv } = await importVite();
|
|
372
|
+
const env = loadEnv("development", process.cwd(), "SERVER");
|
|
373
|
+
const config = {};
|
|
374
|
+
if (env.SERVER_PORT) config.server = { port: parseInt(env.SERVER_PORT, 10) };
|
|
375
|
+
return {
|
|
376
|
+
name: "alepha-dev",
|
|
377
|
+
apply: "serve",
|
|
378
|
+
config: () => config,
|
|
379
|
+
configResolved(resolvedConfig) {
|
|
380
|
+
runner.setConfig(resolvedConfig);
|
|
381
|
+
},
|
|
382
|
+
async handleHotUpdate(ctx) {
|
|
383
|
+
if (options.debug) console.log("[DEBUG] HMR", ctx.file);
|
|
384
|
+
if (ctx.file.includes("/.idea/")) return [];
|
|
385
|
+
const isServerOnly = !ctx.modules[0]?._clientModule;
|
|
386
|
+
const isBrowserOnly = !ctx.modules[0]?._ssrModule;
|
|
387
|
+
const isSsrEnabled = runner.isSsrEnabled();
|
|
388
|
+
if (isBrowserOnly) {
|
|
389
|
+
if (options.debug) console.log("[DEBUG] HMR - browser only - no reason to reload server");
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const root = process.cwd().replace(/\\/g, "/");
|
|
393
|
+
const invalidate = !ctx.file.startsWith(root);
|
|
394
|
+
if (invalidate && options.debug) console.log("[DEBUG] HMR - outside root - invalidate all");
|
|
395
|
+
if (!isSsrEnabled && isServerOnly) {
|
|
396
|
+
await runner.restart(ctx.server, invalidate);
|
|
397
|
+
return [];
|
|
398
|
+
}
|
|
399
|
+
if (isSsrEnabled && ctx.modules[0]) {
|
|
400
|
+
if (await runner.restart(ctx.server, invalidate)) return [];
|
|
401
|
+
if (!runner.isStarted) {
|
|
402
|
+
if (options.debug) console.log("[DEBUG] HMR - abort due to app not started");
|
|
403
|
+
return [];
|
|
404
|
+
}
|
|
405
|
+
if (isServerOnly && runner.isStarted) {
|
|
406
|
+
runner.sendReload(ctx.server);
|
|
407
|
+
return [];
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
async configureServer(server) {
|
|
412
|
+
if (env.SERVER_PORT) server.config.server.port = parseInt(env.SERVER_PORT, 10);
|
|
413
|
+
const middleware = (req, res, next) => {
|
|
414
|
+
if (runner.isStarted && runner.app && req.url && !isViteInternalPath(req.url)) {
|
|
415
|
+
let ended = false;
|
|
416
|
+
const writeHead = res.writeHead.bind(res);
|
|
417
|
+
res.writeHead = (...args) => {
|
|
418
|
+
ended = true;
|
|
419
|
+
return writeHead(args[0], args[1], args[2]);
|
|
420
|
+
};
|
|
421
|
+
return runner.app.events.emit("node:request", {
|
|
422
|
+
req,
|
|
423
|
+
res
|
|
424
|
+
}).then(() => {
|
|
425
|
+
if (!ended) next();
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
next();
|
|
429
|
+
};
|
|
430
|
+
server.middlewares.use((req, res, next) => {
|
|
431
|
+
middleware(req, res, next);
|
|
432
|
+
});
|
|
433
|
+
server.config.logger.info = (msg) => {
|
|
434
|
+
console.log(msg);
|
|
435
|
+
};
|
|
436
|
+
server.config.logger.clearScreen = () => {};
|
|
437
|
+
return () => {
|
|
438
|
+
server.httpServer?.once("listening", () => {
|
|
439
|
+
runner.start(server);
|
|
440
|
+
});
|
|
441
|
+
};
|
|
442
|
+
},
|
|
443
|
+
async closeBundle() {}
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region ../../src/vite/plugins/viteAlephaSsrPreload.ts
|
|
449
|
+
/**
|
|
450
|
+
* Vite plugin that generates a preload manifest for SSR module preloading.
|
|
451
|
+
*
|
|
452
|
+
* Instead of injecting source paths directly into $page definitions (which would
|
|
453
|
+
* leak component paths in the browser bundle), this plugin:
|
|
454
|
+
*
|
|
455
|
+
* 1. Collects all lazy import paths from $page definitions during transform
|
|
456
|
+
* 2. Generates a manifest file mapping short keys to resolved source paths
|
|
457
|
+
* 3. Injects only the short key into $page definitions
|
|
458
|
+
*
|
|
459
|
+
* The manifest is written to `.vite/preload-manifest.json` alongside Vite's
|
|
460
|
+
* other manifests. The CLI build command moves all manifests to
|
|
461
|
+
* `dist/server/.ssr/` where SSRManifestProvider loads them at runtime.
|
|
462
|
+
*
|
|
463
|
+
* Before:
|
|
464
|
+
* ```typescript
|
|
465
|
+
* $page({
|
|
466
|
+
* path: '/users/:id',
|
|
467
|
+
* lazy: () => import('./UserDetail.tsx'),
|
|
468
|
+
* })
|
|
469
|
+
* ```
|
|
470
|
+
*
|
|
471
|
+
* After:
|
|
472
|
+
* ```typescript
|
|
473
|
+
* $page({
|
|
474
|
+
* path: '/users/:id',
|
|
475
|
+
* lazy: () => import('./UserDetail.tsx'),
|
|
476
|
+
* [Symbol.for("alepha.page.preload")]: "a1b2c3",
|
|
477
|
+
* })
|
|
478
|
+
* ```
|
|
479
|
+
*
|
|
480
|
+
* Manifest (.alepha/preload-manifest.json):
|
|
481
|
+
* ```json
|
|
482
|
+
* {
|
|
483
|
+
* "a1b2c3": "src/pages/UserDetail.tsx"
|
|
484
|
+
* }
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
function viteAlephaSsrPreload() {
|
|
488
|
+
let root = "";
|
|
489
|
+
const preloadMap = /* @__PURE__ */ new Map();
|
|
490
|
+
/**
|
|
491
|
+
* Generate a short hash key for a source path.
|
|
492
|
+
* Uses first 8 chars of MD5 hash for brevity while avoiding collisions.
|
|
493
|
+
*/
|
|
494
|
+
function generateKey(sourcePath) {
|
|
495
|
+
return createHash("md5").update(sourcePath).digest("hex").slice(0, 8);
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
name: "alepha-preload",
|
|
499
|
+
configResolved(config) {
|
|
500
|
+
root = config.root;
|
|
501
|
+
},
|
|
502
|
+
transform(code, id) {
|
|
503
|
+
if (!id.match(/\.[tj]sx?$/)) return null;
|
|
504
|
+
if (id.includes("node_modules")) return null;
|
|
505
|
+
if (!code.includes("$page") || !code.includes("lazy")) return null;
|
|
506
|
+
const insertions = [];
|
|
507
|
+
const pageStartRegex = /\$page\s*\(\s*\{/g;
|
|
508
|
+
let pageMatch = pageStartRegex.exec(code);
|
|
509
|
+
while (pageMatch !== null) {
|
|
510
|
+
const objectStartIndex = pageMatch.index + pageMatch[0].length - 1;
|
|
511
|
+
let braceCount = 1;
|
|
512
|
+
let i = objectStartIndex + 1;
|
|
513
|
+
while (i < code.length && braceCount > 0) {
|
|
514
|
+
if (code[i] === "{") braceCount++;
|
|
515
|
+
else if (code[i] === "}") braceCount--;
|
|
516
|
+
i++;
|
|
517
|
+
}
|
|
518
|
+
if (braceCount !== 0) {
|
|
519
|
+
pageMatch = pageStartRegex.exec(code);
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
const objectEndIndex = i - 1;
|
|
523
|
+
const pageContent = code.slice(objectStartIndex, objectEndIndex + 1);
|
|
524
|
+
if (pageContent.includes("alepha.page.preload")) {
|
|
525
|
+
pageMatch = pageStartRegex.exec(code);
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
const lazyMatch = /lazy\s*:\s*\(\s*\)\s*=>\s*import\s*\(\s*['"]([^'"]+)['"]\s*\)/.exec(pageContent);
|
|
529
|
+
if (!lazyMatch) {
|
|
530
|
+
pageMatch = pageStartRegex.exec(code);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
const importPath = lazyMatch[1];
|
|
534
|
+
const currentDir = dirname(id);
|
|
535
|
+
let resolvedPath;
|
|
536
|
+
if (importPath.startsWith(".")) resolvedPath = resolve(currentDir, importPath);
|
|
537
|
+
else if (importPath.startsWith("/")) resolvedPath = resolve(root, importPath.slice(1));
|
|
538
|
+
else {
|
|
539
|
+
pageMatch = pageStartRegex.exec(code);
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
let relativePath = relative(root, resolvedPath);
|
|
543
|
+
relativePath = relativePath.replace(/\\/g, "/");
|
|
544
|
+
if (!relativePath.match(/\.[tj]sx?$/)) relativePath = `${relativePath}.tsx`;
|
|
545
|
+
else if (relativePath.endsWith(".jsx")) relativePath = relativePath.replace(/\.jsx$/, ".tsx");
|
|
546
|
+
else if (relativePath.endsWith(".js")) relativePath = relativePath.replace(/\.js$/, ".ts");
|
|
547
|
+
const key = generateKey(relativePath);
|
|
548
|
+
preloadMap.set(key, relativePath);
|
|
549
|
+
const preloadProperty = `${!code.slice(0, objectEndIndex).trimEnd().endsWith(",") ? "," : ""} [Symbol.for("alepha.page.preload")]: "${key}"`;
|
|
550
|
+
insertions.push({
|
|
551
|
+
position: objectEndIndex,
|
|
552
|
+
text: preloadProperty
|
|
553
|
+
});
|
|
554
|
+
pageMatch = pageStartRegex.exec(code);
|
|
555
|
+
}
|
|
556
|
+
if (insertions.length === 0) return null;
|
|
557
|
+
let result = code;
|
|
558
|
+
for (let j = insertions.length - 1; j >= 0; j--) {
|
|
559
|
+
const { position, text } = insertions[j];
|
|
560
|
+
result = result.slice(0, position) + text + result.slice(position);
|
|
561
|
+
}
|
|
562
|
+
return {
|
|
563
|
+
code: result,
|
|
564
|
+
map: null
|
|
565
|
+
};
|
|
566
|
+
},
|
|
567
|
+
writeBundle(options) {
|
|
568
|
+
const outDir = options.dir || "";
|
|
569
|
+
if (outDir.includes("server")) return;
|
|
570
|
+
if (preloadMap.size > 0) {
|
|
571
|
+
const viteDir = join(outDir, ".vite");
|
|
572
|
+
if (!existsSync(viteDir)) mkdirSync(viteDir, { recursive: true });
|
|
573
|
+
const manifest = Object.fromEntries(preloadMap);
|
|
574
|
+
writeFileSync(join(viteDir, "preload-manifest.json"), JSON.stringify(manifest, null, 2));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
//#endregion
|
|
581
|
+
//#region ../../src/vite/plugins/viteCompress.ts
|
|
582
|
+
const gzipCompress = promisify(gzip);
|
|
583
|
+
const brotliCompress$1 = promisify(brotliCompress);
|
|
584
|
+
function viteCompress(options = {}) {
|
|
585
|
+
const { disabled = false, filter = /\.(js|mjs|cjs|css|wasm|svg)$/ } = options;
|
|
586
|
+
return {
|
|
587
|
+
name: "compress",
|
|
588
|
+
apply: "build",
|
|
589
|
+
async writeBundle(outputOptions, bundle) {
|
|
590
|
+
if (disabled) return;
|
|
591
|
+
const now = Date.now();
|
|
592
|
+
const outputDir = outputOptions.dir || resolve(process.cwd(), "dist");
|
|
593
|
+
const files = Object.keys(bundle).filter((fileName) => {
|
|
594
|
+
if (typeof filter === "function") return filter(fileName);
|
|
595
|
+
return filter.test(fileName);
|
|
596
|
+
}).map((fileName) => ({
|
|
597
|
+
fileName,
|
|
598
|
+
filePath: join(outputDir, fileName)
|
|
599
|
+
}));
|
|
600
|
+
const compressionTasks = [];
|
|
601
|
+
for (const { filePath } of files) compressionTasks.push(compressFile(options, filePath));
|
|
602
|
+
await Promise.all(compressionTasks);
|
|
603
|
+
this.info(`Compressed ${files.length} file${files.length > 1 ? "s" : ""} in ${Date.now() - now}ms.`);
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
async function compressFile(options = {}, filePath) {
|
|
608
|
+
const { brotli = true, gzip: gzip$1 = true } = options;
|
|
609
|
+
const compressionTasks = [];
|
|
610
|
+
const fileContentPromise = promises.readFile(filePath);
|
|
611
|
+
if (gzip$1) {
|
|
612
|
+
const gzipOptions = typeof gzip$1 === "object" ? gzip$1 : { level: 9 };
|
|
613
|
+
compressionTasks.push(fileContentPromise.then(async (content) => {
|
|
614
|
+
const compressed = await gzipCompress(content, gzipOptions);
|
|
615
|
+
await promises.writeFile(`${filePath}.gz`, compressed);
|
|
616
|
+
}));
|
|
617
|
+
}
|
|
618
|
+
if (brotli) {
|
|
619
|
+
const brotliOptions = typeof brotli === "object" ? brotli : {};
|
|
620
|
+
compressionTasks.push(fileContentPromise.then(async (content) => {
|
|
621
|
+
const compressed = await brotliCompress$1(content, brotliOptions);
|
|
622
|
+
await promises.writeFile(`${filePath}.br`, compressed);
|
|
623
|
+
}));
|
|
624
|
+
}
|
|
625
|
+
await Promise.all(compressionTasks);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
//#endregion
|
|
629
|
+
//#region ../../src/vite/helpers/importViteReact.ts
|
|
630
|
+
const importViteReact = async () => {
|
|
631
|
+
try {
|
|
632
|
+
const { default: viteReact } = createRequire(import.meta.url)("@vitejs/plugin-react");
|
|
633
|
+
return viteReact;
|
|
634
|
+
} catch {}
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
//#endregion
|
|
638
|
+
//#region ../../src/vite/tasks/buildClient.ts
|
|
639
|
+
/**
|
|
640
|
+
* Build client-side bundle with Vite.
|
|
641
|
+
*
|
|
642
|
+
* This task compiles the browser/client code for production,
|
|
643
|
+
* including code splitting, minification, and optional compression.
|
|
644
|
+
*/
|
|
645
|
+
async function buildClient(opts) {
|
|
646
|
+
const { build: viteBuild, mergeConfig } = await importVite();
|
|
647
|
+
const plugins = [];
|
|
648
|
+
const viteReact = await importViteReact();
|
|
649
|
+
if (viteReact) plugins.push(viteReact());
|
|
650
|
+
plugins.push(viteAlephaSsrPreload());
|
|
651
|
+
const compress = opts.precompress ? typeof opts.precompress === "object" ? opts.precompress : {} : void 0;
|
|
652
|
+
if (opts.stats) plugins.push(analyzer({ analyzerMode: "static" }));
|
|
653
|
+
if (opts.precompress && compress) plugins.push(viteCompress(compress));
|
|
654
|
+
const logger = opts.silent ? createBufferedLogger() : void 0;
|
|
655
|
+
const viteBuildClientConfig = {
|
|
656
|
+
mode: "production",
|
|
657
|
+
logLevel: opts.silent ? "silent" : void 0,
|
|
658
|
+
define: { "process.env.NODE_ENV": "\"production\"" },
|
|
659
|
+
publicDir: "public",
|
|
660
|
+
build: {
|
|
661
|
+
chunkSizeWarningLimit: 1e3,
|
|
662
|
+
outDir: opts.dist,
|
|
663
|
+
manifest: true,
|
|
664
|
+
ssrManifest: true,
|
|
665
|
+
rollupOptions: { output: {
|
|
666
|
+
entryFileNames: "entry.[hash].js",
|
|
667
|
+
chunkFileNames: "chunk.[hash].js",
|
|
668
|
+
assetFileNames: "asset.[hash][extname]"
|
|
669
|
+
} }
|
|
670
|
+
},
|
|
671
|
+
esbuild: { legalComments: "none" },
|
|
672
|
+
customLogger: logger,
|
|
673
|
+
plugins
|
|
674
|
+
};
|
|
675
|
+
try {
|
|
676
|
+
await viteBuild(mergeConfig(viteBuildClientConfig, opts.config ?? {}));
|
|
677
|
+
} catch (error) {
|
|
678
|
+
logger?.flush();
|
|
679
|
+
throw error;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region ../../src/vite/tasks/generateExternals.ts
|
|
685
|
+
/**
|
|
686
|
+
* Generate minimal package.json with pinned external dependencies.
|
|
687
|
+
*
|
|
688
|
+
* This task creates a package.json in the dist directory containing
|
|
689
|
+
* only the external dependencies needed at runtime, with their versions
|
|
690
|
+
* pinned to the currently installed versions.
|
|
279
691
|
*/
|
|
280
692
|
async function generateExternals(opts) {
|
|
281
693
|
const require = m.createRequire(import.meta.filename);
|
|
@@ -307,6 +719,9 @@ async function generateExternals(opts) {
|
|
|
307
719
|
async function buildServer(opts) {
|
|
308
720
|
const { build: viteBuild, mergeConfig } = await importVite();
|
|
309
721
|
const plugins = [];
|
|
722
|
+
const viteReact = await importViteReact();
|
|
723
|
+
if (viteReact && opts.clientDir) plugins.push(viteReact());
|
|
724
|
+
plugins.push(viteAlephaSsrPreload());
|
|
310
725
|
if (opts.stats) plugins.push(analyzer({ analyzerMode: "static" }));
|
|
311
726
|
const logger = opts.silent ? createBufferedLogger() : void 0;
|
|
312
727
|
const viteBuildServerConfig = {
|
|
@@ -353,12 +768,37 @@ async function buildServer(opts) {
|
|
|
353
768
|
const entryFile = extractEntryFromBundle(opts.entry, result);
|
|
354
769
|
let template = "";
|
|
355
770
|
if (opts.clientDir) template = `__alepha.set("alepha.react.server.template", \`${(await readFile(`${opts.distDir}/${opts.clientDir}/index.html`, "utf-8")).replace(/>\s*</g, "><").trim()}\`);\n`;
|
|
771
|
+
let manifest = "";
|
|
772
|
+
if (opts.clientDir) {
|
|
773
|
+
const viteDir = `${opts.distDir}/${opts.clientDir}/.vite`;
|
|
774
|
+
const combined = {
|
|
775
|
+
ssr: await loadJsonFile(`${viteDir}/ssr-manifest.json`),
|
|
776
|
+
client: await loadJsonFile(`${viteDir}/manifest.json`),
|
|
777
|
+
preload: await loadJsonFile(`${viteDir}/preload-manifest.json`)
|
|
778
|
+
};
|
|
779
|
+
manifest = `__alepha.set("alepha.react.ssr.manifest", ${JSON.stringify(combined)});\n`;
|
|
780
|
+
await rm(viteDir, {
|
|
781
|
+
recursive: true,
|
|
782
|
+
force: true
|
|
783
|
+
});
|
|
784
|
+
}
|
|
356
785
|
await writeFile(`${opts.distDir}/index.js`, `// This file was automatically generated. DO NOT MODIFY.
|
|
357
786
|
// Changes to this file will be lost when the code is regenerated.
|
|
358
|
-
\
|
|
787
|
+
\n${template}${manifest}import './server/${entryFile}';\n`.trim());
|
|
359
788
|
return { entryFile };
|
|
360
789
|
}
|
|
361
790
|
/**
|
|
791
|
+
* Load a JSON file, returning undefined if it doesn't exist.
|
|
792
|
+
*/
|
|
793
|
+
async function loadJsonFile(path$1) {
|
|
794
|
+
try {
|
|
795
|
+
const content = await readFile(path$1, "utf-8");
|
|
796
|
+
return JSON.parse(content);
|
|
797
|
+
} catch {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
362
802
|
* Extract entry filename from Vite build result.
|
|
363
803
|
*/
|
|
364
804
|
function extractEntryFromBundle(entry, result) {
|
|
@@ -418,6 +858,35 @@ async function copyAssets(opts) {
|
|
|
418
858
|
else await fn();
|
|
419
859
|
}
|
|
420
860
|
|
|
861
|
+
//#endregion
|
|
862
|
+
//#region ../../src/vite/tasks/devServer.ts
|
|
863
|
+
/**
|
|
864
|
+
* Start Vite development server with Alepha plugins.
|
|
865
|
+
*
|
|
866
|
+
* This task starts the Vite dev server with all required plugins:
|
|
867
|
+
* - @vitejs/plugin-react (JSX/TSX compilation)
|
|
868
|
+
* - viteAlephaDev (Alepha server integration)
|
|
869
|
+
* - viteAlephaSsrPreload (SSR module preloading)
|
|
870
|
+
*/
|
|
871
|
+
async function devServer(opts = {}) {
|
|
872
|
+
const { createServer, mergeConfig } = await importVite();
|
|
873
|
+
const plugins = [];
|
|
874
|
+
const viteReact = await importViteReact();
|
|
875
|
+
if (viteReact) plugins.push(viteReact());
|
|
876
|
+
plugins.push(viteAlephaSsrPreload());
|
|
877
|
+
plugins.push(await viteAlephaDev({
|
|
878
|
+
serverEntry: opts.entry,
|
|
879
|
+
debug: opts.debug
|
|
880
|
+
}));
|
|
881
|
+
await (await createServer(mergeConfig({
|
|
882
|
+
plugins,
|
|
883
|
+
server: {
|
|
884
|
+
port: opts.port,
|
|
885
|
+
host: opts.host
|
|
886
|
+
}
|
|
887
|
+
}, {}))).listen();
|
|
888
|
+
}
|
|
889
|
+
|
|
421
890
|
//#endregion
|
|
422
891
|
//#region ../../src/vite/tasks/generateCloudflare.ts
|
|
423
892
|
const WARNING_COMMENT$1 = "// This file was automatically generated. DO NOT MODIFY.\n// Changes to this file will be lost when the code is regenerated.\n";
|
|
@@ -482,6 +951,12 @@ export default {
|
|
|
482
951
|
await writeFile(join(root, distDir, "main.cloudflare.js"), `${WARNING_COMMENT$1}\n${workerCode}`.trim());
|
|
483
952
|
}
|
|
484
953
|
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region ../../src/vite/helpers/fileExists.ts
|
|
956
|
+
const fileExists = async (path$1) => {
|
|
957
|
+
return await access(join(process.cwd(), path$1)).then(() => true).catch(() => false);
|
|
958
|
+
};
|
|
959
|
+
|
|
485
960
|
//#endregion
|
|
486
961
|
//#region ../../src/vite/tasks/generateDocker.ts
|
|
487
962
|
/**
|
|
@@ -704,409 +1179,5 @@ async function renderFile(page, options, dist, compress) {
|
|
|
704
1179
|
}
|
|
705
1180
|
|
|
706
1181
|
//#endregion
|
|
707
|
-
|
|
708
|
-
/**
|
|
709
|
-
* Create an Alepha runner for development.
|
|
710
|
-
*
|
|
711
|
-
* The runner manages the lifecycle of an Alepha application during
|
|
712
|
-
* Vite dev server operation, handling start/stop/restart and HMR.
|
|
713
|
-
*/
|
|
714
|
-
function createAlephaRunner(opts) {
|
|
715
|
-
return new AlephaRunner({
|
|
716
|
-
root: process.cwd().replace(/\\/g, "/"),
|
|
717
|
-
started: false,
|
|
718
|
-
log: opts.debug ? (...msg) => console.log(...msg) : () => {},
|
|
719
|
-
entry: opts.entry,
|
|
720
|
-
onReload: () => {}
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
|
-
var AlephaRunner = class {
|
|
724
|
-
state;
|
|
725
|
-
constructor(state) {
|
|
726
|
-
this.state = state;
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Set resolved Vite config.
|
|
730
|
-
*/
|
|
731
|
-
setConfig(config) {
|
|
732
|
-
this.state.config = config;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Check if SSR is enabled for the running app.
|
|
736
|
-
*/
|
|
737
|
-
isSsrEnabled() {
|
|
738
|
-
if (!this.state.app) return false;
|
|
739
|
-
return this.state.app.store.get("alepha.react.server.ssr") ?? false;
|
|
740
|
-
}
|
|
741
|
-
/**
|
|
742
|
-
* Check if app is started.
|
|
743
|
-
*/
|
|
744
|
-
get isStarted() {
|
|
745
|
-
return this.state.started;
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
* Get the running Alepha app instance.
|
|
749
|
-
*/
|
|
750
|
-
get app() {
|
|
751
|
-
return this.state.app;
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Start the Alepha application.
|
|
755
|
-
*/
|
|
756
|
-
async start(server) {
|
|
757
|
-
const { loadEnv } = await importVite();
|
|
758
|
-
global.ssrFixStacktrace = (e) => {
|
|
759
|
-
server.ssrFixStacktrace(e);
|
|
760
|
-
let it = e;
|
|
761
|
-
do {
|
|
762
|
-
server.ssrFixStacktrace(it);
|
|
763
|
-
it = it.cause;
|
|
764
|
-
} while (it instanceof Error);
|
|
765
|
-
};
|
|
766
|
-
if (this.state.started) {
|
|
767
|
-
await this.restart(server, true);
|
|
768
|
-
return;
|
|
769
|
-
}
|
|
770
|
-
if (!this.state.config) {
|
|
771
|
-
this.state.log("[DEBUG] No config - skip starting");
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
this.state.onReload?.();
|
|
775
|
-
this.state.log("[DEBUG] Starting Alepha app...");
|
|
776
|
-
this.state.started = false;
|
|
777
|
-
this.state.app = void 0;
|
|
778
|
-
const fileUrl = pathToFileURL(`${path.resolve(this.state.config.root, this.state.entry)}`).href;
|
|
779
|
-
const env = loadEnv("development", this.state.config.root, "");
|
|
780
|
-
const before = { ...process.env };
|
|
781
|
-
for (const key in env) process.env[key] = env[key];
|
|
782
|
-
process.env.NODE_ENV ??= "development";
|
|
783
|
-
process.env.VITE_ALEPHA_DEV = "true";
|
|
784
|
-
process.env.SERVER_HOST ??= typeof server.config.server.host === "string" ? server.config.server.host : "localhost";
|
|
785
|
-
process.env.SERVER_PORT ??= String(server.config.server.port || "5173");
|
|
786
|
-
try {
|
|
787
|
-
const now = Date.now();
|
|
788
|
-
await server.ssrLoadModule(fileUrl, { fixStacktrace: true });
|
|
789
|
-
this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);
|
|
790
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
791
|
-
this.state.app = globalThis.__alepha;
|
|
792
|
-
if (!this.state.app) {
|
|
793
|
-
this.state.log("[DEBUG] No app found - skip starting");
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
796
|
-
this.state.app.store.set("alepha.node.server", server.httpServer);
|
|
797
|
-
console.log("");
|
|
798
|
-
await this.state.app.start();
|
|
799
|
-
this.state.started = true;
|
|
800
|
-
process.env = { ...before };
|
|
801
|
-
this.state.log("[DEBUG] Starting Done!");
|
|
802
|
-
} catch (e) {
|
|
803
|
-
if (e instanceof Error) {
|
|
804
|
-
let it = e;
|
|
805
|
-
do {
|
|
806
|
-
server.ssrFixStacktrace(it);
|
|
807
|
-
it = it.cause;
|
|
808
|
-
} while (it instanceof Error);
|
|
809
|
-
server.ssrFixStacktrace(e);
|
|
810
|
-
if (e.cause instanceof Error) server.ssrFixStacktrace(e.cause);
|
|
811
|
-
this.state.app?.log?.error("App failed to start:", e);
|
|
812
|
-
this.state.app?.log?.info("Waiting for changes to restart...");
|
|
813
|
-
}
|
|
814
|
-
this.state.log("[DEBUG] Alepha app start error");
|
|
815
|
-
this.state.started = false;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* Stop the Alepha application.
|
|
820
|
-
*/
|
|
821
|
-
async stop() {
|
|
822
|
-
if (this.state.app?.stop && this.state.started) {
|
|
823
|
-
this.state.log("[DEBUG] Stopping Alepha app...");
|
|
824
|
-
await this.state.app.stop();
|
|
825
|
-
this.state.started = false;
|
|
826
|
-
this.state.log("[DEBUG] Stopping Done!");
|
|
827
|
-
} else this.state.log("[DEBUG] Alepha app not started - skip stop");
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Restart the Alepha application.
|
|
831
|
-
*
|
|
832
|
-
* @returns true if the restart was skipped due to locking
|
|
833
|
-
*/
|
|
834
|
-
async restart(server, invalidate) {
|
|
835
|
-
if (this.state.lock) {
|
|
836
|
-
this.state.log("[DEBUG] STILL LOCKING");
|
|
837
|
-
return true;
|
|
838
|
-
}
|
|
839
|
-
this.state.log("[DEBUG] LOCK RESTART");
|
|
840
|
-
this.state.lock = Promise.withResolvers();
|
|
841
|
-
const now = Date.now();
|
|
842
|
-
this.state.log("[DEBUG] RESTART");
|
|
843
|
-
await this.stop();
|
|
844
|
-
this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);
|
|
845
|
-
if (invalidate) server.moduleGraph.invalidateAll();
|
|
846
|
-
await this.start(server);
|
|
847
|
-
this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);
|
|
848
|
-
setTimeout(() => {
|
|
849
|
-
this.state.log("[DEBUG] UNLOCK RESTART");
|
|
850
|
-
this.state.lock?.resolve();
|
|
851
|
-
this.state.lock = void 0;
|
|
852
|
-
}, 500);
|
|
853
|
-
return false;
|
|
854
|
-
}
|
|
855
|
-
/**
|
|
856
|
-
* Send reload event to client.
|
|
857
|
-
*/
|
|
858
|
-
sendReload(server) {
|
|
859
|
-
server.ws.send({
|
|
860
|
-
type: "custom",
|
|
861
|
-
event: "alepha:reload",
|
|
862
|
-
data: {}
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
/**
|
|
867
|
-
* Check if a URL path is a Vite internal file.
|
|
868
|
-
*/
|
|
869
|
-
function isViteInternalPath(pathname) {
|
|
870
|
-
const [path$1] = pathname.split("?");
|
|
871
|
-
if (path$1.startsWith("/@") || path$1.startsWith("/src") || path$1.includes("/node_modules/")) return true;
|
|
872
|
-
return false;
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
//#endregion
|
|
876
|
-
//#region ../../src/vite/plugins/viteAlephaBuild.ts
|
|
877
|
-
/**
|
|
878
|
-
* Alepha build plugin for Vite.
|
|
879
|
-
*
|
|
880
|
-
* This plugin orchestrates the complete build process:
|
|
881
|
-
* 1. Build client (if index.html exists)
|
|
882
|
-
* 2. Build server (SSR)
|
|
883
|
-
* 3. Copy assets from packages
|
|
884
|
-
* 4. Pre-render static pages (if enabled)
|
|
885
|
-
* 5. Generate sitemap (if enabled)
|
|
886
|
-
* 6. Generate deployment config (Vercel/Cloudflare/Docker)
|
|
887
|
-
*
|
|
888
|
-
* Build mode can be controlled via ALEPHA_BUILD_MODE env var for CLI integration.
|
|
889
|
-
*/
|
|
890
|
-
async function viteAlephaBuild(options = {}) {
|
|
891
|
-
const entry = options.serverEntry ?? await boot.getServerEntry();
|
|
892
|
-
const distDir = "dist";
|
|
893
|
-
const clientDir = "public";
|
|
894
|
-
let rootConfig = {};
|
|
895
|
-
return {
|
|
896
|
-
name: "alepha:build",
|
|
897
|
-
apply: "build",
|
|
898
|
-
[OPTIONS]: options,
|
|
899
|
-
config(config, ctx) {
|
|
900
|
-
if (process.env.ALEPHA_BUILD_MODE === "cli") return;
|
|
901
|
-
if (!process.env.VITE_DOUBLE_BUILD_DONE) rootConfig = config;
|
|
902
|
-
if (ctx.isSsrBuild || !process.env.VITE_DOUBLE_BUILD_DONE) config.publicDir = false;
|
|
903
|
-
else config.publicDir = "public";
|
|
904
|
-
},
|
|
905
|
-
async buildStart() {
|
|
906
|
-
const buildMode = process.env.ALEPHA_BUILD_MODE;
|
|
907
|
-
if (buildMode === "cli") return;
|
|
908
|
-
if (process.env.VITE_DOUBLE_BUILD_DONE === "true") return;
|
|
909
|
-
process.env.VITE_DOUBLE_BUILD_DONE = "true";
|
|
910
|
-
const hasClient = options.client !== false && await fileExists("index.html");
|
|
911
|
-
const buildClientOptions = typeof options.client === "object" ? options.client : {};
|
|
912
|
-
const stats = options.stats ?? process.env.ALEPHA_BUILD_STATS === "true";
|
|
913
|
-
if (buildMode === "client") {
|
|
914
|
-
if (hasClient) await buildClient({
|
|
915
|
-
...buildClientOptions,
|
|
916
|
-
config: rootConfig,
|
|
917
|
-
dist: `${distDir}/${clientDir}`,
|
|
918
|
-
stats
|
|
919
|
-
});
|
|
920
|
-
process.exit(0);
|
|
921
|
-
}
|
|
922
|
-
if (buildMode === "server") {
|
|
923
|
-
if (entry) {
|
|
924
|
-
let clientBuilt = false;
|
|
925
|
-
try {
|
|
926
|
-
await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
927
|
-
clientBuilt = true;
|
|
928
|
-
} catch {}
|
|
929
|
-
await buildServer({
|
|
930
|
-
config: { base: rootConfig.base || "" },
|
|
931
|
-
entry,
|
|
932
|
-
distDir,
|
|
933
|
-
clientDir: clientBuilt ? clientDir : void 0,
|
|
934
|
-
stats
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
process.exit(0);
|
|
938
|
-
}
|
|
939
|
-
if (hasClient) await buildClient({
|
|
940
|
-
...buildClientOptions,
|
|
941
|
-
config: rootConfig,
|
|
942
|
-
dist: `${distDir}/${clientDir}`,
|
|
943
|
-
stats
|
|
944
|
-
});
|
|
945
|
-
let template = "";
|
|
946
|
-
if (hasClient) template = await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
947
|
-
if (entry) {
|
|
948
|
-
await buildServer({
|
|
949
|
-
config: { base: rootConfig.base || "" },
|
|
950
|
-
entry,
|
|
951
|
-
distDir,
|
|
952
|
-
clientDir: hasClient ? clientDir : void 0,
|
|
953
|
-
stats
|
|
954
|
-
});
|
|
955
|
-
if (hasClient && options.serverEntry !== false) await unlink(`${distDir}/${clientDir}/index.html`);
|
|
956
|
-
await copyAssets({
|
|
957
|
-
entry: `${distDir}/index.js`,
|
|
958
|
-
distDir
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
if (buildClientOptions.sitemap && entry) await writeFile(`${distDir}/${clientDir}/sitemap.xml`, await generateSitemap({
|
|
962
|
-
entry: `${distDir}/index.js`,
|
|
963
|
-
baseUrl: buildClientOptions.sitemap.hostname
|
|
964
|
-
}));
|
|
965
|
-
if (buildClientOptions.prerender && template) await prerenderPages({
|
|
966
|
-
dist: `${distDir}/${clientDir}`,
|
|
967
|
-
entry: `${distDir}/index.js`,
|
|
968
|
-
compress: buildClientOptions.precompress
|
|
969
|
-
});
|
|
970
|
-
if (options.vercel) await generateVercel({
|
|
971
|
-
distDir,
|
|
972
|
-
clientDir,
|
|
973
|
-
config: typeof options.vercel === "boolean" ? {} : options.vercel
|
|
974
|
-
});
|
|
975
|
-
if (options.cloudflare) await generateCloudflare({
|
|
976
|
-
distDir,
|
|
977
|
-
config: typeof options.cloudflare === "boolean" ? {} : options.cloudflare
|
|
978
|
-
});
|
|
979
|
-
if (options.docker) await generateDocker({
|
|
980
|
-
distDir,
|
|
981
|
-
...typeof options.docker === "boolean" ? {} : options.docker
|
|
982
|
-
});
|
|
983
|
-
process.exit(0);
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
//#endregion
|
|
989
|
-
//#region ../../src/vite/plugins/viteAlephaDev.ts
|
|
990
|
-
/**
|
|
991
|
-
* Plug Alepha into Vite development server.
|
|
992
|
-
*
|
|
993
|
-
* This plugin manages the Alepha application lifecycle during development,
|
|
994
|
-
* handling hot module replacement and request forwarding.
|
|
995
|
-
*/
|
|
996
|
-
async function viteAlephaDev(options = {}) {
|
|
997
|
-
let entry = options.serverEntry;
|
|
998
|
-
if (!entry) {
|
|
999
|
-
entry = await boot.getServerEntry();
|
|
1000
|
-
if (!entry) return {
|
|
1001
|
-
name: "alepha-dev",
|
|
1002
|
-
apply: "serve",
|
|
1003
|
-
config() {}
|
|
1004
|
-
};
|
|
1005
|
-
}
|
|
1006
|
-
const runner = createAlephaRunner({
|
|
1007
|
-
entry,
|
|
1008
|
-
debug: options.debug
|
|
1009
|
-
});
|
|
1010
|
-
return {
|
|
1011
|
-
name: "alepha-dev",
|
|
1012
|
-
apply: "serve",
|
|
1013
|
-
configResolved(resolvedConfig) {
|
|
1014
|
-
runner.setConfig(resolvedConfig);
|
|
1015
|
-
},
|
|
1016
|
-
async handleHotUpdate(ctx) {
|
|
1017
|
-
if (options.debug) console.log("[DEBUG] HMR", ctx.file);
|
|
1018
|
-
if (ctx.file.includes("/.idea/")) return [];
|
|
1019
|
-
const isServerOnly = !ctx.modules[0]?._clientModule;
|
|
1020
|
-
const isBrowserOnly = !ctx.modules[0]?._ssrModule;
|
|
1021
|
-
const isSsrEnabled = runner.isSsrEnabled();
|
|
1022
|
-
if (isBrowserOnly) {
|
|
1023
|
-
if (options.debug) console.log("[DEBUG] HMR - browser only - no reason to reload server");
|
|
1024
|
-
return;
|
|
1025
|
-
}
|
|
1026
|
-
const root = process.cwd().replace(/\\/g, "/");
|
|
1027
|
-
const invalidate = !ctx.file.startsWith(root);
|
|
1028
|
-
if (invalidate && options.debug) console.log("[DEBUG] HMR - outside root - invalidate all");
|
|
1029
|
-
if (!isSsrEnabled && isServerOnly) {
|
|
1030
|
-
await runner.restart(ctx.server, invalidate);
|
|
1031
|
-
return [];
|
|
1032
|
-
}
|
|
1033
|
-
if (isSsrEnabled && ctx.modules[0]) {
|
|
1034
|
-
if (await runner.restart(ctx.server, invalidate)) return [];
|
|
1035
|
-
if (!runner.isStarted) {
|
|
1036
|
-
if (options.debug) console.log("[DEBUG] HMR - abort due to app not started");
|
|
1037
|
-
return [];
|
|
1038
|
-
}
|
|
1039
|
-
if (isServerOnly && runner.isStarted) {
|
|
1040
|
-
runner.sendReload(ctx.server);
|
|
1041
|
-
return [];
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
},
|
|
1045
|
-
async configureServer(server) {
|
|
1046
|
-
server.middlewares.use((req, res, next) => {
|
|
1047
|
-
if (runner.isStarted && runner.app && req.url && !isViteInternalPath(req.url)) {
|
|
1048
|
-
let ended = false;
|
|
1049
|
-
const writeHead = res.writeHead.bind(res);
|
|
1050
|
-
res.writeHead = (...args) => {
|
|
1051
|
-
ended = true;
|
|
1052
|
-
return writeHead(args[0], args[1], args[2]);
|
|
1053
|
-
};
|
|
1054
|
-
return runner.app.events.emit("node:request", {
|
|
1055
|
-
req,
|
|
1056
|
-
res
|
|
1057
|
-
}).then(() => {
|
|
1058
|
-
if (!ended) next();
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
next();
|
|
1062
|
-
});
|
|
1063
|
-
server.config.logger.info = (msg) => {
|
|
1064
|
-
console.log(msg);
|
|
1065
|
-
};
|
|
1066
|
-
server.config.logger.clearScreen = () => {};
|
|
1067
|
-
return async () => {
|
|
1068
|
-
await runner.start(server);
|
|
1069
|
-
};
|
|
1070
|
-
},
|
|
1071
|
-
async closeBundle() {}
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
//#endregion
|
|
1076
|
-
//#region ../../src/vite/plugins/viteAlepha.ts
|
|
1077
|
-
function viteAlepha(options = {}) {
|
|
1078
|
-
if (process.env.NODE_ENV === "test") return [];
|
|
1079
|
-
const plugins = [];
|
|
1080
|
-
if (options.react !== false) try {
|
|
1081
|
-
const { default: viteReact } = createRequire(import.meta.url)("@vitejs/plugin-react");
|
|
1082
|
-
plugins.push(viteReact());
|
|
1083
|
-
} catch (e) {}
|
|
1084
|
-
plugins.push(viteAlephaDev(options), viteAlephaBuild(options));
|
|
1085
|
-
plugins[OPTIONS] = options;
|
|
1086
|
-
return plugins;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
//#endregion
|
|
1090
|
-
//#region ../../src/vite/index.ts
|
|
1091
|
-
/**
|
|
1092
|
-
* Plugin vite for Alepha framework.
|
|
1093
|
-
*
|
|
1094
|
-
* This module provides Vite plugins and configurations to integrate Alepha applications with Vite's build and development processes.
|
|
1095
|
-
*
|
|
1096
|
-
* @example
|
|
1097
|
-
* ```ts
|
|
1098
|
-
* import { defineConfig } from "vite";
|
|
1099
|
-
* import { viteAlepha } from "alepha/vite";
|
|
1100
|
-
*
|
|
1101
|
-
* export default defineConfig({
|
|
1102
|
-
* plugins: [viteAlepha()],
|
|
1103
|
-
* // other Vite configurations...
|
|
1104
|
-
* });
|
|
1105
|
-
* ```
|
|
1106
|
-
*
|
|
1107
|
-
* @module alepha.vite
|
|
1108
|
-
*/
|
|
1109
|
-
|
|
1110
|
-
//#endregion
|
|
1111
|
-
export { AlephaRunner, boot, buildClient, buildServer, compressFile, copyAssets, createAlephaRunner, createBufferedLogger, generateCloudflare, generateDocker, generateExternals, generateSitemap, generateVercel, isViteInternalPath, prerenderPages, viteAlepha, viteAlephaBuild, viteAlephaDev, viteCompress };
|
|
1182
|
+
export { AlephaRunner, boot, buildClient, buildServer, compressFile, copyAssets, createAlephaRunner, createBufferedLogger, devServer, generateCloudflare, generateDocker, generateExternals, generateSitemap, generateVercel, isViteInternalPath, prerenderPages, viteAlephaDev, viteAlephaSsrPreload, viteCompress };
|
|
1112
1183
|
//# sourceMappingURL=index.js.map
|