alepha 0.20.1 → 0.20.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 +0 -1
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.browser.js +49 -0
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +49 -0
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.browser.js +64 -148
- package/dist/api/jobs/index.browser.js.map +1 -1
- package/dist/api/jobs/index.d.ts +339 -600
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +605 -1012
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +79 -27
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +90 -23
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/parameters/index.browser.js +37 -0
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +4 -65
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +37 -0
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts +2 -1
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/payments/index.js +4 -2
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/users/index.d.ts +225 -5199
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +15 -11
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +4 -2
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/bucket/index.js +5 -1
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +5 -1
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +225 -11681
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +732 -257
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.js +7 -1
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +65 -63
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +140 -27
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.js +15 -0
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.d.ts +1 -1
- package/dist/command/index.js +1 -1
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +6 -0
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +8 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +6 -0
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +6 -0
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/smtp/index.js +2 -10522
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +4 -8085
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +3 -33554
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js +32 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js +5 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +1 -361
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +14 -406
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +96 -5117
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +23 -419
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +17 -20
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +2 -613
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +17 -20
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +60 -1
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +86 -1
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.browser.js +16 -1
- package/dist/react/head/index.browser.js.map +1 -1
- package/dist/react/head/index.d.ts +6 -0
- package/dist/react/head/index.d.ts.map +1 -1
- package/dist/react/head/index.js +16 -1
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.js +22 -17
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +78 -12
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +57 -13
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +102 -14
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/index.d.ts +1 -411
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +13 -12293
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +124 -0
- package/dist/react/ui/index.d.ts.map +1 -0
- package/dist/react/ui/index.js +209 -0
- package/dist/react/ui/index.js.map +1 -0
- package/dist/react/websocket/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/router/index.d.ts +13 -13
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +45 -32
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -83
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +2 -391
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +2 -391
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +2 -325
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -1362
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1 -1054
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +16 -1224
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +1 -4
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +19 -4
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +1 -514
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4 -4356
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.js +1 -1
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +1 -0
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js.map +1 -1
- package/dist/topic/core/index.js +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/websocket/index.browser.js +21 -0
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.js +21 -0
- package/dist/websocket/index.js.map +1 -1
- package/package.json +23 -37
- package/src/api/files/__tests__/FileController.spec.ts +1 -1
- package/src/api/files/jobs/FileJobs.ts +2 -1
- package/src/api/jobs/__tests__/$job.spec.ts +320 -2867
- package/src/api/jobs/controllers/AdminJobController.ts +29 -138
- package/src/api/jobs/entities/jobExecutionEntity.ts +27 -19
- package/src/api/jobs/index.browser.ts +5 -7
- package/src/api/jobs/index.ts +23 -51
- package/src/api/jobs/primitives/$job.ts +66 -58
- package/src/api/jobs/providers/JobProvider.ts +561 -566
- package/src/api/jobs/providers/JobQueueProvider.ts +18 -19
- package/src/api/jobs/schemas/jobConfigAtom.ts +20 -23
- package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +3 -27
- package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +5 -7
- package/src/api/jobs/schemas/jobRegistrationSchema.ts +7 -4
- package/src/api/jobs/schemas/triggerJobSchema.ts +0 -1
- package/src/api/jobs/services/JobService.ts +90 -483
- package/src/api/notifications/controllers/AdminNotificationController.ts +19 -12
- package/src/api/notifications/index.ts +7 -4
- package/src/api/notifications/jobs/NotificationJobs.ts +83 -12
- package/src/api/payments/services/PaymentService.ts +4 -2
- package/src/api/users/__tests__/UserJobs.spec.ts +10 -49
- package/src/api/users/audits/UserAudits.ts +3 -1
- package/src/api/users/buckets/UserBuckets.ts +2 -1
- package/src/api/users/index.ts +1 -4
- package/src/api/users/jobs/UserJobs.ts +5 -4
- package/src/api/users/schemas/userQuerySchema.ts +0 -1
- package/src/api/users/services/UserService.ts +1 -5
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
- package/src/api/verifications/jobs/VerificationJobs.ts +2 -1
- package/src/api/verifications/services/VerificationService.ts +1 -0
- package/src/cli/core/__tests__/init.spec.ts +209 -1
- package/src/cli/core/commands/init.ts +9 -9
- package/src/cli/core/services/PackageManagerUtils.ts +22 -12
- package/src/cli/core/services/ProjectScaffolder.ts +300 -70
- package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
- package/src/cli/core/tasks/BuildServerTask.ts +8 -0
- package/src/cli/core/templates/agentMd.ts +2 -8
- package/src/cli/core/templates/apiIndexTs.ts +22 -14
- package/src/cli/core/templates/componentsJsonTs.ts +39 -0
- package/src/cli/core/templates/mainCss.ts +2 -36
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
- package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
- package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
- package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
- package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
- package/src/cli/core/templates/vitestConfigTs.ts +17 -0
- package/src/cli/core/templates/webAppRouterTs.ts +102 -82
- package/src/cli/core/templates/webIndexTs.ts +23 -1
- package/src/cli/platform/__tests__/CloudflareAdapter.spec.ts +22 -71
- package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
- package/src/cli/platform/adapters/CloudflareAdapter.ts +12 -11
- package/src/cli/platform/atoms/platformOptions.ts +9 -0
- package/src/cli/platform/schemas/cloudflare.ts +3 -2
- package/src/cli/platform/services/CloudflareApi.ts +164 -25
- package/src/cli/platform/services/WranglerApi.ts +0 -17
- package/src/command/providers/CliProvider.ts +1 -1
- package/src/core/Alepha.ts +9 -0
- package/src/core/interfaces/Service.ts +3 -1
- package/src/core/providers/TypeProvider.ts +1 -1
- package/src/logger/services/Logger.ts +1 -1
- package/src/mcp/__tests__/$resource.spec.ts +1 -1
- package/src/mcp/__tests__/$tool.spec.ts +1 -1
- package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
- package/src/orm/__tests__/$repository-tests.ts +1 -0
- package/src/orm/__tests__/orm-next-tests.ts +2 -67
- package/src/orm/__tests__/orm-next.spec.ts +0 -21
- package/src/orm/core/index.shared.ts +0 -2
- package/src/orm/core/index.ts +1 -2
- package/src/orm/core/primitives/$repository.ts +3 -6
- package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
- package/src/orm/core/services/ModelBuilder.ts +1 -13
- package/src/orm/core/services/Repository.ts +1 -42
- package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
- package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
- package/src/react/form/index.ts +2 -0
- package/src/react/form/services/parseField.ts +163 -0
- package/src/react/form/services/prettyName.ts +19 -0
- package/src/react/head/providers/BrowserHeadProvider.ts +31 -10
- package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
- package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
- package/src/react/router/primitives/$page.ts +35 -12
- package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
- package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
- package/src/react/router/providers/ReactServerProvider.ts +1 -0
- package/src/react/ui/atoms/uiAtom.ts +28 -0
- package/src/react/ui/components/ColorScheme.tsx +36 -0
- package/src/react/ui/hooks/useColorMode.ts +49 -0
- package/src/react/ui/hooks/useSidebarState.ts +26 -0
- package/src/react/ui/hooks/useTheme.ts +22 -0
- package/src/react/ui/index.ts +35 -0
- package/src/react/ui/services/UiPersistence.ts +41 -0
- package/src/router/TemplatedPathParser.ts +50 -51
- package/src/router/__tests__/RouterProvider.spec.ts +62 -0
- package/src/router/__tests__/TemplatedPathParser.spec.ts +18 -0
- package/src/router/providers/RouterProvider.ts +10 -5
- package/src/scheduler/providers/CronProvider.ts +1 -1
- package/src/security/primitives/$basicAuth.ts +1 -1
- package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
- package/src/server/core/interfaces/ServerRequest.ts +1 -0
- package/src/server/core/providers/ServerProvider.ts +1 -1
- package/src/server/core/providers/ServerRouterProvider.ts +2 -2
- package/src/server/core/services/HttpClient.ts +1 -1
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
- package/src/system/providers/NodeShellProvider.ts +1 -0
- package/src/topic/core/providers/TopicProvider.ts +1 -1
- package/dist/api/invitations/index.d.ts +0 -790
- package/dist/api/invitations/index.d.ts.map +0 -1
- package/dist/api/invitations/index.js +0 -662
- package/dist/api/invitations/index.js.map +0 -1
- package/dist/api/issues/index.d.ts +0 -810
- package/dist/api/issues/index.d.ts.map +0 -1
- package/dist/api/issues/index.js +0 -444
- package/dist/api/issues/index.js.map +0 -1
- package/dist/api/subscriptions/index.d.ts +0 -1692
- package/dist/api/subscriptions/index.d.ts.map +0 -1
- package/dist/api/subscriptions/index.js +0 -1867
- package/dist/api/subscriptions/index.js.map +0 -1
- package/dist/api/workflows/index.browser.js +0 -246
- package/dist/api/workflows/index.browser.js.map +0 -1
- package/dist/api/workflows/index.d.ts +0 -1618
- package/dist/api/workflows/index.d.ts.map +0 -1
- package/dist/api/workflows/index.js +0 -1495
- package/dist/api/workflows/index.js.map +0 -1
- package/dist/react/testing/chunk-DBEY4PJZ.js +0 -16
- package/src/api/invitations/__tests__/InvitationService.spec.ts +0 -439
- package/src/api/invitations/controllers/AdminInvitationController.ts +0 -86
- package/src/api/invitations/controllers/InvitationController.ts +0 -84
- package/src/api/invitations/entities/invitations.ts +0 -33
- package/src/api/invitations/index.ts +0 -58
- package/src/api/invitations/jobs/InvitationJobs.ts +0 -37
- package/src/api/invitations/providers/InvitationProvider.ts +0 -45
- package/src/api/invitations/schemas/createInvitationSchema.ts +0 -12
- package/src/api/invitations/schemas/invitationConfigAtom.ts +0 -20
- package/src/api/invitations/schemas/invitationQuerySchema.ts +0 -15
- package/src/api/invitations/schemas/invitationResourceSchema.ts +0 -6
- package/src/api/invitations/schemas/invitationWithResourceInfoSchema.ts +0 -22
- package/src/api/invitations/schemas/myInvitationsQuerySchema.ts +0 -10
- package/src/api/invitations/services/InvitationService.ts +0 -556
- package/src/api/issues/__tests__/IssueService.spec.ts +0 -263
- package/src/api/issues/controllers/AdminIssueController.ts +0 -149
- package/src/api/issues/controllers/IssueController.ts +0 -44
- package/src/api/issues/entities/issues.ts +0 -49
- package/src/api/issues/index.ts +0 -50
- package/src/api/issues/schemas/createIssueSchema.ts +0 -13
- package/src/api/issues/schemas/issueConfigAtom.ts +0 -13
- package/src/api/issues/schemas/issueQuerySchema.ts +0 -18
- package/src/api/issues/schemas/issueResourceSchema.ts +0 -6
- package/src/api/issues/schemas/myIssueQuerySchema.ts +0 -10
- package/src/api/issues/schemas/updateIssueSchema.ts +0 -13
- package/src/api/issues/services/IssueService.ts +0 -264
- package/src/api/jobs/__tests__/$job-middleware.spec.ts +0 -126
- package/src/api/jobs/__tests__/JobService.spec.ts +0 -31
- package/src/api/jobs/entities/jobExecutionLogEntity.ts +0 -13
- package/src/api/jobs/schemas/jobActivitySchema.ts +0 -15
- package/src/api/jobs/schemas/jobCronInfoSchema.ts +0 -22
- package/src/api/jobs/schemas/jobExecutionDetailResourceSchema.ts +0 -20
- package/src/api/jobs/schemas/jobFailureSchema.ts +0 -9
- package/src/api/jobs/schemas/jobQueueDepthSchema.ts +0 -14
- package/src/api/jobs/schemas/jobStatsSchema.ts +0 -14
- package/src/api/jobs/services/JobService-tests.ts +0 -157
- package/src/api/subscriptions/__tests__/BillingService.spec.ts +0 -218
- package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +0 -278
- package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +0 -212
- package/src/api/subscriptions/controllers/SubscriptionController.ts +0 -189
- package/src/api/subscriptions/entities/subscriptionEvents.ts +0 -54
- package/src/api/subscriptions/entities/subscriptions.ts +0 -68
- package/src/api/subscriptions/index.ts +0 -133
- package/src/api/subscriptions/jobs/SubscriptionJobs.ts +0 -382
- package/src/api/subscriptions/middleware/$requireLimit.ts +0 -50
- package/src/api/subscriptions/middleware/$requirePlan.ts +0 -49
- package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +0 -110
- package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +0 -8
- package/src/api/subscriptions/schemas/changePlanSchema.ts +0 -9
- package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +0 -11
- package/src/api/subscriptions/schemas/entitlementsSchema.ts +0 -21
- package/src/api/subscriptions/schemas/mrrSchema.ts +0 -13
- package/src/api/subscriptions/schemas/planDefinitionSchema.ts +0 -71
- package/src/api/subscriptions/schemas/planResourceSchema.ts +0 -25
- package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +0 -8
- package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +0 -19
- package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +0 -6
- package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +0 -32
- package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +0 -23
- package/src/api/subscriptions/services/BillingService.ts +0 -437
- package/src/api/subscriptions/services/SubscriptionConfig.ts +0 -56
- package/src/api/subscriptions/services/SubscriptionService.ts +0 -867
- package/src/api/subscriptions/services/UsageService.ts +0 -118
- package/src/api/workflows/__tests__/$workflow.spec.ts +0 -616
- package/src/api/workflows/controllers/AdminWorkflowController.ts +0 -191
- package/src/api/workflows/entities/workflowExecutions.ts +0 -74
- package/src/api/workflows/entities/workflowStepExecutions.ts +0 -74
- package/src/api/workflows/entities/workflowStepLogs.ts +0 -13
- package/src/api/workflows/index.browser.ts +0 -22
- package/src/api/workflows/index.ts +0 -115
- package/src/api/workflows/jobs/WorkflowJobs.ts +0 -77
- package/src/api/workflows/primitives/$workflow.ts +0 -202
- package/src/api/workflows/providers/WorkflowProvider.ts +0 -1284
- package/src/api/workflows/schemas/workflowActivitySchema.ts +0 -15
- package/src/api/workflows/schemas/workflowConfigAtom.ts +0 -51
- package/src/api/workflows/schemas/workflowExecutionDetailSchema.ts +0 -18
- package/src/api/workflows/schemas/workflowExecutionQuerySchema.ts +0 -26
- package/src/api/workflows/schemas/workflowExecutionResourceSchema.ts +0 -30
- package/src/api/workflows/schemas/workflowRegistrationSchema.ts +0 -26
- package/src/api/workflows/schemas/workflowStatsSchema.ts +0 -16
- package/src/api/workflows/schemas/workflowStepExecutionResourceSchema.ts +0 -15
- package/src/api/workflows/services/WorkflowService.ts +0 -382
- package/src/cli/core/templates/apiAppSecurityTs.ts +0 -43
- package/src/cli/core/templates/webAdminDashboardTsx.ts +0 -17
- package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
- package/src/orm/core/helpers/parseQueryString.ts +0 -502
- package/src/orm/core/primitives/$view.ts +0 -88
|
@@ -1,30 +1,38 @@
|
|
|
1
1
|
export interface ApiIndexTsOptions {
|
|
2
2
|
appName?: string;
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Include `AlephaApiUsers` (realms, sessions, registration, identities,
|
|
5
|
+
* password reset, email verification, admin endpoints) plus the local
|
|
6
|
+
* `RealmProvider` that declares `$realm({ ... })`.
|
|
7
|
+
*/
|
|
8
|
+
saas?: boolean;
|
|
4
9
|
}
|
|
5
10
|
|
|
6
11
|
export const apiIndexTs = (options: ApiIndexTsOptions = {}) => {
|
|
7
|
-
const { appName = "app",
|
|
12
|
+
const { appName = "app", saas = false } = options;
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
if (saas) {
|
|
15
|
+
return `
|
|
16
|
+
import { $module } from "alepha";
|
|
17
|
+
import { AlephaApiUsers } from "alepha/api/users";
|
|
18
|
+
import { HelloController } from "./controllers/HelloController.ts";
|
|
19
|
+
import { RealmProvider } from "./providers/RealmProvider.ts";
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
export const ApiModule = $module({
|
|
22
|
+
name: "${appName}.api",
|
|
23
|
+
services: [HelloController, RealmProvider],
|
|
24
|
+
imports: [AlephaApiUsers],
|
|
25
|
+
});
|
|
26
|
+
`.trim();
|
|
15
27
|
}
|
|
16
28
|
|
|
17
|
-
imports.push(
|
|
18
|
-
'import { HelloController } from "./controllers/HelloController.ts";',
|
|
19
|
-
);
|
|
20
|
-
services.push("HelloController");
|
|
21
|
-
|
|
22
29
|
return `
|
|
23
|
-
$
|
|
30
|
+
import { $module } from "alepha";
|
|
31
|
+
import { HelloController } from "./controllers/HelloController.ts";
|
|
24
32
|
|
|
25
33
|
export const ApiModule = $module({
|
|
26
34
|
name: "${appName}.api",
|
|
27
|
-
services: [
|
|
35
|
+
services: [HelloController],
|
|
28
36
|
});
|
|
29
37
|
`.trim();
|
|
30
38
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `components.json` is the shadcn CLI's project config — it tells
|
|
3
|
+
* `shadcn add` where to drop primitives, which tailwind tokens to use,
|
|
4
|
+
* which icon library to wire up, and which custom registries to resolve.
|
|
5
|
+
*
|
|
6
|
+
* Aliases follow shadcn's defaults (`@/components`, `@/lib/utils`) so the
|
|
7
|
+
* CLI honors them across `init` + `add` calls. Alepha app code lives at
|
|
8
|
+
* `src/web/` (Home, AppRouter, …) and the shadcn primitives live at
|
|
9
|
+
* `src/components/` — kept separate to make the registry components
|
|
10
|
+
* trivially upgradable via `shadcn add --overwrite`.
|
|
11
|
+
*
|
|
12
|
+
* The `registries` block pre-wires the public Alepha registry — consumers
|
|
13
|
+
* can immediately run e.g. `shadcn add @alepha/auth-login`.
|
|
14
|
+
*/
|
|
15
|
+
export const componentsJsonTs = () =>
|
|
16
|
+
`{
|
|
17
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
18
|
+
"style": "new-york",
|
|
19
|
+
"rsc": false,
|
|
20
|
+
"tsx": true,
|
|
21
|
+
"tailwind": {
|
|
22
|
+
"config": "",
|
|
23
|
+
"css": "src/main.css",
|
|
24
|
+
"baseColor": "neutral",
|
|
25
|
+
"cssVariables": true
|
|
26
|
+
},
|
|
27
|
+
"aliases": {
|
|
28
|
+
"components": "@/components",
|
|
29
|
+
"utils": "@/lib/utils",
|
|
30
|
+
"ui": "@/components/ui",
|
|
31
|
+
"lib": "@/lib",
|
|
32
|
+
"hooks": "@/hooks"
|
|
33
|
+
},
|
|
34
|
+
"iconLibrary": "lucide",
|
|
35
|
+
"registries": {
|
|
36
|
+
"@alepha": "https://alepha.dev/r/{name}.json"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
@@ -1,38 +1,4 @@
|
|
|
1
|
-
export const mainCss = (opts: {
|
|
2
|
-
if (opts.ui) {
|
|
3
|
-
return `/**
|
|
4
|
-
* Alepha UI - Based on Mantine component library
|
|
5
|
-
* Mantine Docs: https://mantine.dev
|
|
6
|
-
* Mantine LLM context: https://mantine.dev/llms.txt
|
|
7
|
-
*
|
|
8
|
-
* Switch theme index: alepha.set(alephaThemeAtom, { index: 1 })
|
|
9
|
-
*
|
|
10
|
-
* Custom themes (in src/web/index.ts):
|
|
11
|
-
*
|
|
12
|
-
* import { alephaThemeListAtom } from "@alepha/ui";
|
|
13
|
-
*
|
|
14
|
-
* export const WebModule = $module({
|
|
15
|
-
* name: "app.web",
|
|
16
|
-
* services: [AppRouter],
|
|
17
|
-
* register(alepha) {
|
|
18
|
-
* alepha.register(AppRouter);
|
|
19
|
-
* alepha.set(alephaThemeListAtom, [{
|
|
20
|
-
* name: "My Theme",
|
|
21
|
-
* description: "Custom theme",
|
|
22
|
-
* primaryColor: "blue",
|
|
23
|
-
* defaultColorScheme: "dark",
|
|
24
|
-
* // ...MantineThemeOverride options
|
|
25
|
-
* }]);
|
|
26
|
-
* },
|
|
27
|
-
* });
|
|
28
|
-
*
|
|
29
|
-
* Alternatives (remove the import below):
|
|
30
|
-
* - Tailwind CSS: https://tailwindcss.com/docs/installation/using-vite
|
|
31
|
-
* - Raw CSS: Write your own styles
|
|
32
|
-
*/
|
|
33
|
-
@import "@alepha/ui/styles";`;
|
|
34
|
-
}
|
|
35
|
-
|
|
1
|
+
export const mainCss = (opts: { tailwind?: boolean } = {}) => {
|
|
36
2
|
if (opts.tailwind) {
|
|
37
3
|
return `@import "tailwindcss";
|
|
38
4
|
|
|
@@ -44,8 +10,8 @@ export const mainCss = (opts: { ui?: boolean; tailwind?: boolean } = {}) => {
|
|
|
44
10
|
* Global styles for your application.
|
|
45
11
|
*
|
|
46
12
|
* Options:
|
|
47
|
-
* - @alepha/ui: Use \`alepha init --ui\` to add Mantine-based components
|
|
48
13
|
* - Tailwind CSS: Use \`alepha init --tailwind\` to add Tailwind CSS
|
|
14
|
+
* - shadcn/ui: Use \`alepha init --shadcn\` to add shadcn/ui setup
|
|
49
15
|
* - Raw CSS: Write your own styles below
|
|
50
16
|
*/
|
|
51
17
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaaS admin layout — full AppShell on /admin with a sidebar, breadcrumbs,
|
|
3
|
+
* a Sonner toaster, and a confirm provider. The page list grows with
|
|
4
|
+
* whatever `admin-*` registry components the user adds.
|
|
5
|
+
*
|
|
6
|
+
* All UI primitives come from `src/components/*` where `shadcn add` drops
|
|
7
|
+
* them; alepha app code lives in `src/web/*` and references them via the
|
|
8
|
+
* `@/components/*` alias.
|
|
9
|
+
*/
|
|
10
|
+
export const saasAdminLayoutTsx = () =>
|
|
11
|
+
`import { AppShell } from "@/components/app-shell";
|
|
12
|
+
import { Toaster } from "@/components/ui/sonner";
|
|
13
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
14
|
+
import { ConfirmProvider } from "@/components/use-confirm";
|
|
15
|
+
import { NestedView, useRouterState } from "alepha/react/router";
|
|
16
|
+
import { ShieldCheck, Users } from "lucide-react";
|
|
17
|
+
|
|
18
|
+
const NAV = [
|
|
19
|
+
{
|
|
20
|
+
label: "Identity",
|
|
21
|
+
items: [
|
|
22
|
+
{ href: "/admin/users", label: "Users", icon: Users },
|
|
23
|
+
{ href: "/admin/sessions", label: "Sessions", icon: ShieldCheck },
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
] as const;
|
|
27
|
+
|
|
28
|
+
const findCrumbs = (pathname: string): { label: string; href?: string }[] => {
|
|
29
|
+
for (const group of NAV) {
|
|
30
|
+
const match = group.items.find((it) => it.href === pathname);
|
|
31
|
+
if (match) return [{ label: group.label }, { label: match.label }];
|
|
32
|
+
}
|
|
33
|
+
return [];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const AdminLayout = () => {
|
|
37
|
+
const state = useRouterState();
|
|
38
|
+
const crumbs = findCrumbs(state.url.pathname);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<TooltipProvider>
|
|
42
|
+
<ConfirmProvider>
|
|
43
|
+
<AppShell
|
|
44
|
+
brand={
|
|
45
|
+
<a
|
|
46
|
+
href="/admin"
|
|
47
|
+
className="flex items-center gap-2 px-2 py-2 font-semibold group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:px-0"
|
|
48
|
+
>
|
|
49
|
+
<span className="bg-primary text-primary-foreground flex size-7 shrink-0 items-center justify-center rounded">
|
|
50
|
+
α
|
|
51
|
+
</span>
|
|
52
|
+
<span className="truncate group-data-[collapsible=icon]:hidden">
|
|
53
|
+
Admin
|
|
54
|
+
</span>
|
|
55
|
+
</a>
|
|
56
|
+
}
|
|
57
|
+
nav={NAV.map((group) => ({
|
|
58
|
+
label: group.label,
|
|
59
|
+
items: group.items.map((it) => ({
|
|
60
|
+
href: it.href,
|
|
61
|
+
label: it.label,
|
|
62
|
+
icon: it.icon,
|
|
63
|
+
active: it.href === state.url.pathname,
|
|
64
|
+
})),
|
|
65
|
+
}))}
|
|
66
|
+
breadcrumbs={crumbs.length ? crumbs : undefined}
|
|
67
|
+
>
|
|
68
|
+
<NestedView />
|
|
69
|
+
</AppShell>
|
|
70
|
+
<Toaster />
|
|
71
|
+
</ConfirmProvider>
|
|
72
|
+
</TooltipProvider>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default AdminLayout;
|
|
77
|
+
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin pages — each is a thin wrapper around the matching `admin-*`
|
|
3
|
+
* registry component (placed at `src/components/admin/*`). The starter
|
|
4
|
+
* ships with Users + Sessions; add more by `shadcn add @alepha/admin-…`
|
|
5
|
+
* and a matching `$page(...)` in AppRouter.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const saasAdminUsersTsx = () =>
|
|
9
|
+
`import { AdminUsers } from "@/components/admin/admin-users";
|
|
10
|
+
|
|
11
|
+
const AdminUsersPage = () => {
|
|
12
|
+
return <AdminUsers />;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default AdminUsersPage;
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const saasAdminSessionsTsx = () =>
|
|
19
|
+
`import { AdminSessions } from "@/components/admin/admin-sessions";
|
|
20
|
+
|
|
21
|
+
const AdminSessionsPage = () => {
|
|
22
|
+
return <AdminSessions />;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default AdminSessionsPage;
|
|
26
|
+
`;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaaS auth layout — wraps every /auth/* page with a centered card.
|
|
3
|
+
* Routes (login, register, reset-password, verify-email) are mounted as
|
|
4
|
+
* children so they share this shell.
|
|
5
|
+
*/
|
|
6
|
+
export const saasAuthLayoutTsx = () =>
|
|
7
|
+
`import { NestedView } from "alepha/react/router";
|
|
8
|
+
|
|
9
|
+
const AuthLayout = () => {
|
|
10
|
+
return (
|
|
11
|
+
<div className="bg-background flex min-h-screen items-center justify-center p-4">
|
|
12
|
+
<div className="w-full max-w-md">
|
|
13
|
+
<NestedView />
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default AuthLayout;
|
|
20
|
+
`;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-page wrapper around the registry components. The registry component
|
|
3
|
+
* receives the realm config from the page loader; the page itself stays a
|
|
4
|
+
* thin shell so apps can layer their branding around it.
|
|
5
|
+
*
|
|
6
|
+
* Registry components land at `src/components/auth/*` (shadcn defaults).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const saasAuthLoginTsx = () =>
|
|
10
|
+
`import { AuthLogin } from "@/components/auth/auth-login";
|
|
11
|
+
import type { RealmConfig } from "alepha/api/users";
|
|
12
|
+
|
|
13
|
+
export interface AuthLoginPageProps {
|
|
14
|
+
realmConfig: RealmConfig;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const AuthLoginPage = (props: AuthLoginPageProps) => {
|
|
18
|
+
return <AuthLogin realmConfig={props.realmConfig} />;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default AuthLoginPage;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const saasAuthRegisterTsx = () =>
|
|
25
|
+
`import { AuthRegister } from "@/components/auth/auth-register";
|
|
26
|
+
import type { RealmConfig } from "alepha/api/users";
|
|
27
|
+
|
|
28
|
+
export interface AuthRegisterPageProps {
|
|
29
|
+
realmConfig: RealmConfig;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const AuthRegisterPage = (props: AuthRegisterPageProps) => {
|
|
33
|
+
return <AuthRegister realmConfig={props.realmConfig} />;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default AuthRegisterPage;
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
export const saasAuthResetPasswordTsx = () =>
|
|
40
|
+
`import { AuthResetPassword } from "@/components/auth/auth-reset-password";
|
|
41
|
+
import type { RealmConfig } from "alepha/api/users";
|
|
42
|
+
|
|
43
|
+
export interface AuthResetPasswordPageProps {
|
|
44
|
+
realmConfig: RealmConfig;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const AuthResetPasswordPage = (props: AuthResetPasswordPageProps) => {
|
|
48
|
+
return <AuthResetPassword realmConfig={props.realmConfig} />;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default AuthResetPasswordPage;
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
export const saasAuthVerifyEmailTsx = () =>
|
|
55
|
+
`import { AuthVerifyEmail } from "@/components/auth/auth-verify-email";
|
|
56
|
+
|
|
57
|
+
const AuthVerifyEmailPage = () => {
|
|
58
|
+
return <AuthVerifyEmail />;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default AuthVerifyEmailPage;
|
|
62
|
+
`;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface SaasRealmProviderOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Email seeded as the default admin. Detected from `git config user.email`
|
|
4
|
+
* at init time; falls through to `admin@example.com` if git isn't configured.
|
|
5
|
+
*/
|
|
6
|
+
adminEmail?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Realm provider scaffolded by `alepha init --saas`.
|
|
11
|
+
*
|
|
12
|
+
* Minimal hello-world setup: credentials login with email, one admin seeded
|
|
13
|
+
* with the developer's git email at scaffold time, and an `admin:ui`
|
|
14
|
+
* permission used by the AppRouter to gate `/admin/*`. The default `admin`
|
|
15
|
+
* role grants `*` (so it inherits `admin:ui`); the default `user` role
|
|
16
|
+
* excludes `admin:*` (so non-admins get a 403 before the shell renders).
|
|
17
|
+
*
|
|
18
|
+
* Add `$env`, more permissions, or stricter settings as the project grows.
|
|
19
|
+
*/
|
|
20
|
+
export const saasRealmProviderTs = (options: SaasRealmProviderOptions = {}) => {
|
|
21
|
+
const adminEmail = options.adminEmail ?? "admin@example.com";
|
|
22
|
+
return `import { $realm } from "alepha/api/users";
|
|
23
|
+
import { $permission } from "alepha/security";
|
|
24
|
+
|
|
25
|
+
export class RealmProvider {
|
|
26
|
+
/**
|
|
27
|
+
* Permission required to open the admin UI. Wired into AppRouter.adminLayout
|
|
28
|
+
* via \`$secure({ permissions: ["admin:ui"] })\`.
|
|
29
|
+
*/
|
|
30
|
+
adminUi = $permission({
|
|
31
|
+
group: "admin",
|
|
32
|
+
name: "ui",
|
|
33
|
+
description: "Access to the admin UI shell",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
realm = $realm({
|
|
37
|
+
settings: {
|
|
38
|
+
adminEmails: [${JSON.stringify(adminEmail)}],
|
|
39
|
+
},
|
|
40
|
+
identities: {
|
|
41
|
+
credentials: true,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Vitest config for a freshly scaffolded Alepha project.
|
|
3
|
+
*
|
|
4
|
+
* Defines `test.root` explicitly so Vitest doesn't walk up the directory
|
|
5
|
+
* tree and inherit a parent monorepo config (which can pull in unrelated
|
|
6
|
+
* setup files, database connections, etc.).
|
|
7
|
+
*/
|
|
8
|
+
export const vitestConfigTs = () =>
|
|
9
|
+
`import { defineConfig } from "vitest/config";
|
|
10
|
+
|
|
11
|
+
export default defineConfig({
|
|
12
|
+
test: {
|
|
13
|
+
root: ".",
|
|
14
|
+
globals: true,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
`;
|
|
@@ -1,97 +1,26 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface WebAppRouterOptions {
|
|
2
2
|
api?: boolean;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
admin?: boolean;
|
|
6
|
-
}) => {
|
|
7
|
-
const imports: string[] = [];
|
|
8
|
-
const classMembers: string[] = [];
|
|
9
|
-
|
|
10
|
-
// UI import and setup
|
|
11
|
-
if (options.ui) {
|
|
12
|
-
imports.push('import { $ui } from "@alepha/ui";');
|
|
13
|
-
}
|
|
3
|
+
saas?: boolean;
|
|
4
|
+
}
|
|
14
5
|
|
|
15
|
-
|
|
16
|
-
if (options.
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Admin imports
|
|
21
|
-
if (options.admin) {
|
|
22
|
-
imports.push('import { $uiAdmin } from "@alepha/ui/admin";');
|
|
23
|
-
imports.push('import { AdminUserRouter } from "@alepha/ui/admin-users";');
|
|
24
|
-
imports.push(
|
|
25
|
-
'import { AdminSessionRouter } from "@alepha/ui/admin-sessions";',
|
|
26
|
-
);
|
|
27
|
-
imports.push('import { $inject } from "alepha";');
|
|
28
|
-
imports.push(
|
|
29
|
-
'import { IconLayoutDashboard, IconUsers } from "@tabler/icons-react";',
|
|
30
|
-
);
|
|
6
|
+
export const webAppRouterTs = (options: WebAppRouterOptions) => {
|
|
7
|
+
if (options.saas) {
|
|
8
|
+
return saasAppRouterTs();
|
|
31
9
|
}
|
|
10
|
+
return basicAppRouterTs(options);
|
|
11
|
+
};
|
|
32
12
|
|
|
33
|
-
|
|
34
|
-
imports
|
|
13
|
+
const basicAppRouterTs = (options: WebAppRouterOptions) => {
|
|
14
|
+
const imports: string[] = ['import { $page } from "alepha/react/router";'];
|
|
15
|
+
const classMembers: string[] = [];
|
|
35
16
|
|
|
36
|
-
// API imports (only if api flag is set)
|
|
37
17
|
if (options.api) {
|
|
38
18
|
imports.push('import { $client } from "alepha/server/links";');
|
|
39
19
|
imports.push(
|
|
40
20
|
'import type { HelloController } from "../api/controllers/HelloController.ts";',
|
|
41
21
|
);
|
|
42
22
|
classMembers.push(" api = $client<HelloController>();");
|
|
43
|
-
}
|
|
44
23
|
|
|
45
|
-
// UI layout setup
|
|
46
|
-
if (options.ui) {
|
|
47
|
-
classMembers.push(" ui = $ui();");
|
|
48
|
-
|
|
49
|
-
if (options.auth) {
|
|
50
|
-
classMembers.push(" uiAuth = $uiAuth();");
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (options.admin) {
|
|
54
|
-
classMembers.push(` // ── Admin Dashboard ─────────────────────────────
|
|
55
|
-
// Defined first so it can be referenced by the admin panel below.
|
|
56
|
-
// \`$uiAdmin\` auto-parents listed pages under the admin layout.
|
|
57
|
-
adminDashboard = $page({
|
|
58
|
-
path: "/",
|
|
59
|
-
label: "Dashboard",
|
|
60
|
-
icon: IconLayoutDashboard,
|
|
61
|
-
lazy: () => import("./components/AdminDashboard.tsx"),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// ── Admin Domain Routers ──────────────────────────
|
|
65
|
-
protected users = $inject(AdminUserRouter);
|
|
66
|
-
protected sessions = $inject(AdminSessionRouter);
|
|
67
|
-
|
|
68
|
-
// ── Admin Panel ─────────────────────────────────
|
|
69
|
-
admin = $uiAdmin({
|
|
70
|
-
pages: [
|
|
71
|
-
this.adminDashboard,
|
|
72
|
-
this.users.adminUsers,
|
|
73
|
-
this.users.adminUserLayout,
|
|
74
|
-
this.sessions.adminSessions,
|
|
75
|
-
],
|
|
76
|
-
sidebarItems: [
|
|
77
|
-
this.adminDashboard,
|
|
78
|
-
{
|
|
79
|
-
label: "Identity",
|
|
80
|
-
icon: IconUsers,
|
|
81
|
-
children: [this.users.adminUsers, this.sessions.adminSessions],
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
});`);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
classMembers.push(` layout = $page({
|
|
88
|
-
parent: this.ui.root,
|
|
89
|
-
children: () => [this.home],
|
|
90
|
-
});`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Home page - with or without loader
|
|
94
|
-
if (options.api) {
|
|
95
24
|
classMembers.push(` home = $page({
|
|
96
25
|
path: "/",
|
|
97
26
|
lazy: () => import("./components/Home.tsx"),
|
|
@@ -110,3 +39,94 @@ export class AppRouter {
|
|
|
110
39
|
${classMembers.join("\n\n")}
|
|
111
40
|
}`;
|
|
112
41
|
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* SaaS router wires three trees onto the app:
|
|
45
|
+
* / → Home
|
|
46
|
+
* /auth/* → AuthLayout + login / register / reset / verify
|
|
47
|
+
* /admin/* → AdminLayout + users / sessions / api-keys / parameters / audits
|
|
48
|
+
*
|
|
49
|
+
* Each auth page resolves the realm config from its loader, so the registry
|
|
50
|
+
* components render with everything they need on first paint.
|
|
51
|
+
*/
|
|
52
|
+
const saasAppRouterTs =
|
|
53
|
+
() => `import type { RealmController } from "alepha/api/users";
|
|
54
|
+
import { $page, NotFound } from "alepha/react/router";
|
|
55
|
+
import { $secure } from "alepha/security";
|
|
56
|
+
import { $client } from "alepha/server/links";
|
|
57
|
+
import type { HelloController } from "../api/controllers/HelloController.ts";
|
|
58
|
+
|
|
59
|
+
export class AppRouter {
|
|
60
|
+
protected readonly api = $client<HelloController>();
|
|
61
|
+
protected readonly realmApi = $client<RealmController>();
|
|
62
|
+
|
|
63
|
+
home = $page({
|
|
64
|
+
path: "/",
|
|
65
|
+
lazy: () => import("./components/Home.tsx"),
|
|
66
|
+
loader: () => this.api.hello(),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// ── /auth — login, register, reset, verify ─────────────────────────────
|
|
70
|
+
authLayout = $page({
|
|
71
|
+
path: "/auth",
|
|
72
|
+
lazy: () => import("./components/auth/AuthLayout.tsx"),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
login = $page({
|
|
76
|
+
parent: this.authLayout,
|
|
77
|
+
path: "/login",
|
|
78
|
+
name: "login",
|
|
79
|
+
head: { title: "Sign in" },
|
|
80
|
+
lazy: () => import("./components/auth/Login.tsx"),
|
|
81
|
+
loader: async () => ({ realmConfig: await this.realmApi.getRealmConfig() }),
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
register = $page({
|
|
85
|
+
parent: this.authLayout,
|
|
86
|
+
path: "/register",
|
|
87
|
+
name: "register",
|
|
88
|
+
head: { title: "Sign up" },
|
|
89
|
+
lazy: () => import("./components/auth/Register.tsx"),
|
|
90
|
+
loader: async () => ({ realmConfig: await this.realmApi.getRealmConfig() }),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
resetPassword = $page({
|
|
94
|
+
parent: this.authLayout,
|
|
95
|
+
path: "/reset-password",
|
|
96
|
+
head: { title: "Reset password" },
|
|
97
|
+
lazy: () => import("./components/auth/ResetPassword.tsx"),
|
|
98
|
+
loader: async () => ({ realmConfig: await this.realmApi.getRealmConfig() }),
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
verifyEmail = $page({
|
|
102
|
+
parent: this.authLayout,
|
|
103
|
+
path: "/verify-email",
|
|
104
|
+
head: { title: "Verify email" },
|
|
105
|
+
lazy: () => import("./components/auth/VerifyEmail.tsx"),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// ── /admin — gated by 'admin:ui' permission, declared in RealmProvider.
|
|
109
|
+
// Children inherit the gate via the parent chain.
|
|
110
|
+
adminLayout = $page({
|
|
111
|
+
path: "/admin",
|
|
112
|
+
use: [$secure({ permissions: ["admin:ui"] })],
|
|
113
|
+
lazy: () => import("./components/admin/AdminLayout.tsx"),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
adminUsers = $page({
|
|
117
|
+
parent: this.adminLayout,
|
|
118
|
+
path: "/users",
|
|
119
|
+
head: { title: "Users" },
|
|
120
|
+
lazy: () => import("./components/admin/Users.tsx"),
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
adminSessions = $page({
|
|
124
|
+
parent: this.adminLayout,
|
|
125
|
+
path: "/sessions",
|
|
126
|
+
head: { title: "Sessions" },
|
|
127
|
+
lazy: () => import("./components/admin/Sessions.tsx"),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
notFound = $page({ path: "/*", component: NotFound });
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
export interface WebIndexTsOptions {
|
|
2
2
|
appName?: string;
|
|
3
|
+
/**
|
|
4
|
+
* SaaS bundle: auth pages need `useAuth()` (ReactAuth) which lives in the
|
|
5
|
+
* `alepha.react.auth` module. Importing it here registers ReactAuth in the
|
|
6
|
+
* container so the auth-* registry components can inject it.
|
|
7
|
+
*/
|
|
8
|
+
saas?: boolean;
|
|
3
9
|
}
|
|
4
10
|
|
|
5
11
|
export const webIndexTs = (options: WebIndexTsOptions = {}) => {
|
|
6
|
-
const { appName = "app" } = options;
|
|
12
|
+
const { appName = "app", saas = false } = options;
|
|
13
|
+
|
|
14
|
+
if (saas) {
|
|
15
|
+
return `
|
|
16
|
+
import { $module } from "alepha";
|
|
17
|
+
import { AlephaReactAuth } from "alepha/react/auth";
|
|
18
|
+
import { AlephaReactI18n } from "alepha/react/i18n";
|
|
19
|
+
import { AppRouter } from "./AppRouter.ts";
|
|
20
|
+
|
|
21
|
+
export const WebModule = $module({
|
|
22
|
+
name: "${appName}.web",
|
|
23
|
+
services: [AppRouter],
|
|
24
|
+
imports: [AlephaReactAuth, AlephaReactI18n],
|
|
25
|
+
});
|
|
26
|
+
`.trim();
|
|
27
|
+
}
|
|
28
|
+
|
|
7
29
|
return `
|
|
8
30
|
import { $module } from "alepha";
|
|
9
31
|
import { AppRouter } from "./AppRouter.ts";
|