alepha 0.18.2 → 0.18.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/assets/devtools-ui/200.html +2 -2
- package/assets/devtools-ui/200.html.br +0 -0
- package/assets/devtools-ui/404.html +2 -2
- package/assets/devtools-ui/404.html.br +0 -0
- package/assets/devtools-ui/{asset.BfSBZ5Dd.css → asset.hG_f8HuK.css} +1 -1
- package/assets/devtools-ui/asset.hG_f8HuK.css.br +0 -0
- package/assets/devtools-ui/chunk.B3au4Lhg.js +1 -0
- package/assets/devtools-ui/chunk.B3au4Lhg.js.br +0 -0
- package/assets/devtools-ui/chunk.BLOrlnMB.js +1 -0
- package/assets/devtools-ui/chunk.BLOrlnMB.js.br +0 -0
- package/assets/devtools-ui/chunk.BLR01ljW.js +1 -0
- package/assets/devtools-ui/chunk.BLR01ljW.js.br +0 -0
- package/assets/devtools-ui/chunk.BTXaIUlA.js +1 -0
- package/assets/devtools-ui/chunk.BTXaIUlA.js.br +0 -0
- package/assets/devtools-ui/{chunk.lJL-lgnW.js → chunk.BhJaxmm8.js} +1 -1
- package/assets/devtools-ui/chunk.BhJaxmm8.js.br +0 -0
- package/assets/devtools-ui/chunk.BtoNxFuL.js +1 -0
- package/assets/devtools-ui/chunk.BtoNxFuL.js.br +0 -0
- package/assets/devtools-ui/chunk.C8YUV2Wd.js +1 -0
- package/assets/devtools-ui/chunk.C8YUV2Wd.js.br +0 -0
- package/assets/devtools-ui/{chunk.M6wyKO_3.js → chunk.CBbIgDzE.js} +2 -2
- package/assets/devtools-ui/chunk.CBbIgDzE.js.br +0 -0
- package/assets/devtools-ui/chunk.CFqIniwA.js +1 -0
- package/assets/devtools-ui/chunk.CFqIniwA.js.br +0 -0
- package/assets/devtools-ui/chunk.CLFF7f7-.js +1 -0
- package/assets/devtools-ui/chunk.CLFF7f7-.js.br +0 -0
- package/assets/devtools-ui/chunk.CRsBbA10.js +1 -0
- package/assets/devtools-ui/chunk.CRsBbA10.js.br +0 -0
- package/assets/devtools-ui/{chunk.DbEH1oOB.js → chunk.CZPo6v95.js} +1 -1
- package/assets/devtools-ui/chunk.CZPo6v95.js.br +0 -0
- package/assets/devtools-ui/chunk.D0fWgNos.js +1 -0
- package/assets/devtools-ui/chunk.D0fWgNos.js.br +1 -0
- package/assets/devtools-ui/chunk.D7-0ziQ6.js +1 -0
- package/assets/devtools-ui/chunk.D7-0ziQ6.js.br +0 -0
- package/assets/devtools-ui/chunk.DAewe0vm.js +1 -0
- package/assets/devtools-ui/chunk.DAewe0vm.js.br +0 -0
- package/assets/devtools-ui/chunk.DJRQEYqK.js +1 -0
- package/assets/devtools-ui/chunk.DJRQEYqK.js.br +0 -0
- package/assets/devtools-ui/{chunk.CZl6J9DF.js → chunk.DMAxv14p.js} +1 -1
- package/assets/devtools-ui/chunk.DMAxv14p.js.br +0 -0
- package/assets/devtools-ui/{chunk.BT2IiBkZ.js → chunk.DMImnNjU.js} +1 -1
- package/assets/devtools-ui/chunk.DMImnNjU.js.br +0 -0
- package/assets/devtools-ui/chunk.DeeQsidk.js +9 -0
- package/assets/devtools-ui/chunk.DeeQsidk.js.br +0 -0
- package/assets/devtools-ui/chunk.DqEwn9Vj.js +7 -0
- package/assets/devtools-ui/chunk.DqEwn9Vj.js.br +0 -0
- package/assets/devtools-ui/chunk.Dt8OsQey.js +1 -0
- package/assets/devtools-ui/chunk.Dt8OsQey.js.br +0 -0
- package/assets/devtools-ui/{chunk.B9pX3zit.js → chunk.Dtp8oa_f.js} +1 -1
- package/assets/devtools-ui/chunk.Dtp8oa_f.js.br +0 -0
- package/assets/devtools-ui/chunk.Dx3JzAYM.js +1 -0
- package/assets/devtools-ui/chunk.Dx3JzAYM.js.br +0 -0
- package/assets/devtools-ui/chunk.GCOj1-5E.js +1 -0
- package/assets/devtools-ui/chunk.GCOj1-5E.js.br +0 -0
- package/assets/devtools-ui/chunk.IC1LD8BH.js +1 -0
- package/assets/devtools-ui/chunk.IC1LD8BH.js.br +0 -0
- package/assets/devtools-ui/chunk.IwuB_TqW.js +1 -0
- package/assets/devtools-ui/chunk.IwuB_TqW.js.br +0 -0
- package/assets/devtools-ui/chunk.Qqapj2zq.js +1 -0
- package/assets/devtools-ui/chunk.Qqapj2zq.js.br +0 -0
- package/assets/devtools-ui/{chunk.C79YouPp.js → chunk.TKKKndOy.js} +1 -1
- package/assets/devtools-ui/chunk.TKKKndOy.js.br +0 -0
- package/assets/devtools-ui/chunk.YHTVhFQT.js +1 -0
- package/assets/devtools-ui/chunk.YHTVhFQT.js.br +0 -0
- package/assets/devtools-ui/chunk.fnod6uEi.js +1 -0
- package/assets/devtools-ui/chunk.fnod6uEi.js.br +0 -0
- package/assets/devtools-ui/chunk.mOCRmXjo.js +1 -0
- package/assets/devtools-ui/chunk.mOCRmXjo.js.br +0 -0
- package/assets/devtools-ui/chunk.qZTNEAK0.js +1 -0
- package/assets/devtools-ui/chunk.qZTNEAK0.js.br +0 -0
- package/assets/devtools-ui/chunk.rc9m0y4-.js +1 -0
- package/assets/devtools-ui/chunk.rc9m0y4-.js.br +0 -0
- package/assets/devtools-ui/entry.Cxc5QLCU.js +80 -0
- package/assets/devtools-ui/entry.Cxc5QLCU.js.br +0 -0
- package/assets/devtools-ui/index.html +2 -2
- package/assets/devtools-ui/index.html.br +0 -0
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.d.ts +61 -5
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +61 -5
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +61 -5
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +4 -2
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +5 -5
- package/dist/api/notifications/index.browser.js +44 -1
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +187 -2
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +143 -8
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +61 -5
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +330 -93
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +27 -36
- package/dist/api/users/index.js.map +1 -1
- package/dist/cli/config/index.d.ts +46 -0
- package/dist/cli/config/index.d.ts.map +1 -0
- package/dist/cli/config/index.js +20 -0
- package/dist/cli/config/index.js.map +1 -0
- package/dist/cli/core/index.d.ts +69 -66
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +329 -196
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +302 -63
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +455 -25
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/core/index.browser.js +125 -87
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +62 -53
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +125 -87
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +125 -87
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +125 -87
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.d.ts +18 -1
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.js +29 -3
- package/dist/crypto/index.js.map +1 -1
- package/dist/devtools/index.js +3 -12
- package/dist/devtools/index.js.map +1 -1
- package/dist/logger/index.d.ts +10 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +19 -9
- package/dist/logger/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +57 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +378 -19
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +328 -9
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +384 -21
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +49 -17
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +47 -21
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +52 -17
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/core/index.d.ts +1 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +6 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +28 -18
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +92 -56
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/router/index.browser.js +448 -116
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +102 -40
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +453 -92
- package/dist/react/router/index.js.map +1 -1
- package/dist/security/index.d.ts +3 -11
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +6 -11
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +22 -24
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +102 -82
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +7 -4
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +13 -12
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +288 -4
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +375 -2
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js +10 -71
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +32 -49
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +73 -100
- package/dist/server/links/index.js.map +1 -1
- package/dist/system/index.browser.js +221 -2
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.d.ts +63 -1
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +221 -1
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js +224 -4
- package/dist/system/index.workerd.js.map +1 -1
- package/package.json +10 -5
- package/src/api/jobs/providers/JobProvider.ts +6 -3
- package/src/api/notifications/controllers/AdminNotificationController.ts +83 -0
- package/src/api/notifications/index.browser.ts +3 -0
- package/src/api/notifications/index.ts +14 -2
- package/src/api/notifications/jobs/NotificationJobs.ts +11 -2
- package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +20 -0
- package/src/api/notifications/schemas/notificationQuerySchema.ts +19 -0
- package/src/api/notifications/schemas/notificationResourceSchema.ts +18 -0
- package/src/api/notifications/services/NotificationSenderService.ts +15 -2
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +28 -32
- package/src/api/users/buckets/UserBuckets.ts +1 -1
- package/src/api/users/jobs/UserJobs.ts +1 -1
- package/src/api/users/primitives/$realm.ts +8 -49
- package/src/api/users/providers/RealmProvider.ts +2 -3
- package/src/api/users/services/RegistrationService.spec.ts +7 -7
- package/src/api/users/services/RegistrationService.ts +3 -3
- package/src/api/users/services/SessionService.spec.ts +4 -4
- package/src/api/users/services/SessionService.ts +3 -3
- package/src/cli/{core → config}/defineConfig.ts +14 -20
- package/src/cli/config/index.ts +1 -0
- package/src/cli/core/commands/db.ts +65 -1
- package/src/cli/core/commands/dev.ts +1 -0
- package/src/cli/core/commands/init.ts +2 -192
- package/src/cli/core/index.ts +34 -11
- package/src/cli/core/providers/ViteDevServerProvider.ts +52 -13
- package/src/cli/core/services/PackageManagerUtils.ts +43 -21
- package/src/cli/core/services/ProjectScaffolder.ts +214 -2
- package/src/cli/core/services/ViteUtils.ts +57 -0
- package/src/cli/core/tasks/BuildClientTask.ts +7 -2
- package/src/cli/core/tasks/BuildCloudflareTask.ts +4 -12
- package/src/cli/core/tasks/BuildServerTask.ts +2 -0
- package/src/cli/core/tasks/BuildVercelTask.ts +165 -168
- package/src/cli/core/templates/alephaConfigTs.ts +1 -1
- package/src/cli/core/templates/apiAppSecurityTs.ts +5 -8
- package/src/cli/core/templates/tsconfigJson.ts +6 -1
- package/src/cli/platform/adapters/CloudflareAdapter.spec.ts +1 -1
- package/src/cli/platform/adapters/CloudflareAdapter.ts +30 -29
- package/src/cli/platform/atoms/platformOptions.ts +21 -0
- package/src/cli/platform/commands/SecretsCommand.spec.ts +298 -0
- package/src/cli/platform/commands/SecretsCommand.ts +283 -0
- package/src/cli/platform/commands/platform.ts +12 -0
- package/src/cli/platform/index.ts +14 -28
- package/src/cli/platform/providers/GitHubSecretStore.spec.ts +153 -0
- package/src/cli/platform/providers/GitHubSecretStore.ts +112 -0
- package/src/cli/platform/providers/MemorySecretStore.ts +114 -0
- package/src/cli/platform/providers/SecretStoreProvider.ts +39 -0
- package/src/cli/platform/schemas/cloudflare.ts +2 -0
- package/src/cli/platform/services/CloudflareApi.ts +5 -2
- package/src/cli/platform/services/DockerComposeGenerator.spec.ts +115 -0
- package/src/cli/platform/services/DockerComposeGenerator.ts +46 -1
- package/src/cli/platform/services/SecretFilterService.spec.ts +111 -0
- package/src/cli/platform/services/SecretFilterService.ts +54 -0
- package/src/core/Alepha.ts +94 -25
- package/src/core/__tests__/Alepha-parseEnv.spec.ts +20 -0
- package/src/core/primitives/$memoize.ts +38 -26
- package/src/core/providers/AlsProvider.ts +2 -0
- package/src/core/providers/EventManager.ts +4 -0
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +1 -4
- package/src/core/providers/KeylessJsonSchemaCodec.ts +19 -125
- package/src/core/providers/SchemaValidator.spec.ts +36 -0
- package/src/core/providers/SchemaValidator.ts +9 -0
- package/src/crypto/index.ts +6 -1
- package/src/crypto/providers/SecretProvider.ts +36 -0
- package/src/devtools/providers/DevToolsProvider.ts +3 -12
- package/src/logger/index.ts +33 -6
- package/src/logger/providers/PrettyFormatterProvider.ts +5 -3
- package/src/orm/__tests__/orm-next-tests.ts +492 -0
- package/src/orm/__tests__/orm-next.spec.ts +140 -0
- package/src/orm/core/constants/PG_SYMBOLS.ts +17 -0
- package/src/orm/core/index.bun.ts +3 -6
- package/src/orm/core/index.shared-server.ts +2 -0
- package/src/orm/core/index.shared.ts +2 -0
- package/src/orm/core/index.ts +5 -7
- package/src/orm/core/interfaces/AggregateQuery.ts +103 -0
- package/src/orm/core/interfaces/PgQueryWhere.ts +7 -0
- package/src/orm/core/primitives/$entity.ts +8 -0
- package/src/orm/core/primitives/$repository.ts +6 -3
- package/src/orm/core/primitives/$view.ts +88 -0
- package/src/orm/core/providers/DbCacheProvider.ts +66 -0
- package/src/orm/core/providers/DrizzleKitProvider.ts +42 -0
- package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -3
- package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +12 -0
- package/src/orm/core/providers/drivers/DatabaseProvider.ts +39 -0
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +2 -3
- package/src/orm/core/schemas/databaseEnvSchema.ts +31 -0
- package/src/orm/core/schemas/insertSchema.ts +13 -3
- package/src/orm/core/schemas/updateSchema.ts +14 -3
- package/src/orm/core/services/ModelBuilder.ts +26 -14
- package/src/orm/core/services/QueryManager.ts +13 -0
- package/src/orm/core/services/Repository.ts +307 -5
- package/src/orm/core/services/SqliteModelBuilder.ts +38 -0
- package/src/orm/postgres/index.bun.ts +4 -7
- package/src/orm/postgres/index.ts +4 -7
- package/src/orm/postgres/providers/BunPostgresProvider.ts +12 -2
- package/src/orm/postgres/providers/NodePostgresProvider.ts +7 -0
- package/src/orm/postgres/providers/PglitePostgresProvider.ts +10 -17
- package/src/orm/postgres/providers/PostgresProvider.ts +7 -36
- package/src/orm/postgres/schemas/postgresEnvSchema.ts +32 -0
- package/src/orm/postgres/services/PostgresModelBuilder.ts +40 -0
- package/src/react/core/components/ErrorBoundary.tsx +5 -2
- package/src/react/form/hooks/useFieldValue.ts +34 -0
- package/src/react/form/hooks/useForm.browser.spec.tsx +94 -9
- package/src/react/form/hooks/useForm.ts +14 -2
- package/src/react/form/hooks/useFormState.ts +10 -10
- package/src/react/form/hooks/useFormValues.ts +29 -0
- package/src/react/form/index.ts +3 -1
- package/src/react/form/services/FormModel.ts +53 -122
- package/src/react/router/components/ErrorViewer.tsx +333 -34
- package/src/react/router/components/NestedView.tsx +10 -3
- package/src/react/router/primitives/$page.browser.spec.tsx +34 -0
- package/src/react/router/primitives/$page.spec.tsx +20 -0
- package/src/react/router/primitives/$page.ts +24 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +14 -2
- package/src/react/router/providers/ReactPageProvider.ts +156 -73
- package/src/react/router/providers/ReactServerProvider.ts +40 -2
- package/src/react/router/providers/ReactServerTemplateProvider.ts +13 -1
- package/src/security/providers/SecurityProvider.ts +5 -27
- package/src/server/auth/primitives/$auth.ts +52 -19
- package/src/server/auth/providers/ServerAuthProvider.ts +145 -139
- package/src/server/cookies/providers/ServerCookiesProvider.ts +12 -24
- package/src/server/core/index.ts +3 -1
- package/src/server/core/primitives/$sse.spec.ts +315 -0
- package/src/server/core/primitives/$sse.ts +715 -0
- package/src/server/links/index.browser.ts +1 -3
- package/src/server/links/index.ts +0 -3
- package/src/server/links/providers/LinkProvider.spec.ts +12 -21
- package/src/server/links/providers/LinkProvider.ts +20 -52
- package/src/server/links/providers/ServerLinksProvider.spec.ts +106 -0
- package/src/server/links/providers/ServerLinksProvider.ts +113 -73
- package/src/server/links/schemas/apiLinksResponseSchema.ts +4 -21
- package/src/server/links/services/BatchCollector.ts +5 -3
- package/src/system/index.browser.ts +1 -0
- package/src/system/index.ts +3 -0
- package/src/system/index.workerd.ts +39 -1
- package/src/system/providers/WorkerdFileSystemProvider.ts +365 -0
- package/assets/devtools-ui/asset.BfSBZ5Dd.css.br +0 -0
- package/assets/devtools-ui/chunk.2NYaoqWt.js +0 -1
- package/assets/devtools-ui/chunk.2NYaoqWt.js.br +0 -0
- package/assets/devtools-ui/chunk.B052Z_xQ.js +0 -1
- package/assets/devtools-ui/chunk.B052Z_xQ.js.br +0 -0
- package/assets/devtools-ui/chunk.B4kVY90C.js +0 -1
- package/assets/devtools-ui/chunk.B4kVY90C.js.br +0 -0
- package/assets/devtools-ui/chunk.B7QJXctB.js +0 -1
- package/assets/devtools-ui/chunk.B7QJXctB.js.br +0 -0
- package/assets/devtools-ui/chunk.B9pX3zit.js.br +0 -0
- package/assets/devtools-ui/chunk.BKF9JxIo.js +0 -1
- package/assets/devtools-ui/chunk.BKF9JxIo.js.br +0 -0
- package/assets/devtools-ui/chunk.BOHgdTP-.js +0 -1
- package/assets/devtools-ui/chunk.BOHgdTP-.js.br +0 -0
- package/assets/devtools-ui/chunk.BOVFxkYC.js +0 -1
- package/assets/devtools-ui/chunk.BOVFxkYC.js.br +0 -0
- package/assets/devtools-ui/chunk.BR842zj5.js +0 -1
- package/assets/devtools-ui/chunk.BR842zj5.js.br +0 -0
- package/assets/devtools-ui/chunk.BT2IiBkZ.js.br +0 -0
- package/assets/devtools-ui/chunk.C79YouPp.js.br +0 -0
- package/assets/devtools-ui/chunk.C8mlBrjW.js +0 -9
- package/assets/devtools-ui/chunk.C8mlBrjW.js.br +0 -0
- package/assets/devtools-ui/chunk.CK0ow3AZ.js +0 -1
- package/assets/devtools-ui/chunk.CK0ow3AZ.js.br +0 -0
- package/assets/devtools-ui/chunk.CZl6J9DF.js.br +0 -0
- package/assets/devtools-ui/chunk.CdNr0YzS.js +0 -1
- package/assets/devtools-ui/chunk.CdNr0YzS.js.br +0 -0
- package/assets/devtools-ui/chunk.Ce6_6iIF.js +0 -1
- package/assets/devtools-ui/chunk.Ce6_6iIF.js.br +0 -0
- package/assets/devtools-ui/chunk.CpyDMr6O.js +0 -1
- package/assets/devtools-ui/chunk.CpyDMr6O.js.br +0 -0
- package/assets/devtools-ui/chunk.CyPmvPnY.js +0 -1
- package/assets/devtools-ui/chunk.CyPmvPnY.js.br +0 -0
- package/assets/devtools-ui/chunk.DTI_geWu.js +0 -1
- package/assets/devtools-ui/chunk.DTI_geWu.js.br +0 -0
- package/assets/devtools-ui/chunk.DbEH1oOB.js.br +0 -0
- package/assets/devtools-ui/chunk.Ddeqj5gv.js +0 -1
- package/assets/devtools-ui/chunk.Ddeqj5gv.js.br +0 -0
- package/assets/devtools-ui/chunk.DpRnB4vJ.js +0 -1
- package/assets/devtools-ui/chunk.DpRnB4vJ.js.br +0 -0
- package/assets/devtools-ui/chunk.DxPGTlsg.js +0 -1
- package/assets/devtools-ui/chunk.DxPGTlsg.js.br +0 -0
- package/assets/devtools-ui/chunk.G7_MMBJS.js +0 -1
- package/assets/devtools-ui/chunk.G7_MMBJS.js.br +0 -0
- package/assets/devtools-ui/chunk.M6wyKO_3.js.br +0 -0
- package/assets/devtools-ui/chunk.OUxNGmQ6.js +0 -1
- package/assets/devtools-ui/chunk.OUxNGmQ6.js.br +0 -0
- package/assets/devtools-ui/chunk.T1kle-fF.js +0 -1
- package/assets/devtools-ui/chunk.T1kle-fF.js.br +0 -0
- package/assets/devtools-ui/chunk.WjpsbQAv.js +0 -1
- package/assets/devtools-ui/chunk.WjpsbQAv.js.br +0 -0
- package/assets/devtools-ui/chunk.c6YgVx86.js +0 -1
- package/assets/devtools-ui/chunk.c6YgVx86.js.br +0 -0
- package/assets/devtools-ui/chunk.dwU3E_MU.js +0 -1
- package/assets/devtools-ui/chunk.dwU3E_MU.js.br +0 -0
- package/assets/devtools-ui/chunk.lJL-lgnW.js.br +0 -0
- package/assets/devtools-ui/chunk.lPWRmvA-.js +0 -7
- package/assets/devtools-ui/chunk.lPWRmvA-.js.br +0 -0
- package/assets/devtools-ui/chunk.p3HJvugM.js +0 -1
- package/assets/devtools-ui/chunk.p3HJvugM.js.br +0 -0
- package/assets/devtools-ui/chunk.r_Xoa_CI.js +0 -1
- package/assets/devtools-ui/chunk.r_Xoa_CI.js.br +0 -0
- package/assets/devtools-ui/chunk.sRNuTYXb.js +0 -1
- package/assets/devtools-ui/chunk.sRNuTYXb.js.br +0 -0
- package/assets/devtools-ui/chunk.tUjcyX5C.js +0 -1
- package/assets/devtools-ui/chunk.tUjcyX5C.js.br +0 -0
- package/assets/devtools-ui/chunk.thjBxvCA.js +0 -1
- package/assets/devtools-ui/chunk.thjBxvCA.js.br +0 -0
- package/assets/devtools-ui/entry.GYhBVRpC.js +0 -78
- package/assets/devtools-ui/entry.GYhBVRpC.js.br +0 -0
- package/src/server/links/services/DefinitionsPool.spec.ts +0 -86
- package/src/server/links/services/DefinitionsPool.ts +0 -43
|
@@ -1,43 +1,142 @@
|
|
|
1
1
|
import type { Alepha } from "alepha";
|
|
2
|
-
import type
|
|
2
|
+
import { type CSSProperties, useState } from "react";
|
|
3
|
+
import { useRouterState } from "../hooks/useRouterState.ts";
|
|
3
4
|
|
|
4
|
-
interface ErrorViewerProps {
|
|
5
|
+
export interface ErrorViewerProps {
|
|
5
6
|
error: Error;
|
|
6
7
|
alepha: Alepha;
|
|
8
|
+
onRetry?: () => void;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
const mono =
|
|
10
12
|
'ui-monospace, "JetBrains Mono", SFMono-Regular, Menlo, Monaco, Consolas, monospace';
|
|
11
13
|
|
|
12
|
-
const ErrorViewer = (
|
|
13
|
-
if (alepha.isProduction()) {
|
|
14
|
-
return <
|
|
14
|
+
const ErrorViewer = (props: ErrorViewerProps) => {
|
|
15
|
+
if (props.alepha.isProduction()) {
|
|
16
|
+
return <ProdErrorPage error={props.error} />;
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
return <DevErrorPage {...props} />;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default ErrorViewer;
|
|
23
|
+
|
|
24
|
+
// ----- Dev Error Page -----
|
|
25
|
+
|
|
26
|
+
const DevErrorPage = (props: ErrorViewerProps) => {
|
|
27
|
+
const [copied, setCopied] = useState(false);
|
|
28
|
+
const state = useRouterState();
|
|
29
|
+
const pathname = state.url.pathname;
|
|
30
|
+
|
|
31
|
+
const handleCopy = () => {
|
|
32
|
+
const text = buildErrorText(props.error);
|
|
33
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
34
|
+
navigator.clipboard.writeText(text);
|
|
35
|
+
setCopied(true);
|
|
36
|
+
setTimeout(() => setCopied(false), 2000);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const status = getHttpStatus(props.error);
|
|
41
|
+
|
|
17
42
|
return (
|
|
18
|
-
<div style={
|
|
19
|
-
<
|
|
43
|
+
<div style={dev.overlay}>
|
|
44
|
+
<div style={dev.card}>
|
|
45
|
+
<div style={dev.header}>
|
|
46
|
+
<div style={dev.headerLeft}>
|
|
47
|
+
<div style={dev.icon}>!</div>
|
|
48
|
+
<div style={dev.title}>{props.error.name || "Error"}</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div style={dev.headerRight}>
|
|
51
|
+
{props.onRetry && (
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
style={dev.retryBtn}
|
|
55
|
+
onClick={props.onRetry}
|
|
56
|
+
>
|
|
57
|
+
Retry
|
|
58
|
+
</button>
|
|
59
|
+
)}
|
|
60
|
+
<button type="button" style={dev.copyBtn} onClick={handleCopy}>
|
|
61
|
+
{copied ? "Copied" : "Copy"}
|
|
62
|
+
</button>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<ErrorBlock error={props.error} />
|
|
67
|
+
|
|
68
|
+
<div style={dev.meta}>
|
|
69
|
+
{pathname && <span style={dev.metaItem}>{pathname}</span>}
|
|
70
|
+
<span style={dev.metaItem}>{new Date().toLocaleTimeString()}</span>
|
|
71
|
+
{status && <span style={dev.statusBadge}>{status}</span>}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
20
74
|
</div>
|
|
21
75
|
);
|
|
22
76
|
};
|
|
23
77
|
|
|
24
|
-
|
|
78
|
+
// ----- Error Block (recursive) -----
|
|
79
|
+
|
|
80
|
+
const ErrorBlock = (props: { error: Error; depth?: number }) => {
|
|
81
|
+
const { error, depth = 0 } = props;
|
|
25
82
|
|
|
26
|
-
function ErrorBlock({ error, depth = 0 }: { error: Error; depth?: number }) {
|
|
27
83
|
return (
|
|
28
84
|
<>
|
|
29
|
-
{depth > 0 && <div style={
|
|
30
|
-
<
|
|
85
|
+
{depth > 0 && <div style={dev.causedBy}>Caused by:</div>}
|
|
86
|
+
<pre style={dev.messageBlock}>
|
|
31
87
|
{error.name}: {error.message}
|
|
32
|
-
</
|
|
33
|
-
{error.stack &&
|
|
88
|
+
</pre>
|
|
89
|
+
{error.stack && (
|
|
90
|
+
<>
|
|
91
|
+
<div style={dev.stackLabel}>STACK TRACE</div>
|
|
92
|
+
<pre style={dev.stackBlock}>{cleanStack(error.stack)}</pre>
|
|
93
|
+
</>
|
|
94
|
+
)}
|
|
34
95
|
{error.cause instanceof Error && (
|
|
35
96
|
<ErrorBlock error={error.cause} depth={depth + 1} />
|
|
36
97
|
)}
|
|
37
98
|
</>
|
|
38
99
|
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// ----- Prod Error Page -----
|
|
103
|
+
|
|
104
|
+
interface ProdErrorPageProps {
|
|
105
|
+
error: Error;
|
|
39
106
|
}
|
|
40
107
|
|
|
108
|
+
const ProdErrorPage = (props: ProdErrorPageProps) => {
|
|
109
|
+
const requestId = (props.error as any).requestId;
|
|
110
|
+
|
|
111
|
+
const handleReload = () => {
|
|
112
|
+
if (typeof window !== "undefined") {
|
|
113
|
+
window.location.reload();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<div style={prod.page}>
|
|
119
|
+
<div style={prod.card}>
|
|
120
|
+
<div style={prod.heading}>Something went wrong</div>
|
|
121
|
+
<div style={prod.subtitle}>
|
|
122
|
+
We're having trouble processing your request.
|
|
123
|
+
</div>
|
|
124
|
+
{requestId && <div style={prod.refText}>Reference: {requestId}</div>}
|
|
125
|
+
<div style={prod.actions}>
|
|
126
|
+
<button type="button" style={prod.reloadBtn} onClick={handleReload}>
|
|
127
|
+
Reload page
|
|
128
|
+
</button>
|
|
129
|
+
<a href="/" style={prod.homeLink}>
|
|
130
|
+
Go home
|
|
131
|
+
</a>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// ----- Helpers -----
|
|
139
|
+
|
|
41
140
|
function cleanStack(stack: string): string {
|
|
42
141
|
return stack
|
|
43
142
|
.split("\n")
|
|
@@ -46,41 +145,241 @@ function cleanStack(stack: string): string {
|
|
|
46
145
|
.join("\n");
|
|
47
146
|
}
|
|
48
147
|
|
|
49
|
-
|
|
50
|
-
|
|
148
|
+
function buildErrorText(error: Error): string {
|
|
149
|
+
const parts: string[] = [];
|
|
150
|
+
|
|
151
|
+
const append = (err: Error, depth: number) => {
|
|
152
|
+
if (depth > 0) {
|
|
153
|
+
parts.push(`\nCaused by:`);
|
|
154
|
+
}
|
|
155
|
+
parts.push(`${err.name}: ${err.message}`);
|
|
156
|
+
if (err.stack) {
|
|
157
|
+
parts.push(cleanStack(err.stack));
|
|
158
|
+
}
|
|
159
|
+
if (err.cause instanceof Error) {
|
|
160
|
+
append(err.cause, depth + 1);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
append(error, 0);
|
|
165
|
+
return parts.join("\n");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function getHttpStatus(error: Error): number | undefined {
|
|
169
|
+
if ("status" in error && typeof (error as any).status === "number") {
|
|
170
|
+
return (error as any).status;
|
|
171
|
+
}
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ----- Dev Styles -----
|
|
176
|
+
|
|
177
|
+
const dev: Record<string, CSSProperties> = {
|
|
178
|
+
overlay: {
|
|
179
|
+
position: "fixed",
|
|
180
|
+
inset: 0,
|
|
181
|
+
zIndex: 2147483647,
|
|
182
|
+
display: "flex",
|
|
183
|
+
alignItems: "center",
|
|
184
|
+
justifyContent: "center",
|
|
51
185
|
padding: "24px",
|
|
186
|
+
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
187
|
+
backdropFilter: "blur(4px)",
|
|
52
188
|
fontFamily: mono,
|
|
53
189
|
fontSize: "13px",
|
|
54
|
-
color: "#
|
|
55
|
-
|
|
190
|
+
color: "#e5e7eb",
|
|
191
|
+
boxSizing: "border-box",
|
|
192
|
+
overflow: "auto",
|
|
56
193
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
194
|
+
card: {
|
|
195
|
+
width: "100%",
|
|
196
|
+
maxWidth: "900px",
|
|
197
|
+
maxHeight: "90vh",
|
|
198
|
+
overflow: "auto",
|
|
199
|
+
padding: "24px",
|
|
200
|
+
backgroundColor: "#111",
|
|
201
|
+
borderLeft: "4px solid #ef4444",
|
|
202
|
+
borderRadius: "8px",
|
|
203
|
+
boxShadow: "0 25px 50px rgba(0, 0, 0, 0.5)",
|
|
204
|
+
},
|
|
205
|
+
header: {
|
|
206
|
+
display: "flex",
|
|
207
|
+
alignItems: "center",
|
|
208
|
+
justifyContent: "space-between",
|
|
209
|
+
marginBottom: "20px",
|
|
210
|
+
flexWrap: "wrap",
|
|
211
|
+
gap: "12px",
|
|
212
|
+
},
|
|
213
|
+
headerLeft: {
|
|
214
|
+
display: "flex",
|
|
215
|
+
alignItems: "center",
|
|
216
|
+
gap: "12px",
|
|
217
|
+
minWidth: 0,
|
|
218
|
+
},
|
|
219
|
+
headerRight: {
|
|
220
|
+
display: "flex",
|
|
221
|
+
gap: "8px",
|
|
222
|
+
flexShrink: 0,
|
|
223
|
+
},
|
|
224
|
+
icon: {
|
|
225
|
+
width: "28px",
|
|
226
|
+
height: "28px",
|
|
227
|
+
borderRadius: "50%",
|
|
228
|
+
backgroundColor: "#ef4444",
|
|
229
|
+
color: "#fff",
|
|
230
|
+
display: "flex",
|
|
231
|
+
alignItems: "center",
|
|
232
|
+
justifyContent: "center",
|
|
233
|
+
fontWeight: 700,
|
|
234
|
+
fontSize: "16px",
|
|
235
|
+
flexShrink: 0,
|
|
236
|
+
},
|
|
237
|
+
title: {
|
|
238
|
+
color: "#f87171",
|
|
239
|
+
fontSize: "18px",
|
|
240
|
+
fontWeight: 700,
|
|
241
|
+
},
|
|
242
|
+
retryBtn: {
|
|
243
|
+
padding: "6px 16px",
|
|
244
|
+
backgroundColor: "#2563eb",
|
|
245
|
+
color: "#fff",
|
|
246
|
+
border: "none",
|
|
247
|
+
borderRadius: "6px",
|
|
248
|
+
cursor: "pointer",
|
|
249
|
+
fontFamily: mono,
|
|
250
|
+
fontSize: "12px",
|
|
60
251
|
fontWeight: 600,
|
|
61
|
-
|
|
252
|
+
},
|
|
253
|
+
copyBtn: {
|
|
254
|
+
padding: "6px 16px",
|
|
255
|
+
backgroundColor: "transparent",
|
|
256
|
+
color: "#9ca3af",
|
|
257
|
+
border: "1px solid #374151",
|
|
258
|
+
borderRadius: "6px",
|
|
259
|
+
cursor: "pointer",
|
|
260
|
+
fontFamily: mono,
|
|
261
|
+
fontSize: "12px",
|
|
262
|
+
fontWeight: 600,
|
|
263
|
+
},
|
|
264
|
+
messageBlock: {
|
|
265
|
+
margin: "0 0 12px",
|
|
266
|
+
padding: "12px",
|
|
267
|
+
backgroundColor: "#1f2937",
|
|
268
|
+
borderRadius: "6px",
|
|
269
|
+
color: "#f9fafb",
|
|
270
|
+
fontSize: "13px",
|
|
271
|
+
lineHeight: 1.6,
|
|
272
|
+
whiteSpace: "pre-wrap",
|
|
62
273
|
wordBreak: "break-word",
|
|
274
|
+
overflow: "auto",
|
|
63
275
|
},
|
|
64
|
-
|
|
276
|
+
stackLabel: {
|
|
277
|
+
fontSize: "10px",
|
|
278
|
+
color: "#6b7280",
|
|
279
|
+
textTransform: "uppercase",
|
|
280
|
+
letterSpacing: "1.5px",
|
|
281
|
+
marginBottom: "6px",
|
|
282
|
+
fontWeight: 600,
|
|
283
|
+
},
|
|
284
|
+
stackBlock: {
|
|
65
285
|
margin: "0 0 20px",
|
|
66
286
|
padding: "12px",
|
|
67
|
-
backgroundColor: "#
|
|
68
|
-
borderRadius: "
|
|
69
|
-
|
|
287
|
+
backgroundColor: "#0f172a",
|
|
288
|
+
borderRadius: "6px",
|
|
289
|
+
color: "#94a3b8",
|
|
70
290
|
fontSize: "12px",
|
|
71
291
|
lineHeight: 1.6,
|
|
72
|
-
color: "#666",
|
|
73
|
-
overflow: "auto",
|
|
74
292
|
whiteSpace: "pre-wrap",
|
|
75
293
|
wordBreak: "break-all",
|
|
294
|
+
overflow: "auto",
|
|
76
295
|
},
|
|
77
|
-
|
|
78
|
-
fontSize: "
|
|
79
|
-
color: "#
|
|
296
|
+
causedBy: {
|
|
297
|
+
fontSize: "10px",
|
|
298
|
+
color: "#6b7280",
|
|
80
299
|
textTransform: "uppercase",
|
|
81
|
-
letterSpacing: "
|
|
82
|
-
marginBottom: "
|
|
83
|
-
paddingTop: "
|
|
84
|
-
borderTop: "1px solid #
|
|
300
|
+
letterSpacing: "1.5px",
|
|
301
|
+
marginBottom: "8px",
|
|
302
|
+
paddingTop: "12px",
|
|
303
|
+
borderTop: "1px solid #374151",
|
|
304
|
+
fontWeight: 600,
|
|
305
|
+
},
|
|
306
|
+
meta: {
|
|
307
|
+
display: "flex",
|
|
308
|
+
gap: "16px",
|
|
309
|
+
alignItems: "center",
|
|
310
|
+
paddingTop: "12px",
|
|
311
|
+
borderTop: "1px solid #1f2937",
|
|
312
|
+
flexWrap: "wrap",
|
|
313
|
+
},
|
|
314
|
+
metaItem: {
|
|
315
|
+
fontSize: "11px",
|
|
316
|
+
color: "#6b7280",
|
|
317
|
+
},
|
|
318
|
+
statusBadge: {
|
|
319
|
+
fontSize: "11px",
|
|
320
|
+
color: "#fbbf24",
|
|
321
|
+
backgroundColor: "#422006",
|
|
322
|
+
padding: "2px 8px",
|
|
323
|
+
borderRadius: "4px",
|
|
324
|
+
fontWeight: 600,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// ----- Prod Styles -----
|
|
329
|
+
|
|
330
|
+
const prod: Record<string, CSSProperties> = {
|
|
331
|
+
page: {
|
|
332
|
+
minHeight: "100vh",
|
|
333
|
+
display: "flex",
|
|
334
|
+
alignItems: "center",
|
|
335
|
+
justifyContent: "center",
|
|
336
|
+
backgroundColor: "#0f172a",
|
|
337
|
+
fontFamily:
|
|
338
|
+
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
339
|
+
padding: "24px",
|
|
340
|
+
},
|
|
341
|
+
card: {
|
|
342
|
+
textAlign: "center",
|
|
343
|
+
maxWidth: "440px",
|
|
344
|
+
},
|
|
345
|
+
heading: {
|
|
346
|
+
fontSize: "28px",
|
|
347
|
+
fontWeight: 700,
|
|
348
|
+
color: "#f1f5f9",
|
|
349
|
+
marginBottom: "12px",
|
|
350
|
+
},
|
|
351
|
+
subtitle: {
|
|
352
|
+
fontSize: "16px",
|
|
353
|
+
color: "#94a3b8",
|
|
354
|
+
marginBottom: "24px",
|
|
355
|
+
lineHeight: 1.5,
|
|
356
|
+
},
|
|
357
|
+
refText: {
|
|
358
|
+
fontSize: "13px",
|
|
359
|
+
color: "#64748b",
|
|
360
|
+
marginBottom: "24px",
|
|
361
|
+
fontFamily: mono,
|
|
362
|
+
},
|
|
363
|
+
actions: {
|
|
364
|
+
display: "flex",
|
|
365
|
+
gap: "12px",
|
|
366
|
+
justifyContent: "center",
|
|
367
|
+
alignItems: "center",
|
|
368
|
+
},
|
|
369
|
+
reloadBtn: {
|
|
370
|
+
padding: "10px 24px",
|
|
371
|
+
backgroundColor: "#2563eb",
|
|
372
|
+
color: "#fff",
|
|
373
|
+
border: "none",
|
|
374
|
+
borderRadius: "8px",
|
|
375
|
+
cursor: "pointer",
|
|
376
|
+
fontSize: "14px",
|
|
377
|
+
fontWeight: 600,
|
|
378
|
+
},
|
|
379
|
+
homeLink: {
|
|
380
|
+
padding: "10px 24px",
|
|
381
|
+
color: "#94a3b8",
|
|
382
|
+
textDecoration: "none",
|
|
383
|
+
fontSize: "14px",
|
|
85
384
|
},
|
|
86
385
|
};
|
|
@@ -9,7 +9,7 @@ import ErrorViewer from "./ErrorViewer.tsx";
|
|
|
9
9
|
|
|
10
10
|
export interface NestedViewProps {
|
|
11
11
|
children?: ReactNode;
|
|
12
|
-
errorBoundary?: false | ((error: Error) => ReactNode);
|
|
12
|
+
errorBoundary?: false | ((error: Error, reset: () => void) => ReactNode);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -39,6 +39,7 @@ const NestedView = (props: NestedViewProps) => {
|
|
|
39
39
|
const onError = routerLayer?.onError;
|
|
40
40
|
const state = useRouterState();
|
|
41
41
|
const alepha = useAlepha();
|
|
42
|
+
const [boundaryKey, setBoundaryKey] = useState(0);
|
|
42
43
|
|
|
43
44
|
const [view, setView] = useState<ReactNode | undefined>(
|
|
44
45
|
state.layers[index]?.element,
|
|
@@ -147,7 +148,9 @@ const NestedView = (props: NestedViewProps) => {
|
|
|
147
148
|
|
|
148
149
|
if (props.errorBoundary) {
|
|
149
150
|
return (
|
|
150
|
-
<ErrorBoundary fallback={props.errorBoundary}>
|
|
151
|
+
<ErrorBoundary key={boundaryKey} fallback={props.errorBoundary}>
|
|
152
|
+
{element}
|
|
153
|
+
</ErrorBoundary>
|
|
151
154
|
);
|
|
152
155
|
}
|
|
153
156
|
|
|
@@ -161,7 +164,11 @@ const NestedView = (props: NestedViewProps) => {
|
|
|
161
164
|
return result as ReactNode;
|
|
162
165
|
};
|
|
163
166
|
|
|
164
|
-
return
|
|
167
|
+
return (
|
|
168
|
+
<ErrorBoundary key={boundaryKey} fallback={fallback}>
|
|
169
|
+
{element}
|
|
170
|
+
</ErrorBoundary>
|
|
171
|
+
);
|
|
165
172
|
};
|
|
166
173
|
|
|
167
174
|
export default memo(NestedView);
|
|
@@ -167,6 +167,40 @@ describe("$page browser tests", () => {
|
|
|
167
167
|
});
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
+
describe("redirect", () => {
|
|
171
|
+
it("should redirect to another page", async () => {
|
|
172
|
+
class App {
|
|
173
|
+
home = $page({
|
|
174
|
+
path: "/",
|
|
175
|
+
redirect: "/dashboard",
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
dashboard = $page({
|
|
179
|
+
path: "/dashboard",
|
|
180
|
+
component: () => <div data-testid="dashboard">Dashboard</div>,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
alepha = Alepha.create().with(AlephaReact).with(App);
|
|
185
|
+
await alepha.start();
|
|
186
|
+
|
|
187
|
+
const router = alepha.inject(ReactRouter);
|
|
188
|
+
|
|
189
|
+
await act(async () => {
|
|
190
|
+
await router.push("/");
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
await waitFor(() => {
|
|
194
|
+
expect(
|
|
195
|
+
document.querySelector('[data-testid="dashboard"]'),
|
|
196
|
+
).toBeDefined();
|
|
197
|
+
expect(
|
|
198
|
+
document.querySelector('[data-testid="dashboard"]')?.textContent,
|
|
199
|
+
).toBe("Dashboard");
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
170
204
|
describe("errorHandler", () => {
|
|
171
205
|
it("should handle errors and redirect", async () => {
|
|
172
206
|
let isAuthenticated = false;
|
|
@@ -649,6 +649,26 @@ describe("$page primitive tests", () => {
|
|
|
649
649
|
expect(rendered.html).toBe("Child received: from parent and from parent");
|
|
650
650
|
});
|
|
651
651
|
|
|
652
|
+
test("$page - redirect shorthand", async ({ expect }) => {
|
|
653
|
+
class App {
|
|
654
|
+
home = $page({
|
|
655
|
+
path: "/",
|
|
656
|
+
redirect: "/dashboard",
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
dashboard = $page({
|
|
660
|
+
path: "/dashboard",
|
|
661
|
+
component: () => "Dashboard",
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
const app = alepha.inject(App);
|
|
666
|
+
await alepha.start();
|
|
667
|
+
|
|
668
|
+
const rendered = await app.home.render();
|
|
669
|
+
expect(rendered.redirect).toBe("/dashboard");
|
|
670
|
+
});
|
|
671
|
+
|
|
652
672
|
test("$page - cache configuration without static", async ({ expect }) => {
|
|
653
673
|
class App {
|
|
654
674
|
cached = $page({
|
|
@@ -372,6 +372,30 @@ export interface PagePrimitiveOptions<
|
|
|
372
372
|
*/
|
|
373
373
|
head?: Head | ((props: TProps, previous?: Head) => Head);
|
|
374
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Redirect to another path when this page is matched.
|
|
377
|
+
*
|
|
378
|
+
* This is a shorthand for throwing a `Redirection` in the loader.
|
|
379
|
+
* The redirect is performed before any loader or component rendering.
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```ts
|
|
383
|
+
* home = $page({
|
|
384
|
+
* path: "/",
|
|
385
|
+
* redirect: "/dashboard",
|
|
386
|
+
* });
|
|
387
|
+
* ```
|
|
388
|
+
*/
|
|
389
|
+
redirect?: string;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Label for the page, used for navigation menus or breadcrumbs.
|
|
393
|
+
*
|
|
394
|
+
* This is optional and can be used by the application to display a user-friendly name for the page.
|
|
395
|
+
* It has no functional impact on routing or rendering.
|
|
396
|
+
*/
|
|
397
|
+
label?: string;
|
|
398
|
+
|
|
375
399
|
/**
|
|
376
400
|
* Source path for SSR module preloading.
|
|
377
401
|
*
|
|
@@ -5,6 +5,7 @@ import { type Route, RouterProvider } from "alepha/router";
|
|
|
5
5
|
import { ForbiddenError } from "alepha/server";
|
|
6
6
|
import { createElement, type ReactNode } from "react";
|
|
7
7
|
import NotFoundPage from "../components/NotFound.tsx";
|
|
8
|
+
import { Redirection } from "../errors/Redirection.ts";
|
|
8
9
|
import {
|
|
9
10
|
isPageRoute,
|
|
10
11
|
type PageRoute,
|
|
@@ -36,7 +37,7 @@ export class ReactBrowserRouterProvider extends RouterProvider<BrowserRoute> {
|
|
|
36
37
|
handler: async () => {
|
|
37
38
|
for (const page of this.pageApi.getPages()) {
|
|
38
39
|
// mount only if a view is provided
|
|
39
|
-
if (page.component || page.lazy) {
|
|
40
|
+
if (page.component || page.lazy || page.redirect) {
|
|
40
41
|
this.push({
|
|
41
42
|
path: page.match,
|
|
42
43
|
page,
|
|
@@ -120,10 +121,21 @@ export class ReactBrowserRouterProvider extends RouterProvider<BrowserRoute> {
|
|
|
120
121
|
await this.alepha.events.emit("react:transition:success", { state });
|
|
121
122
|
} catch (e) {
|
|
122
123
|
this.log.error("Transition has failed", e);
|
|
124
|
+
|
|
125
|
+
let element: ReactNode | undefined;
|
|
126
|
+
try {
|
|
127
|
+
const result = state.onError(e as Error, state);
|
|
128
|
+
if (result != null && !(result instanceof Redirection)) {
|
|
129
|
+
element = result as ReactNode;
|
|
130
|
+
}
|
|
131
|
+
} catch {
|
|
132
|
+
// error handler itself failed, fall through to default
|
|
133
|
+
}
|
|
134
|
+
|
|
123
135
|
state.layers = [
|
|
124
136
|
{
|
|
125
137
|
name: "error",
|
|
126
|
-
element: this.pageApi.renderError(e as Error),
|
|
138
|
+
element: element ?? this.pageApi.renderError(e as Error),
|
|
127
139
|
index: 0,
|
|
128
140
|
path: "/",
|
|
129
141
|
},
|