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,67 @@
|
|
|
1
|
+
import { resetServerHead, getServerHead } from "../runtime/head.js";
|
|
2
|
+
import { renderToString, ssrJsx } from "../runtime/server.js";
|
|
3
|
+
function resolvePageDataHook(mod) {
|
|
4
|
+
if (typeof mod.load === "function")
|
|
5
|
+
return mod.load;
|
|
6
|
+
if (typeof mod.loader === "function")
|
|
7
|
+
return mod.loader;
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
export async function resolvePageRoute(mod, match, ctx) {
|
|
11
|
+
const component = mod.default;
|
|
12
|
+
if (typeof component !== "function")
|
|
13
|
+
return null;
|
|
14
|
+
const layoutImportPromises = (match.route.layoutPaths ?? []).map((layoutPath) => import(layoutPath)), pageLoaderPromise = resolvePageDataHook(mod)?.(ctx), [layoutMods, loaderData] = await Promise.all([
|
|
15
|
+
Promise.all(layoutImportPromises),
|
|
16
|
+
pageLoaderPromise
|
|
17
|
+
]), layoutLoaderPromises = layoutMods.map((layoutMod) => resolvePageDataHook(layoutMod)?.(ctx)), layoutLoaderResults = await Promise.all(layoutLoaderPromises), cssFiles = [];
|
|
18
|
+
if (typeof mod.css === "string")
|
|
19
|
+
cssFiles.push(mod.css);
|
|
20
|
+
if (Array.isArray(mod.css))
|
|
21
|
+
cssFiles.push(...mod.css);
|
|
22
|
+
let pageComponent = component;
|
|
23
|
+
for (let i = layoutMods.length - 1;i >= 0; i--) {
|
|
24
|
+
const Layout = layoutMods[i].default;
|
|
25
|
+
if (typeof Layout === "function") {
|
|
26
|
+
const inner = pageComponent, layoutData = layoutLoaderResults[i];
|
|
27
|
+
pageComponent = (props) => Layout({ ...props, data: layoutData, children: () => inner(props) });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
component,
|
|
32
|
+
pageComponent,
|
|
33
|
+
loaderData,
|
|
34
|
+
cssFiles,
|
|
35
|
+
renderMode: mod.render ?? "async"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function createClientScriptPath(entryFile) {
|
|
39
|
+
return entryFile ? `/_gorsee/${entryFile}` : void 0;
|
|
40
|
+
}
|
|
41
|
+
export function renderPageDocument(pageComponent, ctx, params, loaderData) {
|
|
42
|
+
resetServerHead();
|
|
43
|
+
const vnode = ssrJsx(pageComponent, { params, ctx, data: loaderData }), html = renderToString(vnode), headElements = getServerHead();
|
|
44
|
+
return {
|
|
45
|
+
html,
|
|
46
|
+
headElements,
|
|
47
|
+
title: extractTitle(headElements)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function buildPartialResponsePayload(rendered, loaderData, params, cssFiles, clientScript) {
|
|
51
|
+
return {
|
|
52
|
+
html: rendered.html,
|
|
53
|
+
data: loaderData,
|
|
54
|
+
params: Object.keys(params).length > 0 ? params : void 0,
|
|
55
|
+
title: rendered.title,
|
|
56
|
+
css: cssFiles.length > 0 ? cssFiles : void 0,
|
|
57
|
+
script: clientScript
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function extractTitle(headElements) {
|
|
61
|
+
for (const element of headElements) {
|
|
62
|
+
const titleMatch = element.match(/<title>(.+?)<\/title>/);
|
|
63
|
+
if (titleMatch)
|
|
64
|
+
return titleMatch[1];
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const PARTIAL_NAV_HEADER = "X-Gorsee-Navigate";
|
|
2
|
+
export declare const PARTIAL_NAV_VALUE = "partial";
|
|
3
|
+
export declare function isPartialNavigationRequest(request: Request): boolean;
|
|
4
|
+
export declare function partialNavigationHeaders(extraHeaders?: Record<string, string>): Record<string, string>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const PARTIAL_NAV_HEADER = "X-Gorsee-Navigate", PARTIAL_NAV_VALUE = "partial";
|
|
2
|
+
export function isPartialNavigationRequest(request) {
|
|
3
|
+
if (request.method !== "GET")
|
|
4
|
+
return !1;
|
|
5
|
+
if (request.headers.get(PARTIAL_NAV_HEADER) !== PARTIAL_NAV_VALUE)
|
|
6
|
+
return !1;
|
|
7
|
+
return (request.headers.get("Accept") ?? "").includes("application/json");
|
|
8
|
+
}
|
|
9
|
+
export function partialNavigationHeaders(extraHeaders = {}) {
|
|
10
|
+
return {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
"Cache-Control": "no-store",
|
|
13
|
+
Vary: "Accept, X-Gorsee-Navigate",
|
|
14
|
+
...extraHeaders
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MiddlewareFn } from "./middleware.js";
|
|
2
|
+
/** Compose multiple middleware into a single middleware function */
|
|
3
|
+
export declare function pipe(...middlewares: MiddlewareFn[]): MiddlewareFn;
|
|
4
|
+
/** Create a conditional middleware — runs inner only if predicate passes */
|
|
5
|
+
export declare function when(predicate: (ctx: import("./middleware.js").Context) => boolean, middleware: MiddlewareFn): MiddlewareFn;
|
|
6
|
+
/** Create a middleware that runs only for specific HTTP methods */
|
|
7
|
+
export declare function forMethods(methods: string[], middleware: MiddlewareFn): MiddlewareFn;
|
|
8
|
+
/** Create a middleware that runs only for specific path prefixes */
|
|
9
|
+
export declare function forPaths(prefixes: string[], middleware: MiddlewareFn): MiddlewareFn;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function pipe(...middlewares) {
|
|
2
|
+
if (middlewares.length === 0)
|
|
3
|
+
return async (_ctx, next) => next();
|
|
4
|
+
if (middlewares.length === 1)
|
|
5
|
+
return middlewares[0];
|
|
6
|
+
return async (ctx, next) => {
|
|
7
|
+
let index = 0;
|
|
8
|
+
const run = async () => {
|
|
9
|
+
if (index < middlewares.length) {
|
|
10
|
+
const mw = middlewares[index];
|
|
11
|
+
index++;
|
|
12
|
+
return mw(ctx, run);
|
|
13
|
+
}
|
|
14
|
+
return next();
|
|
15
|
+
};
|
|
16
|
+
return run();
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function when(predicate, middleware) {
|
|
20
|
+
return async (ctx, next) => {
|
|
21
|
+
if (predicate(ctx))
|
|
22
|
+
return middleware(ctx, next);
|
|
23
|
+
return next();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function forMethods(methods, middleware) {
|
|
27
|
+
const methodSet = new Set(methods.map((m) => m.toUpperCase()));
|
|
28
|
+
return when((ctx) => methodSet.has(ctx.request.method), middleware);
|
|
29
|
+
}
|
|
30
|
+
export function forPaths(prefixes, middleware) {
|
|
31
|
+
return when((ctx) => prefixes.some((p) => ctx.url.pathname.startsWith(p)), middleware);
|
|
32
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CacheStore } from "./cache.js";
|
|
2
|
+
import { type RedisLikeClient } from "./redis-client.js";
|
|
3
|
+
interface RedisCacheStoreOptions {
|
|
4
|
+
prefix?: string;
|
|
5
|
+
maxEntryAgeMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function createRedisCacheStore(client: RedisLikeClient, options?: RedisCacheStoreOptions): CacheStore & {
|
|
8
|
+
deleteExpired(): Promise<number>;
|
|
9
|
+
};
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildRedisKey,
|
|
3
|
+
deleteExpiredRedisKeys,
|
|
4
|
+
stripRedisPrefix
|
|
5
|
+
} from "./redis-client.js";
|
|
6
|
+
import { safeJSONParse } from "../ai/json.js";
|
|
7
|
+
function isExpired(entry, maxEntryAgeMs) {
|
|
8
|
+
return Date.now() - entry.createdAt > maxEntryAgeMs;
|
|
9
|
+
}
|
|
10
|
+
export function createRedisCacheStore(client, options = {}) {
|
|
11
|
+
const prefix = options.prefix ?? "gorsee:cache", maxEntryAgeMs = options.maxEntryAgeMs ?? 86400000;
|
|
12
|
+
return {
|
|
13
|
+
async get(key) {
|
|
14
|
+
const raw = await client.get(buildRedisKey(prefix, key));
|
|
15
|
+
if (!raw)
|
|
16
|
+
return;
|
|
17
|
+
const payload = safeJSONParse(raw);
|
|
18
|
+
if (!payload?.entry) {
|
|
19
|
+
await client.del(buildRedisKey(prefix, key));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (isExpired(payload.entry, maxEntryAgeMs)) {
|
|
23
|
+
await client.del(buildRedisKey(prefix, key));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
return payload.entry;
|
|
27
|
+
},
|
|
28
|
+
async set(key, entry) {
|
|
29
|
+
const redisKey = buildRedisKey(prefix, key);
|
|
30
|
+
await client.set(redisKey, JSON.stringify({ entry }));
|
|
31
|
+
if (client.expire)
|
|
32
|
+
await client.expire(redisKey, Math.max(1, Math.ceil(maxEntryAgeMs / 1000)));
|
|
33
|
+
},
|
|
34
|
+
async delete(key) {
|
|
35
|
+
await client.del(buildRedisKey(prefix, key));
|
|
36
|
+
},
|
|
37
|
+
async clear() {
|
|
38
|
+
const keys = await client.keys(`${prefix}:*`);
|
|
39
|
+
if (keys.length === 0)
|
|
40
|
+
return;
|
|
41
|
+
for (const key of keys)
|
|
42
|
+
await client.del(key);
|
|
43
|
+
},
|
|
44
|
+
async keys() {
|
|
45
|
+
const keys = await client.keys(`${prefix}:*`), visibleKeys = [];
|
|
46
|
+
for (const key of keys) {
|
|
47
|
+
const raw = await client.get(key);
|
|
48
|
+
if (!raw)
|
|
49
|
+
continue;
|
|
50
|
+
const payload = safeJSONParse(raw);
|
|
51
|
+
if (!payload?.entry) {
|
|
52
|
+
await client.del(key);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (isExpired(payload.entry, maxEntryAgeMs)) {
|
|
56
|
+
await client.del(key);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
visibleKeys.push(stripRedisPrefix(prefix, key));
|
|
60
|
+
}
|
|
61
|
+
return visibleKeys;
|
|
62
|
+
},
|
|
63
|
+
async deleteExpired() {
|
|
64
|
+
return deleteExpiredRedisKeys(client, `${prefix}:*`, Date.now(), (raw) => {
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(raw).entry.createdAt;
|
|
67
|
+
} catch {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
}, maxEntryAgeMs);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
type Awaitable<T> = T | Promise<T>;
|
|
2
|
+
export interface RedisLikeClient {
|
|
3
|
+
get(key: string): Awaitable<string | null>;
|
|
4
|
+
set(key: string, value: string): Awaitable<unknown>;
|
|
5
|
+
del(key: string): Awaitable<number>;
|
|
6
|
+
keys(pattern: string): Awaitable<string[]>;
|
|
7
|
+
incr?(key: string): Awaitable<number>;
|
|
8
|
+
expire?(key: string, seconds: number): Awaitable<number>;
|
|
9
|
+
pttl?(key: string): Awaitable<number>;
|
|
10
|
+
ttl?(key: string): Awaitable<number>;
|
|
11
|
+
}
|
|
12
|
+
export declare function buildRedisKey(prefix: string, key: string): string;
|
|
13
|
+
export declare function stripRedisPrefix(prefix: string, key: string): string;
|
|
14
|
+
export interface NodeRedisClientLike {
|
|
15
|
+
get(key: string): Awaitable<string | null>;
|
|
16
|
+
set(key: string, value: string): Awaitable<unknown>;
|
|
17
|
+
del(key: string): Awaitable<number>;
|
|
18
|
+
keys(pattern: string): Awaitable<string[]>;
|
|
19
|
+
incr?(key: string): Awaitable<number>;
|
|
20
|
+
expire?(key: string, seconds: number): Awaitable<number>;
|
|
21
|
+
pttl?(key: string): Awaitable<number>;
|
|
22
|
+
ttl?(key: string): Awaitable<number>;
|
|
23
|
+
}
|
|
24
|
+
export interface IORedisClientLike {
|
|
25
|
+
get(key: string): Awaitable<string | null>;
|
|
26
|
+
set(key: string, value: string): Awaitable<unknown>;
|
|
27
|
+
del(key: string): Awaitable<number>;
|
|
28
|
+
keys(pattern: string): Awaitable<string[]>;
|
|
29
|
+
incr?(key: string): Awaitable<number>;
|
|
30
|
+
expire?(key: string, seconds: number): Awaitable<number>;
|
|
31
|
+
pttl?(key: string): Awaitable<number>;
|
|
32
|
+
ttl?(key: string): Awaitable<number>;
|
|
33
|
+
}
|
|
34
|
+
export declare function createNodeRedisLikeClient(client: NodeRedisClientLike): RedisLikeClient;
|
|
35
|
+
export declare function createIORedisLikeClient(client: IORedisClientLike): RedisLikeClient;
|
|
36
|
+
export declare function deleteExpiredRedisKeys(client: RedisLikeClient, pattern: string, now: number, parseCreatedAt: (value: string) => number | undefined, maxEntryAgeMs: number): Promise<number>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function buildRedisKey(prefix, key) {
|
|
2
|
+
return `${prefix}:${key}`;
|
|
3
|
+
}
|
|
4
|
+
export function stripRedisPrefix(prefix, key) {
|
|
5
|
+
const expected = `${prefix}:`;
|
|
6
|
+
return key.startsWith(expected) ? key.slice(expected.length) : key;
|
|
7
|
+
}
|
|
8
|
+
export function createNodeRedisLikeClient(client) {
|
|
9
|
+
return {
|
|
10
|
+
get: (key) => client.get(key),
|
|
11
|
+
set: (key, value) => client.set(key, value),
|
|
12
|
+
del: (key) => client.del(key),
|
|
13
|
+
keys: (pattern) => client.keys(pattern),
|
|
14
|
+
incr: client.incr ? (key) => client.incr(key) : void 0,
|
|
15
|
+
expire: client.expire ? (key, seconds) => client.expire(key, seconds) : void 0,
|
|
16
|
+
pttl: client.pttl ? (key) => client.pttl(key) : void 0,
|
|
17
|
+
ttl: client.ttl ? (key) => client.ttl(key) : void 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createIORedisLikeClient(client) {
|
|
21
|
+
return createNodeRedisLikeClient(client);
|
|
22
|
+
}
|
|
23
|
+
export async function deleteExpiredRedisKeys(client, pattern, now, parseCreatedAt, maxEntryAgeMs) {
|
|
24
|
+
let deleted = 0;
|
|
25
|
+
for (const key of await client.keys(pattern)) {
|
|
26
|
+
const raw = await client.get(key);
|
|
27
|
+
if (raw === null)
|
|
28
|
+
continue;
|
|
29
|
+
const createdAt = parseCreatedAt(raw);
|
|
30
|
+
if (createdAt === void 0)
|
|
31
|
+
continue;
|
|
32
|
+
if (createdAt > now - maxEntryAgeMs)
|
|
33
|
+
continue;
|
|
34
|
+
deleted += await client.del(key);
|
|
35
|
+
}
|
|
36
|
+
return deleted;
|
|
37
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
type RouteModule = Record<string, unknown>;
|
|
2
|
+
export type RequestExecutionKind = "page" | "partial" | "action" | "route-handler" | "rpc" | "static";
|
|
3
|
+
export type RouteRequestExecutionKind = Exclude<RequestExecutionKind, "rpc" | "static">;
|
|
4
|
+
export type RequestVisibility = "public" | "internal";
|
|
5
|
+
export type RequestAccess = "public" | "internal";
|
|
6
|
+
export type RequestMutation = "read" | "write";
|
|
7
|
+
export type RequestResponseShape = "document" | "data" | "raw";
|
|
8
|
+
export interface RequestMetadata {
|
|
9
|
+
request: Request;
|
|
10
|
+
url: URL;
|
|
11
|
+
pathname: string;
|
|
12
|
+
method: string;
|
|
13
|
+
host: string;
|
|
14
|
+
protocol: string;
|
|
15
|
+
trustedOrigin?: string;
|
|
16
|
+
effectiveOrigin: string;
|
|
17
|
+
effectiveHost: string;
|
|
18
|
+
effectiveProto: string;
|
|
19
|
+
origin?: string;
|
|
20
|
+
forwarded?: string;
|
|
21
|
+
forwardedHost?: string;
|
|
22
|
+
forwardedProto?: string;
|
|
23
|
+
forwardedFor?: string;
|
|
24
|
+
proxyTrusted: boolean;
|
|
25
|
+
kind: RequestExecutionKind;
|
|
26
|
+
visibility: RequestVisibility;
|
|
27
|
+
access: RequestAccess;
|
|
28
|
+
mutation: RequestMutation;
|
|
29
|
+
isStateChanging: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface RequestExecutionPolicy {
|
|
32
|
+
kind: RequestExecutionKind;
|
|
33
|
+
visibility: RequestVisibility;
|
|
34
|
+
access: RequestAccess;
|
|
35
|
+
mutation: RequestMutation;
|
|
36
|
+
responseShape: RequestResponseShape;
|
|
37
|
+
requiresTrustedOrigin: boolean;
|
|
38
|
+
allowedContentTypes?: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface RequestPolicyOptions {
|
|
41
|
+
trustedOrigin?: string;
|
|
42
|
+
kind: RequestExecutionKind;
|
|
43
|
+
visibility?: RequestVisibility;
|
|
44
|
+
trustForwardedHeaders?: boolean;
|
|
45
|
+
trustedForwardedHops?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface RequestPolicyValidationOptions {
|
|
48
|
+
allowedContentTypes?: string[];
|
|
49
|
+
}
|
|
50
|
+
export declare function resolveRequestMetadata(request: Request, options: RequestPolicyOptions): RequestMetadata;
|
|
51
|
+
export declare function classifyRouteRequest(mod: RouteModule, request: Request): RouteRequestExecutionKind;
|
|
52
|
+
export declare function validateRequestPolicy(metadata: RequestMetadata, options?: RequestPolicyValidationOptions & Partial<Pick<RequestExecutionPolicy, "requiresTrustedOrigin">>): Response | null;
|
|
53
|
+
export declare function resolveRequestExecutionPolicy(kind: RequestExecutionKind): RequestExecutionPolicy;
|
|
54
|
+
export declare function attachRequestMetadata(locals: Record<string, unknown>, metadata: RequestMetadata, policy?: RequestExecutionPolicy): void;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { isAllowedRequestOrigin } from "./middleware.js";
|
|
2
|
+
import { isPartialNavigationRequest } from "./partial-navigation.js";
|
|
3
|
+
import { RPC_ACCEPTED_CONTENT_TYPES } from "./rpc.js";
|
|
4
|
+
export function resolveRequestMetadata(request, options) {
|
|
5
|
+
const url = new URL(request.url), endpointContract = resolveRequestExecutionPolicy(options.kind), urlProtocol = url.protocol.replace(/:$/, ""), trustedForwardedHops = options.trustForwardedHeaders === !0 ? Math.max(1, options.trustedForwardedHops ?? 1) : 0, forwarded = parseForwardedHeader(request.headers.get("forwarded"), trustedForwardedHops), forwardedHost = normalizeForwardedHost(getTrustedForwardedValue(request.headers.get("x-forwarded-host"), trustedForwardedHops) ?? forwarded.host) ?? forwarded.host ?? void 0, forwardedProto = normalizeForwardedProto(getTrustedForwardedValue(request.headers.get("x-forwarded-proto"), trustedForwardedHops) ?? forwarded.proto) ?? forwarded.proto ?? void 0, forwardedFor = normalizeForwardedFor(getTrustedForwardedValue(request.headers.get("x-forwarded-for"), trustedForwardedHops) ?? forwarded.for) ?? forwarded.for ?? void 0, proxyTrusted = options.trustForwardedHeaders === !0, effectiveHost = proxyTrusted ? forwardedHost ?? (request.headers.get("host") ?? url.host) : request.headers.get("host") ?? url.host, effectiveProto = proxyTrusted ? forwardedProto ?? urlProtocol : urlProtocol;
|
|
6
|
+
return {
|
|
7
|
+
request,
|
|
8
|
+
url,
|
|
9
|
+
pathname: url.pathname,
|
|
10
|
+
method: request.method,
|
|
11
|
+
host: request.headers.get("host") ?? url.host,
|
|
12
|
+
protocol: urlProtocol,
|
|
13
|
+
trustedOrigin: options.trustedOrigin,
|
|
14
|
+
effectiveOrigin: options.trustedOrigin ?? `${effectiveProto}://${effectiveHost}`,
|
|
15
|
+
effectiveHost,
|
|
16
|
+
effectiveProto,
|
|
17
|
+
origin: request.headers.get("origin") ?? void 0,
|
|
18
|
+
forwarded: request.headers.get("forwarded") ?? void 0,
|
|
19
|
+
forwardedHost,
|
|
20
|
+
forwardedProto,
|
|
21
|
+
forwardedFor,
|
|
22
|
+
proxyTrusted,
|
|
23
|
+
kind: options.kind,
|
|
24
|
+
visibility: options.visibility ?? defaultVisibilityForKind(options.kind),
|
|
25
|
+
access: endpointContract.access,
|
|
26
|
+
mutation: endpointContract.mutation,
|
|
27
|
+
isStateChanging: isStateChangingMethod(request.method)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function classifyRouteRequest(mod, request) {
|
|
31
|
+
if (typeof mod.GET === "function" && request.method === "GET" || typeof mod.POST === "function" && request.method === "POST")
|
|
32
|
+
return "route-handler";
|
|
33
|
+
if (request.method === "POST" && typeof mod.action === "function")
|
|
34
|
+
return "action";
|
|
35
|
+
if (isPartialNavigationRequest(request))
|
|
36
|
+
return "partial";
|
|
37
|
+
return "page";
|
|
38
|
+
}
|
|
39
|
+
export function validateRequestPolicy(metadata, options = {}) {
|
|
40
|
+
if (metadata.isStateChanging && options.requiresTrustedOrigin !== !1 && metadata.trustedOrigin && !isAllowedRequestOrigin(metadata.request, metadata.trustedOrigin))
|
|
41
|
+
return new Response("Forbidden", { status: 403 });
|
|
42
|
+
if (options.allowedContentTypes && hasRequestBody(metadata.request)) {
|
|
43
|
+
const contentType = metadata.request.headers.get("content-type") ?? "";
|
|
44
|
+
if (!contentType)
|
|
45
|
+
return new Response("Unsupported Media Type", { status: 415 });
|
|
46
|
+
if (!options.allowedContentTypes.some((allowedType) => contentType.includes(allowedType)))
|
|
47
|
+
return new Response("Unsupported Media Type", { status: 415 });
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
export function resolveRequestExecutionPolicy(kind) {
|
|
52
|
+
switch (kind) {
|
|
53
|
+
case "rpc":
|
|
54
|
+
return {
|
|
55
|
+
kind,
|
|
56
|
+
visibility: "internal",
|
|
57
|
+
access: "internal",
|
|
58
|
+
mutation: "write",
|
|
59
|
+
responseShape: "data",
|
|
60
|
+
requiresTrustedOrigin: !0,
|
|
61
|
+
allowedContentTypes: [...RPC_ACCEPTED_CONTENT_TYPES]
|
|
62
|
+
};
|
|
63
|
+
case "action":
|
|
64
|
+
return {
|
|
65
|
+
kind,
|
|
66
|
+
visibility: "public",
|
|
67
|
+
access: "public",
|
|
68
|
+
mutation: "write",
|
|
69
|
+
responseShape: "data",
|
|
70
|
+
requiresTrustedOrigin: !0,
|
|
71
|
+
allowedContentTypes: [
|
|
72
|
+
"application/x-www-form-urlencoded",
|
|
73
|
+
"multipart/form-data",
|
|
74
|
+
"application/json"
|
|
75
|
+
]
|
|
76
|
+
};
|
|
77
|
+
case "partial":
|
|
78
|
+
return {
|
|
79
|
+
kind,
|
|
80
|
+
visibility: "internal",
|
|
81
|
+
access: "internal",
|
|
82
|
+
mutation: "read",
|
|
83
|
+
responseShape: "data",
|
|
84
|
+
requiresTrustedOrigin: !1
|
|
85
|
+
};
|
|
86
|
+
case "route-handler":
|
|
87
|
+
return {
|
|
88
|
+
kind,
|
|
89
|
+
visibility: "public",
|
|
90
|
+
access: "public",
|
|
91
|
+
mutation: "write",
|
|
92
|
+
responseShape: "raw",
|
|
93
|
+
requiresTrustedOrigin: !0
|
|
94
|
+
};
|
|
95
|
+
case "page":
|
|
96
|
+
case "static":
|
|
97
|
+
return {
|
|
98
|
+
kind,
|
|
99
|
+
visibility: "public",
|
|
100
|
+
access: "public",
|
|
101
|
+
mutation: "read",
|
|
102
|
+
responseShape: kind === "static" ? "raw" : "document",
|
|
103
|
+
requiresTrustedOrigin: !1
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export function attachRequestMetadata(locals, metadata, policy = resolveRequestExecutionPolicy(metadata.kind)) {
|
|
108
|
+
locals.requestKind = metadata.kind;
|
|
109
|
+
locals.requestVisibility = policy.visibility;
|
|
110
|
+
locals.requestPolicy = policy;
|
|
111
|
+
locals.requestAccess = policy.access;
|
|
112
|
+
locals.requestMutation = policy.mutation;
|
|
113
|
+
locals.requestResponseShape = policy.responseShape;
|
|
114
|
+
locals.requestHost = metadata.host;
|
|
115
|
+
locals.requestProtocol = metadata.protocol;
|
|
116
|
+
locals.requestOrigin = metadata.origin;
|
|
117
|
+
locals.requestEffectiveOrigin = metadata.effectiveOrigin;
|
|
118
|
+
locals.requestEffectiveHost = metadata.effectiveHost;
|
|
119
|
+
locals.requestEffectiveProto = metadata.effectiveProto;
|
|
120
|
+
locals.requestProxyTrusted = metadata.proxyTrusted;
|
|
121
|
+
locals.requestForwarded = metadata.forwarded;
|
|
122
|
+
locals.forwardedHost = metadata.forwardedHost;
|
|
123
|
+
locals.forwardedProto = metadata.forwardedProto;
|
|
124
|
+
locals.forwardedFor = metadata.forwardedFor;
|
|
125
|
+
}
|
|
126
|
+
function defaultVisibilityForKind(kind) {
|
|
127
|
+
return kind === "partial" || kind === "rpc" ? "internal" : "public";
|
|
128
|
+
}
|
|
129
|
+
function isStateChangingMethod(method) {
|
|
130
|
+
return !["GET", "HEAD", "OPTIONS"].includes(method.toUpperCase());
|
|
131
|
+
}
|
|
132
|
+
function hasRequestBody(request) {
|
|
133
|
+
return Number(request.headers.get("content-length") ?? "0") > 0 || request.body !== null;
|
|
134
|
+
}
|
|
135
|
+
function parseForwardedHeader(header, trustedHops = 1) {
|
|
136
|
+
if (!header)
|
|
137
|
+
return {};
|
|
138
|
+
const entries = splitHeaderList(header, ",");
|
|
139
|
+
if (entries.length === 0)
|
|
140
|
+
return {};
|
|
141
|
+
const trustedEntry = entries[Math.max(0, entries.length - trustedHops)] ?? entries[entries.length - 1];
|
|
142
|
+
if (!trustedEntry)
|
|
143
|
+
return {};
|
|
144
|
+
const result = {};
|
|
145
|
+
for (const segment of splitHeaderList(trustedEntry, ";")) {
|
|
146
|
+
const [rawKey, rawValue] = segment.split("=", 2);
|
|
147
|
+
if (!rawKey || !rawValue)
|
|
148
|
+
continue;
|
|
149
|
+
const key = rawKey.trim().toLowerCase(), value = normalizeForwardedValue(rawValue);
|
|
150
|
+
if (!value)
|
|
151
|
+
continue;
|
|
152
|
+
if (key === "for")
|
|
153
|
+
result.for = normalizeForwardedFor(value);
|
|
154
|
+
if (key === "host")
|
|
155
|
+
result.host = normalizeForwardedHost(value);
|
|
156
|
+
if (key === "proto")
|
|
157
|
+
result.proto = normalizeForwardedProto(value);
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
function getTrustedForwardedValue(header, trustedHops) {
|
|
162
|
+
if (!header)
|
|
163
|
+
return;
|
|
164
|
+
const values = splitHeaderList(header, ",");
|
|
165
|
+
if (values.length === 0)
|
|
166
|
+
return;
|
|
167
|
+
return normalizeForwardedValue(values[Math.max(0, values.length - trustedHops)] ?? values[values.length - 1]);
|
|
168
|
+
}
|
|
169
|
+
function splitHeaderList(input, separator) {
|
|
170
|
+
const parts = [];
|
|
171
|
+
let current = "", quoted = !1;
|
|
172
|
+
for (const char of input) {
|
|
173
|
+
if (char === '"')
|
|
174
|
+
quoted = !quoted;
|
|
175
|
+
if (char === separator && !quoted) {
|
|
176
|
+
const trimmed = current.trim();
|
|
177
|
+
if (trimmed)
|
|
178
|
+
parts.push(trimmed);
|
|
179
|
+
current = "";
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
current += char;
|
|
183
|
+
}
|
|
184
|
+
const trimmed = current.trim();
|
|
185
|
+
if (trimmed)
|
|
186
|
+
parts.push(trimmed);
|
|
187
|
+
return parts;
|
|
188
|
+
}
|
|
189
|
+
function normalizeForwardedValue(value) {
|
|
190
|
+
if (typeof value !== "string")
|
|
191
|
+
return;
|
|
192
|
+
const normalized = value.trim().replace(/^"|"$/g, "").trim();
|
|
193
|
+
return normalized ? normalized : void 0;
|
|
194
|
+
}
|
|
195
|
+
function normalizeForwardedHost(value) {
|
|
196
|
+
const normalized = normalizeForwardedValue(value);
|
|
197
|
+
if (!normalized)
|
|
198
|
+
return;
|
|
199
|
+
if (/[/?#\s]/.test(normalized))
|
|
200
|
+
return;
|
|
201
|
+
return normalized.toLowerCase();
|
|
202
|
+
}
|
|
203
|
+
function normalizeForwardedProto(value) {
|
|
204
|
+
const normalized = normalizeForwardedValue(value)?.replace(/:$/, "").toLowerCase();
|
|
205
|
+
if (!normalized)
|
|
206
|
+
return;
|
|
207
|
+
return ["http", "https", "ws", "wss"].includes(normalized) ? normalized : void 0;
|
|
208
|
+
}
|
|
209
|
+
function normalizeForwardedFor(value) {
|
|
210
|
+
const normalized = normalizeForwardedValue(value);
|
|
211
|
+
if (!normalized)
|
|
212
|
+
return;
|
|
213
|
+
if (/[/?#\s]/.test(normalized))
|
|
214
|
+
return;
|
|
215
|
+
return normalized;
|
|
216
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type RPCRegistry } from "./rpc.js";
|
|
2
|
+
import type { MiddlewareFn } from "./middleware.js";
|
|
3
|
+
import { type RequestSecurityPolicy } from "./request-security-policy.js";
|
|
4
|
+
interface RateLimitResult {
|
|
5
|
+
allowed: boolean;
|
|
6
|
+
resetAt: number;
|
|
7
|
+
}
|
|
8
|
+
interface RateLimiterLike {
|
|
9
|
+
check(key: string): RateLimitResult | Promise<RateLimitResult>;
|
|
10
|
+
}
|
|
11
|
+
export declare function createRateLimitResponse(rateLimiter: RateLimiterLike, key: string): Promise<Response | null>;
|
|
12
|
+
export declare function applyResponseHeaders(response: Response, headers: Record<string, string>): Response;
|
|
13
|
+
export interface RPCRequestOptions {
|
|
14
|
+
registry?: Pick<RPCRegistry, "getHandler">;
|
|
15
|
+
middlewares?: MiddlewareFn[];
|
|
16
|
+
trustedOrigin?: string;
|
|
17
|
+
trustForwardedHeaders?: boolean;
|
|
18
|
+
trustedForwardedHops?: number;
|
|
19
|
+
securityPolicy?: RequestSecurityPolicy;
|
|
20
|
+
}
|
|
21
|
+
export declare function handleRPCWithHeaders(request: Request, headers: Record<string, string>, options?: RPCRequestOptions): Promise<Response | null>;
|
|
22
|
+
export declare function handleRPCRequestWithPolicy(request: Request, options?: RPCRequestOptions): Promise<Response | null>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { handleRPCRequest, handleRPCRequestWithRegistry } from "./rpc.js";
|
|
2
|
+
import { executeServerExecution } from "./server-execution.js";
|
|
3
|
+
import {
|
|
4
|
+
createRequestSecurityPolicy
|
|
5
|
+
} from "./request-security-policy.js";
|
|
6
|
+
export async function createRateLimitResponse(rateLimiter, key) {
|
|
7
|
+
const result = await rateLimiter.check(key);
|
|
8
|
+
if (result.allowed)
|
|
9
|
+
return null;
|
|
10
|
+
return new Response("Too Many Requests", {
|
|
11
|
+
status: 429,
|
|
12
|
+
headers: {
|
|
13
|
+
"Retry-After": String(Math.ceil((result.resetAt - Date.now()) / 1000))
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export function applyResponseHeaders(response, headers) {
|
|
18
|
+
for (const key in headers)
|
|
19
|
+
response.headers.set(key, headers[key]);
|
|
20
|
+
return response;
|
|
21
|
+
}
|
|
22
|
+
export async function handleRPCWithHeaders(request, headers, options = {}) {
|
|
23
|
+
const response = await handleRPCRequestWithPolicy(request, options);
|
|
24
|
+
if (!response)
|
|
25
|
+
return null;
|
|
26
|
+
return applyResponseHeaders(response, headers);
|
|
27
|
+
}
|
|
28
|
+
export async function handleRPCRequestWithPolicy(request, options = {}) {
|
|
29
|
+
const { registry, middlewares = [] } = options, pathname = new URL(request.url).pathname;
|
|
30
|
+
if (!/^\/api\/_rpc\/[a-zA-Z0-9]+$/.test(pathname))
|
|
31
|
+
return null;
|
|
32
|
+
const securityPolicy = options.securityPolicy ?? createRequestSecurityPolicy({
|
|
33
|
+
trustedOrigin: options.trustedOrigin,
|
|
34
|
+
trustForwardedHeaders: options.trustForwardedHeaders,
|
|
35
|
+
trustedForwardedHops: options.trustedForwardedHops
|
|
36
|
+
});
|
|
37
|
+
return await executeServerExecution({
|
|
38
|
+
request,
|
|
39
|
+
kind: "rpc",
|
|
40
|
+
securityPolicy,
|
|
41
|
+
middlewares,
|
|
42
|
+
route: pathname,
|
|
43
|
+
handler: async () => registry ? await handleRPCRequestWithRegistry(request, registry) : await handleRPCRequest(request)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RequestExecutionPolicy, RequestMetadata } from "./request-policy.js";
|
|
2
|
+
export interface RequestSecurityPolicy {
|
|
3
|
+
trustedOrigin?: string;
|
|
4
|
+
trustForwardedHeaders: boolean;
|
|
5
|
+
trustedForwardedHops: number;
|
|
6
|
+
trustedHosts: string[];
|
|
7
|
+
enforceTrustedHosts: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface RequestSecurityPolicyOptions {
|
|
10
|
+
trustedOrigin?: string;
|
|
11
|
+
trustForwardedHeaders?: boolean;
|
|
12
|
+
trustedForwardedHops?: number;
|
|
13
|
+
trustedHosts?: string[];
|
|
14
|
+
enforceTrustedHosts?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function createRequestSecurityPolicy(options?: RequestSecurityPolicyOptions): RequestSecurityPolicy;
|
|
17
|
+
export declare function validateRequestSecurityPolicy(metadata: RequestMetadata, executionPolicy: RequestExecutionPolicy, securityPolicy: RequestSecurityPolicy): Response | null;
|