gorsee 0.2.3 → 0.2.5
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 +261 -213
- package/dist-pkg/ai/artifact-lifecycle.d.ts +25 -0
- package/dist-pkg/ai/artifact-lifecycle.js +98 -0
- package/dist-pkg/ai/bridge.d.ts +26 -0
- package/dist-pkg/ai/bridge.js +82 -0
- package/dist-pkg/ai/bundle.d.ts +46 -0
- package/dist-pkg/ai/bundle.js +247 -0
- package/dist-pkg/ai/contracts.d.ts +1 -0
- package/dist-pkg/ai/contracts.js +1 -0
- package/dist-pkg/ai/ide.d.ts +37 -0
- package/dist-pkg/ai/ide.js +56 -0
- package/dist-pkg/ai/index.d.ts +85 -0
- package/dist-pkg/ai/index.js +267 -0
- package/dist-pkg/ai/json.d.ts +6 -0
- package/dist-pkg/ai/json.js +14 -0
- package/dist-pkg/ai/mcp.d.ts +28 -0
- package/dist-pkg/ai/mcp.js +152 -0
- package/dist-pkg/ai/session-pack.d.ts +28 -0
- package/dist-pkg/ai/session-pack.js +57 -0
- package/dist-pkg/ai/store.d.ts +67 -0
- package/dist-pkg/ai/store.js +174 -0
- package/dist-pkg/ai/summary.d.ts +57 -0
- package/dist-pkg/ai/summary.js +148 -0
- package/dist-pkg/ai/watch.d.ts +15 -0
- package/dist-pkg/ai/watch.js +66 -0
- package/dist-pkg/auth/action-tokens.d.ts +50 -0
- package/dist-pkg/auth/action-tokens.js +79 -0
- package/dist-pkg/auth/index.d.ts +70 -0
- package/dist-pkg/auth/index.js +199 -0
- package/dist-pkg/auth/redis-session-store.d.ts +7 -0
- package/dist-pkg/auth/redis-session-store.js +42 -0
- package/dist-pkg/auth/signing.d.ts +4 -0
- package/dist-pkg/auth/signing.js +33 -0
- package/dist-pkg/auth/sqlite-session-store.d.ts +12 -0
- package/dist-pkg/auth/sqlite-session-store.js +83 -0
- package/dist-pkg/auth/store-utils.d.ts +2 -0
- package/dist-pkg/auth/store-utils.js +20 -0
- package/dist-pkg/bin/gorsee.js +2 -0
- package/dist-pkg/build/backends/experimental-rolldown.d.ts +6 -0
- package/dist-pkg/build/backends/experimental-rolldown.js +9 -0
- package/dist-pkg/build/backends/register.d.ts +7 -0
- package/dist-pkg/build/backends/register.js +24 -0
- package/dist-pkg/build/backends/rolldown.d.ts +16 -0
- package/dist-pkg/build/backends/rolldown.js +176 -0
- package/dist-pkg/build/client-backend.d.ts +31 -0
- package/dist-pkg/build/client-backend.js +97 -0
- package/dist-pkg/build/client.d.ts +12 -0
- package/dist-pkg/build/client.js +93 -0
- package/dist-pkg/build/css-modules.d.ts +10 -0
- package/dist-pkg/build/css-modules.js +51 -0
- package/dist-pkg/build/devalue-parse.d.ts +1 -0
- package/dist-pkg/build/devalue-parse.js +1 -0
- package/dist-pkg/build/diagnostics.d.ts +20 -0
- package/dist-pkg/build/diagnostics.js +35 -0
- package/dist-pkg/build/fixtures.d.ts +7 -0
- package/dist-pkg/build/fixtures.js +60 -0
- package/dist-pkg/build/framework-imports.d.ts +4 -0
- package/dist-pkg/build/framework-imports.js +58 -0
- package/dist-pkg/build/init.d.ts +1 -0
- package/dist-pkg/build/init.js +6 -0
- package/dist-pkg/build/manifest.d.ts +3 -0
- package/dist-pkg/build/manifest.js +23 -0
- package/dist-pkg/build/parity.d.ts +32 -0
- package/dist-pkg/build/parity.js +71 -0
- package/dist-pkg/build/plugin.d.ts +11 -0
- package/dist-pkg/build/plugin.js +8 -0
- package/dist-pkg/build/readiness.d.ts +11 -0
- package/dist-pkg/build/readiness.js +18 -0
- package/dist-pkg/build/route-client-transform.d.ts +17 -0
- package/dist-pkg/build/route-client-transform.js +48 -0
- package/dist-pkg/build/route-metadata.d.ts +6 -0
- package/dist-pkg/build/route-metadata.js +8 -0
- package/dist-pkg/build/rpc-transform.d.ts +1 -0
- package/dist-pkg/build/rpc-transform.js +44 -0
- package/dist-pkg/build/server-bundle.d.ts +4 -0
- package/dist-pkg/build/server-bundle.js +261 -0
- package/dist-pkg/build/server-strip.d.ts +2 -0
- package/dist-pkg/build/server-strip.js +32 -0
- package/dist-pkg/build/ssg.d.ts +12 -0
- package/dist-pkg/build/ssg.js +36 -0
- package/dist-pkg/cli/bun-plugin.d.ts +2 -0
- package/dist-pkg/cli/bun-plugin.js +14 -0
- package/dist-pkg/cli/canonical-import-rewrite.d.ts +18 -0
- package/dist-pkg/cli/canonical-import-rewrite.js +94 -0
- package/dist-pkg/cli/canonical-imports.d.ts +8 -0
- package/dist-pkg/cli/canonical-imports.js +131 -0
- package/dist-pkg/cli/check-ast.d.ts +20 -0
- package/dist-pkg/cli/check-ast.js +126 -0
- package/dist-pkg/cli/cmd-ai.d.ts +4 -0
- package/dist-pkg/cli/cmd-ai.js +290 -0
- package/dist-pkg/cli/cmd-build.d.ts +12 -0
- package/dist-pkg/cli/cmd-build.js +198 -0
- package/dist-pkg/cli/cmd-check.d.ts +25 -0
- package/dist-pkg/cli/cmd-check.js +573 -0
- package/dist-pkg/cli/cmd-create.d.ts +6 -0
- package/dist-pkg/cli/cmd-create.js +600 -0
- package/dist-pkg/cli/cmd-deploy.d.ts +6 -0
- package/dist-pkg/cli/cmd-deploy.js +381 -0
- package/dist-pkg/cli/cmd-dev.d.ts +5 -0
- package/dist-pkg/cli/cmd-dev.js +5 -0
- package/dist-pkg/cli/cmd-docs.d.ts +50 -0
- package/dist-pkg/cli/cmd-docs.js +122 -0
- package/dist-pkg/cli/cmd-generate.d.ts +12 -0
- package/dist-pkg/cli/cmd-generate.js +320 -0
- package/dist-pkg/cli/cmd-migrate.d.ts +7 -0
- package/dist-pkg/cli/cmd-migrate.js +42 -0
- package/dist-pkg/cli/cmd-routes.d.ts +6 -0
- package/dist-pkg/cli/cmd-routes.js +24 -0
- package/dist-pkg/cli/cmd-start.d.ts +13 -0
- package/dist-pkg/cli/cmd-start.js +32 -0
- package/dist-pkg/cli/cmd-test.d.ts +20 -0
- package/dist-pkg/cli/cmd-test.js +103 -0
- package/dist-pkg/cli/cmd-typegen.d.ts +7 -0
- package/dist-pkg/cli/cmd-typegen.js +66 -0
- package/dist-pkg/cli/cmd-upgrade.d.ts +38 -0
- package/dist-pkg/cli/cmd-upgrade.js +232 -0
- package/dist-pkg/cli/context.d.ts +4 -0
- package/dist-pkg/cli/context.js +4 -0
- package/dist-pkg/cli/framework-md.d.ts +1 -0
- package/dist-pkg/cli/framework-md.js +391 -0
- package/dist-pkg/cli/index.d.ts +6 -0
- package/dist-pkg/cli/index.js +106 -0
- package/dist-pkg/cli/release-version.d.ts +2 -0
- package/dist-pkg/cli/release-version.js +33 -0
- package/dist-pkg/client.d.ts +16 -0
- package/dist-pkg/client.js +71 -0
- package/dist-pkg/compat.d.ts +1 -0
- package/dist-pkg/compat.js +1 -0
- package/dist-pkg/compiler/analysis-backend.d.ts +20 -0
- package/dist-pkg/compiler/analysis-backend.js +164 -0
- package/dist-pkg/compiler/backends/experimental-oxc.d.ts +6 -0
- package/dist-pkg/compiler/backends/experimental-oxc.js +9 -0
- package/dist-pkg/compiler/backends/oxc.d.ts +16 -0
- package/dist-pkg/compiler/backends/oxc.js +198 -0
- package/dist-pkg/compiler/backends/register.d.ts +7 -0
- package/dist-pkg/compiler/backends/register.js +22 -0
- package/dist-pkg/compiler/fixtures.d.ts +2 -0
- package/dist-pkg/compiler/fixtures.js +118 -0
- package/dist-pkg/compiler/init.d.ts +1 -0
- package/dist-pkg/compiler/init.js +6 -0
- package/dist-pkg/compiler/module-analysis.d.ts +13 -0
- package/dist-pkg/compiler/module-analysis.js +50 -0
- package/dist-pkg/compiler/parity.d.ts +35 -0
- package/dist-pkg/compiler/parity.js +89 -0
- package/dist-pkg/compiler/readiness.d.ts +11 -0
- package/dist-pkg/compiler/readiness.js +18 -0
- package/dist-pkg/compiler/route-facts.d.ts +34 -0
- package/dist-pkg/compiler/route-facts.js +75 -0
- package/dist-pkg/content/index.d.ts +27 -0
- package/dist-pkg/content/index.js +287 -0
- package/dist-pkg/db/index.d.ts +3 -0
- package/dist-pkg/db/index.js +6 -0
- package/dist-pkg/db/migrate.d.ts +7 -0
- package/dist-pkg/db/migrate.js +53 -0
- package/dist-pkg/db/postgres.d.ts +29 -0
- package/dist-pkg/db/postgres.js +59 -0
- package/dist-pkg/db/sqlite.d.ts +10 -0
- package/dist-pkg/db/sqlite.js +22 -0
- package/dist-pkg/deploy/cloudflare.d.ts +8 -0
- package/{src/deploy/cloudflare.ts → dist-pkg/deploy/cloudflare.js} +24 -26
- package/dist-pkg/deploy/conformance.d.ts +21 -0
- package/dist-pkg/deploy/conformance.js +98 -0
- package/dist-pkg/deploy/dockerfile.d.ts +3 -0
- package/{src/deploy/dockerfile.ts → dist-pkg/deploy/dockerfile.js} +8 -10
- package/dist-pkg/deploy/fly.d.ts +3 -0
- package/{src/deploy/fly.ts → dist-pkg/deploy/fly.js} +11 -12
- package/dist-pkg/deploy/index.d.ts +6 -0
- package/dist-pkg/deploy/index.js +26 -0
- package/dist-pkg/deploy/netlify.d.ts +2 -0
- package/{src/deploy/netlify.ts → dist-pkg/deploy/netlify.js} +17 -11
- package/dist-pkg/deploy/runtime.d.ts +2 -0
- package/dist-pkg/deploy/runtime.js +3 -0
- package/dist-pkg/deploy/vercel.d.ts +22 -0
- package/dist-pkg/deploy/vercel.js +53 -0
- package/dist-pkg/dev/error-overlay.d.ts +1 -0
- package/{src/dev/error-overlay.ts → dist-pkg/dev/error-overlay.js} +13 -23
- package/dist-pkg/dev/hmr.d.ts +30 -0
- package/dist-pkg/dev/hmr.js +86 -0
- package/dist-pkg/dev/partial-handler.d.ts +9 -0
- package/dist-pkg/dev/partial-handler.js +24 -0
- package/dist-pkg/dev/request-handler.d.ts +30 -0
- package/dist-pkg/dev/request-handler.js +67 -0
- package/dist-pkg/dev/watcher.d.ts +6 -0
- package/dist-pkg/dev/watcher.js +34 -0
- package/dist-pkg/dev.d.ts +11 -0
- package/dist-pkg/dev.js +268 -0
- package/dist-pkg/env/index.d.ts +3 -0
- package/dist-pkg/env/index.js +57 -0
- package/dist-pkg/errors/catalog.d.ts +9 -0
- package/{src/errors/catalog.ts → dist-pkg/errors/catalog.js} +8 -24
- package/dist-pkg/errors/formatter.d.ts +22 -0
- package/dist-pkg/errors/formatter.js +43 -0
- package/dist-pkg/errors/index.d.ts +2 -0
- package/dist-pkg/errors/index.js +2 -0
- package/dist-pkg/forms/action.d.ts +15 -0
- package/dist-pkg/forms/action.js +20 -0
- package/dist-pkg/forms/index.d.ts +4 -0
- package/dist-pkg/forms/index.js +12 -0
- package/dist-pkg/i18n/index.d.ts +61 -0
- package/dist-pkg/i18n/index.js +147 -0
- package/dist-pkg/index-client.d.ts +1 -0
- package/dist-pkg/index-client.js +1 -0
- package/dist-pkg/index.d.ts +32 -0
- package/dist-pkg/index.js +79 -0
- package/dist-pkg/jsx-runtime-client.d.ts +8 -0
- package/dist-pkg/jsx-runtime-client.js +1 -0
- package/dist-pkg/jsx-runtime.d.ts +13 -0
- package/dist-pkg/jsx-runtime.js +5 -0
- package/dist-pkg/jsx-types-html.d.ts +221 -0
- package/dist-pkg/jsx-types-html.js +0 -0
- package/dist-pkg/log/index.d.ts +8 -0
- package/dist-pkg/log/index.js +55 -0
- package/dist-pkg/plugins/drizzle.d.ts +16 -0
- package/dist-pkg/plugins/drizzle.js +50 -0
- package/dist-pkg/plugins/index.d.ts +62 -0
- package/dist-pkg/plugins/index.js +147 -0
- package/dist-pkg/plugins/lucia.d.ts +26 -0
- package/dist-pkg/plugins/lucia.js +63 -0
- package/dist-pkg/plugins/prisma.d.ts +14 -0
- package/dist-pkg/plugins/prisma.js +57 -0
- package/dist-pkg/plugins/resend.d.ts +21 -0
- package/dist-pkg/plugins/resend.js +45 -0
- package/dist-pkg/plugins/s3.d.ts +18 -0
- package/dist-pkg/plugins/s3.js +63 -0
- package/dist-pkg/plugins/stripe.d.ts +32 -0
- package/dist-pkg/plugins/stripe.js +69 -0
- package/dist-pkg/plugins/tailwind.d.ts +15 -0
- package/dist-pkg/plugins/tailwind.js +58 -0
- package/dist-pkg/prod.d.ts +21 -0
- package/dist-pkg/prod.js +347 -0
- package/dist-pkg/reactive/computed.d.ts +3 -0
- package/dist-pkg/reactive/computed.js +15 -0
- package/dist-pkg/reactive/data.d.ts +25 -0
- package/dist-pkg/reactive/data.js +56 -0
- package/dist-pkg/reactive/diagnostics.d.ts +100 -0
- package/dist-pkg/reactive/diagnostics.js +363 -0
- package/dist-pkg/reactive/effect.d.ts +3 -0
- package/dist-pkg/reactive/effect.js +6 -0
- package/dist-pkg/reactive/index.d.ts +9 -0
- package/dist-pkg/reactive/index.js +18 -0
- package/dist-pkg/reactive/live.d.ts +15 -0
- package/dist-pkg/reactive/live.js +58 -0
- package/dist-pkg/reactive/optimistic.d.ts +20 -0
- package/dist-pkg/reactive/optimistic.js +54 -0
- package/dist-pkg/reactive/resource.d.ts +25 -0
- package/dist-pkg/reactive/resource.js +97 -0
- package/dist-pkg/reactive/signal.d.ts +4 -0
- package/dist-pkg/reactive/signal.js +17 -0
- package/dist-pkg/reactive/store.d.ts +6 -0
- package/dist-pkg/reactive/store.js +19 -0
- package/dist-pkg/router/index.d.ts +2 -0
- package/dist-pkg/router/index.js +2 -0
- package/dist-pkg/router/matcher.d.ts +7 -0
- package/dist-pkg/router/matcher.js +40 -0
- package/dist-pkg/router/scanner.d.ts +14 -0
- package/dist-pkg/router/scanner.js +141 -0
- package/dist-pkg/routes/index.d.ts +1 -0
- package/dist-pkg/routes/index.js +10 -0
- package/dist-pkg/runtime/app-config.d.ts +26 -0
- package/dist-pkg/runtime/app-config.js +69 -0
- package/dist-pkg/runtime/client.d.ts +3 -0
- package/dist-pkg/runtime/client.js +31 -0
- package/dist-pkg/runtime/devtools.d.ts +64 -0
- package/dist-pkg/runtime/devtools.js +132 -0
- package/dist-pkg/runtime/error-boundary.d.ts +6 -0
- package/dist-pkg/runtime/error-boundary.js +17 -0
- package/dist-pkg/runtime/event-replay.d.ts +3 -0
- package/{src/runtime/event-replay.ts → dist-pkg/runtime/event-replay.js} +7 -22
- package/dist-pkg/runtime/event-source.d.ts +7 -0
- package/dist-pkg/runtime/event-source.js +24 -0
- package/dist-pkg/runtime/form.d.ts +24 -0
- package/dist-pkg/runtime/form.js +59 -0
- package/dist-pkg/runtime/head.d.ts +7 -0
- package/dist-pkg/runtime/head.js +90 -0
- package/dist-pkg/runtime/html-escape.d.ts +7 -0
- package/dist-pkg/runtime/html-escape.js +39 -0
- package/dist-pkg/runtime/hydration.d.ts +15 -0
- package/dist-pkg/runtime/hydration.js +103 -0
- package/dist-pkg/runtime/image.d.ts +49 -0
- package/dist-pkg/runtime/image.js +144 -0
- package/dist-pkg/runtime/index.d.ts +17 -0
- package/dist-pkg/runtime/index.js +59 -0
- package/dist-pkg/runtime/island-hydrator.d.ts +12 -0
- package/dist-pkg/runtime/island-hydrator.js +49 -0
- package/dist-pkg/runtime/island.d.ts +19 -0
- package/dist-pkg/runtime/island.js +36 -0
- package/dist-pkg/runtime/jsx-runtime.d.ts +12 -0
- package/dist-pkg/runtime/jsx-runtime.js +173 -0
- package/dist-pkg/runtime/link.d.ts +16 -0
- package/dist-pkg/runtime/link.js +47 -0
- package/dist-pkg/runtime/project.d.ts +37 -0
- package/dist-pkg/runtime/project.js +36 -0
- package/dist-pkg/runtime/renderable.d.ts +6 -0
- package/dist-pkg/runtime/renderable.js +0 -0
- package/dist-pkg/runtime/router.d.ts +47 -0
- package/dist-pkg/runtime/router.js +476 -0
- package/dist-pkg/runtime/server.d.ts +8 -0
- package/dist-pkg/runtime/server.js +71 -0
- package/dist-pkg/runtime/stream.d.ts +29 -0
- package/dist-pkg/runtime/stream.js +106 -0
- package/dist-pkg/runtime/suspense.d.ts +6 -0
- package/dist-pkg/runtime/suspense.js +16 -0
- package/dist-pkg/runtime/typed-routes.d.ts +24 -0
- package/dist-pkg/runtime/typed-routes.js +77 -0
- package/dist-pkg/runtime/validated-form.d.ts +40 -0
- package/dist-pkg/runtime/validated-form.js +120 -0
- package/dist-pkg/security/cors.d.ts +10 -0
- package/dist-pkg/security/cors.js +56 -0
- package/dist-pkg/security/csrf.d.ts +9 -0
- package/dist-pkg/security/csrf.js +53 -0
- package/dist-pkg/security/headers.d.ts +11 -0
- package/dist-pkg/security/headers.js +31 -0
- package/dist-pkg/security/index.d.ts +5 -0
- package/dist-pkg/security/index.js +5 -0
- package/dist-pkg/security/rate-limit.d.ts +10 -0
- package/dist-pkg/security/rate-limit.js +49 -0
- package/dist-pkg/security/redis-rate-limit.d.ts +14 -0
- package/dist-pkg/security/redis-rate-limit.js +23 -0
- package/dist-pkg/server/action.d.ts +21 -0
- package/dist-pkg/server/action.js +64 -0
- package/dist-pkg/server/cache-utils.d.ts +2 -0
- package/dist-pkg/server/cache-utils.js +26 -0
- package/dist-pkg/server/cache.d.ts +33 -0
- package/dist-pkg/server/cache.js +236 -0
- package/dist-pkg/server/compress.d.ts +2 -0
- package/dist-pkg/server/compress.js +49 -0
- package/dist-pkg/server/endpoint-execution.d.ts +28 -0
- package/dist-pkg/server/endpoint-execution.js +37 -0
- package/dist-pkg/server/etag.d.ts +3 -0
- package/dist-pkg/server/etag.js +18 -0
- package/dist-pkg/server/guard.d.ts +16 -0
- package/dist-pkg/server/guard.js +45 -0
- package/dist-pkg/server/html-shell.d.ts +12 -0
- package/dist-pkg/server/html-shell.js +52 -0
- package/dist-pkg/server/index.d.ts +36 -0
- package/dist-pkg/server/index.js +170 -0
- package/dist-pkg/server/jobs.d.ts +41 -0
- package/dist-pkg/server/jobs.js +81 -0
- package/dist-pkg/server/manifest.d.ts +19 -0
- package/dist-pkg/server/manifest.js +36 -0
- package/dist-pkg/server/middleware.d.ts +39 -0
- package/dist-pkg/server/middleware.js +122 -0
- package/dist-pkg/server/mime.d.ts +1 -0
- package/{src/server/mime.ts → dist-pkg/server/mime.js} +6 -17
- package/dist-pkg/server/not-found.d.ts +6 -0
- package/dist-pkg/server/not-found.js +24 -0
- package/dist-pkg/server/page-render.d.ts +29 -0
- package/dist-pkg/server/page-render.js +67 -0
- package/dist-pkg/server/partial-navigation.d.ts +4 -0
- package/dist-pkg/server/partial-navigation.js +16 -0
- package/dist-pkg/server/pipe.d.ts +9 -0
- package/dist-pkg/server/pipe.js +32 -0
- package/dist-pkg/server/redis-cache-store.d.ts +10 -0
- package/dist-pkg/server/redis-cache-store.js +73 -0
- package/dist-pkg/server/redis-client.d.ts +37 -0
- package/dist-pkg/server/redis-client.js +37 -0
- package/dist-pkg/server/request-policy.d.ts +55 -0
- package/dist-pkg/server/request-policy.js +216 -0
- package/dist-pkg/server/request-preflight.d.ts +23 -0
- package/dist-pkg/server/request-preflight.js +45 -0
- package/dist-pkg/server/request-security-policy.d.ts +17 -0
- package/dist-pkg/server/request-security-policy.js +34 -0
- package/dist-pkg/server/request-surface.d.ts +8 -0
- package/dist-pkg/server/request-surface.js +19 -0
- package/dist-pkg/server/route-request.d.ts +31 -0
- package/dist-pkg/server/route-request.js +112 -0
- package/dist-pkg/server/route-response.d.ts +22 -0
- package/dist-pkg/server/route-response.js +58 -0
- package/dist-pkg/server/rpc-hash.d.ts +2 -0
- package/dist-pkg/server/rpc-hash.js +7 -0
- package/dist-pkg/server/rpc-protocol.d.ts +22 -0
- package/dist-pkg/server/rpc-protocol.js +28 -0
- package/dist-pkg/server/rpc-utils.d.ts +2 -0
- package/dist-pkg/server/rpc-utils.js +26 -0
- package/dist-pkg/server/rpc.d.ts +20 -0
- package/dist-pkg/server/rpc.js +147 -0
- package/dist-pkg/server/runtime-dispatch.d.ts +19 -0
- package/dist-pkg/server/runtime-dispatch.js +67 -0
- package/dist-pkg/server/server-execution.d.ts +22 -0
- package/dist-pkg/server/server-execution.js +53 -0
- package/dist-pkg/server/sqlite-cache-store.d.ts +13 -0
- package/dist-pkg/server/sqlite-cache-store.js +88 -0
- package/dist-pkg/server/sse.d.ts +9 -0
- package/dist-pkg/server/sse.js +34 -0
- package/dist-pkg/server/static-file.d.ts +9 -0
- package/dist-pkg/server/static-file.js +43 -0
- package/dist-pkg/server/ws.d.ts +18 -0
- package/dist-pkg/server/ws.js +40 -0
- package/dist-pkg/server-entry.d.ts +19 -0
- package/dist-pkg/server-entry.js +93 -0
- package/dist-pkg/testing/index.d.ts +98 -0
- package/dist-pkg/testing/index.js +254 -0
- package/dist-pkg/types/index.d.ts +4 -0
- package/dist-pkg/types/index.js +4 -0
- package/dist-pkg/types/safe-html.d.ts +7 -0
- package/dist-pkg/types/safe-html.js +19 -0
- package/dist-pkg/types/safe-sql.d.ts +8 -0
- package/dist-pkg/types/safe-sql.js +14 -0
- package/dist-pkg/types/safe-url.d.ts +7 -0
- package/dist-pkg/types/safe-url.js +20 -0
- package/dist-pkg/types/user-input.d.ts +9 -0
- package/dist-pkg/types/user-input.js +3 -0
- package/dist-pkg/unsafe/index.d.ts +12 -0
- package/dist-pkg/unsafe/index.js +6 -0
- package/package.json +102 -44
- package/bin/gorsee.js +0 -14
- package/src/auth/index.ts +0 -178
- package/src/auth/redis-session-store.ts +0 -46
- package/src/auth/sqlite-session-store.ts +0 -98
- package/src/auth/store-utils.ts +0 -21
- package/src/build/client.ts +0 -139
- package/src/build/css-modules.ts +0 -69
- package/src/build/devalue-parse.ts +0 -2
- package/src/build/manifest.ts +0 -34
- package/src/build/route-metadata.ts +0 -12
- package/src/build/rpc-transform.ts +0 -62
- package/src/build/server-strip.ts +0 -87
- package/src/build/ssg.ts +0 -70
- package/src/cli/bun-plugin.ts +0 -58
- package/src/cli/cmd-build.ts +0 -153
- package/src/cli/cmd-check.ts +0 -239
- package/src/cli/cmd-create.ts +0 -328
- package/src/cli/cmd-deploy.ts +0 -149
- package/src/cli/cmd-dev.ts +0 -13
- package/src/cli/cmd-docs.ts +0 -152
- package/src/cli/cmd-generate.ts +0 -155
- package/src/cli/cmd-migrate.ts +0 -53
- package/src/cli/cmd-routes.ts +0 -36
- package/src/cli/cmd-start.ts +0 -30
- package/src/cli/cmd-test.ts +0 -129
- package/src/cli/cmd-typegen.ts +0 -93
- package/src/cli/cmd-upgrade.ts +0 -143
- package/src/cli/context.ts +0 -12
- package/src/cli/framework-md.ts +0 -223
- package/src/cli/index.ts +0 -107
- package/src/client.ts +0 -26
- package/src/db/index.ts +0 -2
- package/src/db/migrate.ts +0 -89
- package/src/db/sqlite.ts +0 -40
- package/src/deploy/index.ts +0 -31
- package/src/deploy/vercel.ts +0 -94
- package/src/dev/hmr.ts +0 -31
- package/src/dev/partial-handler.ts +0 -52
- package/src/dev/request-handler.ts +0 -127
- package/src/dev/watcher.ts +0 -48
- package/src/dev.ts +0 -208
- package/src/env/index.ts +0 -74
- package/src/errors/formatter.ts +0 -63
- package/src/errors/index.ts +0 -2
- package/src/i18n/index.ts +0 -72
- package/src/index-client.ts +0 -4
- package/src/index.ts +0 -43
- package/src/jsx-runtime-client.ts +0 -13
- package/src/jsx-runtime.ts +0 -20
- package/src/jsx-types-html.ts +0 -242
- package/src/log/index.ts +0 -44
- package/src/plugins/drizzle.ts +0 -84
- package/src/plugins/index.ts +0 -86
- package/src/plugins/lucia.ts +0 -111
- package/src/plugins/prisma.ts +0 -85
- package/src/plugins/resend.ts +0 -78
- package/src/plugins/s3.ts +0 -102
- package/src/plugins/stripe.ts +0 -133
- package/src/plugins/tailwind.ts +0 -92
- package/src/prod.ts +0 -252
- package/src/reactive/computed.ts +0 -7
- package/src/reactive/effect.ts +0 -7
- package/src/reactive/index.ts +0 -7
- package/src/reactive/live.ts +0 -97
- package/src/reactive/optimistic.ts +0 -83
- package/src/reactive/resource.ts +0 -138
- package/src/reactive/signal.ts +0 -20
- package/src/reactive/store.ts +0 -36
- package/src/router/index.ts +0 -2
- package/src/router/matcher.ts +0 -53
- package/src/router/scanner.ts +0 -206
- package/src/runtime/client.ts +0 -28
- package/src/runtime/error-boundary.ts +0 -35
- package/src/runtime/form.ts +0 -49
- package/src/runtime/head.ts +0 -113
- package/src/runtime/html-escape.ts +0 -30
- package/src/runtime/hydration.ts +0 -95
- package/src/runtime/image.ts +0 -48
- package/src/runtime/index.ts +0 -12
- package/src/runtime/island-hydrator.ts +0 -84
- package/src/runtime/island.ts +0 -88
- package/src/runtime/jsx-runtime.ts +0 -167
- package/src/runtime/link.ts +0 -45
- package/src/runtime/project.ts +0 -73
- package/src/runtime/router.ts +0 -224
- package/src/runtime/server.ts +0 -102
- package/src/runtime/stream.ts +0 -182
- package/src/runtime/suspense.ts +0 -37
- package/src/runtime/typed-routes.ts +0 -26
- package/src/runtime/validated-form.ts +0 -106
- package/src/security/cors.ts +0 -80
- package/src/security/csrf.ts +0 -85
- package/src/security/headers.ts +0 -50
- package/src/security/index.ts +0 -4
- package/src/security/rate-limit.ts +0 -80
- package/src/server/action.ts +0 -48
- package/src/server/cache-utils.ts +0 -23
- package/src/server/cache.ts +0 -125
- package/src/server/compress.ts +0 -60
- package/src/server/etag.ts +0 -23
- package/src/server/guard.ts +0 -69
- package/src/server/html-shell.ts +0 -69
- package/src/server/index.ts +0 -57
- package/src/server/manifest.ts +0 -36
- package/src/server/middleware.ts +0 -159
- package/src/server/not-found.ts +0 -35
- package/src/server/page-render.ts +0 -123
- package/src/server/pipe.ts +0 -46
- package/src/server/redis-cache-store.ts +0 -87
- package/src/server/redis-client.ts +0 -71
- package/src/server/request-preflight.ts +0 -45
- package/src/server/route-request.ts +0 -72
- package/src/server/rpc-hash.ts +0 -17
- package/src/server/rpc-utils.ts +0 -27
- package/src/server/rpc.ts +0 -177
- package/src/server/sqlite-cache-store.ts +0 -109
- package/src/server/sse.ts +0 -96
- package/src/server/static-file.ts +0 -63
- package/src/server/ws.ts +0 -56
- package/src/server-entry.ts +0 -36
- package/src/testing/index.ts +0 -74
- package/src/types/index.ts +0 -4
- package/src/types/safe-html.ts +0 -32
- package/src/types/safe-sql.ts +0 -28
- package/src/types/safe-url.ts +0 -40
- package/src/types/user-input.ts +0 -12
- package/src/unsafe/index.ts +0 -18
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function createRequestSecurityPolicy(options = {}) {
|
|
2
|
+
const trustedHosts = new Set, explicitTrustedHosts = options.trustedHosts ?? [];
|
|
3
|
+
for (const host of options.trustedHosts ?? [])
|
|
4
|
+
if (host.trim())
|
|
5
|
+
trustedHosts.add(normalizeHost(host));
|
|
6
|
+
if (options.trustedOrigin)
|
|
7
|
+
try {
|
|
8
|
+
trustedHosts.add(normalizeHost(new URL(options.trustedOrigin).host));
|
|
9
|
+
} catch {}
|
|
10
|
+
return {
|
|
11
|
+
trustedOrigin: options.trustedOrigin,
|
|
12
|
+
trustForwardedHeaders: options.trustForwardedHeaders === !0,
|
|
13
|
+
trustedForwardedHops: options.trustForwardedHeaders === !0 ? Math.max(1, options.trustedForwardedHops ?? 1) : 0,
|
|
14
|
+
trustedHosts: [...trustedHosts],
|
|
15
|
+
enforceTrustedHosts: options.enforceTrustedHosts ?? explicitTrustedHosts.length > 0
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function validateRequestSecurityPolicy(metadata, executionPolicy, securityPolicy) {
|
|
19
|
+
if (securityPolicy.enforceTrustedHosts && securityPolicy.trustedHosts.length > 0 && !securityPolicy.trustedHosts.includes(normalizeHost(metadata.effectiveHost)))
|
|
20
|
+
return new Response("Invalid Host", { status: 400 });
|
|
21
|
+
if (executionPolicy.access === "internal" && securityPolicy.trustedOrigin && metadata.origin && !sameOrigin(metadata.origin, securityPolicy.trustedOrigin))
|
|
22
|
+
return new Response("Forbidden", { status: 403 });
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function normalizeHost(host) {
|
|
26
|
+
return host.trim().toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
function sameOrigin(left, right) {
|
|
29
|
+
try {
|
|
30
|
+
return new URL(left).origin === new URL(right).origin;
|
|
31
|
+
} catch {
|
|
32
|
+
return !1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type RuntimeRequestSurface = "hmr" | "rpc" | "bundle" | "static" | "prerendered" | "route" | "not-found";
|
|
2
|
+
export interface RuntimeRequestPlanOptions {
|
|
3
|
+
pathname: string;
|
|
4
|
+
hasRouteMatch: boolean;
|
|
5
|
+
allowHMR?: boolean;
|
|
6
|
+
allowPrerendered?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function createRuntimeRequestPlan(options: RuntimeRequestPlanOptions): RuntimeRequestSurface[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function createRuntimeRequestPlan(options) {
|
|
2
|
+
const { pathname, hasRouteMatch, allowHMR = !1, allowPrerendered = !1 } = options;
|
|
3
|
+
if (allowHMR && pathname === "/__gorsee_hmr")
|
|
4
|
+
return ["hmr"];
|
|
5
|
+
if (/^\/api\/_rpc\/[a-zA-Z0-9]+$/.test(pathname))
|
|
6
|
+
return ["rpc"];
|
|
7
|
+
if (pathname.startsWith("/_gorsee/"))
|
|
8
|
+
return ["bundle", "not-found"];
|
|
9
|
+
const plan = [];
|
|
10
|
+
if (pathname !== "/") {
|
|
11
|
+
plan.push("static");
|
|
12
|
+
if (allowPrerendered)
|
|
13
|
+
plan.push("prerendered");
|
|
14
|
+
}
|
|
15
|
+
if (hasRouteMatch)
|
|
16
|
+
plan.push("route");
|
|
17
|
+
plan.push("not-found");
|
|
18
|
+
return plan;
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Context, type MiddlewareFn } from "./middleware.js";
|
|
2
|
+
import { type ResolvedPageRoute } from "./page-render.js";
|
|
3
|
+
import { type RequestSecurityPolicy } from "./request-security-policy.js";
|
|
4
|
+
import type { MatchResult } from "../router/matcher.js";
|
|
5
|
+
import { type AITraceContext } from "../ai/index.js";
|
|
6
|
+
type RouteModule = Record<string, unknown>;
|
|
7
|
+
interface RouteRequestContext {
|
|
8
|
+
match: MatchResult;
|
|
9
|
+
request: Request;
|
|
10
|
+
mod: RouteModule;
|
|
11
|
+
ctx: Context;
|
|
12
|
+
}
|
|
13
|
+
interface ResolvedRouteRequestContext extends RouteRequestContext {
|
|
14
|
+
resolved: ResolvedPageRoute;
|
|
15
|
+
}
|
|
16
|
+
interface RouteRequestOptions {
|
|
17
|
+
match: MatchResult;
|
|
18
|
+
request: Request;
|
|
19
|
+
trustedOrigin?: string;
|
|
20
|
+
trustForwardedHeaders?: boolean;
|
|
21
|
+
trustedForwardedHops?: number;
|
|
22
|
+
securityPolicy?: RequestSecurityPolicy;
|
|
23
|
+
trace?: Partial<AITraceContext>;
|
|
24
|
+
extraMiddlewares?: MiddlewareFn[];
|
|
25
|
+
onActionRequest?: (ctx: RouteRequestContext) => Promise<Response>;
|
|
26
|
+
onPartialRequest: (ctx: ResolvedRouteRequestContext) => Promise<Response>;
|
|
27
|
+
onPageRequest: (ctx: ResolvedRouteRequestContext) => Promise<Response>;
|
|
28
|
+
onRouteError?: (error: unknown, ctx: RouteRequestContext) => Promise<Response>;
|
|
29
|
+
}
|
|
30
|
+
export declare function handleRouteRequest(options: RouteRequestOptions): Promise<Response>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RedirectError,
|
|
3
|
+
sanitizeRedirectTarget
|
|
4
|
+
} from "./middleware.js";
|
|
5
|
+
import { handleAction } from "./action.js";
|
|
6
|
+
import { resolvePageRoute } from "./page-render.js";
|
|
7
|
+
import { executeServerExecution } from "./server-execution.js";
|
|
8
|
+
import {
|
|
9
|
+
classifyRouteRequest
|
|
10
|
+
} from "./request-policy.js";
|
|
11
|
+
import {
|
|
12
|
+
createRequestSecurityPolicy
|
|
13
|
+
} from "./request-security-policy.js";
|
|
14
|
+
import { emitAIEvent } from "../ai/index.js";
|
|
15
|
+
export async function handleRouteRequest(options) {
|
|
16
|
+
const { match, request, extraMiddlewares = [], onActionRequest, onPartialRequest, onPageRequest, onRouteError } = options, mod = await import(match.route.filePath), requestKind = classifyRouteRequest(mod, request), securityPolicy = options.securityPolicy ?? createRequestSecurityPolicy({
|
|
17
|
+
trustedOrigin: options.trustedOrigin,
|
|
18
|
+
trustForwardedHeaders: options.trustForwardedHeaders,
|
|
19
|
+
trustedForwardedHops: options.trustedForwardedHops
|
|
20
|
+
});
|
|
21
|
+
let routeCtx, resolvedRouteCtx;
|
|
22
|
+
try {
|
|
23
|
+
const middlewares = await loadRouteMiddlewares(match, mod, extraMiddlewares);
|
|
24
|
+
return await executeServerExecution({
|
|
25
|
+
request,
|
|
26
|
+
kind: requestKind,
|
|
27
|
+
params: match.params,
|
|
28
|
+
securityPolicy,
|
|
29
|
+
middlewares,
|
|
30
|
+
trace: options.trace,
|
|
31
|
+
route: match.route.path,
|
|
32
|
+
handler: async ({ ctx }) => {
|
|
33
|
+
routeCtx = { match, request, mod, ctx };
|
|
34
|
+
if (requestKind === "route-handler") {
|
|
35
|
+
const handlerName = request.method === "POST" ? "POST" : "GET";
|
|
36
|
+
return mod[handlerName](ctx);
|
|
37
|
+
}
|
|
38
|
+
if (requestKind === "action") {
|
|
39
|
+
if (onActionRequest)
|
|
40
|
+
return onActionRequest(routeCtx);
|
|
41
|
+
return handleActionRequest(mod.action, ctx, request);
|
|
42
|
+
}
|
|
43
|
+
if (requestKind === "partial")
|
|
44
|
+
return onPartialRequest(await ensureResolvedRouteContext());
|
|
45
|
+
return onPageRequest(await ensureResolvedRouteContext());
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error instanceof RedirectError) {
|
|
50
|
+
const ctx = routeCtx?.ctx;
|
|
51
|
+
await emitAIEvent({
|
|
52
|
+
kind: "redirect",
|
|
53
|
+
severity: "info",
|
|
54
|
+
source: "runtime",
|
|
55
|
+
message: "route redirect thrown",
|
|
56
|
+
requestId: typeof ctx?.locals.requestId === "string" ? ctx.locals.requestId : void 0,
|
|
57
|
+
traceId: typeof ctx?.locals.traceId === "string" ? ctx.locals.traceId : void 0,
|
|
58
|
+
spanId: typeof ctx?.locals.spanId === "string" ? ctx.locals.spanId : void 0,
|
|
59
|
+
route: match.route.path,
|
|
60
|
+
data: {
|
|
61
|
+
method: request.method,
|
|
62
|
+
pathname: ctx?.url.pathname ?? new URL(request.url).pathname,
|
|
63
|
+
status: error.status,
|
|
64
|
+
requestKind
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return new Response(null, {
|
|
68
|
+
status: error.status,
|
|
69
|
+
headers: {
|
|
70
|
+
Location: sanitizeRedirectTarget(error.url, securityPolicy.trustedOrigin ?? routeCtx?.ctx.url ?? new URL(request.url))
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (onRouteError && routeCtx)
|
|
75
|
+
return onRouteError(error, routeCtx);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
async function ensureResolvedRouteContext() {
|
|
79
|
+
if (resolvedRouteCtx)
|
|
80
|
+
return resolvedRouteCtx;
|
|
81
|
+
if (!routeCtx)
|
|
82
|
+
throw Error("Route context is not initialized");
|
|
83
|
+
const resolved = await resolvePageRoute(mod, match, routeCtx.ctx);
|
|
84
|
+
if (!resolved)
|
|
85
|
+
throw Error("Route has no default export");
|
|
86
|
+
resolvedRouteCtx = { ...routeCtx, resolved };
|
|
87
|
+
return resolvedRouteCtx;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function loadRouteMiddlewares(match, mod, extraMiddlewares) {
|
|
91
|
+
const middlewares = [...extraMiddlewares];
|
|
92
|
+
for (const mwPath of match.route.middlewarePaths) {
|
|
93
|
+
const mwMod = await import(mwPath);
|
|
94
|
+
if (typeof mwMod.default === "function")
|
|
95
|
+
middlewares.push(mwMod.default);
|
|
96
|
+
}
|
|
97
|
+
if (typeof mod.guard === "function")
|
|
98
|
+
middlewares.push(mod.guard);
|
|
99
|
+
return middlewares;
|
|
100
|
+
}
|
|
101
|
+
async function handleActionRequest(action, ctx, request) {
|
|
102
|
+
const result = await handleAction(action, ctx);
|
|
103
|
+
if (request.headers.get("Accept")?.includes("application/json"))
|
|
104
|
+
return new Response(JSON.stringify(result), {
|
|
105
|
+
status: result.status,
|
|
106
|
+
headers: { "Content-Type": "application/json" }
|
|
107
|
+
});
|
|
108
|
+
return new Response(null, {
|
|
109
|
+
status: 303,
|
|
110
|
+
headers: { Location: request.url }
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MatchResult } from "../router/matcher.js";
|
|
2
|
+
import type { Context } from "./middleware.js";
|
|
3
|
+
import { type HTMLWrapOptions } from "./html-shell.js";
|
|
4
|
+
import { type ResolvedPageRoute } from "./page-render.js";
|
|
5
|
+
interface RouteResponseOptions {
|
|
6
|
+
match: MatchResult;
|
|
7
|
+
ctx: Context;
|
|
8
|
+
resolved: ResolvedPageRoute;
|
|
9
|
+
clientScript?: string;
|
|
10
|
+
nonce?: string;
|
|
11
|
+
secHeaders?: Record<string, string>;
|
|
12
|
+
wrapHTML?: (body: string, nonce: string | undefined, options?: HTMLWrapOptions) => string;
|
|
13
|
+
}
|
|
14
|
+
export declare function renderRoutePageResponse(options: RouteResponseOptions): Promise<Response>;
|
|
15
|
+
export declare function renderRoutePartialResponse(options: RouteResponseOptions): Response;
|
|
16
|
+
export declare function renderRouteErrorBoundaryResponse(errorPath: string, error: Error, options: {
|
|
17
|
+
match: MatchResult;
|
|
18
|
+
nonce?: string;
|
|
19
|
+
secHeaders?: Record<string, string>;
|
|
20
|
+
wrapHTML: (body: string, nonce: string | undefined, options?: HTMLWrapOptions) => string;
|
|
21
|
+
}): Promise<Response>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { renderToString, ssrJsx } from "../runtime/server.js";
|
|
2
|
+
import { renderToStream, streamJsx } from "../runtime/stream.js";
|
|
3
|
+
import { getServerHead, resetServerHead } from "../runtime/head.js";
|
|
4
|
+
import {
|
|
5
|
+
buildPartialResponsePayload,
|
|
6
|
+
renderPageDocument
|
|
7
|
+
} from "./page-render.js";
|
|
8
|
+
import { partialNavigationHeaders } from "./partial-navigation.js";
|
|
9
|
+
export async function renderRoutePageResponse(options) {
|
|
10
|
+
const { match, ctx, resolved, clientScript, nonce, secHeaders = {}, wrapHTML } = options, { pageComponent, loaderData, cssFiles, renderMode } = resolved, pageProps = { params: match.params, ctx, data: loaderData }, htmlOptions = {
|
|
11
|
+
clientScript,
|
|
12
|
+
loaderData,
|
|
13
|
+
params: match.params,
|
|
14
|
+
cssFiles
|
|
15
|
+
};
|
|
16
|
+
if (renderMode === "stream") {
|
|
17
|
+
if (!wrapHTML)
|
|
18
|
+
throw Error("wrapHTML is required for streaming page responses");
|
|
19
|
+
resetServerHead();
|
|
20
|
+
const vnode = streamJsx(pageComponent, pageProps), stream = renderToStream(vnode, {
|
|
21
|
+
shell: (body) => wrapHTML(body, nonce, {
|
|
22
|
+
...htmlOptions,
|
|
23
|
+
headElements: getServerHead()
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
return new Response(stream, {
|
|
27
|
+
headers: { "Content-Type": "text/html", ...secHeaders }
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const rendered = renderPageDocument(pageComponent, ctx, match.params, loaderData);
|
|
31
|
+
if (!wrapHTML)
|
|
32
|
+
return new Response(rendered.html, {
|
|
33
|
+
headers: { "Content-Type": "text/html", ...secHeaders }
|
|
34
|
+
});
|
|
35
|
+
const html = wrapHTML(rendered.html, nonce, {
|
|
36
|
+
...htmlOptions,
|
|
37
|
+
headElements: rendered.headElements
|
|
38
|
+
});
|
|
39
|
+
return new Response(html, {
|
|
40
|
+
headers: { "Content-Type": "text/html", ...secHeaders }
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function renderRoutePartialResponse(options) {
|
|
44
|
+
const { match, ctx, resolved, clientScript, secHeaders = {} } = options, { pageComponent, loaderData, cssFiles } = resolved, rendered = renderPageDocument(pageComponent, ctx, match.params, loaderData), payload = buildPartialResponsePayload(rendered, loaderData, match.params, cssFiles, clientScript);
|
|
45
|
+
return new Response(JSON.stringify(payload), {
|
|
46
|
+
headers: partialNavigationHeaders(secHeaders)
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export async function renderRouteErrorBoundaryResponse(errorPath, error, options) {
|
|
50
|
+
const { match, nonce, secHeaders = {}, wrapHTML } = options, ErrorComponent = (await import(errorPath)).default;
|
|
51
|
+
if (typeof ErrorComponent !== "function")
|
|
52
|
+
throw error;
|
|
53
|
+
const vnode = ssrJsx(ErrorComponent, { error, params: match.params }), body = renderToString(vnode), html = wrapHTML(body, nonce, { title: "Error" });
|
|
54
|
+
return new Response(html, {
|
|
55
|
+
status: 500,
|
|
56
|
+
headers: { "Content-Type": "text/html", ...secHeaders }
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export function hashRPC(filePath, index) {
|
|
3
|
+
return createHash("sha256").update(`${filePath}:${index}`).digest("hex").slice(0, 12);
|
|
4
|
+
}
|
|
5
|
+
export function scanServerCalls(source, filePath) {
|
|
6
|
+
return [...source.matchAll(/\bserver\s*\(\s*(?=async\s|function\s)/g)].map((_, i) => hashRPC(filePath, i));
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const RPC_PROTOCOL_VERSION: 1;
|
|
2
|
+
export declare const RPC_CONTENT_TYPE = "application/vnd.gorsee-rpc+json";
|
|
3
|
+
export declare const RPC_ACCEPTED_CONTENT_TYPES: readonly ["application/vnd.gorsee-rpc+json", "application/json"];
|
|
4
|
+
export interface RPCRequestEnvelope {
|
|
5
|
+
v: typeof RPC_PROTOCOL_VERSION;
|
|
6
|
+
args: unknown[];
|
|
7
|
+
}
|
|
8
|
+
export interface RPCSuccessEnvelope {
|
|
9
|
+
v: typeof RPC_PROTOCOL_VERSION;
|
|
10
|
+
ok: true;
|
|
11
|
+
encoding: "devalue";
|
|
12
|
+
data: string;
|
|
13
|
+
}
|
|
14
|
+
export interface RPCErrorEnvelope {
|
|
15
|
+
v: typeof RPC_PROTOCOL_VERSION;
|
|
16
|
+
ok: false;
|
|
17
|
+
error: string;
|
|
18
|
+
}
|
|
19
|
+
export type RPCResponseEnvelope = RPCSuccessEnvelope | RPCErrorEnvelope;
|
|
20
|
+
export declare function encodeRPCSuccess(data: string): RPCSuccessEnvelope;
|
|
21
|
+
export declare function encodeRPCError(error: string): RPCErrorEnvelope;
|
|
22
|
+
export declare function decodeRPCRequest(body: unknown): unknown[] | null;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const RPC_PROTOCOL_VERSION = 1, RPC_CONTENT_TYPE = "application/vnd.gorsee-rpc+json", RPC_ACCEPTED_CONTENT_TYPES = [RPC_CONTENT_TYPE, "application/json"];
|
|
2
|
+
export function encodeRPCSuccess(data) {
|
|
3
|
+
return {
|
|
4
|
+
v: RPC_PROTOCOL_VERSION,
|
|
5
|
+
ok: !0,
|
|
6
|
+
encoding: "devalue",
|
|
7
|
+
data
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function encodeRPCError(error) {
|
|
11
|
+
return {
|
|
12
|
+
v: RPC_PROTOCOL_VERSION,
|
|
13
|
+
ok: !1,
|
|
14
|
+
error
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function decodeRPCRequest(body) {
|
|
18
|
+
if (Array.isArray(body))
|
|
19
|
+
return body;
|
|
20
|
+
if (!body || typeof body !== "object")
|
|
21
|
+
return null;
|
|
22
|
+
const candidate = body;
|
|
23
|
+
if (candidate.v !== RPC_PROTOCOL_VERSION)
|
|
24
|
+
return null;
|
|
25
|
+
if (!Array.isArray(candidate.args))
|
|
26
|
+
return null;
|
|
27
|
+
return candidate.args;
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function createScopedRPCRegistry(registry, scope) {
|
|
2
|
+
const prefix = `${scope}:`, fileCounters = new Map, scopedIds = new Set;
|
|
3
|
+
return {
|
|
4
|
+
getHandler: (id) => registry.getHandler(prefix + id),
|
|
5
|
+
setHandler: (id, fn) => {
|
|
6
|
+
const scopedId = prefix + id;
|
|
7
|
+
scopedIds.add(scopedId);
|
|
8
|
+
registry.setHandler(scopedId, fn);
|
|
9
|
+
},
|
|
10
|
+
deleteHandler: (id) => {
|
|
11
|
+
const scopedId = prefix + id;
|
|
12
|
+
scopedIds.delete(scopedId);
|
|
13
|
+
registry.deleteHandler(scopedId);
|
|
14
|
+
},
|
|
15
|
+
clear: () => {
|
|
16
|
+
for (const scopedId of scopedIds)
|
|
17
|
+
registry.deleteHandler(scopedId);
|
|
18
|
+
scopedIds.clear();
|
|
19
|
+
fileCounters.clear();
|
|
20
|
+
},
|
|
21
|
+
getFileCallCount: (file) => fileCounters.get(file) ?? 0,
|
|
22
|
+
setFileCallCount: (file, count) => {
|
|
23
|
+
fileCounters.set(file, count);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RPC_ACCEPTED_CONTENT_TYPES, RPC_CONTENT_TYPE } from "./rpc-protocol.js";
|
|
2
|
+
export interface ServerOptions {
|
|
3
|
+
}
|
|
4
|
+
export type RPCHandler = (...args: unknown[]) => Promise<unknown>;
|
|
5
|
+
export interface RPCRegistry {
|
|
6
|
+
getHandler(id: string): RPCHandler | undefined;
|
|
7
|
+
setHandler(id: string, fn: RPCHandler): void;
|
|
8
|
+
deleteHandler(id: string): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
getFileCallCount(file: string): number;
|
|
11
|
+
setFileCallCount(file: string, count: number): void;
|
|
12
|
+
}
|
|
13
|
+
export declare function createMemoryRPCRegistry(): RPCRegistry;
|
|
14
|
+
export declare function __registerRPC(id: string, fn: RPCHandler): void;
|
|
15
|
+
export declare function __resetRPCState(): void;
|
|
16
|
+
export declare function getRPCHandler(id: string): RPCHandler | undefined;
|
|
17
|
+
export declare function server<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => Promise<TReturn>, _options?: ServerOptions): (...args: TArgs) => Promise<TReturn>;
|
|
18
|
+
export declare function handleRPCRequestWithRegistry(request: Request, registry: Pick<RPCRegistry, "getHandler">): Promise<Response | null>;
|
|
19
|
+
export { RPC_CONTENT_TYPE, RPC_ACCEPTED_CONTENT_TYPES };
|
|
20
|
+
export declare function handleRPCRequest(request: Request): Promise<Response | null>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { stringify } from "devalue";
|
|
2
|
+
import { hashRPC } from "./rpc-hash.js";
|
|
3
|
+
import {
|
|
4
|
+
decodeRPCRequest,
|
|
5
|
+
encodeRPCError,
|
|
6
|
+
encodeRPCSuccess,
|
|
7
|
+
RPC_ACCEPTED_CONTENT_TYPES,
|
|
8
|
+
RPC_CONTENT_TYPE
|
|
9
|
+
} from "./rpc-protocol.js";
|
|
10
|
+
const MAX_RPC_PAYLOAD = 1048576;
|
|
11
|
+
export function createMemoryRPCRegistry() {
|
|
12
|
+
const rpcHandlers = new Map, fileCallCounters = new Map;
|
|
13
|
+
return {
|
|
14
|
+
getHandler: (id) => rpcHandlers.get(id),
|
|
15
|
+
setHandler: (id, fn) => {
|
|
16
|
+
rpcHandlers.set(id, fn);
|
|
17
|
+
},
|
|
18
|
+
deleteHandler: (id) => {
|
|
19
|
+
rpcHandlers.delete(id);
|
|
20
|
+
},
|
|
21
|
+
clear: () => {
|
|
22
|
+
rpcHandlers.clear();
|
|
23
|
+
fileCallCounters.clear();
|
|
24
|
+
},
|
|
25
|
+
getFileCallCount: (file) => fileCallCounters.get(file) ?? 0,
|
|
26
|
+
setFileCallCount: (file, count) => {
|
|
27
|
+
fileCallCounters.set(file, count);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const defaultRPCRegistry = createMemoryRPCRegistry();
|
|
32
|
+
export function __registerRPC(id, fn) {
|
|
33
|
+
defaultRPCRegistry.setHandler(id, fn);
|
|
34
|
+
}
|
|
35
|
+
export function __resetRPCState() {
|
|
36
|
+
defaultRPCRegistry.clear();
|
|
37
|
+
}
|
|
38
|
+
export function getRPCHandler(id) {
|
|
39
|
+
return defaultRPCRegistry.getHandler(id);
|
|
40
|
+
}
|
|
41
|
+
function getCallerFile() {
|
|
42
|
+
const orig = Error.prepareStackTrace;
|
|
43
|
+
Error.prepareStackTrace = (_err, stack) => stack;
|
|
44
|
+
const stack = Error().stack;
|
|
45
|
+
Error.prepareStackTrace = orig;
|
|
46
|
+
for (let i = 2;i < stack.length; i++) {
|
|
47
|
+
const file = stack[i]?.getFileName();
|
|
48
|
+
if (file && !file.includes("/server/rpc.ts") && !file.includes("node_modules"))
|
|
49
|
+
return file;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
export function server(fn, _options) {
|
|
54
|
+
const callerFile = getCallerFile();
|
|
55
|
+
if (callerFile) {
|
|
56
|
+
const counter = defaultRPCRegistry.getFileCallCount(callerFile);
|
|
57
|
+
defaultRPCRegistry.setFileCallCount(callerFile, counter + 1);
|
|
58
|
+
const id = hashRPC(callerFile, counter);
|
|
59
|
+
defaultRPCRegistry.setHandler(id, fn);
|
|
60
|
+
}
|
|
61
|
+
return fn;
|
|
62
|
+
}
|
|
63
|
+
export async function handleRPCRequestWithRegistry(request, registry) {
|
|
64
|
+
const match = new URL(request.url).pathname.match(/^\/api\/_rpc\/([a-zA-Z0-9]+)$/);
|
|
65
|
+
if (!match)
|
|
66
|
+
return null;
|
|
67
|
+
if (request.method !== "POST")
|
|
68
|
+
return new Response(JSON.stringify(encodeRPCError("Method not allowed")), {
|
|
69
|
+
status: 405,
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": RPC_CONTENT_TYPE,
|
|
72
|
+
Allow: "POST"
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const id = match[1], handler = registry.getHandler(id);
|
|
76
|
+
if (!handler)
|
|
77
|
+
return new Response(JSON.stringify(encodeRPCError(`RPC handler not found: ${id}`)), {
|
|
78
|
+
status: 404,
|
|
79
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
80
|
+
});
|
|
81
|
+
try {
|
|
82
|
+
let args = [];
|
|
83
|
+
if (Number(request.headers.get("content-length") ?? "0") > MAX_RPC_PAYLOAD)
|
|
84
|
+
return new Response(JSON.stringify(encodeRPCError("Request body too large")), {
|
|
85
|
+
status: 413,
|
|
86
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
87
|
+
});
|
|
88
|
+
const reader = request.body?.getReader();
|
|
89
|
+
let bodyBytes = 0;
|
|
90
|
+
const chunks = [];
|
|
91
|
+
if (reader)
|
|
92
|
+
while (!0) {
|
|
93
|
+
const { done, value } = await reader.read();
|
|
94
|
+
if (done)
|
|
95
|
+
break;
|
|
96
|
+
bodyBytes += value.byteLength;
|
|
97
|
+
if (bodyBytes > MAX_RPC_PAYLOAD) {
|
|
98
|
+
reader.cancel();
|
|
99
|
+
return new Response(JSON.stringify(encodeRPCError("Request body too large")), {
|
|
100
|
+
status: 413,
|
|
101
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
chunks.push(value);
|
|
105
|
+
}
|
|
106
|
+
const body = new TextDecoder().decode(chunks.length === 1 ? chunks[0] : Buffer.concat(chunks));
|
|
107
|
+
if (body) {
|
|
108
|
+
let parsed;
|
|
109
|
+
try {
|
|
110
|
+
parsed = JSON.parse(body);
|
|
111
|
+
} catch {
|
|
112
|
+
return new Response(JSON.stringify(encodeRPCError("Invalid JSON in request body")), {
|
|
113
|
+
status: 400,
|
|
114
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const decodedArgs = decodeRPCRequest(parsed);
|
|
118
|
+
if (!decodedArgs)
|
|
119
|
+
return new Response(JSON.stringify(encodeRPCError("RPC args must be an array")), {
|
|
120
|
+
status: 400,
|
|
121
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
122
|
+
});
|
|
123
|
+
args = decodedArgs;
|
|
124
|
+
}
|
|
125
|
+
const result = await handler(...args), serialized = stringify(result);
|
|
126
|
+
if (Buffer.byteLength(serialized, "utf-8") > MAX_RPC_PAYLOAD)
|
|
127
|
+
return new Response(JSON.stringify(encodeRPCError("Response body too large")), {
|
|
128
|
+
status: 413,
|
|
129
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
130
|
+
});
|
|
131
|
+
return new Response(JSON.stringify(encodeRPCSuccess(serialized)), {
|
|
132
|
+
status: 200,
|
|
133
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
134
|
+
});
|
|
135
|
+
} catch (err) {
|
|
136
|
+
const message = err instanceof Error ? err.message : "Internal server error";
|
|
137
|
+
return new Response(JSON.stringify(encodeRPCError(message)), {
|
|
138
|
+
status: 500,
|
|
139
|
+
headers: { "Content-Type": RPC_CONTENT_TYPE }
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export { RPC_CONTENT_TYPE, RPC_ACCEPTED_CONTENT_TYPES };
|
|
145
|
+
export async function handleRPCRequest(request) {
|
|
146
|
+
return handleRPCRequestWithRegistry(request, defaultRPCRegistry);
|
|
147
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type AIEventSource, type AITraceContext } from "../ai/index.js";
|
|
2
|
+
import type { RuntimeRequestSurface } from "./request-surface.js";
|
|
3
|
+
type DispatchableRuntimeSurface = Exclude<RuntimeRequestSurface, "hmr">;
|
|
4
|
+
export interface RuntimeDispatchResult {
|
|
5
|
+
surface: DispatchableRuntimeSurface;
|
|
6
|
+
response: Response;
|
|
7
|
+
}
|
|
8
|
+
export interface RuntimeDispatchOptions {
|
|
9
|
+
plan: DispatchableRuntimeSurface[];
|
|
10
|
+
pathname: string;
|
|
11
|
+
request: Request;
|
|
12
|
+
trace: Pick<AITraceContext, "requestId" | "traceId" | "spanId">;
|
|
13
|
+
startTs: number;
|
|
14
|
+
source: AIEventSource;
|
|
15
|
+
route?: string;
|
|
16
|
+
handlers: Partial<Record<DispatchableRuntimeSurface, () => Promise<Response | null>>>;
|
|
17
|
+
}
|
|
18
|
+
export declare function dispatchRuntimeRequestPlan(options: RuntimeDispatchOptions): Promise<RuntimeDispatchResult | null>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { emitAIEvent } from "../ai/index.js";
|
|
2
|
+
export async function dispatchRuntimeRequestPlan(options) {
|
|
3
|
+
for (const surface of options.plan) {
|
|
4
|
+
const handler = options.handlers[surface];
|
|
5
|
+
if (!handler)
|
|
6
|
+
continue;
|
|
7
|
+
const response = await handler();
|
|
8
|
+
if (!response)
|
|
9
|
+
continue;
|
|
10
|
+
if (surface === "not-found")
|
|
11
|
+
await emitAIEvent({
|
|
12
|
+
kind: "route.miss",
|
|
13
|
+
severity: "warn",
|
|
14
|
+
source: options.source,
|
|
15
|
+
message: "no route matched",
|
|
16
|
+
requestId: options.trace.requestId,
|
|
17
|
+
traceId: options.trace.traceId,
|
|
18
|
+
spanId: options.trace.spanId,
|
|
19
|
+
durationMs: Number((performance.now() - options.startTs).toFixed(2)),
|
|
20
|
+
data: {
|
|
21
|
+
method: options.request.method,
|
|
22
|
+
pathname: options.pathname
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
else
|
|
26
|
+
await emitAIEvent({
|
|
27
|
+
kind: "request.finish",
|
|
28
|
+
severity: response.status >= 400 ? "warn" : "info",
|
|
29
|
+
source: options.source,
|
|
30
|
+
message: describeSurfaceMessage(surface),
|
|
31
|
+
requestId: options.trace.requestId,
|
|
32
|
+
traceId: options.trace.traceId,
|
|
33
|
+
spanId: options.trace.spanId,
|
|
34
|
+
route: options.route,
|
|
35
|
+
durationMs: Number((performance.now() - options.startTs).toFixed(2)),
|
|
36
|
+
data: {
|
|
37
|
+
method: options.request.method,
|
|
38
|
+
pathname: options.pathname,
|
|
39
|
+
status: response.status,
|
|
40
|
+
handler: describeSurfaceHandler(surface, response)
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return { surface, response };
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function describeSurfaceMessage(surface) {
|
|
48
|
+
switch (surface) {
|
|
49
|
+
case "rpc":
|
|
50
|
+
return "rpc request handled";
|
|
51
|
+
case "bundle":
|
|
52
|
+
return "client bundle served";
|
|
53
|
+
case "static":
|
|
54
|
+
return "static asset served";
|
|
55
|
+
case "prerendered":
|
|
56
|
+
return "prerendered page served";
|
|
57
|
+
case "route":
|
|
58
|
+
return "route request handled";
|
|
59
|
+
case "not-found":
|
|
60
|
+
return "no route matched";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function describeSurfaceHandler(surface, response) {
|
|
64
|
+
if (surface === "route")
|
|
65
|
+
return response.headers.get("Content-Type")?.includes("application/json") ? "partial" : "route";
|
|
66
|
+
return surface;
|
|
67
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type EndpointExecutionContext, type EndpointExecutionTrace } from "./endpoint-execution.js";
|
|
2
|
+
import type { MiddlewareFn } from "./middleware.js";
|
|
3
|
+
import type { RequestExecutionKind } from "./request-policy.js";
|
|
4
|
+
import type { RequestSecurityPolicy } from "./request-security-policy.js";
|
|
5
|
+
export type ServerExecutionKind = Exclude<RequestExecutionKind, "static">;
|
|
6
|
+
export interface ServerExecutionContext extends EndpointExecutionContext {
|
|
7
|
+
kind: ServerExecutionKind;
|
|
8
|
+
trace: EndpointExecutionTrace;
|
|
9
|
+
}
|
|
10
|
+
export interface ServerExecutionOptions {
|
|
11
|
+
request: Request;
|
|
12
|
+
kind: ServerExecutionKind;
|
|
13
|
+
params?: Record<string, string>;
|
|
14
|
+
middlewares?: MiddlewareFn[];
|
|
15
|
+
trustedOrigin?: string;
|
|
16
|
+
trustForwardedHeaders?: boolean;
|
|
17
|
+
securityPolicy?: RequestSecurityPolicy;
|
|
18
|
+
trace?: EndpointExecutionTrace;
|
|
19
|
+
route?: string;
|
|
20
|
+
handler: (context: ServerExecutionContext) => Promise<Response>;
|
|
21
|
+
}
|
|
22
|
+
export declare function executeServerExecution(options: ServerExecutionOptions): Promise<Response>;
|