create-jen-app 1.2.3 → 1.2.4
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/dist/colors.js +0 -17
- package/dist/create.js +5 -17
- package/dist/generator.js +14 -31
- package/dist/index.js +6 -1
- package/package.json +1 -1
- package/templates/ssr-isr/README.md +77 -0
- package/templates/ssr-isr/build.js +118 -0
- package/templates/ssr-isr/jen.config.ts +109 -0
- package/templates/ssr-isr/jenjs.d.ts +22 -0
- package/templates/ssr-isr/lib/api/(hello).js +9 -0
- package/templates/ssr-isr/lib/auth/cookie-utils.js +79 -0
- package/templates/ssr-isr/lib/auth/index.js +2 -0
- package/templates/ssr-isr/lib/auth/jwt.js +57 -0
- package/templates/ssr-isr/lib/auth/session.js +92 -0
- package/templates/ssr-isr/lib/build/asset-hashing.d.ts +10 -0
- package/templates/ssr-isr/lib/build/asset-hashing.js +25 -0
- package/templates/ssr-isr/lib/build/asset-manifest.d.ts +11 -0
- package/templates/ssr-isr/lib/build/asset-manifest.js +21 -0
- package/templates/{static → ssr-isr}/lib/build/build.d.ts +1 -1
- package/templates/ssr-isr/lib/build/build.js +141 -0
- package/templates/{static → ssr-isr}/lib/build/island-hydration.d.ts +8 -5
- package/templates/ssr-isr/lib/build/island-hydration.js +44 -0
- package/templates/ssr-isr/lib/build/minifier.d.ts +20 -0
- package/templates/ssr-isr/lib/build/minifier.js +46 -0
- package/templates/ssr-isr/lib/build/page-renderer.d.ts +17 -0
- package/templates/ssr-isr/lib/build/page-renderer.js +28 -0
- package/templates/ssr-isr/lib/build/production-build.d.ts +10 -0
- package/templates/ssr-isr/lib/build/production-build.js +13 -0
- package/templates/ssr-isr/lib/build/ssg-pipeline.d.ts +15 -0
- package/templates/ssr-isr/lib/build/ssg-pipeline.js +113 -0
- package/templates/ssr-isr/lib/build-tools/build-site.js +36 -0
- package/templates/ssr-isr/lib/cache/index.js +10 -0
- package/templates/ssr-isr/lib/cache/memory.js +40 -0
- package/templates/ssr-isr/lib/cache/redis.js +61 -0
- package/templates/ssr-isr/lib/cli/banner.js +28 -0
- package/templates/ssr-isr/lib/cli/templates/ssg/jen.config.js +32 -0
- package/templates/ssr-isr/lib/cli/templates/ssg/site/index.js +9 -0
- package/templates/ssr-isr/lib/cli/templates/ssr/jen.config.js +32 -0
- package/templates/ssr-isr/lib/cli/templates/ssr/site/index.js +9 -0
- package/templates/ssr-isr/lib/compilers/esbuild-plugins.js +111 -0
- package/templates/ssr-isr/lib/compilers/svelte.js +44 -0
- package/templates/ssr-isr/lib/compilers/vue.js +90 -0
- package/templates/ssr-isr/lib/core/http.js +71 -0
- package/templates/ssr-isr/lib/core/middleware-hooks.js +97 -0
- package/templates/ssr-isr/lib/core/paths.js +39 -0
- package/templates/ssr-isr/lib/core/routes/match.js +47 -0
- package/templates/ssr-isr/lib/core/routes/scan.js +190 -0
- package/templates/ssr-isr/lib/core/types.js +1 -0
- package/templates/ssr-isr/lib/css/compiler.js +74 -0
- package/templates/ssr-isr/lib/db/connector.js +42 -0
- package/templates/ssr-isr/lib/db/drivers/jdb.js +44 -0
- package/templates/ssr-isr/lib/db/drivers/sql.js +182 -0
- package/templates/ssr-isr/lib/db/index.js +48 -0
- package/templates/ssr-isr/lib/db/types.js +1 -0
- package/templates/ssr-isr/lib/graphql/index.js +52 -0
- package/templates/ssr-isr/lib/graphql/resolvers.js +25 -0
- package/templates/ssr-isr/lib/graphql/schema.js +35 -0
- package/templates/ssr-isr/lib/i18n/en.json +4 -0
- package/templates/ssr-isr/lib/i18n/es.json +4 -0
- package/templates/ssr-isr/lib/i18n/index.js +15 -0
- package/templates/ssr-isr/lib/import/jen-import.js +161 -0
- package/templates/ssr-isr/lib/index.js +116 -0
- package/templates/ssr-isr/lib/jdb/engine.js +275 -0
- package/templates/ssr-isr/lib/jdb/index.js +34 -0
- package/templates/ssr-isr/lib/jdb/types.js +1 -0
- package/templates/ssr-isr/lib/jdb/utils.js +176 -0
- package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.js +0 -17
- package/templates/ssr-isr/lib/middleware/builtins/cors.js +54 -0
- package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.js +0 -17
- package/templates/ssr-isr/lib/middleware/context.js +124 -0
- package/templates/{static → ssr-isr}/lib/middleware/decorators.js +0 -17
- package/templates/{static → ssr-isr}/lib/middleware/errors/handler.js +0 -17
- package/templates/ssr-isr/lib/middleware/errors/http-error.js +10 -0
- package/templates/ssr-isr/lib/middleware/kernel.js +85 -0
- package/templates/ssr-isr/lib/middleware/pipeline.js +148 -0
- package/templates/ssr-isr/lib/middleware/registry.js +85 -0
- package/templates/ssr-isr/lib/middleware/response.js +107 -0
- package/templates/ssr-isr/lib/middleware/types.d.ts +1 -0
- package/templates/ssr-isr/lib/middleware/types.js +1 -0
- package/templates/ssr-isr/lib/middleware/utils/matcher.js +13 -0
- package/templates/{static → ssr-isr}/lib/native/bundle.js +0 -17
- package/templates/{static → ssr-isr}/lib/native/dev-server.js +0 -17
- package/templates/{static → ssr-isr}/lib/native/index.js +0 -17
- package/templates/{static → ssr-isr}/lib/native/optimizer.js +0 -17
- package/templates/ssr-isr/lib/native/style-compiler.js +19 -0
- package/templates/ssr-isr/lib/plugin/loader.js +36 -0
- package/templates/ssr-isr/lib/runtime/client-runtime.js +25 -0
- package/templates/ssr-isr/lib/runtime/hmr.js +59 -0
- package/templates/ssr-isr/lib/runtime/hydrate.js +55 -0
- package/templates/ssr-isr/lib/runtime/island-hydration-client.js +146 -0
- package/templates/ssr-isr/lib/runtime/islands.js +110 -0
- package/templates/ssr-isr/lib/runtime/render.js +244 -0
- package/templates/ssr-isr/lib/server/api-routes.js +237 -0
- package/templates/ssr-isr/lib/server/api.js +108 -0
- package/templates/ssr-isr/lib/server/app.js +438 -0
- package/templates/ssr-isr/lib/server/runtimeServe.js +169 -0
- package/templates/ssr-isr/lib/server/ssr.js +202 -0
- package/templates/ssr-isr/lib/shared/log.js +64 -0
- package/templates/ssr-isr/package.json +23 -0
- package/templates/ssr-isr/server.js +128 -0
- package/templates/ssr-isr/site/pages/(index).tsx +11 -0
- package/templates/ssr-isr/site/styles/global.scss +37 -0
- package/templates/ssr-isr/tsconfig.json +39 -0
- package/templates/static/build.js +30 -18
- package/templates/static/jen.config.ts +0 -18
- package/templates/static/jenjs.d.ts +0 -18
- package/templates/static/lib/api/(hello).js +0 -17
- package/templates/static/lib/api/examples/files/[...slug].js +22 -0
- package/templates/static/lib/api/examples/hello.js +11 -0
- package/templates/static/lib/api/examples/posts/[id].js +37 -0
- package/templates/static/lib/api/examples/posts.js +37 -0
- package/templates/static/lib/api/examples/search.js +23 -0
- package/templates/static/lib/api/index.js +41 -0
- package/templates/static/lib/api/loader.js +234 -0
- package/templates/static/lib/api/router.js +259 -0
- package/templates/static/lib/assets/types.js +1 -0
- package/templates/static/lib/auth/cookie-utils.js +3 -16
- package/templates/static/lib/auth/index.js +0 -17
- package/templates/static/lib/auth/jwt.js +0 -17
- package/templates/static/lib/auth/session.js +0 -17
- package/templates/static/lib/build/asset-hashing.js +44 -36
- package/templates/static/lib/build/asset-manifest.js +16 -33
- package/templates/static/lib/build/build.js +270 -125
- package/templates/static/lib/build/bundle-analyzer-ui.js +417 -0
- package/templates/static/lib/build/bundle-analyzer.js +945 -0
- package/templates/static/lib/build/code-splitter.js +194 -0
- package/templates/static/lib/build/feature-analyzer.js +190 -0
- package/templates/static/lib/build/feature-gate.js +257 -0
- package/templates/static/lib/build/island-hydration.js +17 -35
- package/templates/static/lib/build/lazy-loader.js +322 -0
- package/templates/static/lib/build/minifier.js +40 -59
- package/templates/static/lib/build/page-renderer.js +23 -40
- package/templates/static/lib/build/production-build.js +9 -26
- package/templates/static/lib/build/rust-hashing.js +71 -0
- package/templates/static/lib/build/script-optimizer.js +285 -0
- package/templates/static/lib/build/ssg-pipeline.js +100 -106
- package/templates/static/lib/build/vercel-output.js +298 -0
- package/templates/static/lib/build-tools/build-site.js +0 -17
- package/templates/static/lib/cache/index.js +0 -17
- package/templates/static/lib/cache/memory.js +0 -17
- package/templates/static/lib/cache/redis.js +0 -17
- package/templates/static/lib/cli/banner.js +0 -17
- package/templates/static/lib/cli/templates/ssg/jen.config.js +0 -17
- package/templates/static/lib/cli/templates/ssr/jen.config.js +0 -17
- package/templates/static/lib/client/Image.js +42 -0
- package/templates/static/lib/client/Link.js +190 -0
- package/templates/static/lib/client/PWA.js +46 -0
- package/templates/static/lib/client/Seo.js +97 -0
- package/templates/static/lib/client/index.js +9 -0
- package/templates/static/lib/client/useNavigation.js +25 -0
- package/templates/static/lib/client/useRouter.js +64 -0
- package/templates/static/lib/client-routing/Link.js +17 -0
- package/templates/static/lib/client-routing/index.js +19 -0
- package/templates/static/lib/client-routing/router.js +151 -0
- package/templates/static/lib/client-routing/signal.js +147 -0
- package/templates/static/lib/compilers/esbuild-plugins.js +0 -17
- package/templates/static/lib/compilers/svelte.js +0 -17
- package/templates/static/lib/compilers/vue.js +0 -17
- package/templates/static/lib/core/config.js +0 -17
- package/templates/static/lib/core/feature-guard.js +136 -0
- package/templates/static/lib/core/features.js +99 -0
- package/templates/static/lib/core/http.js +0 -17
- package/templates/static/lib/core/layouts/index.js +10 -0
- package/templates/static/lib/core/layouts/render.js +158 -0
- package/templates/static/lib/core/layouts/scan.js +112 -0
- package/templates/static/lib/core/layouts/types.js +1 -0
- package/templates/static/lib/core/lifecycle.js +129 -0
- package/templates/static/lib/core/loader-schema.js +81 -0
- package/templates/static/lib/core/middleware-hooks.js +0 -17
- package/templates/static/lib/core/paths.js +0 -17
- package/templates/static/lib/core/routes/advanced.js +114 -0
- package/templates/static/lib/core/routes/handlers.js +181 -0
- package/templates/static/lib/core/routes/match.js +89 -17
- package/templates/static/lib/core/routes/orchestrator.js +171 -0
- package/templates/static/lib/core/routes/rendering-config.js +131 -0
- package/templates/static/lib/core/routes/scan.js +0 -17
- package/templates/static/lib/core/types.js +0 -17
- package/templates/static/lib/css/compiler.js +1 -18
- package/templates/static/lib/data-fetching/cache.js +223 -0
- package/templates/static/lib/data-fetching/client.js +202 -0
- package/templates/static/lib/data-fetching/feature-guard.js +29 -0
- package/templates/static/lib/data-fetching/graphql.js +265 -0
- package/templates/static/lib/data-fetching/index.js +57 -0
- package/templates/static/lib/data-fetching/rest.js +256 -0
- package/templates/static/lib/data-fetching/server.js +182 -0
- package/templates/static/lib/data-fetching/types.js +5 -0
- package/templates/static/lib/db/connector.js +0 -17
- package/templates/static/lib/db/drivers/jdb.js +0 -17
- package/templates/static/lib/db/drivers/sql.js +0 -17
- package/templates/static/lib/db/index.js +0 -17
- package/templates/static/lib/db/types.js +0 -17
- package/templates/static/lib/devtools/component-tree.js +106 -0
- package/templates/static/lib/devtools/devtools.js +638 -0
- package/templates/static/lib/devtools/event-bus.js +29 -0
- package/templates/static/lib/devtools/event-logger.js +67 -0
- package/templates/static/lib/devtools/index.js +9 -0
- package/templates/static/lib/devtools/integration.js +149 -0
- package/templates/static/lib/devtools/performance.js +84 -0
- package/templates/static/lib/devtools/persistence.js +57 -0
- package/templates/static/lib/devtools/plugins.js +97 -0
- package/templates/static/lib/devtools/search.js +89 -0
- package/templates/static/lib/devtools/ui.js +769 -0
- package/templates/static/lib/features/api/handler.js +10 -0
- package/templates/static/lib/features/api/index.js +5 -0
- package/templates/static/lib/features/api/types.js +4 -0
- package/templates/static/lib/features/middleware/compiled.js +7 -0
- package/templates/static/lib/features/middleware/index.js +5 -0
- package/templates/static/lib/features/middleware/types.js +4 -0
- package/templates/static/lib/fonts/index.js +46 -0
- package/templates/static/lib/fonts/inject.js +125 -0
- package/templates/static/lib/fonts/loader.js +196 -0
- package/templates/static/lib/fonts/types.js +1 -0
- package/templates/static/lib/graphql/index.js +1 -18
- package/templates/static/lib/graphql/resolvers.js +20 -13
- package/templates/static/lib/graphql/schema.js +0 -17
- package/templates/static/lib/i18n/index.js +7 -19
- package/templates/static/lib/import/jen-import.js +1 -18
- package/templates/static/lib/index.js +79 -125
- package/templates/static/lib/jdb/engine.js +0 -17
- package/templates/static/lib/jdb/index.js +1 -18
- package/templates/static/lib/jdb/types.js +0 -17
- package/templates/static/lib/jdb/utils.js +0 -17
- package/templates/static/lib/middleware/builtins/cors.js +3 -16
- package/templates/static/lib/middleware/context.js +0 -17
- package/templates/static/lib/middleware/kernel.js +117 -25
- package/templates/static/lib/middleware/pipeline.js +0 -17
- package/templates/static/lib/middleware/registry.js +0 -17
- package/templates/static/lib/middleware/response.js +0 -17
- package/templates/static/lib/plugin/examples/analytics-plugin.js +183 -0
- package/templates/static/lib/plugin/examples/cdn-upload-plugin.js +94 -0
- package/templates/static/lib/plugin/loader.js +0 -17
- package/templates/static/lib/plugin/plugin-manager.js +177 -0
- package/templates/static/lib/plugin/types.js +28 -0
- package/templates/static/lib/runtime/client-runtime.js +0 -17
- package/templates/static/lib/runtime/hmr.js +0 -17
- package/templates/static/lib/runtime/hydrate.js +0 -17
- package/templates/static/lib/runtime/island-hydration-client.js +0 -17
- package/templates/static/lib/runtime/islands.js +0 -17
- package/templates/static/lib/runtime/render.js +208 -50
- package/templates/static/lib/security/security-config.js +60 -0
- package/templates/static/lib/security/security-middleware.js +229 -0
- package/templates/static/lib/server/api-routes.js +153 -43
- package/templates/static/lib/server/api.js +0 -17
- package/templates/static/lib/server/app.js +539 -223
- package/templates/static/lib/server/isr.js +365 -0
- package/templates/static/lib/server/runtimeServe.js +31 -24
- package/templates/static/lib/server/ssr.js +98 -22
- package/templates/static/lib/server-actions/handler.js +180 -0
- package/templates/static/lib/server-actions/index.js +19 -0
- package/templates/static/lib/server-actions/middleware.js +146 -0
- package/templates/static/lib/server-actions/scan.js +152 -0
- package/templates/static/lib/server-actions/types.js +1 -0
- package/templates/static/lib/server-actions/validators.js +156 -0
- package/templates/static/lib/shared/log.js +19 -20
- package/templates/static/lib/telemetry/api/rate-limiter.js +32 -0
- package/templates/static/lib/telemetry/api/validator.js +67 -0
- package/templates/static/lib/telemetry/client.js +121 -0
- package/templates/static/lib/telemetry/tests/rate-limiter.test.js +46 -0
- package/templates/static/lib/telemetry/tests/validator.test.js +62 -0
- package/templates/static/lib/vendor/glob/glob.js +4766 -0
- package/templates/static/lib/vendor/preact/LICENSE +21 -0
- package/templates/static/lib/vendor/preact/preact.module.js +797 -0
- package/templates/static/lib/vendor/sass/sass.node.mjs +212 -0
- package/templates/static/package.json +4 -0
- package/templates/static/server.js +22 -22
- package/templates/static/site/(home).tsx +0 -18
- package/templates/static/tsconfig.json +5 -1
- package/templates/static/.esbuild/jen.config.js +0 -19
- package/templates/static/lib/build/asset-hashing.d.ts +0 -10
- package/templates/static/lib/build/asset-manifest.d.ts +0 -11
- package/templates/static/lib/build/minifier.d.ts +0 -20
- package/templates/static/lib/build/page-renderer.d.ts +0 -17
- package/templates/static/lib/build/production-build.d.ts +0 -10
- package/templates/static/lib/build/ssg-pipeline.d.ts +0 -15
- package/templates/static/lib/middleware/errors/http-error.js +0 -27
- package/templates/static/lib/middleware/types.js +0 -18
- package/templates/static/lib/middleware/utils/matcher.js +0 -30
- package/templates/static/lib/native/style-compiler.js +0 -36
- /package/templates/{static → ssr-isr}/lib/api/(hello).d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/cookie-utils.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/jwt.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/auth/session.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/build-tools/build-site.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cache/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cache/memory.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cache/redis.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/banner.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/jen.config.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/site/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/jen.config.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/site/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/compilers/esbuild-plugins.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/compilers/svelte.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/compilers/vue.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/config.d.ts +0 -0
- /package/templates/{static/lib/middleware/types.d.ts → ssr-isr/lib/core/config.js} +0 -0
- /package/templates/{static → ssr-isr}/lib/core/http.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/middleware-hooks.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/paths.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/routes/match.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/routes/scan.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/core/types.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/css/compiler.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/connector.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/drivers/jdb.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/drivers/sql.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/db/types.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/graphql/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/graphql/resolvers.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/graphql/schema.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/i18n/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/import/jen-import.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/engine.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/types.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/jdb/utils.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/cors.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/context.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/decorators.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/errors/handler.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/errors/http-error.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/kernel.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/pipeline.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/registry.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/response.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/middleware/utils/matcher.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/bundle.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/dev-server.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/index.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/optimizer.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/native/style-compiler.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/plugin/loader.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/client-runtime.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/hmr.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/hydrate.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/island-hydration-client.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/islands.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/runtime/render.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/api-routes.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/api.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/app.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/runtimeServe.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/server/ssr.d.ts +0 -0
- /package/templates/{static → ssr-isr}/lib/shared/log.d.ts +0 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join, basename } from "node:path";
|
|
3
|
+
import esbuild from "esbuild";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
/** Cache directory for transpiled API routes. */
|
|
6
|
+
const apiCacheDir = join(process.cwd(), "node_modules", ".jen", "api-cache");
|
|
7
|
+
/**
|
|
8
|
+
* Transpile a TypeScript API route file to JavaScript.
|
|
9
|
+
* Uses esbuild to convert TS → JS, bundle dependencies, and output as ESM.
|
|
10
|
+
* The transpiled file is cached in node_modules/.jen/api-cache with a timestamp
|
|
11
|
+
* in the filename to allow side-by-side versions if the file changes.
|
|
12
|
+
*
|
|
13
|
+
* Bundles the route with external dependencies excluded (preact, jenjs).
|
|
14
|
+
* This enables tree-shaking of server-only exports like loader().
|
|
15
|
+
*
|
|
16
|
+
* @param filePath - Absolute path to .ts file
|
|
17
|
+
* @returns Path to transpiled .mjs file in cache directory
|
|
18
|
+
* @throws If esbuild fails to transpile
|
|
19
|
+
*/
|
|
20
|
+
async function transpileApiRoute(filePath) {
|
|
21
|
+
const outfile = join(
|
|
22
|
+
apiCacheDir,
|
|
23
|
+
basename(filePath).replace(/\.ts$/, `.${Date.now()}.mjs`),
|
|
24
|
+
);
|
|
25
|
+
await esbuild.build({
|
|
26
|
+
entryPoints: [filePath],
|
|
27
|
+
outfile,
|
|
28
|
+
format: "esm",
|
|
29
|
+
platform: "node",
|
|
30
|
+
target: "es2022",
|
|
31
|
+
bundle: true,
|
|
32
|
+
external: ["preact", "preact-render-to-string", "jenjs"],
|
|
33
|
+
write: true,
|
|
34
|
+
});
|
|
35
|
+
return outfile;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Attempt to route and handle an API request.
|
|
39
|
+
* Returns true if the request was handled (success or error response sent),
|
|
40
|
+
* false if no matching API route exists (caller should try next handler).
|
|
41
|
+
*
|
|
42
|
+
* Routing:
|
|
43
|
+
* - /api/endpoint → site/api/endpoint.ts
|
|
44
|
+
* - /api/users/123 → site/api/users/[id].ts (dynamic params supported)
|
|
45
|
+
* - /api/ (no segments) → 404
|
|
46
|
+
*
|
|
47
|
+
* Resolution order:
|
|
48
|
+
* 1. Try exact file match (e.g., /api/hello → api/hello.ts)
|
|
49
|
+
* 2. Try dynamic route match (e.g., /api/123 → api/[id].ts)
|
|
50
|
+
*
|
|
51
|
+
* Process:
|
|
52
|
+
* 1. Validate request starts with /api/
|
|
53
|
+
* 2. Resolve route file (exact or dynamic match)
|
|
54
|
+
* 3. Transpile if TypeScript
|
|
55
|
+
* 4. Load module and find handler for HTTP method
|
|
56
|
+
* 5. Parse request body
|
|
57
|
+
* 6. Call handler with context
|
|
58
|
+
* 7. Serialize response (Response, string, or object)
|
|
59
|
+
*
|
|
60
|
+
* All errors send JSON response with error message.
|
|
61
|
+
* HTTP 405 (Method Not Allowed) if method handler not exported.
|
|
62
|
+
* HTTP 404 if no matching route file.
|
|
63
|
+
* HTTP 500 if handler throws or transpilation fails.
|
|
64
|
+
*
|
|
65
|
+
* @param opts - Options containing request, response, and site directory
|
|
66
|
+
* @returns true if handled, false if no API route found
|
|
67
|
+
*/
|
|
68
|
+
export async function tryHandleApiRoute(opts) {
|
|
69
|
+
const { req, res, siteDir } = opts;
|
|
70
|
+
const url = new URL(
|
|
71
|
+
req.url ?? "/",
|
|
72
|
+
`http://${req.headers.host ?? "localhost"}`,
|
|
73
|
+
);
|
|
74
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
75
|
+
// Only handle /api/* requests
|
|
76
|
+
if (!url.pathname.startsWith("/api/")) return false;
|
|
77
|
+
// Extract path segments after /api/ prefix
|
|
78
|
+
const pathParts = url.pathname
|
|
79
|
+
.slice("/api/".length)
|
|
80
|
+
.split("/")
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
// /api/ with no segments is 404
|
|
83
|
+
if (pathParts.length === 0) {
|
|
84
|
+
res.statusCode = 404;
|
|
85
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
86
|
+
res.end(JSON.stringify({ error: "API route not found" }));
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
// Resolve route file (exact match or dynamic)
|
|
90
|
+
let apiFile = null;
|
|
91
|
+
let routeParams = {};
|
|
92
|
+
// Try exact file match: /api/hello/world → api/hello/world.ts
|
|
93
|
+
const exactPath = join(
|
|
94
|
+
process.cwd(),
|
|
95
|
+
siteDir,
|
|
96
|
+
"api",
|
|
97
|
+
`${pathParts.join("/")}.ts`,
|
|
98
|
+
);
|
|
99
|
+
if (existsSync(exactPath)) {
|
|
100
|
+
apiFile = exactPath;
|
|
101
|
+
} else {
|
|
102
|
+
// Try dynamic route match: /api/users/123 → api/users/[id].ts
|
|
103
|
+
const basePath = join(process.cwd(), siteDir, "api");
|
|
104
|
+
for (let i = pathParts.length; i >= 1; i--) {
|
|
105
|
+
const staticSegments = pathParts.slice(0, i);
|
|
106
|
+
const dynamicSegments = pathParts.slice(i);
|
|
107
|
+
// Simple approach: check api/[param].ts for /api/123
|
|
108
|
+
// TODO: Support nested dynamic routes like api/users/[id]/posts/[postId].ts
|
|
109
|
+
if (staticSegments.length === 0 && dynamicSegments.length === 1) {
|
|
110
|
+
const paramFile = join(basePath, `[${dynamicSegments[0]}].ts`);
|
|
111
|
+
if (existsSync(paramFile)) {
|
|
112
|
+
apiFile = paramFile;
|
|
113
|
+
routeParams[dynamicSegments[0]] = dynamicSegments[0];
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!apiFile) {
|
|
120
|
+
res.statusCode = 404;
|
|
121
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
122
|
+
res.end(JSON.stringify({ error: "API route not found" }));
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
// Transpile TypeScript to JavaScript
|
|
126
|
+
let moduleUrl = apiFile;
|
|
127
|
+
if (apiFile.endsWith(".ts")) {
|
|
128
|
+
moduleUrl = await transpileApiRoute(apiFile);
|
|
129
|
+
}
|
|
130
|
+
// Load module and get method handlers
|
|
131
|
+
let mod;
|
|
132
|
+
try {
|
|
133
|
+
// Cache-busting query param ensures fresh module (important in dev mode)
|
|
134
|
+
mod = await import(pathToFileURL(moduleUrl).href + `?t=${Date.now()}`);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
res.statusCode = 500;
|
|
137
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
138
|
+
res.end(
|
|
139
|
+
JSON.stringify({
|
|
140
|
+
error: "Failed to load API route",
|
|
141
|
+
details: err.message,
|
|
142
|
+
}),
|
|
143
|
+
);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
// Get handler for the HTTP method
|
|
147
|
+
const handler = mod[method];
|
|
148
|
+
if (!handler) {
|
|
149
|
+
res.statusCode = 405;
|
|
150
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
151
|
+
res.setHeader("allow", Object.keys(mod).join(", "));
|
|
152
|
+
res.end(JSON.stringify({ error: `${method} not allowed` }));
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
// Parse request body
|
|
156
|
+
const body = await readRequestBody(req);
|
|
157
|
+
// Build handler context
|
|
158
|
+
const ctx = {
|
|
159
|
+
req,
|
|
160
|
+
res,
|
|
161
|
+
url,
|
|
162
|
+
method,
|
|
163
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
164
|
+
body,
|
|
165
|
+
params: routeParams,
|
|
166
|
+
};
|
|
167
|
+
// Execute handler and serialize response
|
|
168
|
+
try {
|
|
169
|
+
const result = await handler(ctx);
|
|
170
|
+
// If handler manually wrote response, don't double-send
|
|
171
|
+
if (res.writableEnded) return true;
|
|
172
|
+
// Serialize Response object
|
|
173
|
+
if (result instanceof Response) {
|
|
174
|
+
res.statusCode = result.status;
|
|
175
|
+
result.headers.forEach((v, k) => res.setHeader(k, v));
|
|
176
|
+
const buf = Buffer.from(await result.arrayBuffer());
|
|
177
|
+
res.end(buf);
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
// Serialize string as plain text
|
|
181
|
+
if (typeof result === "string") {
|
|
182
|
+
res.statusCode = 200;
|
|
183
|
+
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
184
|
+
res.end(result);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
// Serialize object as JSON (null is valid)
|
|
188
|
+
res.statusCode = 200;
|
|
189
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
190
|
+
res.end(JSON.stringify(result ?? null));
|
|
191
|
+
return true;
|
|
192
|
+
} catch (err) {
|
|
193
|
+
res.statusCode = 500;
|
|
194
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
195
|
+
res.end(
|
|
196
|
+
JSON.stringify({ error: "Internal server error", details: err.message }),
|
|
197
|
+
);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Parse request body based on Content-Type header.
|
|
203
|
+
* Reads all chunks from the request stream and deserializes based on content type.
|
|
204
|
+
*
|
|
205
|
+
* - GET/HEAD: Returns null (no body expected)
|
|
206
|
+
* - JSON (application/json): Parses and returns object; falls back to { __raw } if invalid JSON
|
|
207
|
+
* - Other: Returns { __raw } with raw body string
|
|
208
|
+
*
|
|
209
|
+
* This function is shared between different request handlers in the framework.
|
|
210
|
+
*
|
|
211
|
+
* @param req - Node.js IncomingMessage to read body from
|
|
212
|
+
* @returns Parsed body object or null
|
|
213
|
+
*/
|
|
214
|
+
async function readRequestBody(req) {
|
|
215
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
216
|
+
// Methods without bodies per HTTP spec
|
|
217
|
+
if (method === "GET" || method === "HEAD") return null;
|
|
218
|
+
// Read all body chunks
|
|
219
|
+
const chunks = [];
|
|
220
|
+
for await (const chunk of req) {
|
|
221
|
+
chunks.push(Buffer.from(chunk));
|
|
222
|
+
}
|
|
223
|
+
if (chunks.length === 0) return null;
|
|
224
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
225
|
+
const ct = (req.headers["content-type"] ?? "").toString();
|
|
226
|
+
// Try to parse JSON
|
|
227
|
+
if (ct.includes("application/json")) {
|
|
228
|
+
try {
|
|
229
|
+
return JSON.parse(raw);
|
|
230
|
+
} catch {
|
|
231
|
+
// Return raw body if JSON parsing fails
|
|
232
|
+
return { __raw: raw };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Return raw body for non-JSON content
|
|
236
|
+
return { __raw: raw };
|
|
237
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join, normalize } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
const MAX_BODY_SIZE = 1024 * 1024; // 1MB
|
|
5
|
+
const VALID_ROUTE_PATTERN = /^[a-zA-Z0-9_\-/]+$/; // Only alphanumeric, underscore, hyphen, forward slash
|
|
6
|
+
function isValidRouteName(name) {
|
|
7
|
+
if (!name || name.length > 255) return false;
|
|
8
|
+
if (name.includes("..") || name.includes("\\") || name.startsWith("/"))
|
|
9
|
+
return false;
|
|
10
|
+
return VALID_ROUTE_PATTERN.test(name);
|
|
11
|
+
}
|
|
12
|
+
export async function tryHandleApiRoute(opts) {
|
|
13
|
+
const { req, res, siteDir } = opts;
|
|
14
|
+
const url = new URL(
|
|
15
|
+
req.url ?? "/",
|
|
16
|
+
`http://${req.headers.host ?? "localhost"}`,
|
|
17
|
+
);
|
|
18
|
+
if (!url.pathname.startsWith("/api/")) return false;
|
|
19
|
+
// /api/hello -> site/api/(hello).ts
|
|
20
|
+
let name = url.pathname.slice("/api/".length) || "home";
|
|
21
|
+
// Security: Validate route name to prevent path traversal
|
|
22
|
+
if (!isValidRouteName(name)) {
|
|
23
|
+
res.statusCode = 400;
|
|
24
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
25
|
+
res.end(JSON.stringify({ error: "Invalid API route format" }));
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
const file = join(process.cwd(), siteDir, "api", `(${name}).ts`);
|
|
29
|
+
// Ensure the resolved path is within the api directory (prevent directory traversal)
|
|
30
|
+
const apiDir = normalize(join(process.cwd(), siteDir, "api"));
|
|
31
|
+
if (!normalize(file).startsWith(apiDir)) {
|
|
32
|
+
res.statusCode = 403;
|
|
33
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
34
|
+
res.end(JSON.stringify({ error: "Forbidden" }));
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (!existsSync(file)) {
|
|
38
|
+
res.statusCode = 404;
|
|
39
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
40
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// Use pathToFileURL to handle Windows paths correctly
|
|
44
|
+
const mod = await import(pathToFileURL(file).href + `?t=${Date.now()}`);
|
|
45
|
+
const handler = mod?.default;
|
|
46
|
+
if (typeof handler !== "function") {
|
|
47
|
+
res.statusCode = 500;
|
|
48
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
49
|
+
res.end(
|
|
50
|
+
JSON.stringify({ error: "API route missing default export function" }),
|
|
51
|
+
);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
const body = await readBody(req);
|
|
55
|
+
const ctx = {
|
|
56
|
+
req,
|
|
57
|
+
res,
|
|
58
|
+
url,
|
|
59
|
+
method: req.method ?? "GET",
|
|
60
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
61
|
+
body,
|
|
62
|
+
};
|
|
63
|
+
const out = await handler(ctx);
|
|
64
|
+
if (res.writableEnded) return true;
|
|
65
|
+
if (out instanceof Response) {
|
|
66
|
+
res.statusCode = out.status;
|
|
67
|
+
out.headers.forEach((v, k) => res.setHeader(k, v));
|
|
68
|
+
const buf = Buffer.from(await out.arrayBuffer());
|
|
69
|
+
res.end(buf);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
if (typeof out === "string") {
|
|
73
|
+
res.statusCode = 200;
|
|
74
|
+
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
75
|
+
res.end(out);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
res.statusCode = 200;
|
|
79
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
80
|
+
res.end(JSON.stringify(out ?? null));
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
async function readBody(req) {
|
|
84
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
85
|
+
if (method === "GET" || method === "HEAD") return null;
|
|
86
|
+
const chunks = [];
|
|
87
|
+
let totalSize = 0;
|
|
88
|
+
for await (const chunk of req) {
|
|
89
|
+
totalSize += chunk.length;
|
|
90
|
+
if (totalSize > MAX_BODY_SIZE) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Request body exceeds maximum size of ${MAX_BODY_SIZE} bytes`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
chunks.push(Buffer.from(chunk));
|
|
96
|
+
}
|
|
97
|
+
if (chunks.length === 0) return null;
|
|
98
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
99
|
+
const ct = req.headers["content-type"] ?? "";
|
|
100
|
+
if (typeof ct === "string" && ct.includes("application/json")) {
|
|
101
|
+
try {
|
|
102
|
+
return JSON.parse(raw);
|
|
103
|
+
} catch {
|
|
104
|
+
return { __raw: raw };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { __raw: raw };
|
|
108
|
+
}
|