everything-dev 1.53.2 → 2.0.0-rc.0
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 +2 -11
- package/dist/_virtual/_rolldown/runtime.cjs +17 -2
- package/dist/_virtual/_rolldown/runtime.mjs +36 -0
- package/dist/api/auth-middleware.cjs +161 -0
- package/dist/api/auth-middleware.cjs.map +1 -0
- package/dist/api/auth-middleware.d.cts +69 -0
- package/dist/api/auth-middleware.d.mts +69 -0
- package/dist/api/auth-middleware.mjs +160 -0
- package/dist/api/auth-middleware.mjs.map +1 -0
- package/dist/api-contract.cjs +250 -62
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs +246 -65
- package/dist/api-contract.mjs.map +1 -1
- package/dist/app.cjs +99 -26
- package/dist/app.cjs.map +1 -1
- package/dist/app.d.cts +3 -0
- package/dist/app.d.mts +3 -0
- package/dist/app.mjs +100 -27
- package/dist/app.mjs.map +1 -1
- package/dist/auth-login.cjs +163 -0
- package/dist/auth-login.cjs.map +1 -0
- package/dist/auth-login.mjs +162 -0
- package/dist/auth-login.mjs.map +1 -0
- package/dist/auth-session.cjs +64 -0
- package/dist/auth-session.cjs.map +1 -0
- package/dist/auth-session.mjs +58 -0
- package/dist/auth-session.mjs.map +1 -0
- package/dist/auth-types-gen.cjs +0 -1
- package/dist/auth-types-gen.cjs.map +1 -1
- package/dist/build.cjs +37 -173
- package/dist/build.cjs.map +1 -1
- package/dist/build.mjs +37 -171
- package/dist/build.mjs.map +1 -1
- package/dist/bundle-cache.cjs +74 -0
- package/dist/bundle-cache.cjs.map +1 -0
- package/dist/bundle-cache.d.cts +27 -0
- package/dist/bundle-cache.d.mts +27 -0
- package/dist/bundle-cache.mjs +68 -0
- package/dist/bundle-cache.mjs.map +1 -0
- package/dist/bundle-fs-resolve.cjs +209 -0
- package/dist/bundle-fs-resolve.cjs.map +1 -0
- package/dist/bundle-fs-resolve.d.cts +76 -0
- package/dist/bundle-fs-resolve.d.mts +76 -0
- package/dist/bundle-fs-resolve.mjs +202 -0
- package/dist/bundle-fs-resolve.mjs.map +1 -0
- package/dist/cdn-deploy.cjs +126 -0
- package/dist/cdn-deploy.cjs.map +1 -0
- package/dist/cdn-deploy.mjs +124 -0
- package/dist/cdn-deploy.mjs.map +1 -0
- package/dist/cli/db-doctor.cjs +19 -19
- package/dist/cli/db-doctor.cjs.map +1 -1
- package/dist/cli/db-doctor.mjs +18 -18
- package/dist/cli/db-doctor.mjs.map +1 -1
- package/dist/cli/db-repair.cjs +9 -32
- package/dist/cli/db-repair.cjs.map +1 -1
- package/dist/cli/db-repair.mjs +9 -32
- package/dist/cli/db-repair.mjs.map +1 -1
- package/dist/cli/framework-version.cjs +7 -3
- package/dist/cli/framework-version.cjs.map +1 -1
- package/dist/cli/framework-version.mjs +7 -3
- package/dist/cli/framework-version.mjs.map +1 -1
- package/dist/cli/infra.cjs +159 -251
- package/dist/cli/infra.cjs.map +1 -1
- package/dist/cli/infra.mjs +154 -242
- package/dist/cli/infra.mjs.map +1 -1
- package/dist/cli/init.cjs +624 -196
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +61 -8
- package/dist/cli/init.d.mts +61 -8
- package/dist/cli/init.mjs +613 -194
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/parse.cjs +8 -7
- package/dist/cli/parse.cjs.map +1 -1
- package/dist/cli/parse.mjs +9 -7
- package/dist/cli/parse.mjs.map +1 -1
- package/dist/cli/prompts.cjs +14 -1
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs +14 -1
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/prune.cjs +220 -0
- package/dist/cli/prune.cjs.map +1 -0
- package/dist/cli/prune.mjs +220 -0
- package/dist/cli/prune.mjs.map +1 -0
- package/dist/cli/snapshot.cjs +2 -1
- package/dist/cli/snapshot.cjs.map +1 -1
- package/dist/cli/snapshot.mjs +2 -1
- package/dist/cli/snapshot.mjs.map +1 -1
- package/dist/cli/status.cjs +5 -4
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs +6 -5
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +156 -58
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +158 -63
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/timing.cjs +0 -1
- package/dist/cli/timing.cjs.map +1 -1
- package/dist/cli/upgrade.cjs +95 -69
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +97 -72
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli/utils/helpers.cjs.map +1 -1
- package/dist/cli.cjs +320 -72
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +316 -68
- package/dist/cli.mjs.map +1 -1
- package/dist/code-artifacts.cjs +76 -8
- package/dist/code-artifacts.cjs.map +1 -1
- package/dist/code-artifacts.mjs +76 -10
- package/dist/code-artifacts.mjs.map +1 -1
- package/dist/commands/build.cjs +65 -0
- package/dist/commands/build.cjs.map +1 -0
- package/dist/commands/build.mjs +65 -0
- package/dist/commands/build.mjs.map +1 -0
- package/dist/commands/config.cjs +77 -0
- package/dist/commands/config.cjs.map +1 -0
- package/dist/commands/config.d.cts +8 -0
- package/dist/commands/config.d.mts +8 -0
- package/dist/commands/config.mjs +74 -0
- package/dist/commands/config.mjs.map +1 -0
- package/dist/commands/db.cjs +107 -0
- package/dist/commands/db.cjs.map +1 -0
- package/dist/commands/db.mjs +107 -0
- package/dist/commands/db.mjs.map +1 -0
- package/dist/commands/deploy.cjs +336 -0
- package/dist/commands/deploy.cjs.map +1 -0
- package/dist/commands/deploy.mjs +334 -0
- package/dist/commands/deploy.mjs.map +1 -0
- package/dist/commands/dev.cjs +75 -0
- package/dist/commands/dev.cjs.map +1 -0
- package/dist/commands/dev.mjs +73 -0
- package/dist/commands/dev.mjs.map +1 -0
- package/dist/commands/init.cjs +234 -0
- package/dist/commands/init.cjs.map +1 -0
- package/dist/commands/init.mjs +231 -0
- package/dist/commands/init.mjs.map +1 -0
- package/dist/commands/keys.cjs +255 -0
- package/dist/commands/keys.cjs.map +1 -0
- package/dist/commands/keys.mjs +253 -0
- package/dist/commands/keys.mjs.map +1 -0
- package/dist/commands/ops.cjs +199 -0
- package/dist/commands/ops.cjs.map +1 -0
- package/dist/commands/ops.mjs +197 -0
- package/dist/commands/ops.mjs.map +1 -0
- package/dist/commands/plugins.cjs +211 -0
- package/dist/commands/plugins.cjs.map +1 -0
- package/dist/commands/plugins.mjs +211 -0
- package/dist/commands/plugins.mjs.map +1 -0
- package/dist/commands/shared.cjs +8 -0
- package/dist/commands/shared.cjs.map +1 -0
- package/dist/commands/shared.d.cts +6 -0
- package/dist/commands/shared.d.mts +6 -0
- package/dist/commands/shared.mjs +8 -0
- package/dist/commands/shared.mjs.map +1 -0
- package/dist/commands/upgrade.cjs +325 -0
- package/dist/commands/upgrade.cjs.map +1 -0
- package/dist/commands/upgrade.mjs +323 -0
- package/dist/commands/upgrade.mjs.map +1 -0
- package/dist/components/dev-render.cjs +340 -0
- package/dist/components/dev-render.cjs.map +1 -0
- package/dist/components/dev-render.mjs +332 -0
- package/dist/components/dev-render.mjs.map +1 -0
- package/dist/config.cjs +460 -221
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +491 -48
- package/dist/config.d.mts +491 -48
- package/dist/config.mjs +439 -212
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +327 -50
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +1951 -1062
- package/dist/contract.d.mts +1951 -1062
- package/dist/contract.meta.cjs +107 -12
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +166 -8
- package/dist/contract.meta.d.mts +166 -8
- package/dist/contract.meta.mjs +107 -11
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +580 -327
- package/dist/contract.mjs.map +1 -1
- package/dist/dag.cjs +5 -3
- package/dist/dag.cjs.map +1 -1
- package/dist/dag.mjs +6 -3
- package/dist/dag.mjs.map +1 -1
- package/dist/db/binding.cjs +80 -0
- package/dist/db/binding.cjs.map +1 -0
- package/dist/db/binding.d.cts +39 -0
- package/dist/db/binding.d.mts +39 -0
- package/dist/db/binding.mjs +78 -0
- package/dist/db/binding.mjs.map +1 -0
- package/dist/db/bindings.cjs +78 -0
- package/dist/db/bindings.cjs.map +1 -0
- package/dist/db/bindings.d.cts +34 -0
- package/dist/db/bindings.d.mts +34 -0
- package/dist/db/bindings.mjs +76 -0
- package/dist/db/bindings.mjs.map +1 -0
- package/dist/db/core.cjs +204 -0
- package/dist/db/core.cjs.map +1 -0
- package/dist/db/core.d.cts +69 -0
- package/dist/db/core.d.mts +69 -0
- package/dist/db/core.mjs +192 -0
- package/dist/db/core.mjs.map +1 -0
- package/dist/db/driver.cjs +167 -0
- package/dist/db/driver.cjs.map +1 -0
- package/dist/db/driver.d.cts +50 -0
- package/dist/db/driver.d.mts +50 -0
- package/dist/db/driver.mjs +165 -0
- package/dist/db/driver.mjs.map +1 -0
- package/dist/db/drizzle-kit.cjs +177 -0
- package/dist/db/drizzle-kit.cjs.map +1 -0
- package/dist/db/drizzle-kit.d.cts +25 -0
- package/dist/db/drizzle-kit.d.mts +25 -0
- package/dist/db/drizzle-kit.mjs +175 -0
- package/dist/db/drizzle-kit.mjs.map +1 -0
- package/dist/db/errors.cjs +27 -0
- package/dist/db/errors.cjs.map +1 -0
- package/dist/db/errors.d.cts +16 -0
- package/dist/db/errors.d.mts +16 -0
- package/dist/db/errors.mjs +26 -0
- package/dist/db/errors.mjs.map +1 -0
- package/dist/db/identity.cjs +55 -0
- package/dist/db/identity.cjs.map +1 -0
- package/dist/db/identity.d.cts +40 -0
- package/dist/db/identity.d.mts +40 -0
- package/dist/db/identity.mjs +53 -0
- package/dist/db/identity.mjs.map +1 -0
- package/dist/db/index.cjs +43 -0
- package/dist/db/index.d.cts +9 -0
- package/dist/db/index.d.mts +9 -0
- package/dist/db/index.mjs +10 -0
- package/dist/db/run-migrations.cjs +343 -0
- package/dist/db/run-migrations.cjs.map +1 -0
- package/dist/db/run-migrations.d.cts +87 -0
- package/dist/db/run-migrations.d.mts +87 -0
- package/dist/db/run-migrations.mjs +341 -0
- package/dist/db/run-migrations.mjs.map +1 -0
- package/dist/delegate-signer.cjs +85 -0
- package/dist/delegate-signer.cjs.map +1 -0
- package/dist/delegate-signer.mjs +84 -0
- package/dist/delegate-signer.mjs.map +1 -0
- package/dist/deploy-diff.cjs +119 -0
- package/dist/deploy-diff.cjs.map +1 -0
- package/dist/deploy-diff.mjs +109 -0
- package/dist/deploy-diff.mjs.map +1 -0
- package/dist/descriptor/constructors.cjs +49 -0
- package/dist/descriptor/constructors.cjs.map +1 -0
- package/dist/descriptor/constructors.d.cts +27 -0
- package/dist/descriptor/constructors.d.mts +27 -0
- package/dist/descriptor/constructors.mjs +45 -0
- package/dist/descriptor/constructors.mjs.map +1 -0
- package/dist/descriptor/index.cjs +24 -0
- package/dist/descriptor/index.d.cts +5 -0
- package/dist/descriptor/index.d.mts +5 -0
- package/dist/descriptor/index.mjs +6 -0
- package/dist/descriptor/resolve.cjs +258 -0
- package/dist/descriptor/resolve.cjs.map +1 -0
- package/dist/descriptor/resolve.d.cts +50 -0
- package/dist/descriptor/resolve.d.mts +50 -0
- package/dist/descriptor/resolve.mjs +252 -0
- package/dist/descriptor/resolve.mjs.map +1 -0
- package/dist/descriptor/schema.cjs +109 -0
- package/dist/descriptor/schema.cjs.map +1 -0
- package/dist/descriptor/schema.d.cts +217 -0
- package/dist/descriptor/schema.d.mts +217 -0
- package/dist/descriptor/schema.mjs +102 -0
- package/dist/descriptor/schema.mjs.map +1 -0
- package/dist/descriptor/serialize.cjs +45 -0
- package/dist/descriptor/serialize.cjs.map +1 -0
- package/dist/descriptor/serialize.d.cts +7 -0
- package/dist/descriptor/serialize.d.mts +7 -0
- package/dist/descriptor/serialize.mjs +45 -0
- package/dist/descriptor/serialize.mjs.map +1 -0
- package/dist/dev-log-pipeline.cjs +273 -0
- package/dist/dev-log-pipeline.cjs.map +1 -0
- package/dist/dev-log-pipeline.mjs +267 -0
- package/dist/dev-log-pipeline.mjs.map +1 -0
- package/dist/dev-logs.cjs +39 -8
- package/dist/dev-logs.cjs.map +1 -1
- package/dist/dev-logs.mjs +37 -9
- package/dist/dev-logs.mjs.map +1 -1
- package/dist/dev-program.cjs +405 -0
- package/dist/dev-program.cjs.map +1 -0
- package/dist/dev-program.d.cts +10 -0
- package/dist/dev-program.d.mts +10 -0
- package/dist/dev-program.mjs +395 -0
- package/dist/dev-program.mjs.map +1 -0
- package/dist/dev-session-data.d.cts +27 -0
- package/dist/dev-session-data.d.mts +27 -0
- package/dist/dev-session.cjs +178 -105
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +180 -105
- package/dist/dev-session.mjs.map +1 -1
- package/dist/env/process-env.cjs +16 -0
- package/dist/env/process-env.cjs.map +1 -0
- package/dist/env/process-env.mjs +13 -0
- package/dist/env/process-env.mjs.map +1 -0
- package/dist/env/project-env.cjs +144 -0
- package/dist/env/project-env.cjs.map +1 -0
- package/dist/env/project-env.d.cts +1 -0
- package/dist/env/project-env.d.mts +1 -0
- package/dist/env/project-env.mjs +132 -0
- package/dist/env/project-env.mjs.map +1 -0
- package/dist/fastkv.cjs +59 -12
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.d.cts +42 -6
- package/dist/fastkv.d.mts +42 -6
- package/dist/fastkv.mjs +58 -13
- package/dist/fastkv.mjs.map +1 -1
- package/dist/fingerprint.cjs +57 -0
- package/dist/fingerprint.cjs.map +1 -0
- package/dist/fingerprint.d.cts +14 -0
- package/dist/fingerprint.d.mts +14 -0
- package/dist/fingerprint.mjs +55 -0
- package/dist/fingerprint.mjs.map +1 -0
- package/dist/http-client.cjs +17 -17
- package/dist/http-client.cjs.map +1 -1
- package/dist/http-client.mjs +17 -17
- package/dist/http-client.mjs.map +1 -1
- package/dist/image-deploy.cjs +186 -0
- package/dist/image-deploy.cjs.map +1 -0
- package/dist/image-deploy.mjs +182 -0
- package/dist/image-deploy.mjs.map +1 -0
- package/dist/index.cjs +66 -18
- package/dist/index.d.cts +8 -7
- package/dist/index.d.mts +8 -7
- package/dist/index.mjs +6 -5
- package/dist/infra/docker.cjs +77 -0
- package/dist/infra/docker.cjs.map +1 -0
- package/dist/infra/docker.d.cts +10 -0
- package/dist/infra/docker.d.mts +10 -0
- package/dist/infra/docker.mjs +69 -0
- package/dist/infra/docker.mjs.map +1 -0
- package/dist/infra/materializer.cjs +74 -0
- package/dist/infra/materializer.cjs.map +1 -0
- package/dist/infra/materializer.mjs +70 -0
- package/dist/infra/materializer.mjs.map +1 -0
- package/dist/infra/planner.cjs +135 -103
- package/dist/infra/planner.cjs.map +1 -1
- package/dist/infra/planner.mjs +137 -104
- package/dist/infra/planner.mjs.map +1 -1
- package/dist/infra/port-ownership.cjs +57 -0
- package/dist/infra/port-ownership.cjs.map +1 -0
- package/dist/infra/port-ownership.mjs +57 -0
- package/dist/infra/port-ownership.mjs.map +1 -0
- package/dist/infra/preflight.cjs +45 -33
- package/dist/infra/preflight.cjs.map +1 -1
- package/dist/infra/preflight.d.cts +1 -0
- package/dist/infra/preflight.d.mts +1 -0
- package/dist/infra/preflight.mjs +46 -34
- package/dist/infra/preflight.mjs.map +1 -1
- package/dist/infra/types.cjs.map +1 -1
- package/dist/infra/types.d.cts +2 -0
- package/dist/infra/types.d.mts +2 -0
- package/dist/infra/types.mjs.map +1 -1
- package/dist/integrity.cjs +50 -61
- package/dist/integrity.cjs.map +1 -1
- package/dist/integrity.d.cts +16 -10
- package/dist/integrity.d.mts +16 -10
- package/dist/integrity.mjs +50 -59
- package/dist/integrity.mjs.map +1 -1
- package/dist/internal/manifest-normalizer.cjs +8 -2
- package/dist/internal/manifest-normalizer.cjs.map +1 -1
- package/dist/internal/manifest-normalizer.mjs +9 -3
- package/dist/internal/manifest-normalizer.mjs.map +1 -1
- package/dist/merge.cjs +19 -1
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.d.cts +1 -1
- package/dist/merge.d.mts +1 -1
- package/dist/merge.mjs +19 -2
- package/dist/merge.mjs.map +1 -1
- package/dist/mf.cjs +190 -3
- package/dist/mf.cjs.map +1 -1
- package/dist/mf.d.cts +24 -2
- package/dist/mf.d.mts +24 -2
- package/dist/mf.mjs +189 -4
- package/dist/mf.mjs.map +1 -1
- package/dist/near-cli.cjs +59 -91
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs +58 -90
- package/dist/near-cli.mjs.map +1 -1
- package/dist/near-signer.cjs +73 -0
- package/dist/near-signer.cjs.map +1 -0
- package/dist/near-signer.mjs +70 -0
- package/dist/near-signer.mjs.map +1 -0
- package/dist/network.cjs +0 -1
- package/dist/network.cjs.map +1 -1
- package/dist/orchestrator.cjs +256 -87
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +248 -87
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/platform-deploy.cjs +81 -0
- package/dist/platform-deploy.cjs.map +1 -0
- package/dist/platform-deploy.mjs +80 -0
- package/dist/platform-deploy.mjs.map +1 -0
- package/dist/plugin.cjs +54 -1389
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +6 -896
- package/dist/plugin.d.mts +6 -896
- package/dist/plugin.mjs +53 -1387
- package/dist/plugin.mjs.map +1 -1
- package/dist/process-kill.cjs +44 -0
- package/dist/process-kill.cjs.map +1 -0
- package/dist/process-kill.mjs +43 -0
- package/dist/process-kill.mjs.map +1 -0
- package/dist/process-registry.cjs +64 -9
- package/dist/process-registry.cjs.map +1 -1
- package/dist/process-registry.mjs +61 -10
- package/dist/process-registry.mjs.map +1 -1
- package/dist/progress.cjs +45 -0
- package/dist/progress.cjs.map +1 -0
- package/dist/progress.d.cts +13 -0
- package/dist/progress.d.mts +13 -0
- package/dist/progress.mjs +42 -0
- package/dist/progress.mjs.map +1 -0
- package/dist/publish.cjs +513 -79
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +515 -82
- package/dist/publish.mjs.map +1 -1
- package/dist/registry-use.cjs +41 -0
- package/dist/registry-use.cjs.map +1 -0
- package/dist/registry-use.mjs +40 -0
- package/dist/registry-use.mjs.map +1 -0
- package/dist/resolution/session.cjs +335 -0
- package/dist/resolution/session.cjs.map +1 -0
- package/dist/resolution/session.d.cts +105 -0
- package/dist/resolution/session.d.mts +105 -0
- package/dist/resolution/session.mjs +331 -0
- package/dist/resolution/session.mjs.map +1 -0
- package/dist/rollback.cjs +131 -0
- package/dist/rollback.cjs.map +1 -0
- package/dist/rollback.mjs +128 -0
- package/dist/rollback.mjs.map +1 -0
- package/dist/sdk.cjs +7 -7
- package/dist/sdk.d.cts +3 -3
- package/dist/sdk.d.mts +3 -3
- package/dist/sdk.mjs +2 -2
- package/dist/service-descriptor.cjs +67 -34
- package/dist/service-descriptor.cjs.map +1 -1
- package/dist/service-descriptor.d.cts +4 -1
- package/dist/service-descriptor.d.mts +3 -0
- package/dist/service-descriptor.mjs +63 -35
- package/dist/service-descriptor.mjs.map +1 -1
- package/dist/shared-deps.cjs +17 -16
- package/dist/shared-deps.cjs.map +1 -1
- package/dist/shared-deps.mjs +17 -16
- package/dist/shared-deps.mjs.map +1 -1
- package/dist/start-config-source.cjs +24 -0
- package/dist/start-config-source.cjs.map +1 -0
- package/dist/start-config-source.d.cts +29 -0
- package/dist/start-config-source.d.mts +29 -0
- package/dist/start-config-source.mjs +22 -0
- package/dist/start-config-source.mjs.map +1 -0
- package/dist/storage-upload.cjs +145 -0
- package/dist/storage-upload.cjs.map +1 -0
- package/dist/storage-upload.mjs +143 -0
- package/dist/storage-upload.mjs.map +1 -0
- package/dist/types.cjs +126 -20
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +867 -585
- package/dist/types.d.mts +867 -585
- package/dist/types.mjs +307 -208
- package/dist/types.mjs.map +1 -1
- package/dist/ui/api.cjs +105 -0
- package/dist/ui/api.cjs.map +1 -0
- package/dist/ui/api.d.cts +31 -0
- package/dist/ui/api.d.mts +31 -0
- package/dist/ui/api.mjs +99 -0
- package/dist/ui/api.mjs.map +1 -0
- package/dist/ui/auth-guards.cjs +50 -0
- package/dist/ui/auth-guards.cjs.map +1 -0
- package/dist/ui/auth-guards.d.cts +39 -0
- package/dist/ui/auth-guards.d.mts +39 -0
- package/dist/ui/auth-guards.mjs +48 -0
- package/dist/ui/auth-guards.mjs.map +1 -0
- package/dist/ui/auth.cjs +197 -0
- package/dist/ui/auth.cjs.map +1 -0
- package/dist/ui/auth.d.cts +56 -0
- package/dist/ui/auth.d.mts +56 -0
- package/dist/ui/auth.mjs +179 -0
- package/dist/ui/auth.mjs.map +1 -0
- package/dist/ui/entry.cjs +16 -0
- package/dist/ui/entry.cjs.map +1 -0
- package/dist/ui/entry.d.cts +12 -0
- package/dist/ui/entry.d.mts +12 -0
- package/dist/ui/entry.mjs +15 -0
- package/dist/ui/entry.mjs.map +1 -0
- package/dist/ui/head.cjs +14 -7
- package/dist/ui/head.cjs.map +1 -1
- package/dist/ui/head.mjs +15 -7
- package/dist/ui/head.mjs.map +1 -1
- package/dist/ui/hydrate.cjs +265 -0
- package/dist/ui/hydrate.cjs.map +1 -0
- package/dist/ui/hydrate.d.cts +48 -0
- package/dist/ui/hydrate.d.mts +48 -0
- package/dist/ui/hydrate.mjs +263 -0
- package/dist/ui/hydrate.mjs.map +1 -0
- package/dist/ui/i18n.cjs +153 -0
- package/dist/ui/i18n.cjs.map +1 -0
- package/dist/ui/i18n.d.cts +29 -0
- package/dist/ui/i18n.d.mts +29 -0
- package/dist/ui/i18n.mjs +140 -0
- package/dist/ui/i18n.mjs.map +1 -0
- package/dist/ui/index.cjs +19 -1
- package/dist/ui/index.d.cts +6 -3
- package/dist/ui/index.d.mts +6 -3
- package/dist/ui/index.mjs +5 -2
- package/dist/ui/locale.cjs +53 -0
- package/dist/ui/locale.cjs.map +1 -0
- package/dist/ui/locale.d.cts +18 -0
- package/dist/ui/locale.d.mts +18 -0
- package/dist/ui/locale.mjs +49 -0
- package/dist/ui/locale.mjs.map +1 -0
- package/dist/ui/manifest/index.cjs +25 -0
- package/dist/ui/manifest/index.cjs.map +1 -0
- package/dist/ui/manifest/index.d.cts +9 -0
- package/dist/ui/manifest/index.d.mts +9 -0
- package/dist/ui/manifest/index.mjs +13 -0
- package/dist/ui/manifest/index.mjs.map +1 -0
- package/dist/ui/manifest-generator.cjs +8 -0
- package/dist/ui/manifest-generator.d.cts +1 -0
- package/dist/ui/manifest-generator.d.mts +1 -0
- package/dist/ui/manifest-generator.mjs +3 -0
- package/dist/ui/message-catalogs.cjs +8 -0
- package/dist/ui/message-catalogs.cjs.map +1 -0
- package/dist/ui/message-catalogs.d.cts +5 -0
- package/dist/ui/message-catalogs.d.mts +5 -0
- package/dist/ui/message-catalogs.mjs +8 -0
- package/dist/ui/message-catalogs.mjs.map +1 -0
- package/dist/ui/metadata.cjs +0 -1
- package/dist/ui/metadata.cjs.map +1 -1
- package/dist/ui/metadata.d.cts +1 -1
- package/dist/ui/metadata.d.mts +1 -1
- package/dist/ui/plugin-path.cjs +37 -0
- package/dist/ui/plugin-path.cjs.map +1 -0
- package/dist/ui/plugin-path.d.cts +25 -0
- package/dist/ui/plugin-path.d.mts +25 -0
- package/dist/ui/plugin-path.mjs +35 -0
- package/dist/ui/plugin-path.mjs.map +1 -0
- package/dist/ui/router-client.cjs +61 -0
- package/dist/ui/router-client.cjs.map +1 -0
- package/dist/ui/router-client.d.cts +20 -0
- package/dist/ui/router-client.d.mts +20 -0
- package/dist/ui/router-client.mjs +60 -0
- package/dist/ui/router-client.mjs.map +1 -0
- package/dist/ui/router-defaults.cjs +48 -0
- package/dist/ui/router-defaults.cjs.map +1 -0
- package/dist/ui/router-defaults.d.cts +8 -0
- package/dist/ui/router-defaults.d.mts +8 -0
- package/dist/ui/router-defaults.mjs +45 -0
- package/dist/ui/router-defaults.mjs.map +1 -0
- package/dist/ui/router-error.cjs +70 -0
- package/dist/ui/router-error.cjs.map +1 -0
- package/dist/ui/router-error.d.cts +19 -0
- package/dist/ui/router-error.d.mts +19 -0
- package/dist/ui/router-error.mjs +69 -0
- package/dist/ui/router-error.mjs.map +1 -0
- package/dist/ui/router-server.cjs +153 -0
- package/dist/ui/router-server.cjs.map +1 -0
- package/dist/ui/router-server.d.cts +38 -0
- package/dist/ui/router-server.d.mts +38 -0
- package/dist/ui/router-server.mjs +152 -0
- package/dist/ui/router-server.mjs.map +1 -0
- package/dist/ui/router.cjs +4 -16
- package/dist/ui/router.cjs.map +1 -1
- package/dist/ui/router.mjs +4 -15
- package/dist/ui/router.mjs.map +1 -1
- package/dist/ui/runtime.cjs +5 -1
- package/dist/ui/runtime.cjs.map +1 -1
- package/dist/ui/runtime.d.cts +2 -1
- package/dist/ui/runtime.d.mts +2 -1
- package/dist/ui/runtime.mjs +5 -1
- package/dist/ui/runtime.mjs.map +1 -1
- package/dist/ui/slot.cjs +34 -0
- package/dist/ui/slot.cjs.map +1 -0
- package/dist/ui/slot.d.cts +43 -0
- package/dist/ui/slot.d.mts +43 -0
- package/dist/ui/slot.mjs +34 -0
- package/dist/ui/slot.mjs.map +1 -0
- package/dist/ui/tenant.cjs +300 -0
- package/dist/ui/tenant.cjs.map +1 -0
- package/dist/ui/tenant.d.cts +122 -0
- package/dist/ui/tenant.d.mts +122 -0
- package/dist/ui/tenant.mjs +279 -0
- package/dist/ui/tenant.mjs.map +1 -0
- package/dist/ui/types.d.cts +32 -2
- package/dist/ui/types.d.mts +32 -2
- package/dist/ui/version-check.cjs +47 -0
- package/dist/ui/version-check.cjs.map +1 -0
- package/dist/ui/version-check.d.cts +23 -0
- package/dist/ui/version-check.d.mts +23 -0
- package/dist/ui/version-check.mjs +46 -0
- package/dist/ui/version-check.mjs.map +1 -0
- package/dist/utils/banner.cjs +2 -2
- package/dist/utils/banner.cjs.map +1 -1
- package/dist/utils/banner.mjs +2 -2
- package/dist/utils/banner.mjs.map +1 -1
- package/dist/utils/linkify.cjs +1 -1
- package/dist/utils/linkify.cjs.map +1 -1
- package/dist/utils/linkify.mjs +1 -0
- package/dist/utils/linkify.mjs.map +1 -1
- package/dist/utils/run.cjs +6 -6
- package/dist/utils/run.cjs.map +1 -1
- package/dist/utils/run.mjs +6 -6
- package/dist/utils/run.mjs.map +1 -1
- package/dist/utils/save-config.cjs +12 -0
- package/dist/utils/save-config.cjs.map +1 -1
- package/dist/utils/save-config.mjs +12 -0
- package/dist/utils/save-config.mjs.map +1 -1
- package/dist/utils/snapshot-hash.cjs +10 -0
- package/dist/utils/snapshot-hash.cjs.map +1 -0
- package/dist/utils/snapshot-hash.mjs +10 -0
- package/dist/utils/snapshot-hash.mjs.map +1 -0
- package/dist/utils/string.cjs +0 -1
- package/dist/utils/string.cjs.map +1 -1
- package/dist/utils/theme.cjs +30 -12
- package/dist/utils/theme.cjs.map +1 -1
- package/dist/utils/theme.mjs +30 -11
- package/dist/utils/theme.mjs.map +1 -1
- package/dist/version-manifest-deploy.cjs +50 -0
- package/dist/version-manifest-deploy.cjs.map +1 -0
- package/dist/version-manifest-deploy.mjs +49 -0
- package/dist/version-manifest-deploy.mjs.map +1 -0
- package/dist/version-manifest-resolve.cjs +42 -0
- package/dist/version-manifest-resolve.cjs.map +1 -0
- package/dist/version-manifest-resolve.d.cts +38 -0
- package/dist/version-manifest-resolve.d.mts +38 -0
- package/dist/version-manifest-resolve.mjs +40 -0
- package/dist/version-manifest-resolve.mjs.map +1 -0
- package/dist/version-status.cjs +18 -0
- package/dist/version-status.cjs.map +1 -0
- package/dist/version-status.d.cts +22 -0
- package/dist/version-status.d.mts +22 -0
- package/dist/version-status.mjs +17 -0
- package/dist/version-status.mjs.map +1 -0
- package/dist/workspace-catalog.cjs +53 -0
- package/dist/workspace-catalog.cjs.map +1 -0
- package/dist/workspace-catalog.mjs +51 -0
- package/dist/workspace-catalog.mjs.map +1 -0
- package/dist/workspace.cjs +237 -0
- package/dist/workspace.cjs.map +1 -0
- package/dist/workspace.mjs +233 -0
- package/dist/workspace.mjs.map +1 -0
- package/package.json +179 -27
- package/skills/add-a-route/SKILL.md +132 -0
- package/skills/api-and-auth/SKILL.md +87 -21
- package/skills/api-and-auth/references/middleware.md +1 -1
- package/skills/cli-reference/SKILL.md +48 -21
- package/skills/code-style/SKILL.md +8 -0
- package/skills/dev-workflow/SKILL.md +50 -26
- package/skills/extends-config/SKILL.md +31 -19
- package/skills/init-upgrade/SKILL.md +29 -16
- package/skills/plugin-development/SKILL.md +46 -112
- package/skills/plugin-development/references/database.md +82 -0
- package/skills/plugin-development/references/request-context.md +67 -0
- package/skills/publish-sync/SKILL.md +99 -22
- package/skills/registry/SKILL.md +82 -0
- package/skills/super-app/SKILL.md +25 -15
- package/skills/talk-to-the-app/SKILL.md +138 -0
- package/skills/ui-integration/SKILL.md +93 -11
- package/dist/cli/db-studio.cjs +0 -131
- package/dist/cli/db-studio.cjs.map +0 -1
- package/dist/cli/db-studio.mjs +0 -127
- package/dist/cli/db-studio.mjs.map +0 -1
- package/dist/cli/init.d.cts.map +0 -1
- package/dist/cli/init.d.mts.map +0 -1
- package/dist/components/dev-view.cjs +0 -309
- package/dist/components/dev-view.cjs.map +0 -1
- package/dist/components/dev-view.mjs +0 -309
- package/dist/components/dev-view.mjs.map +0 -1
- package/dist/components/streaming-view.cjs +0 -134
- package/dist/components/streaming-view.cjs.map +0 -1
- package/dist/components/streaming-view.mjs +0 -132
- package/dist/components/streaming-view.mjs.map +0 -1
- package/dist/config.d.cts.map +0 -1
- package/dist/config.d.mts.map +0 -1
- package/dist/contract.d.cts.map +0 -1
- package/dist/contract.d.mts.map +0 -1
- package/dist/contract.meta.d.cts.map +0 -1
- package/dist/contract.meta.d.mts.map +0 -1
- package/dist/dag.d.cts.map +0 -1
- package/dist/dag.d.mts.map +0 -1
- package/dist/db.cjs +0 -81
- package/dist/db.cjs.map +0 -1
- package/dist/db.d.cts +0 -30
- package/dist/db.d.cts.map +0 -1
- package/dist/db.d.mts +0 -30
- package/dist/db.d.mts.map +0 -1
- package/dist/db.mjs +0 -75
- package/dist/db.mjs.map +0 -1
- package/dist/fastkv.d.cts.map +0 -1
- package/dist/fastkv.d.mts.map +0 -1
- package/dist/integrity.d.cts.map +0 -1
- package/dist/integrity.d.mts.map +0 -1
- package/dist/merge.d.cts.map +0 -1
- package/dist/merge.d.mts.map +0 -1
- package/dist/mf.d.cts.map +0 -1
- package/dist/mf.d.mts.map +0 -1
- package/dist/plugin.d.cts.map +0 -1
- package/dist/plugin.d.mts.map +0 -1
- package/dist/service-descriptor.d.cts.map +0 -1
- package/dist/service-descriptor.d.mts.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/dist/ui/head.d.cts.map +0 -1
- package/dist/ui/head.d.mts.map +0 -1
- package/dist/ui/metadata.d.cts.map +0 -1
- package/dist/ui/metadata.d.mts.map +0 -1
- package/dist/ui/router.d.cts.map +0 -1
- package/dist/ui/router.d.mts.map +0 -1
- package/dist/ui/runtime.d.cts.map +0 -1
- package/dist/ui/runtime.d.mts.map +0 -1
- package/dist/ui/types.d.cts.map +0 -1
- package/dist/ui/types.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant.cjs","names":["getRuntimeConfig","z"],"sources":["../../src/ui/tenant.ts"],"sourcesContent":["/**\n * Tenant helpers shared by every ui workspace.\n *\n * Two halves of the tenant surface live here:\n * - origin construction (`buildTenantUrl`, `tenantLabel`, `gatewayForAccount`)\n * - the pure helpers for the org node-config editor: a validated draft of the\n * fields a tenant may customize in its published bos.config.json, prefilled\n * from the currently published config, diffed against it, and an in-browser\n * sha384 preflight so a wrong UI bundle cannot brick the tenant site.\n */\n\nimport { z } from \"zod\";\nimport type { ClientRuntimeConfig } from \"../types\";\nimport { UI_REMOTE_ENTRY_FILENAME, UI_REMOTE_SERVER_ENTRY_FILENAME } from \"./manifest\";\nimport { getRuntimeConfig } from \"./runtime\";\n\nconst LOCALHOST_SUFFIX = \".localhost\";\n\nexport function isLocalHostname(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return (\n normalized === \"localhost\" ||\n normalized === \"127.0.0.1\" ||\n normalized === \"[::1]\" ||\n normalized.endsWith(LOCALHOST_SUFFIX)\n );\n}\n\n/** Strips a `<label>.<gatewayId>` hostname (or a bare label) down to its label. */\nexport function tenantLabel(hostnameOrLabel: string, gatewayId?: string): string {\n const normalized = hostnameOrLabel.trim().toLowerCase().replace(/\\/+$/, \"\");\n if (!normalized) return \"\";\n const gateway = gatewayId?.trim().toLowerCase();\n if (gateway && normalized.endsWith(`.${gateway}`)) {\n return normalized.slice(0, -(gateway.length + 1));\n }\n if (normalized.endsWith(LOCALHOST_SUFFIX)) {\n return normalized.slice(0, -LOCALHOST_SUFFIX.length);\n }\n return normalized.split(\".\")[0] ?? \"\";\n}\n\nexport interface BuildTenantUrlOptions {\n /** Current browser origin hostname. Defaults to `window.location.hostname`. */\n currentHostname?: string;\n /** Current browser origin port. Defaults to `window.location.port`. */\n currentPort?: string;\n /** Appended to the origin, e.g. `/stake`. */\n path?: string;\n}\n\n/**\n * Builds the absolute origin for a tenant, dev-aware.\n *\n * `buildTenantUrl(\"chicago\", \"citynode.app\")`\n * -> `https://chicago.citynode.app` in production\n * -> `http://chicago.localhost:3000` when served from localhost\n */\nexport function buildTenantUrl(\n hostnameOrLabel: string,\n gatewayId: string,\n options: BuildTenantUrlOptions = {},\n): string | null {\n const label = tenantLabel(hostnameOrLabel, gatewayId);\n if (!label) return null;\n\n const path = options.path ?? \"\";\n const currentHostname =\n options.currentHostname ??\n (typeof window === \"undefined\" ? undefined : window.location.hostname);\n\n if (currentHostname && isLocalHostname(currentHostname)) {\n const currentPort =\n options.currentPort ?? (typeof window === \"undefined\" ? \"\" : window.location.port);\n const port = currentPort ? `:${currentPort}` : \"\";\n return `http://${label}${LOCALHOST_SUFFIX}${port}${path}`;\n }\n\n const gateway = gatewayId.trim().toLowerCase();\n if (!gateway) return null;\n return `https://${label}.${gateway}${path}`;\n}\n\n/**\n * The gateway a slug should publish under for the given owner account,\n * derived from the runtime config instead of hardcoded per-network domains.\n *\n * When the account lives on the same network as the runtime, the current\n * runtime's gateway id is the answer. When the networks differ, the runtime\n * config carries no gateway for that other network, so null is returned and\n * the caller surfaces it rather than guessing a domain.\n */\nexport function gatewayForAccount(\n accountId: string,\n config: Pick<ClientRuntimeConfig, \"networkId\" | \"runtime\"> = getRuntimeConfig(),\n): string | null {\n const gatewayId = config.runtime?.gatewayId;\n if (!gatewayId) return null;\n const testnetAccount = accountId.trim().toLowerCase().endsWith(\".testnet\");\n return testnetAccount === (config.networkId === \"testnet\") ? gatewayId : null;\n}\n\nexport interface TenantUiOverride {\n production: string;\n /** direct entry SRI — only for genuinely fixed-name bundles without a pin */\n integrity?: string;\n /** version-manifest pin — the deploy unit for hashed, atomic deploys */\n pin?: { manifest: string; integrity: string };\n ssr?: string;\n ssrIntegrity?: string;\n}\n\nexport const INTEGRITY_PATTERN = /^sha384-[A-Za-z0-9+/=]+$/;\n\nexport const defaultTenantConfigDraftMessages = {\n url: \"must be a valid URL\",\n integrity: \"must look like sha384-… (base64)\",\n manifest: \"must look like versions/<version-id>.json\",\n title: \"title is required\",\n description: \"description is required\",\n uiPair: \"a UI bundle needs both its URL and its integrity (direct hash or manifest pin)\",\n integrityMode:\n \"choose one integrity mode — a direct entry hash or a version-manifest pin, not both\",\n pinPair: \"a version-manifest pin needs both the manifest filename and its integrity\",\n ssrPair: \"an SSR bundle needs both its URL and its integrity hash\",\n};\n\nexport function createTenantConfigDraftSchema(\n messages: Partial<typeof defaultTenantConfigDraftMessages> = {},\n) {\n const copy = { ...defaultTenantConfigDraftMessages, ...messages };\n const optionalUrl = z\n .string()\n .trim()\n .url(copy.url)\n .or(z.literal(\"\"))\n .transform((value) => value.trim());\n const optionalIntegrity = z\n .string()\n .trim()\n .regex(INTEGRITY_PATTERN, copy.integrity)\n .or(z.literal(\"\"));\n const optionalManifestName = z\n .string()\n .trim()\n .regex(/^versions\\/[0-9a-f]{16}\\.json$/, copy.manifest)\n .or(z.literal(\"\"));\n return z\n .object({\n title: z.string().trim().min(1, copy.title),\n description: z.string().trim().min(1, copy.description),\n repository: optionalUrl,\n uiProduction: optionalUrl,\n uiIntegrity: optionalIntegrity,\n uiManifest: optionalManifestName,\n uiPinIntegrity: optionalIntegrity,\n ssrUrl: optionalUrl,\n ssrIntegrity: optionalIntegrity,\n })\n .refine((draft) => !!draft.uiProduction === !!(draft.uiIntegrity || draft.uiManifest), {\n message: copy.uiPair,\n path: [\"uiIntegrity\"],\n })\n .refine((draft) => !draft.uiIntegrity || !draft.uiManifest, {\n message: copy.integrityMode,\n path: [\"uiManifest\"],\n })\n .refine((draft) => !!draft.uiManifest === !!draft.uiPinIntegrity, {\n message: copy.pinPair,\n path: [\"uiPinIntegrity\"],\n })\n .refine((draft) => !!draft.ssrUrl === !!draft.ssrIntegrity, {\n message: copy.ssrPair,\n path: [\"ssrIntegrity\"],\n });\n}\nexport const tenantConfigDraftSchema = createTenantConfigDraftSchema();\n\nexport type TenantConfigDraft = z.infer<typeof tenantConfigDraftSchema>;\n\nexport const emptyTenantConfigDraft: TenantConfigDraft = {\n title: \"\",\n description: \"\",\n repository: \"\",\n uiProduction: \"\",\n uiIntegrity: \"\",\n uiManifest: \"\",\n uiPinIntegrity: \"\",\n ssrUrl: \"\",\n ssrIntegrity: \"\",\n};\n\ninterface ResolvedUiConfig {\n production?: unknown;\n integrity?: unknown;\n pin?: { manifest?: unknown; integrity?: unknown };\n ssr?: unknown;\n ssrIntegrity?: unknown;\n}\n\nfunction readUi(resolvedConfig: Record<string, unknown> | null | undefined): ResolvedUiConfig {\n const app = resolvedConfig?.app as { ui?: ResolvedUiConfig } | undefined;\n return app?.ui ?? {};\n}\n\nconst asString = (value: unknown) => (typeof value === \"string\" ? value : \"\");\n\nexport function buildDraftFromResolvedConfig(\n resolvedConfig: Record<string, unknown> | null | undefined,\n fallback: { title: string },\n): TenantConfigDraft {\n const ui = readUi(resolvedConfig);\n const title = asString(resolvedConfig?.title) || fallback.title;\n return {\n title,\n description: asString(resolvedConfig?.description) || title,\n repository: asString(resolvedConfig?.repository),\n uiProduction: asString(ui.production),\n uiIntegrity: asString(ui.integrity),\n uiManifest: asString(ui.pin?.manifest),\n uiPinIntegrity: asString(ui.pin?.integrity),\n ssrUrl: asString(ui.ssr),\n ssrIntegrity: asString(ui.ssrIntegrity),\n };\n}\n\nexport interface DraftDiffEntry {\n field: string;\n from: string;\n to: string;\n}\n\nexport function diffDraft(\n draft: TenantConfigDraft,\n resolvedConfig: Record<string, unknown> | null | undefined,\n): DraftDiffEntry[] {\n const ui = readUi(resolvedConfig);\n const pairs: [string, string, string][] = [\n [\"title\", asString(resolvedConfig?.title), draft.title],\n [\"description\", asString(resolvedConfig?.description), draft.description],\n [\"repository\", asString(resolvedConfig?.repository), draft.repository],\n [\"ui bundle\", asString(ui.production), draft.uiProduction],\n [\"ui integrity\", asString(ui.integrity), draft.uiIntegrity],\n [\"ui manifest pin\", asString(ui.pin?.manifest), draft.uiManifest],\n [\"ui pin integrity\", asString(ui.pin?.integrity), draft.uiPinIntegrity],\n [\"ssr bundle\", asString(ui.ssr), draft.ssrUrl],\n [\"ssr integrity\", asString(ui.ssrIntegrity), draft.ssrIntegrity],\n ];\n return pairs\n .filter(([, from, to]) => from !== to)\n .map(([field, from, to]) => ({ field, from: from || \"—\", to: to || \"—\" }));\n}\n\n/** The `app` block for the published config, or undefined when no UI override is set. */\nexport function draftUiOverride(draft: TenantConfigDraft): { ui: TenantUiOverride } | undefined {\n if (!draft.uiProduction) return undefined;\n if (draft.uiManifest && draft.uiPinIntegrity) {\n return {\n ui: {\n production: normalizeBundleBaseUrl(draft.uiProduction),\n pin: { manifest: draft.uiManifest, integrity: draft.uiPinIntegrity },\n ...(draft.ssrUrl && draft.ssrIntegrity\n ? { ssr: normalizeBundleBaseUrl(draft.ssrUrl), ssrIntegrity: draft.ssrIntegrity }\n : {}),\n },\n };\n }\n if (!draft.uiIntegrity) return undefined;\n return {\n ui: {\n production: normalizeBundleBaseUrl(draft.uiProduction),\n integrity: draft.uiIntegrity,\n ...(draft.ssrUrl && draft.ssrIntegrity\n ? { ssr: normalizeBundleBaseUrl(draft.ssrUrl), ssrIntegrity: draft.ssrIntegrity }\n : {}),\n },\n };\n}\n\nexport type IntegrityCheckResult =\n | { status: \"match\" }\n | { status: \"mismatch\"; computed: string }\n | { status: \"unverified\"; reason: string };\n\nfunction toBase64(bytes: Uint8Array): string {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n return btoa(binary);\n}\n\nexport async function computeSubresourceIntegrity(url: string): Promise<string> {\n const response = await fetch(url, { cache: \"no-store\" });\n if (!response.ok) {\n throw new Error(`fetching the bundle returned ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n const digest = await crypto.subtle.digest(\"SHA-384\", buffer);\n return `sha384-${toBase64(new Uint8Array(digest))}`;\n}\n\nexport function resolveClientEntryUrl(url: string): string {\n if (/\\/remoteEntry(\\.[a-f0-9]{8,})?\\.js$/.test(url)) return url;\n if (url.endsWith(\"/mf-manifest.json\"))\n return `${url.replace(/\\/mf-manifest\\.json$/, \"\")}/${UI_REMOTE_ENTRY_FILENAME}`;\n return `${url.replace(/\\/$/, \"\")}/${UI_REMOTE_ENTRY_FILENAME}`;\n}\n\nexport function resolveServerEntryUrl(url: string): string {\n return `${url.replace(/\\/$/, \"\")}/${UI_REMOTE_SERVER_ENTRY_FILENAME}`;\n}\n\nexport function normalizeBundleBaseUrl(url: string): string {\n return url\n .trim()\n .replace(/\\/remoteEntry(\\.server)?(\\.[a-f0-9]{8,})?\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\");\n}\n\nexport async function computeUiEntryIntegrity(baseUrl: string): Promise<string> {\n return computeSubresourceIntegrity(resolveClientEntryUrl(baseUrl.trim()));\n}\n\nexport async function computeSsrEntryIntegrity(baseUrl: string): Promise<string> {\n return computeSubresourceIntegrity(resolveServerEntryUrl(baseUrl.trim()));\n}\n\nasync function verifyEntryIntegrity(\n entryUrl: string,\n expected: string,\n): Promise<IntegrityCheckResult> {\n try {\n const computed = await computeSubresourceIntegrity(entryUrl);\n return computed === expected ? { status: \"match\" } : { status: \"mismatch\", computed };\n } catch (error) {\n return {\n status: \"unverified\",\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function verifyUiIntegrity(\n baseUrl: string,\n expected: string,\n): Promise<IntegrityCheckResult> {\n return verifyEntryIntegrity(resolveClientEntryUrl(baseUrl.trim()), expected);\n}\n\n/**\n * Pin preflight: fetch the pinned version-manifest document and SRI-compare it\n * against the pin — the manifest's own `entryIntegrity` covers the entry bytes\n * at serve time.\n */\nexport async function verifyUiPin(\n baseUrl: string,\n pin: { manifest: string; integrity: string },\n): Promise<IntegrityCheckResult> {\n const manifestUrl = `${baseUrl.trim().replace(/\\/$/, \"\")}/${pin.manifest.replace(/^\\//, \"\")}`;\n return verifyEntryIntegrity(manifestUrl, pin.integrity);\n}\n\nexport async function verifySsrIntegrity(\n baseUrl: string,\n expected: string,\n): Promise<IntegrityCheckResult> {\n return verifyEntryIntegrity(resolveServerEntryUrl(baseUrl.trim()), expected);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ClientRuntimeConfig } from "../types.cjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/ui/tenant.d.ts
|
|
4
|
+
declare function isLocalHostname(hostname: string): boolean;
|
|
5
|
+
/** Strips a `<label>.<gatewayId>` hostname (or a bare label) down to its label. */
|
|
6
|
+
declare function tenantLabel(hostnameOrLabel: string, gatewayId?: string): string;
|
|
7
|
+
interface BuildTenantUrlOptions {
|
|
8
|
+
/** Current browser origin hostname. Defaults to `window.location.hostname`. */
|
|
9
|
+
currentHostname?: string;
|
|
10
|
+
/** Current browser origin port. Defaults to `window.location.port`. */
|
|
11
|
+
currentPort?: string;
|
|
12
|
+
/** Appended to the origin, e.g. `/stake`. */
|
|
13
|
+
path?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds the absolute origin for a tenant, dev-aware.
|
|
17
|
+
*
|
|
18
|
+
* `buildTenantUrl("chicago", "citynode.app")`
|
|
19
|
+
* -> `https://chicago.citynode.app` in production
|
|
20
|
+
* -> `http://chicago.localhost:3000` when served from localhost
|
|
21
|
+
*/
|
|
22
|
+
declare function buildTenantUrl(hostnameOrLabel: string, gatewayId: string, options?: BuildTenantUrlOptions): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* The gateway a slug should publish under for the given owner account,
|
|
25
|
+
* derived from the runtime config instead of hardcoded per-network domains.
|
|
26
|
+
*
|
|
27
|
+
* When the account lives on the same network as the runtime, the current
|
|
28
|
+
* runtime's gateway id is the answer. When the networks differ, the runtime
|
|
29
|
+
* config carries no gateway for that other network, so null is returned and
|
|
30
|
+
* the caller surfaces it rather than guessing a domain.
|
|
31
|
+
*/
|
|
32
|
+
declare function gatewayForAccount(accountId: string, config?: Pick<ClientRuntimeConfig, "networkId" | "runtime">): string | null;
|
|
33
|
+
interface TenantUiOverride {
|
|
34
|
+
production: string;
|
|
35
|
+
/** direct entry SRI — only for genuinely fixed-name bundles without a pin */
|
|
36
|
+
integrity?: string;
|
|
37
|
+
/** version-manifest pin — the deploy unit for hashed, atomic deploys */
|
|
38
|
+
pin?: {
|
|
39
|
+
manifest: string;
|
|
40
|
+
integrity: string;
|
|
41
|
+
};
|
|
42
|
+
ssr?: string;
|
|
43
|
+
ssrIntegrity?: string;
|
|
44
|
+
}
|
|
45
|
+
declare const INTEGRITY_PATTERN: RegExp;
|
|
46
|
+
declare const defaultTenantConfigDraftMessages: {
|
|
47
|
+
url: string;
|
|
48
|
+
integrity: string;
|
|
49
|
+
manifest: string;
|
|
50
|
+
title: string;
|
|
51
|
+
description: string;
|
|
52
|
+
uiPair: string;
|
|
53
|
+
integrityMode: string;
|
|
54
|
+
pinPair: string;
|
|
55
|
+
ssrPair: string;
|
|
56
|
+
};
|
|
57
|
+
declare function createTenantConfigDraftSchema(messages?: Partial<typeof defaultTenantConfigDraftMessages>): z.ZodObject<{
|
|
58
|
+
title: z.ZodString;
|
|
59
|
+
description: z.ZodString;
|
|
60
|
+
repository: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
61
|
+
uiProduction: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
62
|
+
uiIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
63
|
+
uiManifest: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
64
|
+
uiPinIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
65
|
+
ssrUrl: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
66
|
+
ssrIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
declare const tenantConfigDraftSchema: z.ZodObject<{
|
|
69
|
+
title: z.ZodString;
|
|
70
|
+
description: z.ZodString;
|
|
71
|
+
repository: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
72
|
+
uiProduction: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
73
|
+
uiIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
74
|
+
uiManifest: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
75
|
+
uiPinIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
76
|
+
ssrUrl: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
77
|
+
ssrIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
type TenantConfigDraft = z.infer<typeof tenantConfigDraftSchema>;
|
|
80
|
+
declare const emptyTenantConfigDraft: TenantConfigDraft;
|
|
81
|
+
declare function buildDraftFromResolvedConfig(resolvedConfig: Record<string, unknown> | null | undefined, fallback: {
|
|
82
|
+
title: string;
|
|
83
|
+
}): TenantConfigDraft;
|
|
84
|
+
interface DraftDiffEntry {
|
|
85
|
+
field: string;
|
|
86
|
+
from: string;
|
|
87
|
+
to: string;
|
|
88
|
+
}
|
|
89
|
+
declare function diffDraft(draft: TenantConfigDraft, resolvedConfig: Record<string, unknown> | null | undefined): DraftDiffEntry[];
|
|
90
|
+
/** The `app` block for the published config, or undefined when no UI override is set. */
|
|
91
|
+
declare function draftUiOverride(draft: TenantConfigDraft): {
|
|
92
|
+
ui: TenantUiOverride;
|
|
93
|
+
} | undefined;
|
|
94
|
+
type IntegrityCheckResult = {
|
|
95
|
+
status: "match";
|
|
96
|
+
} | {
|
|
97
|
+
status: "mismatch";
|
|
98
|
+
computed: string;
|
|
99
|
+
} | {
|
|
100
|
+
status: "unverified";
|
|
101
|
+
reason: string;
|
|
102
|
+
};
|
|
103
|
+
declare function computeSubresourceIntegrity(url: string): Promise<string>;
|
|
104
|
+
declare function resolveClientEntryUrl(url: string): string;
|
|
105
|
+
declare function resolveServerEntryUrl(url: string): string;
|
|
106
|
+
declare function normalizeBundleBaseUrl(url: string): string;
|
|
107
|
+
declare function computeUiEntryIntegrity(baseUrl: string): Promise<string>;
|
|
108
|
+
declare function computeSsrEntryIntegrity(baseUrl: string): Promise<string>;
|
|
109
|
+
declare function verifyUiIntegrity(baseUrl: string, expected: string): Promise<IntegrityCheckResult>;
|
|
110
|
+
/**
|
|
111
|
+
* Pin preflight: fetch the pinned version-manifest document and SRI-compare it
|
|
112
|
+
* against the pin — the manifest's own `entryIntegrity` covers the entry bytes
|
|
113
|
+
* at serve time.
|
|
114
|
+
*/
|
|
115
|
+
declare function verifyUiPin(baseUrl: string, pin: {
|
|
116
|
+
manifest: string;
|
|
117
|
+
integrity: string;
|
|
118
|
+
}): Promise<IntegrityCheckResult>;
|
|
119
|
+
declare function verifySsrIntegrity(baseUrl: string, expected: string): Promise<IntegrityCheckResult>;
|
|
120
|
+
//#endregion
|
|
121
|
+
export { BuildTenantUrlOptions, DraftDiffEntry, INTEGRITY_PATTERN, IntegrityCheckResult, TenantConfigDraft, TenantUiOverride, buildDraftFromResolvedConfig, buildTenantUrl, computeSsrEntryIntegrity, computeSubresourceIntegrity, computeUiEntryIntegrity, createTenantConfigDraftSchema, defaultTenantConfigDraftMessages, diffDraft, draftUiOverride, emptyTenantConfigDraft, gatewayForAccount, isLocalHostname, normalizeBundleBaseUrl, resolveClientEntryUrl, resolveServerEntryUrl, tenantConfigDraftSchema, tenantLabel, verifySsrIntegrity, verifyUiIntegrity, verifyUiPin };
|
|
122
|
+
//# sourceMappingURL=tenant.d.cts.map
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ClientRuntimeConfig } from "../types.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/ui/tenant.d.ts
|
|
4
|
+
declare function isLocalHostname(hostname: string): boolean;
|
|
5
|
+
/** Strips a `<label>.<gatewayId>` hostname (or a bare label) down to its label. */
|
|
6
|
+
declare function tenantLabel(hostnameOrLabel: string, gatewayId?: string): string;
|
|
7
|
+
interface BuildTenantUrlOptions {
|
|
8
|
+
/** Current browser origin hostname. Defaults to `window.location.hostname`. */
|
|
9
|
+
currentHostname?: string;
|
|
10
|
+
/** Current browser origin port. Defaults to `window.location.port`. */
|
|
11
|
+
currentPort?: string;
|
|
12
|
+
/** Appended to the origin, e.g. `/stake`. */
|
|
13
|
+
path?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds the absolute origin for a tenant, dev-aware.
|
|
17
|
+
*
|
|
18
|
+
* `buildTenantUrl("chicago", "citynode.app")`
|
|
19
|
+
* -> `https://chicago.citynode.app` in production
|
|
20
|
+
* -> `http://chicago.localhost:3000` when served from localhost
|
|
21
|
+
*/
|
|
22
|
+
declare function buildTenantUrl(hostnameOrLabel: string, gatewayId: string, options?: BuildTenantUrlOptions): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* The gateway a slug should publish under for the given owner account,
|
|
25
|
+
* derived from the runtime config instead of hardcoded per-network domains.
|
|
26
|
+
*
|
|
27
|
+
* When the account lives on the same network as the runtime, the current
|
|
28
|
+
* runtime's gateway id is the answer. When the networks differ, the runtime
|
|
29
|
+
* config carries no gateway for that other network, so null is returned and
|
|
30
|
+
* the caller surfaces it rather than guessing a domain.
|
|
31
|
+
*/
|
|
32
|
+
declare function gatewayForAccount(accountId: string, config?: Pick<ClientRuntimeConfig, "networkId" | "runtime">): string | null;
|
|
33
|
+
interface TenantUiOverride {
|
|
34
|
+
production: string;
|
|
35
|
+
/** direct entry SRI — only for genuinely fixed-name bundles without a pin */
|
|
36
|
+
integrity?: string;
|
|
37
|
+
/** version-manifest pin — the deploy unit for hashed, atomic deploys */
|
|
38
|
+
pin?: {
|
|
39
|
+
manifest: string;
|
|
40
|
+
integrity: string;
|
|
41
|
+
};
|
|
42
|
+
ssr?: string;
|
|
43
|
+
ssrIntegrity?: string;
|
|
44
|
+
}
|
|
45
|
+
declare const INTEGRITY_PATTERN: RegExp;
|
|
46
|
+
declare const defaultTenantConfigDraftMessages: {
|
|
47
|
+
url: string;
|
|
48
|
+
integrity: string;
|
|
49
|
+
manifest: string;
|
|
50
|
+
title: string;
|
|
51
|
+
description: string;
|
|
52
|
+
uiPair: string;
|
|
53
|
+
integrityMode: string;
|
|
54
|
+
pinPair: string;
|
|
55
|
+
ssrPair: string;
|
|
56
|
+
};
|
|
57
|
+
declare function createTenantConfigDraftSchema(messages?: Partial<typeof defaultTenantConfigDraftMessages>): z.ZodObject<{
|
|
58
|
+
title: z.ZodString;
|
|
59
|
+
description: z.ZodString;
|
|
60
|
+
repository: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
61
|
+
uiProduction: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
62
|
+
uiIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
63
|
+
uiManifest: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
64
|
+
uiPinIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
65
|
+
ssrUrl: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
66
|
+
ssrIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
declare const tenantConfigDraftSchema: z.ZodObject<{
|
|
69
|
+
title: z.ZodString;
|
|
70
|
+
description: z.ZodString;
|
|
71
|
+
repository: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
72
|
+
uiProduction: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
73
|
+
uiIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
74
|
+
uiManifest: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
75
|
+
uiPinIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
76
|
+
ssrUrl: z.ZodPipe<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, z.ZodTransform<string, string>>;
|
|
77
|
+
ssrIntegrity: z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
type TenantConfigDraft = z.infer<typeof tenantConfigDraftSchema>;
|
|
80
|
+
declare const emptyTenantConfigDraft: TenantConfigDraft;
|
|
81
|
+
declare function buildDraftFromResolvedConfig(resolvedConfig: Record<string, unknown> | null | undefined, fallback: {
|
|
82
|
+
title: string;
|
|
83
|
+
}): TenantConfigDraft;
|
|
84
|
+
interface DraftDiffEntry {
|
|
85
|
+
field: string;
|
|
86
|
+
from: string;
|
|
87
|
+
to: string;
|
|
88
|
+
}
|
|
89
|
+
declare function diffDraft(draft: TenantConfigDraft, resolvedConfig: Record<string, unknown> | null | undefined): DraftDiffEntry[];
|
|
90
|
+
/** The `app` block for the published config, or undefined when no UI override is set. */
|
|
91
|
+
declare function draftUiOverride(draft: TenantConfigDraft): {
|
|
92
|
+
ui: TenantUiOverride;
|
|
93
|
+
} | undefined;
|
|
94
|
+
type IntegrityCheckResult = {
|
|
95
|
+
status: "match";
|
|
96
|
+
} | {
|
|
97
|
+
status: "mismatch";
|
|
98
|
+
computed: string;
|
|
99
|
+
} | {
|
|
100
|
+
status: "unverified";
|
|
101
|
+
reason: string;
|
|
102
|
+
};
|
|
103
|
+
declare function computeSubresourceIntegrity(url: string): Promise<string>;
|
|
104
|
+
declare function resolveClientEntryUrl(url: string): string;
|
|
105
|
+
declare function resolveServerEntryUrl(url: string): string;
|
|
106
|
+
declare function normalizeBundleBaseUrl(url: string): string;
|
|
107
|
+
declare function computeUiEntryIntegrity(baseUrl: string): Promise<string>;
|
|
108
|
+
declare function computeSsrEntryIntegrity(baseUrl: string): Promise<string>;
|
|
109
|
+
declare function verifyUiIntegrity(baseUrl: string, expected: string): Promise<IntegrityCheckResult>;
|
|
110
|
+
/**
|
|
111
|
+
* Pin preflight: fetch the pinned version-manifest document and SRI-compare it
|
|
112
|
+
* against the pin — the manifest's own `entryIntegrity` covers the entry bytes
|
|
113
|
+
* at serve time.
|
|
114
|
+
*/
|
|
115
|
+
declare function verifyUiPin(baseUrl: string, pin: {
|
|
116
|
+
manifest: string;
|
|
117
|
+
integrity: string;
|
|
118
|
+
}): Promise<IntegrityCheckResult>;
|
|
119
|
+
declare function verifySsrIntegrity(baseUrl: string, expected: string): Promise<IntegrityCheckResult>;
|
|
120
|
+
//#endregion
|
|
121
|
+
export { BuildTenantUrlOptions, DraftDiffEntry, INTEGRITY_PATTERN, IntegrityCheckResult, TenantConfigDraft, TenantUiOverride, buildDraftFromResolvedConfig, buildTenantUrl, computeSsrEntryIntegrity, computeSubresourceIntegrity, computeUiEntryIntegrity, createTenantConfigDraftSchema, defaultTenantConfigDraftMessages, diffDraft, draftUiOverride, emptyTenantConfigDraft, gatewayForAccount, isLocalHostname, normalizeBundleBaseUrl, resolveClientEntryUrl, resolveServerEntryUrl, tenantConfigDraftSchema, tenantLabel, verifySsrIntegrity, verifyUiIntegrity, verifyUiPin };
|
|
122
|
+
//# sourceMappingURL=tenant.d.mts.map
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { getRuntimeConfig } from "./runtime.mjs";
|
|
2
|
+
import { manifest_exports } from "./manifest/index.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/ui/tenant.ts
|
|
6
|
+
/**
|
|
7
|
+
* Tenant helpers shared by every ui workspace.
|
|
8
|
+
*
|
|
9
|
+
* Two halves of the tenant surface live here:
|
|
10
|
+
* - origin construction (`buildTenantUrl`, `tenantLabel`, `gatewayForAccount`)
|
|
11
|
+
* - the pure helpers for the org node-config editor: a validated draft of the
|
|
12
|
+
* fields a tenant may customize in its published bos.config.json, prefilled
|
|
13
|
+
* from the currently published config, diffed against it, and an in-browser
|
|
14
|
+
* sha384 preflight so a wrong UI bundle cannot brick the tenant site.
|
|
15
|
+
*/
|
|
16
|
+
const LOCALHOST_SUFFIX = ".localhost";
|
|
17
|
+
function isLocalHostname(hostname) {
|
|
18
|
+
const normalized = hostname.toLowerCase();
|
|
19
|
+
return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "[::1]" || normalized.endsWith(LOCALHOST_SUFFIX);
|
|
20
|
+
}
|
|
21
|
+
/** Strips a `<label>.<gatewayId>` hostname (or a bare label) down to its label. */
|
|
22
|
+
function tenantLabel(hostnameOrLabel, gatewayId) {
|
|
23
|
+
const normalized = hostnameOrLabel.trim().toLowerCase().replace(/\/+$/, "");
|
|
24
|
+
if (!normalized) return "";
|
|
25
|
+
const gateway = gatewayId?.trim().toLowerCase();
|
|
26
|
+
if (gateway && normalized.endsWith(`.${gateway}`)) return normalized.slice(0, -(gateway.length + 1));
|
|
27
|
+
if (normalized.endsWith(LOCALHOST_SUFFIX)) return normalized.slice(0, -10);
|
|
28
|
+
return normalized.split(".")[0] ?? "";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds the absolute origin for a tenant, dev-aware.
|
|
32
|
+
*
|
|
33
|
+
* `buildTenantUrl("chicago", "citynode.app")`
|
|
34
|
+
* -> `https://chicago.citynode.app` in production
|
|
35
|
+
* -> `http://chicago.localhost:3000` when served from localhost
|
|
36
|
+
*/
|
|
37
|
+
function buildTenantUrl(hostnameOrLabel, gatewayId, options = {}) {
|
|
38
|
+
const label = tenantLabel(hostnameOrLabel, gatewayId);
|
|
39
|
+
if (!label) return null;
|
|
40
|
+
const path = options.path ?? "";
|
|
41
|
+
const currentHostname = options.currentHostname ?? (typeof window === "undefined" ? void 0 : window.location.hostname);
|
|
42
|
+
if (currentHostname && isLocalHostname(currentHostname)) {
|
|
43
|
+
const currentPort = options.currentPort ?? (typeof window === "undefined" ? "" : window.location.port);
|
|
44
|
+
const port = currentPort ? `:${currentPort}` : "";
|
|
45
|
+
return `http://${label}${LOCALHOST_SUFFIX}${port}${path}`;
|
|
46
|
+
}
|
|
47
|
+
const gateway = gatewayId.trim().toLowerCase();
|
|
48
|
+
if (!gateway) return null;
|
|
49
|
+
return `https://${label}.${gateway}${path}`;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The gateway a slug should publish under for the given owner account,
|
|
53
|
+
* derived from the runtime config instead of hardcoded per-network domains.
|
|
54
|
+
*
|
|
55
|
+
* When the account lives on the same network as the runtime, the current
|
|
56
|
+
* runtime's gateway id is the answer. When the networks differ, the runtime
|
|
57
|
+
* config carries no gateway for that other network, so null is returned and
|
|
58
|
+
* the caller surfaces it rather than guessing a domain.
|
|
59
|
+
*/
|
|
60
|
+
function gatewayForAccount(accountId, config = getRuntimeConfig()) {
|
|
61
|
+
const gatewayId = config.runtime?.gatewayId;
|
|
62
|
+
if (!gatewayId) return null;
|
|
63
|
+
return accountId.trim().toLowerCase().endsWith(".testnet") === (config.networkId === "testnet") ? gatewayId : null;
|
|
64
|
+
}
|
|
65
|
+
const INTEGRITY_PATTERN = /^sha384-[A-Za-z0-9+/=]+$/;
|
|
66
|
+
const defaultTenantConfigDraftMessages = {
|
|
67
|
+
url: "must be a valid URL",
|
|
68
|
+
integrity: "must look like sha384-… (base64)",
|
|
69
|
+
manifest: "must look like versions/<version-id>.json",
|
|
70
|
+
title: "title is required",
|
|
71
|
+
description: "description is required",
|
|
72
|
+
uiPair: "a UI bundle needs both its URL and its integrity (direct hash or manifest pin)",
|
|
73
|
+
integrityMode: "choose one integrity mode — a direct entry hash or a version-manifest pin, not both",
|
|
74
|
+
pinPair: "a version-manifest pin needs both the manifest filename and its integrity",
|
|
75
|
+
ssrPair: "an SSR bundle needs both its URL and its integrity hash"
|
|
76
|
+
};
|
|
77
|
+
function createTenantConfigDraftSchema(messages = {}) {
|
|
78
|
+
const copy = {
|
|
79
|
+
...defaultTenantConfigDraftMessages,
|
|
80
|
+
...messages
|
|
81
|
+
};
|
|
82
|
+
const optionalUrl = z.string().trim().url(copy.url).or(z.literal("")).transform((value) => value.trim());
|
|
83
|
+
const optionalIntegrity = z.string().trim().regex(INTEGRITY_PATTERN, copy.integrity).or(z.literal(""));
|
|
84
|
+
const optionalManifestName = z.string().trim().regex(/^versions\/[0-9a-f]{16}\.json$/, copy.manifest).or(z.literal(""));
|
|
85
|
+
return z.object({
|
|
86
|
+
title: z.string().trim().min(1, copy.title),
|
|
87
|
+
description: z.string().trim().min(1, copy.description),
|
|
88
|
+
repository: optionalUrl,
|
|
89
|
+
uiProduction: optionalUrl,
|
|
90
|
+
uiIntegrity: optionalIntegrity,
|
|
91
|
+
uiManifest: optionalManifestName,
|
|
92
|
+
uiPinIntegrity: optionalIntegrity,
|
|
93
|
+
ssrUrl: optionalUrl,
|
|
94
|
+
ssrIntegrity: optionalIntegrity
|
|
95
|
+
}).refine((draft) => !!draft.uiProduction === !!(draft.uiIntegrity || draft.uiManifest), {
|
|
96
|
+
message: copy.uiPair,
|
|
97
|
+
path: ["uiIntegrity"]
|
|
98
|
+
}).refine((draft) => !draft.uiIntegrity || !draft.uiManifest, {
|
|
99
|
+
message: copy.integrityMode,
|
|
100
|
+
path: ["uiManifest"]
|
|
101
|
+
}).refine((draft) => !!draft.uiManifest === !!draft.uiPinIntegrity, {
|
|
102
|
+
message: copy.pinPair,
|
|
103
|
+
path: ["uiPinIntegrity"]
|
|
104
|
+
}).refine((draft) => !!draft.ssrUrl === !!draft.ssrIntegrity, {
|
|
105
|
+
message: copy.ssrPair,
|
|
106
|
+
path: ["ssrIntegrity"]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const tenantConfigDraftSchema = createTenantConfigDraftSchema();
|
|
110
|
+
const emptyTenantConfigDraft = {
|
|
111
|
+
title: "",
|
|
112
|
+
description: "",
|
|
113
|
+
repository: "",
|
|
114
|
+
uiProduction: "",
|
|
115
|
+
uiIntegrity: "",
|
|
116
|
+
uiManifest: "",
|
|
117
|
+
uiPinIntegrity: "",
|
|
118
|
+
ssrUrl: "",
|
|
119
|
+
ssrIntegrity: ""
|
|
120
|
+
};
|
|
121
|
+
function readUi(resolvedConfig) {
|
|
122
|
+
return (resolvedConfig?.app)?.ui ?? {};
|
|
123
|
+
}
|
|
124
|
+
const asString = (value) => typeof value === "string" ? value : "";
|
|
125
|
+
function buildDraftFromResolvedConfig(resolvedConfig, fallback) {
|
|
126
|
+
const ui = readUi(resolvedConfig);
|
|
127
|
+
const title = asString(resolvedConfig?.title) || fallback.title;
|
|
128
|
+
return {
|
|
129
|
+
title,
|
|
130
|
+
description: asString(resolvedConfig?.description) || title,
|
|
131
|
+
repository: asString(resolvedConfig?.repository),
|
|
132
|
+
uiProduction: asString(ui.production),
|
|
133
|
+
uiIntegrity: asString(ui.integrity),
|
|
134
|
+
uiManifest: asString(ui.pin?.manifest),
|
|
135
|
+
uiPinIntegrity: asString(ui.pin?.integrity),
|
|
136
|
+
ssrUrl: asString(ui.ssr),
|
|
137
|
+
ssrIntegrity: asString(ui.ssrIntegrity)
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function diffDraft(draft, resolvedConfig) {
|
|
141
|
+
const ui = readUi(resolvedConfig);
|
|
142
|
+
return [
|
|
143
|
+
[
|
|
144
|
+
"title",
|
|
145
|
+
asString(resolvedConfig?.title),
|
|
146
|
+
draft.title
|
|
147
|
+
],
|
|
148
|
+
[
|
|
149
|
+
"description",
|
|
150
|
+
asString(resolvedConfig?.description),
|
|
151
|
+
draft.description
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
"repository",
|
|
155
|
+
asString(resolvedConfig?.repository),
|
|
156
|
+
draft.repository
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
"ui bundle",
|
|
160
|
+
asString(ui.production),
|
|
161
|
+
draft.uiProduction
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"ui integrity",
|
|
165
|
+
asString(ui.integrity),
|
|
166
|
+
draft.uiIntegrity
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
"ui manifest pin",
|
|
170
|
+
asString(ui.pin?.manifest),
|
|
171
|
+
draft.uiManifest
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
"ui pin integrity",
|
|
175
|
+
asString(ui.pin?.integrity),
|
|
176
|
+
draft.uiPinIntegrity
|
|
177
|
+
],
|
|
178
|
+
[
|
|
179
|
+
"ssr bundle",
|
|
180
|
+
asString(ui.ssr),
|
|
181
|
+
draft.ssrUrl
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
"ssr integrity",
|
|
185
|
+
asString(ui.ssrIntegrity),
|
|
186
|
+
draft.ssrIntegrity
|
|
187
|
+
]
|
|
188
|
+
].filter(([, from, to]) => from !== to).map(([field, from, to]) => ({
|
|
189
|
+
field,
|
|
190
|
+
from: from || "—",
|
|
191
|
+
to: to || "—"
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
/** The `app` block for the published config, or undefined when no UI override is set. */
|
|
195
|
+
function draftUiOverride(draft) {
|
|
196
|
+
if (!draft.uiProduction) return void 0;
|
|
197
|
+
if (draft.uiManifest && draft.uiPinIntegrity) return { ui: {
|
|
198
|
+
production: normalizeBundleBaseUrl(draft.uiProduction),
|
|
199
|
+
pin: {
|
|
200
|
+
manifest: draft.uiManifest,
|
|
201
|
+
integrity: draft.uiPinIntegrity
|
|
202
|
+
},
|
|
203
|
+
...draft.ssrUrl && draft.ssrIntegrity ? {
|
|
204
|
+
ssr: normalizeBundleBaseUrl(draft.ssrUrl),
|
|
205
|
+
ssrIntegrity: draft.ssrIntegrity
|
|
206
|
+
} : {}
|
|
207
|
+
} };
|
|
208
|
+
if (!draft.uiIntegrity) return void 0;
|
|
209
|
+
return { ui: {
|
|
210
|
+
production: normalizeBundleBaseUrl(draft.uiProduction),
|
|
211
|
+
integrity: draft.uiIntegrity,
|
|
212
|
+
...draft.ssrUrl && draft.ssrIntegrity ? {
|
|
213
|
+
ssr: normalizeBundleBaseUrl(draft.ssrUrl),
|
|
214
|
+
ssrIntegrity: draft.ssrIntegrity
|
|
215
|
+
} : {}
|
|
216
|
+
} };
|
|
217
|
+
}
|
|
218
|
+
function toBase64(bytes) {
|
|
219
|
+
let binary = "";
|
|
220
|
+
const chunkSize = 32768;
|
|
221
|
+
for (let offset = 0; offset < bytes.length; offset += chunkSize) binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));
|
|
222
|
+
return btoa(binary);
|
|
223
|
+
}
|
|
224
|
+
async function computeSubresourceIntegrity(url) {
|
|
225
|
+
const response = await fetch(url, { cache: "no-store" });
|
|
226
|
+
if (!response.ok) throw new Error(`fetching the bundle returned ${response.status}`);
|
|
227
|
+
const buffer = await response.arrayBuffer();
|
|
228
|
+
const digest = await crypto.subtle.digest("SHA-384", buffer);
|
|
229
|
+
return `sha384-${toBase64(new Uint8Array(digest))}`;
|
|
230
|
+
}
|
|
231
|
+
function resolveClientEntryUrl(url) {
|
|
232
|
+
if (/\/remoteEntry(\.[a-f0-9]{8,})?\.js$/.test(url)) return url;
|
|
233
|
+
if (url.endsWith("/mf-manifest.json")) return `${url.replace(/\/mf-manifest\.json$/, "")}/${manifest_exports.UI_REMOTE_ENTRY_FILENAME}`;
|
|
234
|
+
return `${url.replace(/\/$/, "")}/${manifest_exports.UI_REMOTE_ENTRY_FILENAME}`;
|
|
235
|
+
}
|
|
236
|
+
function resolveServerEntryUrl(url) {
|
|
237
|
+
return `${url.replace(/\/$/, "")}/${manifest_exports.UI_REMOTE_SERVER_ENTRY_FILENAME}`;
|
|
238
|
+
}
|
|
239
|
+
function normalizeBundleBaseUrl(url) {
|
|
240
|
+
return url.trim().replace(/\/remoteEntry(\.server)?(\.[a-f0-9]{8,})?\.js$/, "").replace(/\/mf-manifest\.json$/, "");
|
|
241
|
+
}
|
|
242
|
+
async function computeUiEntryIntegrity(baseUrl) {
|
|
243
|
+
return computeSubresourceIntegrity(resolveClientEntryUrl(baseUrl.trim()));
|
|
244
|
+
}
|
|
245
|
+
async function computeSsrEntryIntegrity(baseUrl) {
|
|
246
|
+
return computeSubresourceIntegrity(resolveServerEntryUrl(baseUrl.trim()));
|
|
247
|
+
}
|
|
248
|
+
async function verifyEntryIntegrity(entryUrl, expected) {
|
|
249
|
+
try {
|
|
250
|
+
const computed = await computeSubresourceIntegrity(entryUrl);
|
|
251
|
+
return computed === expected ? { status: "match" } : {
|
|
252
|
+
status: "mismatch",
|
|
253
|
+
computed
|
|
254
|
+
};
|
|
255
|
+
} catch (error) {
|
|
256
|
+
return {
|
|
257
|
+
status: "unverified",
|
|
258
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async function verifyUiIntegrity(baseUrl, expected) {
|
|
263
|
+
return verifyEntryIntegrity(resolveClientEntryUrl(baseUrl.trim()), expected);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Pin preflight: fetch the pinned version-manifest document and SRI-compare it
|
|
267
|
+
* against the pin — the manifest's own `entryIntegrity` covers the entry bytes
|
|
268
|
+
* at serve time.
|
|
269
|
+
*/
|
|
270
|
+
async function verifyUiPin(baseUrl, pin) {
|
|
271
|
+
return verifyEntryIntegrity(`${baseUrl.trim().replace(/\/$/, "")}/${pin.manifest.replace(/^\//, "")}`, pin.integrity);
|
|
272
|
+
}
|
|
273
|
+
async function verifySsrIntegrity(baseUrl, expected) {
|
|
274
|
+
return verifyEntryIntegrity(resolveServerEntryUrl(baseUrl.trim()), expected);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
//#endregion
|
|
278
|
+
export { INTEGRITY_PATTERN, buildDraftFromResolvedConfig, buildTenantUrl, computeSsrEntryIntegrity, computeSubresourceIntegrity, computeUiEntryIntegrity, createTenantConfigDraftSchema, defaultTenantConfigDraftMessages, diffDraft, draftUiOverride, emptyTenantConfigDraft, gatewayForAccount, isLocalHostname, normalizeBundleBaseUrl, resolveClientEntryUrl, resolveServerEntryUrl, tenantConfigDraftSchema, tenantLabel, verifySsrIntegrity, verifyUiIntegrity, verifyUiPin };
|
|
279
|
+
//# sourceMappingURL=tenant.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant.mjs","names":["UI_REMOTE_ENTRY_FILENAME","UI_REMOTE_SERVER_ENTRY_FILENAME"],"sources":["../../src/ui/tenant.ts"],"sourcesContent":["/**\n * Tenant helpers shared by every ui workspace.\n *\n * Two halves of the tenant surface live here:\n * - origin construction (`buildTenantUrl`, `tenantLabel`, `gatewayForAccount`)\n * - the pure helpers for the org node-config editor: a validated draft of the\n * fields a tenant may customize in its published bos.config.json, prefilled\n * from the currently published config, diffed against it, and an in-browser\n * sha384 preflight so a wrong UI bundle cannot brick the tenant site.\n */\n\nimport { z } from \"zod\";\nimport type { ClientRuntimeConfig } from \"../types\";\nimport { UI_REMOTE_ENTRY_FILENAME, UI_REMOTE_SERVER_ENTRY_FILENAME } from \"./manifest\";\nimport { getRuntimeConfig } from \"./runtime\";\n\nconst LOCALHOST_SUFFIX = \".localhost\";\n\nexport function isLocalHostname(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return (\n normalized === \"localhost\" ||\n normalized === \"127.0.0.1\" ||\n normalized === \"[::1]\" ||\n normalized.endsWith(LOCALHOST_SUFFIX)\n );\n}\n\n/** Strips a `<label>.<gatewayId>` hostname (or a bare label) down to its label. */\nexport function tenantLabel(hostnameOrLabel: string, gatewayId?: string): string {\n const normalized = hostnameOrLabel.trim().toLowerCase().replace(/\\/+$/, \"\");\n if (!normalized) return \"\";\n const gateway = gatewayId?.trim().toLowerCase();\n if (gateway && normalized.endsWith(`.${gateway}`)) {\n return normalized.slice(0, -(gateway.length + 1));\n }\n if (normalized.endsWith(LOCALHOST_SUFFIX)) {\n return normalized.slice(0, -LOCALHOST_SUFFIX.length);\n }\n return normalized.split(\".\")[0] ?? \"\";\n}\n\nexport interface BuildTenantUrlOptions {\n /** Current browser origin hostname. Defaults to `window.location.hostname`. */\n currentHostname?: string;\n /** Current browser origin port. Defaults to `window.location.port`. */\n currentPort?: string;\n /** Appended to the origin, e.g. `/stake`. */\n path?: string;\n}\n\n/**\n * Builds the absolute origin for a tenant, dev-aware.\n *\n * `buildTenantUrl(\"chicago\", \"citynode.app\")`\n * -> `https://chicago.citynode.app` in production\n * -> `http://chicago.localhost:3000` when served from localhost\n */\nexport function buildTenantUrl(\n hostnameOrLabel: string,\n gatewayId: string,\n options: BuildTenantUrlOptions = {},\n): string | null {\n const label = tenantLabel(hostnameOrLabel, gatewayId);\n if (!label) return null;\n\n const path = options.path ?? \"\";\n const currentHostname =\n options.currentHostname ??\n (typeof window === \"undefined\" ? undefined : window.location.hostname);\n\n if (currentHostname && isLocalHostname(currentHostname)) {\n const currentPort =\n options.currentPort ?? (typeof window === \"undefined\" ? \"\" : window.location.port);\n const port = currentPort ? `:${currentPort}` : \"\";\n return `http://${label}${LOCALHOST_SUFFIX}${port}${path}`;\n }\n\n const gateway = gatewayId.trim().toLowerCase();\n if (!gateway) return null;\n return `https://${label}.${gateway}${path}`;\n}\n\n/**\n * The gateway a slug should publish under for the given owner account,\n * derived from the runtime config instead of hardcoded per-network domains.\n *\n * When the account lives on the same network as the runtime, the current\n * runtime's gateway id is the answer. When the networks differ, the runtime\n * config carries no gateway for that other network, so null is returned and\n * the caller surfaces it rather than guessing a domain.\n */\nexport function gatewayForAccount(\n accountId: string,\n config: Pick<ClientRuntimeConfig, \"networkId\" | \"runtime\"> = getRuntimeConfig(),\n): string | null {\n const gatewayId = config.runtime?.gatewayId;\n if (!gatewayId) return null;\n const testnetAccount = accountId.trim().toLowerCase().endsWith(\".testnet\");\n return testnetAccount === (config.networkId === \"testnet\") ? gatewayId : null;\n}\n\nexport interface TenantUiOverride {\n production: string;\n /** direct entry SRI — only for genuinely fixed-name bundles without a pin */\n integrity?: string;\n /** version-manifest pin — the deploy unit for hashed, atomic deploys */\n pin?: { manifest: string; integrity: string };\n ssr?: string;\n ssrIntegrity?: string;\n}\n\nexport const INTEGRITY_PATTERN = /^sha384-[A-Za-z0-9+/=]+$/;\n\nexport const defaultTenantConfigDraftMessages = {\n url: \"must be a valid URL\",\n integrity: \"must look like sha384-… (base64)\",\n manifest: \"must look like versions/<version-id>.json\",\n title: \"title is required\",\n description: \"description is required\",\n uiPair: \"a UI bundle needs both its URL and its integrity (direct hash or manifest pin)\",\n integrityMode:\n \"choose one integrity mode — a direct entry hash or a version-manifest pin, not both\",\n pinPair: \"a version-manifest pin needs both the manifest filename and its integrity\",\n ssrPair: \"an SSR bundle needs both its URL and its integrity hash\",\n};\n\nexport function createTenantConfigDraftSchema(\n messages: Partial<typeof defaultTenantConfigDraftMessages> = {},\n) {\n const copy = { ...defaultTenantConfigDraftMessages, ...messages };\n const optionalUrl = z\n .string()\n .trim()\n .url(copy.url)\n .or(z.literal(\"\"))\n .transform((value) => value.trim());\n const optionalIntegrity = z\n .string()\n .trim()\n .regex(INTEGRITY_PATTERN, copy.integrity)\n .or(z.literal(\"\"));\n const optionalManifestName = z\n .string()\n .trim()\n .regex(/^versions\\/[0-9a-f]{16}\\.json$/, copy.manifest)\n .or(z.literal(\"\"));\n return z\n .object({\n title: z.string().trim().min(1, copy.title),\n description: z.string().trim().min(1, copy.description),\n repository: optionalUrl,\n uiProduction: optionalUrl,\n uiIntegrity: optionalIntegrity,\n uiManifest: optionalManifestName,\n uiPinIntegrity: optionalIntegrity,\n ssrUrl: optionalUrl,\n ssrIntegrity: optionalIntegrity,\n })\n .refine((draft) => !!draft.uiProduction === !!(draft.uiIntegrity || draft.uiManifest), {\n message: copy.uiPair,\n path: [\"uiIntegrity\"],\n })\n .refine((draft) => !draft.uiIntegrity || !draft.uiManifest, {\n message: copy.integrityMode,\n path: [\"uiManifest\"],\n })\n .refine((draft) => !!draft.uiManifest === !!draft.uiPinIntegrity, {\n message: copy.pinPair,\n path: [\"uiPinIntegrity\"],\n })\n .refine((draft) => !!draft.ssrUrl === !!draft.ssrIntegrity, {\n message: copy.ssrPair,\n path: [\"ssrIntegrity\"],\n });\n}\nexport const tenantConfigDraftSchema = createTenantConfigDraftSchema();\n\nexport type TenantConfigDraft = z.infer<typeof tenantConfigDraftSchema>;\n\nexport const emptyTenantConfigDraft: TenantConfigDraft = {\n title: \"\",\n description: \"\",\n repository: \"\",\n uiProduction: \"\",\n uiIntegrity: \"\",\n uiManifest: \"\",\n uiPinIntegrity: \"\",\n ssrUrl: \"\",\n ssrIntegrity: \"\",\n};\n\ninterface ResolvedUiConfig {\n production?: unknown;\n integrity?: unknown;\n pin?: { manifest?: unknown; integrity?: unknown };\n ssr?: unknown;\n ssrIntegrity?: unknown;\n}\n\nfunction readUi(resolvedConfig: Record<string, unknown> | null | undefined): ResolvedUiConfig {\n const app = resolvedConfig?.app as { ui?: ResolvedUiConfig } | undefined;\n return app?.ui ?? {};\n}\n\nconst asString = (value: unknown) => (typeof value === \"string\" ? value : \"\");\n\nexport function buildDraftFromResolvedConfig(\n resolvedConfig: Record<string, unknown> | null | undefined,\n fallback: { title: string },\n): TenantConfigDraft {\n const ui = readUi(resolvedConfig);\n const title = asString(resolvedConfig?.title) || fallback.title;\n return {\n title,\n description: asString(resolvedConfig?.description) || title,\n repository: asString(resolvedConfig?.repository),\n uiProduction: asString(ui.production),\n uiIntegrity: asString(ui.integrity),\n uiManifest: asString(ui.pin?.manifest),\n uiPinIntegrity: asString(ui.pin?.integrity),\n ssrUrl: asString(ui.ssr),\n ssrIntegrity: asString(ui.ssrIntegrity),\n };\n}\n\nexport interface DraftDiffEntry {\n field: string;\n from: string;\n to: string;\n}\n\nexport function diffDraft(\n draft: TenantConfigDraft,\n resolvedConfig: Record<string, unknown> | null | undefined,\n): DraftDiffEntry[] {\n const ui = readUi(resolvedConfig);\n const pairs: [string, string, string][] = [\n [\"title\", asString(resolvedConfig?.title), draft.title],\n [\"description\", asString(resolvedConfig?.description), draft.description],\n [\"repository\", asString(resolvedConfig?.repository), draft.repository],\n [\"ui bundle\", asString(ui.production), draft.uiProduction],\n [\"ui integrity\", asString(ui.integrity), draft.uiIntegrity],\n [\"ui manifest pin\", asString(ui.pin?.manifest), draft.uiManifest],\n [\"ui pin integrity\", asString(ui.pin?.integrity), draft.uiPinIntegrity],\n [\"ssr bundle\", asString(ui.ssr), draft.ssrUrl],\n [\"ssr integrity\", asString(ui.ssrIntegrity), draft.ssrIntegrity],\n ];\n return pairs\n .filter(([, from, to]) => from !== to)\n .map(([field, from, to]) => ({ field, from: from || \"—\", to: to || \"—\" }));\n}\n\n/** The `app` block for the published config, or undefined when no UI override is set. */\nexport function draftUiOverride(draft: TenantConfigDraft): { ui: TenantUiOverride } | undefined {\n if (!draft.uiProduction) return undefined;\n if (draft.uiManifest && draft.uiPinIntegrity) {\n return {\n ui: {\n production: normalizeBundleBaseUrl(draft.uiProduction),\n pin: { manifest: draft.uiManifest, integrity: draft.uiPinIntegrity },\n ...(draft.ssrUrl && draft.ssrIntegrity\n ? { ssr: normalizeBundleBaseUrl(draft.ssrUrl), ssrIntegrity: draft.ssrIntegrity }\n : {}),\n },\n };\n }\n if (!draft.uiIntegrity) return undefined;\n return {\n ui: {\n production: normalizeBundleBaseUrl(draft.uiProduction),\n integrity: draft.uiIntegrity,\n ...(draft.ssrUrl && draft.ssrIntegrity\n ? { ssr: normalizeBundleBaseUrl(draft.ssrUrl), ssrIntegrity: draft.ssrIntegrity }\n : {}),\n },\n };\n}\n\nexport type IntegrityCheckResult =\n | { status: \"match\" }\n | { status: \"mismatch\"; computed: string }\n | { status: \"unverified\"; reason: string };\n\nfunction toBase64(bytes: Uint8Array): string {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n return btoa(binary);\n}\n\nexport async function computeSubresourceIntegrity(url: string): Promise<string> {\n const response = await fetch(url, { cache: \"no-store\" });\n if (!response.ok) {\n throw new Error(`fetching the bundle returned ${response.status}`);\n }\n const buffer = await response.arrayBuffer();\n const digest = await crypto.subtle.digest(\"SHA-384\", buffer);\n return `sha384-${toBase64(new Uint8Array(digest))}`;\n}\n\nexport function resolveClientEntryUrl(url: string): string {\n if (/\\/remoteEntry(\\.[a-f0-9]{8,})?\\.js$/.test(url)) return url;\n if (url.endsWith(\"/mf-manifest.json\"))\n return `${url.replace(/\\/mf-manifest\\.json$/, \"\")}/${UI_REMOTE_ENTRY_FILENAME}`;\n return `${url.replace(/\\/$/, \"\")}/${UI_REMOTE_ENTRY_FILENAME}`;\n}\n\nexport function resolveServerEntryUrl(url: string): string {\n return `${url.replace(/\\/$/, \"\")}/${UI_REMOTE_SERVER_ENTRY_FILENAME}`;\n}\n\nexport function normalizeBundleBaseUrl(url: string): string {\n return url\n .trim()\n .replace(/\\/remoteEntry(\\.server)?(\\.[a-f0-9]{8,})?\\.js$/, \"\")\n .replace(/\\/mf-manifest\\.json$/, \"\");\n}\n\nexport async function computeUiEntryIntegrity(baseUrl: string): Promise<string> {\n return computeSubresourceIntegrity(resolveClientEntryUrl(baseUrl.trim()));\n}\n\nexport async function computeSsrEntryIntegrity(baseUrl: string): Promise<string> {\n return computeSubresourceIntegrity(resolveServerEntryUrl(baseUrl.trim()));\n}\n\nasync function verifyEntryIntegrity(\n entryUrl: string,\n expected: string,\n): Promise<IntegrityCheckResult> {\n try {\n const computed = await computeSubresourceIntegrity(entryUrl);\n return computed === expected ? { status: \"match\" } : { status: \"mismatch\", computed };\n } catch (error) {\n return {\n status: \"unverified\",\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function verifyUiIntegrity(\n baseUrl: string,\n expected: string,\n): Promise<IntegrityCheckResult> {\n return verifyEntryIntegrity(resolveClientEntryUrl(baseUrl.trim()), expected);\n}\n\n/**\n * Pin preflight: fetch the pinned version-manifest document and SRI-compare it\n * against the pin — the manifest's own `entryIntegrity` covers the entry bytes\n * at serve time.\n */\nexport async function verifyUiPin(\n baseUrl: string,\n pin: { manifest: string; integrity: string },\n): Promise<IntegrityCheckResult> {\n const manifestUrl = `${baseUrl.trim().replace(/\\/$/, \"\")}/${pin.manifest.replace(/^\\//, \"\")}`;\n return verifyEntryIntegrity(manifestUrl, pin.integrity);\n}\n\nexport async function verifySsrIntegrity(\n baseUrl: string,\n expected: string,\n): Promise<IntegrityCheckResult> {\n return verifyEntryIntegrity(resolveServerEntryUrl(baseUrl.trim()), expected);\n}\n"],"mappings":"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"}
|