create-jen-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +89 -0
- package/dist/index.js +72 -0
- package/package.json +50 -0
- package/templates/static/.esbuild/jen.config.js +1 -0
- package/templates/static/README.md +67 -0
- package/templates/static/build.js +106 -0
- package/templates/static/jen.config.ts +128 -0
- package/templates/static/jenjs.d.ts +33 -0
- package/templates/static/lib/api/(hello).d.ts +7 -0
- package/templates/static/lib/api/(hello).js +26 -0
- package/templates/static/lib/auth/cookie-utils.d.ts +24 -0
- package/templates/static/lib/auth/cookie-utils.js +99 -0
- package/templates/static/lib/auth/index.d.ts +2 -0
- package/templates/static/lib/auth/index.js +19 -0
- package/templates/static/lib/auth/jwt.d.ts +2 -0
- package/templates/static/lib/auth/jwt.js +30 -0
- package/templates/static/lib/auth/session.d.ts +44 -0
- package/templates/static/lib/auth/session.js +111 -0
- package/templates/static/lib/build/asset-hashing.d.ts +10 -0
- package/templates/static/lib/build/asset-hashing.js +42 -0
- package/templates/static/lib/build/asset-manifest.d.ts +11 -0
- package/templates/static/lib/build/asset-manifest.js +38 -0
- package/templates/static/lib/build/build.d.ts +4 -0
- package/templates/static/lib/build/build.js +113 -0
- package/templates/static/lib/build/island-hydration.d.ts +25 -0
- package/templates/static/lib/build/island-hydration.js +62 -0
- package/templates/static/lib/build/minifier.d.ts +20 -0
- package/templates/static/lib/build/minifier.js +65 -0
- package/templates/static/lib/build/page-renderer.d.ts +17 -0
- package/templates/static/lib/build/page-renderer.js +45 -0
- package/templates/static/lib/build/production-build.d.ts +10 -0
- package/templates/static/lib/build/production-build.js +30 -0
- package/templates/static/lib/build/ssg-pipeline.d.ts +15 -0
- package/templates/static/lib/build/ssg-pipeline.js +119 -0
- package/templates/static/lib/build-tools/build-site.d.ts +6 -0
- package/templates/static/lib/build-tools/build-site.js +56 -0
- package/templates/static/lib/cache/index.d.ts +2 -0
- package/templates/static/lib/cache/index.js +19 -0
- package/templates/static/lib/cache/memory.d.ts +6 -0
- package/templates/static/lib/cache/memory.js +31 -0
- package/templates/static/lib/cache/redis.d.ts +6 -0
- package/templates/static/lib/cache/redis.js +33 -0
- package/templates/static/lib/cli/banner.d.ts +1 -0
- package/templates/static/lib/cli/banner.js +41 -0
- package/templates/static/lib/cli/templates/ssg/jen.config.d.ts +3 -0
- package/templates/static/lib/cli/templates/ssg/jen.config.js +49 -0
- package/templates/static/lib/cli/templates/ssg/site/index.d.ts +2 -0
- package/templates/static/lib/cli/templates/ssg/site/index.js +4 -0
- package/templates/static/lib/cli/templates/ssr/jen.config.d.ts +3 -0
- package/templates/static/lib/cli/templates/ssr/jen.config.js +49 -0
- package/templates/static/lib/cli/templates/ssr/site/index.d.ts +2 -0
- package/templates/static/lib/cli/templates/ssr/site/index.js +4 -0
- package/templates/static/lib/compilers/esbuild-plugins.d.ts +6 -0
- package/templates/static/lib/compilers/esbuild-plugins.js +130 -0
- package/templates/static/lib/compilers/svelte.d.ts +18 -0
- package/templates/static/lib/compilers/svelte.js +61 -0
- package/templates/static/lib/compilers/vue.d.ts +15 -0
- package/templates/static/lib/compilers/vue.js +99 -0
- package/templates/static/lib/core/config.d.ts +53 -0
- package/templates/static/lib/core/config.js +18 -0
- package/templates/static/lib/core/http.d.ts +3 -0
- package/templates/static/lib/core/http.js +42 -0
- package/templates/static/lib/core/middleware-hooks.d.ts +46 -0
- package/templates/static/lib/core/middleware-hooks.js +69 -0
- package/templates/static/lib/core/paths.d.ts +6 -0
- package/templates/static/lib/core/paths.js +24 -0
- package/templates/static/lib/core/routes/match.d.ts +6 -0
- package/templates/static/lib/core/routes/match.js +31 -0
- package/templates/static/lib/core/routes/scan.d.ts +9 -0
- package/templates/static/lib/core/routes/scan.js +148 -0
- package/templates/static/lib/core/types.d.ts +18 -0
- package/templates/static/lib/core/types.js +18 -0
- package/templates/static/lib/css/compiler.d.ts +20 -0
- package/templates/static/lib/css/compiler.js +87 -0
- package/templates/static/lib/db/connector.d.ts +4 -0
- package/templates/static/lib/db/connector.js +33 -0
- package/templates/static/lib/db/drivers/jdb.d.ts +13 -0
- package/templates/static/lib/db/drivers/jdb.js +59 -0
- package/templates/static/lib/db/drivers/sql.d.ts +18 -0
- package/templates/static/lib/db/drivers/sql.js +182 -0
- package/templates/static/lib/db/index.d.ts +19 -0
- package/templates/static/lib/db/index.js +65 -0
- package/templates/static/lib/db/types.d.ts +29 -0
- package/templates/static/lib/db/types.js +18 -0
- package/templates/static/lib/graphql/index.d.ts +1 -0
- package/templates/static/lib/graphql/index.js +22 -0
- package/templates/static/lib/graphql/resolvers.d.ts +17 -0
- package/templates/static/lib/graphql/resolvers.js +26 -0
- package/templates/static/lib/graphql/schema.d.ts +1 -0
- package/templates/static/lib/graphql/schema.js +20 -0
- package/templates/static/lib/i18n/en.json +4 -0
- package/templates/static/lib/i18n/es.json +4 -0
- package/templates/static/lib/i18n/index.d.ts +8 -0
- package/templates/static/lib/i18n/index.js +32 -0
- package/templates/static/lib/import/jen-import.d.ts +27 -0
- package/templates/static/lib/import/jen-import.js +128 -0
- package/templates/static/lib/index.d.ts +81 -0
- package/templates/static/lib/index.js +120 -0
- package/templates/static/lib/jdb/engine.d.ts +9 -0
- package/templates/static/lib/jdb/engine.js +176 -0
- package/templates/static/lib/jdb/index.d.ts +2 -0
- package/templates/static/lib/jdb/index.js +19 -0
- package/templates/static/lib/jdb/types.d.ts +46 -0
- package/templates/static/lib/jdb/types.js +18 -0
- package/templates/static/lib/jdb/utils.d.ts +6 -0
- package/templates/static/lib/jdb/utils.js +141 -0
- package/templates/static/lib/middleware/builtins/body-parser.d.ts +1 -0
- package/templates/static/lib/middleware/builtins/body-parser.js +55 -0
- package/templates/static/lib/middleware/builtins/cors.d.ts +13 -0
- package/templates/static/lib/middleware/builtins/cors.js +67 -0
- package/templates/static/lib/middleware/builtins/logger.d.ts +1 -0
- package/templates/static/lib/middleware/builtins/logger.js +33 -0
- package/templates/static/lib/middleware/builtins/rate-limit.d.ts +5 -0
- package/templates/static/lib/middleware/builtins/rate-limit.js +76 -0
- package/templates/static/lib/middleware/builtins/request-id.d.ts +1 -0
- package/templates/static/lib/middleware/builtins/request-id.js +25 -0
- package/templates/static/lib/middleware/builtins/security-headers.d.ts +1 -0
- package/templates/static/lib/middleware/builtins/security-headers.js +39 -0
- package/templates/static/lib/middleware/context.d.ts +18 -0
- package/templates/static/lib/middleware/context.js +50 -0
- package/templates/static/lib/middleware/decorators.d.ts +2 -0
- package/templates/static/lib/middleware/decorators.js +61 -0
- package/templates/static/lib/middleware/errors/handler.d.ts +1 -0
- package/templates/static/lib/middleware/errors/handler.js +65 -0
- package/templates/static/lib/middleware/errors/http-error.d.ts +5 -0
- package/templates/static/lib/middleware/errors/http-error.js +27 -0
- package/templates/static/lib/middleware/kernel.d.ts +6 -0
- package/templates/static/lib/middleware/kernel.js +39 -0
- package/templates/static/lib/middleware/pipeline.d.ts +4 -0
- package/templates/static/lib/middleware/pipeline.js +67 -0
- package/templates/static/lib/middleware/registry.d.ts +10 -0
- package/templates/static/lib/middleware/registry.js +41 -0
- package/templates/static/lib/middleware/response.d.ts +13 -0
- package/templates/static/lib/middleware/response.js +60 -0
- package/templates/static/lib/middleware/types.d.ts +1 -0
- package/templates/static/lib/middleware/types.js +18 -0
- package/templates/static/lib/middleware/utils/matcher.d.ts +1 -0
- package/templates/static/lib/middleware/utils/matcher.js +31 -0
- package/templates/static/lib/native/bundle.d.ts +19 -0
- package/templates/static/lib/native/bundle.js +39 -0
- package/templates/static/lib/native/dev-server.d.ts +6 -0
- package/templates/static/lib/native/dev-server.js +38 -0
- package/templates/static/lib/native/index.d.ts +30 -0
- package/templates/static/lib/native/index.js +48 -0
- package/templates/static/lib/native/optimizer.d.ts +17 -0
- package/templates/static/lib/native/optimizer.js +37 -0
- package/templates/static/lib/native/style-compiler.d.ts +10 -0
- package/templates/static/lib/native/style-compiler.js +36 -0
- package/templates/static/lib/plugin/loader.d.ts +8 -0
- package/templates/static/lib/plugin/loader.js +59 -0
- package/templates/static/lib/runtime/client-runtime.d.ts +1 -0
- package/templates/static/lib/runtime/client-runtime.js +28 -0
- package/templates/static/lib/runtime/hmr.d.ts +1 -0
- package/templates/static/lib/runtime/hmr.js +54 -0
- package/templates/static/lib/runtime/hydrate.d.ts +1 -0
- package/templates/static/lib/runtime/hydrate.js +45 -0
- package/templates/static/lib/runtime/island-hydration-client.d.ts +5 -0
- package/templates/static/lib/runtime/island-hydration-client.js +132 -0
- package/templates/static/lib/runtime/islands.d.ts +46 -0
- package/templates/static/lib/runtime/islands.js +89 -0
- package/templates/static/lib/runtime/render.d.ts +13 -0
- package/templates/static/lib/runtime/render.js +183 -0
- package/templates/static/lib/server/api-routes.d.ts +44 -0
- package/templates/static/lib/server/api-routes.js +196 -0
- package/templates/static/lib/server/api.d.ts +6 -0
- package/templates/static/lib/server/api.js +124 -0
- package/templates/static/lib/server/app.d.ts +10 -0
- package/templates/static/lib/server/app.js +381 -0
- package/templates/static/lib/server/runtimeServe.d.ts +4 -0
- package/templates/static/lib/server/runtimeServe.js +125 -0
- package/templates/static/lib/shared/log.d.ts +5 -0
- package/templates/static/lib/shared/log.js +31 -0
- package/templates/static/node_modules/.bin/esbuild +16 -0
- package/templates/static/node_modules/.bin/esbuild.cmd +17 -0
- package/templates/static/node_modules/.bin/esbuild.ps1 +28 -0
- package/templates/static/node_modules/.bin/tsc +16 -0
- package/templates/static/node_modules/.bin/tsc.cmd +17 -0
- package/templates/static/node_modules/.bin/tsc.ps1 +28 -0
- package/templates/static/node_modules/.bin/tsserver +16 -0
- package/templates/static/node_modules/.bin/tsserver.cmd +17 -0
- package/templates/static/node_modules/.bin/tsserver.ps1 +28 -0
- package/templates/static/node_modules/.jen/cache/B__Jen.js_packages_create-jen-app_templates_static_site_(home).tsx.mjs +14 -0
- package/templates/static/node_modules/.jen/cache/B__Jen.js_packages_create-jen-app_yo_site_(home).tsx.mjs +11 -0
- package/templates/static/node_modules/.package-lock.json +585 -0
- package/templates/static/node_modules/@esbuild/win32-x64/README.md +3 -0
- package/templates/static/node_modules/@esbuild/win32-x64/esbuild.exe +0 -0
- package/templates/static/node_modules/@esbuild/win32-x64/package.json +20 -0
- package/templates/static/node_modules/@jenjs/master/README.md +24 -0
- package/templates/static/node_modules/@jenjs/master/index.js +3655 -0
- package/templates/static/node_modules/@jenjs/master/package.json +36 -0
- package/templates/static/node_modules/@polka/url/build.js +49 -0
- package/templates/static/node_modules/@polka/url/build.mjs +47 -0
- package/templates/static/node_modules/@polka/url/index.d.ts +11 -0
- package/templates/static/node_modules/@polka/url/package.json +30 -0
- package/templates/static/node_modules/@polka/url/readme.md +68 -0
- package/templates/static/node_modules/@types/node/LICENSE +21 -0
- package/templates/static/node_modules/@types/node/README.md +15 -0
- package/templates/static/node_modules/@types/node/assert/strict.d.ts +111 -0
- package/templates/static/node_modules/@types/node/assert.d.ts +1078 -0
- package/templates/static/node_modules/@types/node/async_hooks.d.ts +603 -0
- package/templates/static/node_modules/@types/node/buffer.buffer.d.ts +472 -0
- package/templates/static/node_modules/@types/node/buffer.d.ts +1934 -0
- package/templates/static/node_modules/@types/node/child_process.d.ts +1476 -0
- package/templates/static/node_modules/@types/node/cluster.d.ts +578 -0
- package/templates/static/node_modules/@types/node/compatibility/disposable.d.ts +14 -0
- package/templates/static/node_modules/@types/node/compatibility/index.d.ts +9 -0
- package/templates/static/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
- package/templates/static/node_modules/@types/node/compatibility/iterators.d.ts +20 -0
- package/templates/static/node_modules/@types/node/console.d.ts +452 -0
- package/templates/static/node_modules/@types/node/constants.d.ts +21 -0
- package/templates/static/node_modules/@types/node/crypto.d.ts +4545 -0
- package/templates/static/node_modules/@types/node/dgram.d.ts +600 -0
- package/templates/static/node_modules/@types/node/diagnostics_channel.d.ts +578 -0
- package/templates/static/node_modules/@types/node/dns/promises.d.ts +503 -0
- package/templates/static/node_modules/@types/node/dns.d.ts +923 -0
- package/templates/static/node_modules/@types/node/domain.d.ts +170 -0
- package/templates/static/node_modules/@types/node/events.d.ts +976 -0
- package/templates/static/node_modules/@types/node/fs/promises.d.ts +1295 -0
- package/templates/static/node_modules/@types/node/fs.d.ts +4461 -0
- package/templates/static/node_modules/@types/node/globals.d.ts +172 -0
- package/templates/static/node_modules/@types/node/globals.typedarray.d.ts +38 -0
- package/templates/static/node_modules/@types/node/http.d.ts +2089 -0
- package/templates/static/node_modules/@types/node/http2.d.ts +2644 -0
- package/templates/static/node_modules/@types/node/https.d.ts +579 -0
- package/templates/static/node_modules/@types/node/index.d.ts +97 -0
- package/templates/static/node_modules/@types/node/inspector.d.ts +253 -0
- package/templates/static/node_modules/@types/node/inspector.generated.d.ts +4052 -0
- package/templates/static/node_modules/@types/node/module.d.ts +891 -0
- package/templates/static/node_modules/@types/node/net.d.ts +1057 -0
- package/templates/static/node_modules/@types/node/os.d.ts +506 -0
- package/templates/static/node_modules/@types/node/package.json +145 -0
- package/templates/static/node_modules/@types/node/path.d.ts +200 -0
- package/templates/static/node_modules/@types/node/perf_hooks.d.ts +968 -0
- package/templates/static/node_modules/@types/node/process.d.ts +2089 -0
- package/templates/static/node_modules/@types/node/punycode.d.ts +117 -0
- package/templates/static/node_modules/@types/node/querystring.d.ts +152 -0
- package/templates/static/node_modules/@types/node/readline/promises.d.ts +161 -0
- package/templates/static/node_modules/@types/node/readline.d.ts +594 -0
- package/templates/static/node_modules/@types/node/repl.d.ts +428 -0
- package/templates/static/node_modules/@types/node/sea.d.ts +153 -0
- package/templates/static/node_modules/@types/node/sqlite.d.ts +721 -0
- package/templates/static/node_modules/@types/node/stream/consumers.d.ts +38 -0
- package/templates/static/node_modules/@types/node/stream/promises.d.ts +90 -0
- package/templates/static/node_modules/@types/node/stream/web.d.ts +622 -0
- package/templates/static/node_modules/@types/node/stream.d.ts +1664 -0
- package/templates/static/node_modules/@types/node/string_decoder.d.ts +67 -0
- package/templates/static/node_modules/@types/node/test.d.ts +2163 -0
- package/templates/static/node_modules/@types/node/timers/promises.d.ts +108 -0
- package/templates/static/node_modules/@types/node/timers.d.ts +287 -0
- package/templates/static/node_modules/@types/node/tls.d.ts +1319 -0
- package/templates/static/node_modules/@types/node/trace_events.d.ts +197 -0
- package/templates/static/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
- package/templates/static/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
- package/templates/static/node_modules/@types/node/ts5.6/index.d.ts +97 -0
- package/templates/static/node_modules/@types/node/tty.d.ts +208 -0
- package/templates/static/node_modules/@types/node/url.d.ts +984 -0
- package/templates/static/node_modules/@types/node/util.d.ts +2606 -0
- package/templates/static/node_modules/@types/node/v8.d.ts +920 -0
- package/templates/static/node_modules/@types/node/vm.d.ts +1000 -0
- package/templates/static/node_modules/@types/node/wasi.d.ts +181 -0
- package/templates/static/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
- package/templates/static/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/templates/static/node_modules/@types/node/web-globals/events.d.ts +97 -0
- package/templates/static/node_modules/@types/node/web-globals/fetch.d.ts +55 -0
- package/templates/static/node_modules/@types/node/web-globals/navigator.d.ts +22 -0
- package/templates/static/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/templates/static/node_modules/@types/node/worker_threads.d.ts +784 -0
- package/templates/static/node_modules/@types/node/zlib.d.ts +683 -0
- package/templates/static/node_modules/esbuild/LICENSE.md +21 -0
- package/templates/static/node_modules/esbuild/README.md +3 -0
- package/templates/static/node_modules/esbuild/bin/esbuild +223 -0
- package/templates/static/node_modules/esbuild/install.js +289 -0
- package/templates/static/node_modules/esbuild/lib/main.d.ts +716 -0
- package/templates/static/node_modules/esbuild/lib/main.js +2242 -0
- package/templates/static/node_modules/esbuild/package.json +49 -0
- package/templates/static/node_modules/mrmime/index.d.ts +2 -0
- package/templates/static/node_modules/mrmime/index.js +449 -0
- package/templates/static/node_modules/mrmime/index.mjs +448 -0
- package/templates/static/node_modules/mrmime/license +21 -0
- package/templates/static/node_modules/mrmime/package.json +44 -0
- package/templates/static/node_modules/mrmime/readme.md +130 -0
- package/templates/static/node_modules/preact/LICENSE +21 -0
- package/templates/static/node_modules/preact/README.md +185 -0
- package/templates/static/node_modules/preact/compat/client.d.ts +13 -0
- package/templates/static/node_modules/preact/compat/client.js +21 -0
- package/templates/static/node_modules/preact/compat/client.mjs +24 -0
- package/templates/static/node_modules/preact/compat/dist/compat.js +2 -0
- package/templates/static/node_modules/preact/compat/dist/compat.js.map +1 -0
- package/templates/static/node_modules/preact/compat/dist/compat.mjs +2 -0
- package/templates/static/node_modules/preact/compat/dist/compat.module.js +2 -0
- package/templates/static/node_modules/preact/compat/dist/compat.module.js.map +1 -0
- package/templates/static/node_modules/preact/compat/dist/compat.umd.js +2 -0
- package/templates/static/node_modules/preact/compat/dist/compat.umd.js.map +1 -0
- package/templates/static/node_modules/preact/compat/jsx-dev-runtime.js +3 -0
- package/templates/static/node_modules/preact/compat/jsx-dev-runtime.mjs +3 -0
- package/templates/static/node_modules/preact/compat/jsx-runtime.js +3 -0
- package/templates/static/node_modules/preact/compat/jsx-runtime.mjs +3 -0
- package/templates/static/node_modules/preact/compat/package.json +55 -0
- package/templates/static/node_modules/preact/compat/scheduler.js +15 -0
- package/templates/static/node_modules/preact/compat/scheduler.mjs +23 -0
- package/templates/static/node_modules/preact/compat/server.browser.js +11 -0
- package/templates/static/node_modules/preact/compat/server.js +36 -0
- package/templates/static/node_modules/preact/compat/server.mjs +17 -0
- package/templates/static/node_modules/preact/compat/src/Children.js +21 -0
- package/templates/static/node_modules/preact/compat/src/PureComponent.js +16 -0
- package/templates/static/node_modules/preact/compat/src/forwardRef.js +44 -0
- package/templates/static/node_modules/preact/compat/src/hooks.js +70 -0
- package/templates/static/node_modules/preact/compat/src/index.d.ts +351 -0
- package/templates/static/node_modules/preact/compat/src/index.js +238 -0
- package/templates/static/node_modules/preact/compat/src/internal.d.ts +48 -0
- package/templates/static/node_modules/preact/compat/src/memo.js +35 -0
- package/templates/static/node_modules/preact/compat/src/portals.js +78 -0
- package/templates/static/node_modules/preact/compat/src/render.js +313 -0
- package/templates/static/node_modules/preact/compat/src/suspense-list.d.ts +16 -0
- package/templates/static/node_modules/preact/compat/src/suspense-list.js +127 -0
- package/templates/static/node_modules/preact/compat/src/suspense.d.ts +19 -0
- package/templates/static/node_modules/preact/compat/src/suspense.js +291 -0
- package/templates/static/node_modules/preact/compat/src/util.js +33 -0
- package/templates/static/node_modules/preact/compat/test-utils.js +1 -0
- package/templates/static/node_modules/preact/compat/test-utils.mjs +1 -0
- package/templates/static/node_modules/preact/debug/dist/debug.js +2 -0
- package/templates/static/node_modules/preact/debug/dist/debug.js.map +1 -0
- package/templates/static/node_modules/preact/debug/dist/debug.mjs +2 -0
- package/templates/static/node_modules/preact/debug/dist/debug.module.js +2 -0
- package/templates/static/node_modules/preact/debug/dist/debug.module.js.map +1 -0
- package/templates/static/node_modules/preact/debug/dist/debug.umd.js +2 -0
- package/templates/static/node_modules/preact/debug/dist/debug.umd.js.map +1 -0
- package/templates/static/node_modules/preact/debug/package.json +27 -0
- package/templates/static/node_modules/preact/debug/src/check-props.js +54 -0
- package/templates/static/node_modules/preact/debug/src/component-stack.js +146 -0
- package/templates/static/node_modules/preact/debug/src/constants.js +3 -0
- package/templates/static/node_modules/preact/debug/src/debug.js +593 -0
- package/templates/static/node_modules/preact/debug/src/index.d.ts +23 -0
- package/templates/static/node_modules/preact/debug/src/index.js +12 -0
- package/templates/static/node_modules/preact/debug/src/internal.d.ts +82 -0
- package/templates/static/node_modules/preact/debug/src/util.js +15 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.js +2 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.js.map +1 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.mjs +2 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.module.js +2 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.module.js.map +1 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.umd.js +2 -0
- package/templates/static/node_modules/preact/devtools/dist/devtools.umd.js.map +1 -0
- package/templates/static/node_modules/preact/devtools/package.json +25 -0
- package/templates/static/node_modules/preact/devtools/src/devtools.js +21 -0
- package/templates/static/node_modules/preact/devtools/src/index.d.ts +8 -0
- package/templates/static/node_modules/preact/devtools/src/index.js +15 -0
- package/templates/static/node_modules/preact/dist/preact.js +2 -0
- package/templates/static/node_modules/preact/dist/preact.js.map +1 -0
- package/templates/static/node_modules/preact/dist/preact.min.js +2 -0
- package/templates/static/node_modules/preact/dist/preact.min.js.map +1 -0
- package/templates/static/node_modules/preact/dist/preact.min.module.js +2 -0
- package/templates/static/node_modules/preact/dist/preact.min.module.js.map +1 -0
- package/templates/static/node_modules/preact/dist/preact.min.umd.js +2 -0
- package/templates/static/node_modules/preact/dist/preact.min.umd.js.map +1 -0
- package/templates/static/node_modules/preact/dist/preact.mjs +2 -0
- package/templates/static/node_modules/preact/dist/preact.module.js +2 -0
- package/templates/static/node_modules/preact/dist/preact.module.js.map +1 -0
- package/templates/static/node_modules/preact/dist/preact.umd.js +2 -0
- package/templates/static/node_modules/preact/dist/preact.umd.js.map +1 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.js +2 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.js.map +1 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.mjs +2 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.module.js +2 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.module.js.map +1 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.umd.js +2 -0
- package/templates/static/node_modules/preact/hooks/dist/hooks.umd.js.map +1 -0
- package/templates/static/node_modules/preact/hooks/package.json +35 -0
- package/templates/static/node_modules/preact/hooks/src/index.d.ts +145 -0
- package/templates/static/node_modules/preact/hooks/src/index.js +555 -0
- package/templates/static/node_modules/preact/hooks/src/internal.d.ts +103 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.js +2 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.js.map +1 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.mjs +2 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js +2 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js.map +1 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.umd.js +2 -0
- package/templates/static/node_modules/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +1 -0
- package/templates/static/node_modules/preact/jsx-runtime/package.json +28 -0
- package/templates/static/node_modules/preact/jsx-runtime/src/index.d.ts +62 -0
- package/templates/static/node_modules/preact/jsx-runtime/src/index.js +206 -0
- package/templates/static/node_modules/preact/jsx-runtime/src/utils.js +36 -0
- package/templates/static/node_modules/preact/package.json +258 -0
- package/templates/static/node_modules/preact/src/cjs.js +3 -0
- package/templates/static/node_modules/preact/src/clone-element.js +48 -0
- package/templates/static/node_modules/preact/src/component.js +249 -0
- package/templates/static/node_modules/preact/src/constants.js +22 -0
- package/templates/static/node_modules/preact/src/create-context.js +60 -0
- package/templates/static/node_modules/preact/src/create-element.js +97 -0
- package/templates/static/node_modules/preact/src/diff/catch-error.js +46 -0
- package/templates/static/node_modules/preact/src/diff/children.js +451 -0
- package/templates/static/node_modules/preact/src/diff/index.js +684 -0
- package/templates/static/node_modules/preact/src/diff/props.js +173 -0
- package/templates/static/node_modules/preact/src/dom.d.ts +2476 -0
- package/templates/static/node_modules/preact/src/index-5.d.ts +399 -0
- package/templates/static/node_modules/preact/src/index.d.ts +402 -0
- package/templates/static/node_modules/preact/src/index.js +13 -0
- package/templates/static/node_modules/preact/src/internal.d.ts +190 -0
- package/templates/static/node_modules/preact/src/jsx.d.ts +2878 -0
- package/templates/static/node_modules/preact/src/options.js +16 -0
- package/templates/static/node_modules/preact/src/render.js +78 -0
- package/templates/static/node_modules/preact/src/util.js +28 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.js +2 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.js.map +1 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.mjs +2 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.module.js +2 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.module.js.map +1 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.umd.js +2 -0
- package/templates/static/node_modules/preact/test-utils/dist/testUtils.umd.js.map +1 -0
- package/templates/static/node_modules/preact/test-utils/package.json +28 -0
- package/templates/static/node_modules/preact/test-utils/src/index.d.ts +3 -0
- package/templates/static/node_modules/preact/test-utils/src/index.js +129 -0
- package/templates/static/node_modules/preact-render-to-string/LICENSE +21 -0
- package/templates/static/node_modules/preact-render-to-string/README.md +149 -0
- package/templates/static/node_modules/preact-render-to-string/dist/commonjs.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.d.ts +17 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.js +6 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.mjs +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.module.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.module.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.umd.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/index.umd.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/internal.d.ts +35 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/commonjs.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.js +4 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.mjs +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.module.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.module.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.umd.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx/index.umd.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/jsx.d.ts +24 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.mjs +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.module.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.module.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.umd.js +2 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/index.umd.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.js +884 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.mjs +884 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.module.js +884 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.module.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.umd.js +888 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream/node/index.umd.js.map +1 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream-node.d.ts +19 -0
- package/templates/static/node_modules/preact-render-to-string/dist/stream.d.ts +10 -0
- package/templates/static/node_modules/preact-render-to-string/jsx.d.ts +24 -0
- package/templates/static/node_modules/preact-render-to-string/jsx.js +1 -0
- package/templates/static/node_modules/preact-render-to-string/package.json +152 -0
- package/templates/static/node_modules/preact-render-to-string/src/index.d.ts +17 -0
- package/templates/static/node_modules/preact-render-to-string/src/index.js +764 -0
- package/templates/static/node_modules/preact-render-to-string/src/internal.d.ts +35 -0
- package/templates/static/node_modules/preact-render-to-string/src/jsx.d.ts +24 -0
- package/templates/static/node_modules/preact-render-to-string/src/jsx.js +102 -0
- package/templates/static/node_modules/preact-render-to-string/src/lib/chunked.js +97 -0
- package/templates/static/node_modules/preact-render-to-string/src/lib/client.js +62 -0
- package/templates/static/node_modules/preact-render-to-string/src/lib/constants.js +20 -0
- package/templates/static/node_modules/preact-render-to-string/src/lib/polyfills.js +8 -0
- package/templates/static/node_modules/preact-render-to-string/src/lib/util.js +208 -0
- package/templates/static/node_modules/preact-render-to-string/src/pretty.js +491 -0
- package/templates/static/node_modules/preact-render-to-string/src/stream-node.d.ts +19 -0
- package/templates/static/node_modules/preact-render-to-string/src/stream-node.js +84 -0
- package/templates/static/node_modules/preact-render-to-string/src/stream.d.ts +10 -0
- package/templates/static/node_modules/preact-render-to-string/src/stream.js +43 -0
- package/templates/static/node_modules/preact-render-to-string/typings.json +5 -0
- package/templates/static/node_modules/sirv/build.js +197 -0
- package/templates/static/node_modules/sirv/build.mjs +197 -0
- package/templates/static/node_modules/sirv/index.d.mts +29 -0
- package/templates/static/node_modules/sirv/index.d.ts +33 -0
- package/templates/static/node_modules/sirv/package.json +40 -0
- package/templates/static/node_modules/sirv/readme.md +238 -0
- package/templates/static/node_modules/totalist/dist/index.js +24 -0
- package/templates/static/node_modules/totalist/dist/index.mjs +22 -0
- package/templates/static/node_modules/totalist/index.d.ts +3 -0
- package/templates/static/node_modules/totalist/license +21 -0
- package/templates/static/node_modules/totalist/package.json +55 -0
- package/templates/static/node_modules/totalist/readme.md +109 -0
- package/templates/static/node_modules/totalist/sync/index.d.ts +3 -0
- package/templates/static/node_modules/totalist/sync/index.js +17 -0
- package/templates/static/node_modules/totalist/sync/index.mjs +15 -0
- package/templates/static/node_modules/typescript/bin/tsc +2 -0
- package/templates/static/node_modules/typescript/bin/tsserver +2 -0
- package/templates/static/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/lib.d.ts +22 -0
- package/templates/static/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
- package/templates/static/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
- package/templates/static/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
- package/templates/static/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
- package/templates/static/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
- package/templates/static/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/templates/static/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
- package/templates/static/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
- package/templates/static/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
- package/templates/static/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
- package/templates/static/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
- package/templates/static/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
- package/templates/static/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
- package/templates/static/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/templates/static/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
- package/templates/static/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
- package/templates/static/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
- package/templates/static/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
- package/templates/static/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
- package/templates/static/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
- package/templates/static/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
- package/templates/static/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
- package/templates/static/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
- package/templates/static/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
- package/templates/static/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
- package/templates/static/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
- package/templates/static/node_modules/typescript/lib/lib.es6.d.ts +23 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
- package/templates/static/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
- package/templates/static/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
- package/templates/static/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
- package/templates/static/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
- package/templates/static/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
- package/templates/static/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
- package/templates/static/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
- package/templates/static/node_modules/typescript/lib/tsc.js +8 -0
- package/templates/static/node_modules/typescript/lib/tsserver.js +8 -0
- package/templates/static/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
- package/templates/static/node_modules/typescript/lib/tsserverlibrary.js +21 -0
- package/templates/static/node_modules/typescript/lib/typescript.d.ts +11437 -0
- package/templates/static/package.json +20 -0
- package/templates/static/server.js +130 -0
- package/templates/static/site/(home).tsx +12 -0
- package/templates/static/site/styles/global.scss +78 -0
- package/templates/static/tsconfig.json +39 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Jen.js.
|
|
3
|
+
* Copyright (C) 2026 oopsio
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Mark a component as an interactive island.
|
|
20
|
+
* Wraps component with hydration metadata.
|
|
21
|
+
*
|
|
22
|
+
* Usage in route:
|
|
23
|
+
* import { Island } from "jenjs";
|
|
24
|
+
* const Counter = Island(CounterImpl, "load");
|
|
25
|
+
*
|
|
26
|
+
* Then use in JSX: <Counter count={5} />
|
|
27
|
+
*
|
|
28
|
+
* Server will:
|
|
29
|
+
* - Render the component to HTML
|
|
30
|
+
* - Emit hydration markers
|
|
31
|
+
* - Include serialized props
|
|
32
|
+
*
|
|
33
|
+
* Client will:
|
|
34
|
+
* - Discover islands from markers
|
|
35
|
+
* - Hydrate based on strategy
|
|
36
|
+
*/
|
|
37
|
+
export function Island(Component, strategy) {
|
|
38
|
+
// Mark component metadata for server-side detection
|
|
39
|
+
Component.__island = true;
|
|
40
|
+
Component.__hydrationStrategy = strategy;
|
|
41
|
+
return Component;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Generate island hydration markers for server-rendered HTML.
|
|
45
|
+
* Call this after SSR to inject island metadata.
|
|
46
|
+
*/
|
|
47
|
+
export function createIslandMarker(id, componentPath, strategy, props) {
|
|
48
|
+
const propsJson = JSON.stringify(props).replace(/</g, "\\u003c");
|
|
49
|
+
return `<!--__ISLAND_${strategy.toUpperCase()}__:${id}:${componentPath}:${propsJson}-->`;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Extract islands from server-rendered HTML.
|
|
53
|
+
* Called by client to discover islands and their hydration strategy.
|
|
54
|
+
*/
|
|
55
|
+
export function extractIslandsFromHtml(html) {
|
|
56
|
+
const islands = [];
|
|
57
|
+
// Match: <!--__ISLAND_LOAD__:id:componentPath:props-->
|
|
58
|
+
const regex = /<!--__ISLAND_(LOAD|IDLE|VISIBLE)__:([^:]+):([^:]+):(.+?)-->/g;
|
|
59
|
+
let match;
|
|
60
|
+
while ((match = regex.exec(html)) !== null) {
|
|
61
|
+
const strategy = match[1].toLowerCase();
|
|
62
|
+
const id = match[2];
|
|
63
|
+
const componentPath = match[3];
|
|
64
|
+
const propsStr = match[4].replace(/\\u003c/g, "<");
|
|
65
|
+
// Validate island ID and component path
|
|
66
|
+
if (!id || !componentPath) {
|
|
67
|
+
console.warn('Invalid island marker: missing id or componentPath');
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
// Validate props is valid JSON
|
|
72
|
+
const props = JSON.parse(propsStr);
|
|
73
|
+
if (typeof props !== 'object' || props === null) {
|
|
74
|
+
console.warn(`Invalid props for island ${id}: expected object, got ${typeof props}`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
islands.push({
|
|
78
|
+
id,
|
|
79
|
+
component: componentPath,
|
|
80
|
+
strategy,
|
|
81
|
+
props,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.warn(`Failed to parse props for island ${id}:`, err instanceof Error ? err.message : String(err));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return islands;
|
|
89
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FrameworkConfig } from "../core/config.js";
|
|
2
|
+
import type { RouteEntry } from "../core/routes/scan.js";
|
|
3
|
+
export declare function renderRouteToHtml(opts: {
|
|
4
|
+
config: FrameworkConfig;
|
|
5
|
+
route: RouteEntry;
|
|
6
|
+
req?: any;
|
|
7
|
+
res?: any;
|
|
8
|
+
url: URL;
|
|
9
|
+
params: Record<string, string>;
|
|
10
|
+
query: Record<string, string>;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
cookies: Record<string, string>;
|
|
13
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Jen.js.
|
|
3
|
+
* Copyright (C) 2026 oopsio
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
import { createRouteMiddlewareContext, executeRouteMiddleware, } from "../core/middleware-hooks.js";
|
|
19
|
+
import { createIslandMarker } from "./islands.js";
|
|
20
|
+
import { h } from "preact";
|
|
21
|
+
import renderToString from "preact-render-to-string";
|
|
22
|
+
import { pathToFileURL } from "node:url";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
import { mkdirSync, existsSync } from "node:fs";
|
|
25
|
+
import esbuild from "esbuild";
|
|
26
|
+
import { vueEsbuildPlugin, svelteEsbuildPlugin } from "../compilers/esbuild-plugins.js";
|
|
27
|
+
function escapeHtml(s) {
|
|
28
|
+
return s
|
|
29
|
+
.replaceAll("&", "&")
|
|
30
|
+
.replaceAll("<", "<")
|
|
31
|
+
.replaceAll(">", ">")
|
|
32
|
+
.replaceAll('"', """)
|
|
33
|
+
.replaceAll("'", "'");
|
|
34
|
+
}
|
|
35
|
+
function getCachePath(filePath) {
|
|
36
|
+
const cacheDir = join(process.cwd(), "node_modules", ".jen", "cache");
|
|
37
|
+
if (!existsSync(cacheDir)) {
|
|
38
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
// Flatten path to avoid directory structure issues
|
|
41
|
+
const flatName = filePath.replace(/[\\/:]/g, "_").replace(/^_+/, "");
|
|
42
|
+
return join(cacheDir, flatName + ".mjs");
|
|
43
|
+
}
|
|
44
|
+
export async function renderRouteToHtml(opts) {
|
|
45
|
+
const { config, route, url, params, query, headers, cookies } = opts;
|
|
46
|
+
// Transpile route file if needed
|
|
47
|
+
let moduleUrl = route.filePath;
|
|
48
|
+
const ext = route.filePath.slice(-4).toLowerCase();
|
|
49
|
+
const requiresTranspile = [".tsx", ".ts", ".vue", ".svelte"].some((e) => route.filePath.toLowerCase().endsWith(e));
|
|
50
|
+
if (requiresTranspile) {
|
|
51
|
+
const outfile = getCachePath(route.filePath);
|
|
52
|
+
await esbuild.build({
|
|
53
|
+
entryPoints: [route.filePath],
|
|
54
|
+
outfile,
|
|
55
|
+
format: "esm",
|
|
56
|
+
platform: "node", // Use node platform for SSR to support built-ins
|
|
57
|
+
target: "es2022",
|
|
58
|
+
bundle: true, // Bundle to resolve local imports (simple)
|
|
59
|
+
external: ["preact", "preact-render-to-string", "jenjs"], // Keep framework externals
|
|
60
|
+
write: true,
|
|
61
|
+
plugins: [vueEsbuildPlugin(), svelteEsbuildPlugin()],
|
|
62
|
+
});
|
|
63
|
+
moduleUrl = outfile;
|
|
64
|
+
}
|
|
65
|
+
// Cache busting for dynamic import
|
|
66
|
+
let mod;
|
|
67
|
+
try {
|
|
68
|
+
mod = await import(pathToFileURL(moduleUrl).href + "?t=" + Date.now());
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
throw new Error(`Failed to import route module ${route.filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
72
|
+
}
|
|
73
|
+
// Execute route middleware if present (only in server context)
|
|
74
|
+
let middlewareData = {};
|
|
75
|
+
if (opts.req && opts.res) {
|
|
76
|
+
const middlewareCtx = createRouteMiddlewareContext({
|
|
77
|
+
req: opts.req,
|
|
78
|
+
res: opts.res,
|
|
79
|
+
url,
|
|
80
|
+
params,
|
|
81
|
+
query,
|
|
82
|
+
headers,
|
|
83
|
+
cookies,
|
|
84
|
+
});
|
|
85
|
+
const middlewares = [];
|
|
86
|
+
if (mod.middleware) {
|
|
87
|
+
if (Array.isArray(mod.middleware)) {
|
|
88
|
+
middlewares.push(...mod.middleware);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
middlewares.push(mod.middleware);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
await executeRouteMiddleware(middlewares, middlewareCtx);
|
|
96
|
+
middlewareData = middlewareCtx.data || {};
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
if (err.message === "__REDIRECT__" || err.message === "__JSON__") {
|
|
100
|
+
// Already sent response
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
throw err;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const loaderCtx = {
|
|
107
|
+
url,
|
|
108
|
+
params,
|
|
109
|
+
query,
|
|
110
|
+
headers,
|
|
111
|
+
cookies,
|
|
112
|
+
data: middlewareData, // Pass middleware data to loader
|
|
113
|
+
};
|
|
114
|
+
let data = null;
|
|
115
|
+
if (typeof mod.loader === "function") {
|
|
116
|
+
data = await mod.loader(loaderCtx);
|
|
117
|
+
}
|
|
118
|
+
if (!mod.default) {
|
|
119
|
+
throw new Error(`Route module ${route.filePath} does not export a default component`);
|
|
120
|
+
}
|
|
121
|
+
const Page = mod.default;
|
|
122
|
+
// Check if hydration is disabled
|
|
123
|
+
const shouldHydrate = mod.hydrate !== false;
|
|
124
|
+
const app = h(Page, { data, params, query });
|
|
125
|
+
let bodyHtml = renderToString(app);
|
|
126
|
+
// If this module exports island components, add hydration markers
|
|
127
|
+
// Look for components marked with __island metadata
|
|
128
|
+
for (const [key, value] of Object.entries(mod)) {
|
|
129
|
+
if (typeof value === "function" &&
|
|
130
|
+
value.__island &&
|
|
131
|
+
value.__hydrationStrategy) {
|
|
132
|
+
const strategy = value.__hydrationStrategy;
|
|
133
|
+
const componentPath = route.filePath;
|
|
134
|
+
const islandId = `island-${Math.random().toString(36).slice(2, 9)}`;
|
|
135
|
+
const marker = createIslandMarker(islandId, componentPath, strategy, {});
|
|
136
|
+
// Mark location in HTML for client to find
|
|
137
|
+
// Note: In a real implementation, we'd track island renders more carefully
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const headParts = [];
|
|
141
|
+
headParts.push(...config.inject.head);
|
|
142
|
+
if (mod.Head) {
|
|
143
|
+
try {
|
|
144
|
+
const headNode = h(mod.Head, { data, params, query });
|
|
145
|
+
const headHtml = renderToString(headNode);
|
|
146
|
+
headParts.push(headHtml);
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.error(`Failed to render Head component for ${route.filePath}:`, err instanceof Error ? err.message : String(err));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
headParts.push(`<link rel="stylesheet" href="/styles.css">`);
|
|
153
|
+
// Build HTML
|
|
154
|
+
let html = `<!doctype html>
|
|
155
|
+
<html>
|
|
156
|
+
<head>
|
|
157
|
+
${headParts.join("\n")}
|
|
158
|
+
</head>
|
|
159
|
+
<body>
|
|
160
|
+
<div id="app">${bodyHtml}</div>`;
|
|
161
|
+
// Only inject hydration script if enabled
|
|
162
|
+
if (shouldHydrate) {
|
|
163
|
+
// Serialize framework data with proper escaping
|
|
164
|
+
// Escape </script to prevent script injection
|
|
165
|
+
const frameworkDataStr = JSON.stringify({ data, params, query }, null, 2).replace(/<\/script/gi, "<\\/script");
|
|
166
|
+
const hydrateFile = `/__hydrate?file=${encodeURIComponent(route.filePath)}`;
|
|
167
|
+
html += `
|
|
168
|
+
<script id="__FRAMEWORK_DATA__" type="application/json">
|
|
169
|
+
${frameworkDataStr}
|
|
170
|
+
</script>
|
|
171
|
+
<script type="module">
|
|
172
|
+
import { hydrateClient } from "/__runtime/hydrate.js";
|
|
173
|
+
import { initializeIslands } from "/__runtime/island-hydration-client.js";
|
|
174
|
+
hydrateClient(${JSON.stringify(hydrateFile)});
|
|
175
|
+
initializeIslands();
|
|
176
|
+
</script>`;
|
|
177
|
+
}
|
|
178
|
+
html += `
|
|
179
|
+
${config.inject.bodyEnd.join("\n")}
|
|
180
|
+
</body>
|
|
181
|
+
</html>`;
|
|
182
|
+
return html;
|
|
183
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* API route handler context.
|
|
4
|
+
*/
|
|
5
|
+
export interface ApiRouteContext {
|
|
6
|
+
req: IncomingMessage;
|
|
7
|
+
res: ServerResponse;
|
|
8
|
+
url: URL;
|
|
9
|
+
method: string;
|
|
10
|
+
query: Record<string, string>;
|
|
11
|
+
body: any;
|
|
12
|
+
params: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* API handler function.
|
|
16
|
+
* Return Response, string, or object (auto JSON).
|
|
17
|
+
*/
|
|
18
|
+
export type ApiHandler = (ctx: ApiRouteContext) => Promise<Response | string | Record<string, any> | null> | Response | string | Record<string, any> | null;
|
|
19
|
+
/**
|
|
20
|
+
* API route module.
|
|
21
|
+
* Export GET, POST, PUT, DELETE, etc.
|
|
22
|
+
*/
|
|
23
|
+
export interface ApiRouteModule {
|
|
24
|
+
GET?: ApiHandler;
|
|
25
|
+
POST?: ApiHandler;
|
|
26
|
+
PUT?: ApiHandler;
|
|
27
|
+
DELETE?: ApiHandler;
|
|
28
|
+
PATCH?: ApiHandler;
|
|
29
|
+
HEAD?: ApiHandler;
|
|
30
|
+
OPTIONS?: ApiHandler;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Try to handle an API route.
|
|
34
|
+
* Returns true if handled (success or error), false if no route found.
|
|
35
|
+
*
|
|
36
|
+
* Routes:
|
|
37
|
+
* /api/hello → site/api/hello.ts (GET, POST, etc.)
|
|
38
|
+
* /api/users/123 → site/api/users/[id].ts
|
|
39
|
+
*/
|
|
40
|
+
export declare function tryHandleApiRoute(opts: {
|
|
41
|
+
req: IncomingMessage;
|
|
42
|
+
res: ServerResponse;
|
|
43
|
+
siteDir: string;
|
|
44
|
+
}): Promise<boolean>;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Jen.js.
|
|
3
|
+
* Copyright (C) 2026 oopsio
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync } from "node:fs";
|
|
19
|
+
import { join, basename } from "node:path";
|
|
20
|
+
import esbuild from "esbuild";
|
|
21
|
+
import { pathToFileURL } from "node:url";
|
|
22
|
+
const apiCacheDir = join(process.cwd(), "node_modules", ".jen", "api-cache");
|
|
23
|
+
/**
|
|
24
|
+
* Transpile API route file (TS → JS).
|
|
25
|
+
*/
|
|
26
|
+
async function transpileApiRoute(filePath) {
|
|
27
|
+
const outfile = join(apiCacheDir, basename(filePath).replace(/\.ts$/, `.${Date.now()}.mjs`));
|
|
28
|
+
await esbuild.build({
|
|
29
|
+
entryPoints: [filePath],
|
|
30
|
+
outfile,
|
|
31
|
+
format: "esm",
|
|
32
|
+
platform: "node",
|
|
33
|
+
target: "es2022",
|
|
34
|
+
bundle: true,
|
|
35
|
+
external: ["preact", "preact-render-to-string", "jenjs"],
|
|
36
|
+
write: true,
|
|
37
|
+
});
|
|
38
|
+
return outfile;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Try to handle an API route.
|
|
42
|
+
* Returns true if handled (success or error), false if no route found.
|
|
43
|
+
*
|
|
44
|
+
* Routes:
|
|
45
|
+
* /api/hello → site/api/hello.ts (GET, POST, etc.)
|
|
46
|
+
* /api/users/123 → site/api/users/[id].ts
|
|
47
|
+
*/
|
|
48
|
+
export async function tryHandleApiRoute(opts) {
|
|
49
|
+
const { req, res, siteDir } = opts;
|
|
50
|
+
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
51
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
52
|
+
// Must start with /api/
|
|
53
|
+
if (!url.pathname.startsWith("/api/"))
|
|
54
|
+
return false;
|
|
55
|
+
const pathParts = url.pathname
|
|
56
|
+
.slice("/api/".length)
|
|
57
|
+
.split("/")
|
|
58
|
+
.filter(Boolean);
|
|
59
|
+
if (pathParts.length === 0) {
|
|
60
|
+
res.statusCode = 404;
|
|
61
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
62
|
+
res.end(JSON.stringify({ error: "API route not found" }));
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// Try exact match first: /api/hello → api/hello.ts
|
|
66
|
+
let apiFile = null;
|
|
67
|
+
let routeParams = {};
|
|
68
|
+
const exactPath = join(process.cwd(), siteDir, "api", `${pathParts.join("/")}.ts`);
|
|
69
|
+
if (existsSync(exactPath)) {
|
|
70
|
+
apiFile = exactPath;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Try dynamic route: /api/users/123 → api/users/[id].ts
|
|
74
|
+
const basePath = join(process.cwd(), siteDir, "api");
|
|
75
|
+
for (let i = pathParts.length; i >= 1; i--) {
|
|
76
|
+
const staticSegments = pathParts.slice(0, i);
|
|
77
|
+
const dynamicSegments = pathParts.slice(i);
|
|
78
|
+
const tryDynamic = join(basePath, ...staticSegments.map((s) => `[${s}]`), `[${staticSegments[staticSegments.length - 1]}].ts`);
|
|
79
|
+
// Actually, try: api/[id].ts for /api/123
|
|
80
|
+
// and api/users/[id].ts for /api/users/123
|
|
81
|
+
// Simple approach: check api/[param].ts
|
|
82
|
+
if (staticSegments.length === 0 && dynamicSegments.length === 1) {
|
|
83
|
+
const paramFile = join(basePath, `[${dynamicSegments[0]}].ts`);
|
|
84
|
+
if (existsSync(paramFile)) {
|
|
85
|
+
apiFile = paramFile;
|
|
86
|
+
routeParams[dynamicSegments[0]] = dynamicSegments[0];
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!apiFile) {
|
|
93
|
+
res.statusCode = 404;
|
|
94
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
95
|
+
res.end(JSON.stringify({ error: "API route not found" }));
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
// Transpile if TS
|
|
99
|
+
let moduleUrl = apiFile;
|
|
100
|
+
if (apiFile.endsWith(".ts")) {
|
|
101
|
+
moduleUrl = await transpileApiRoute(apiFile);
|
|
102
|
+
}
|
|
103
|
+
// Load module
|
|
104
|
+
let mod;
|
|
105
|
+
try {
|
|
106
|
+
mod = await import(pathToFileURL(moduleUrl).href + `?t=${Date.now()}`);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
res.statusCode = 500;
|
|
110
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
111
|
+
res.end(JSON.stringify({
|
|
112
|
+
error: "Failed to load API route",
|
|
113
|
+
details: err.message,
|
|
114
|
+
}));
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
// Find handler for method
|
|
118
|
+
const handler = mod[method];
|
|
119
|
+
if (!handler) {
|
|
120
|
+
res.statusCode = 405;
|
|
121
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
122
|
+
res.setHeader("allow", Object.keys(mod).join(", "));
|
|
123
|
+
res.end(JSON.stringify({ error: `${method} not allowed` }));
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
// Read body
|
|
127
|
+
const body = await readRequestBody(req);
|
|
128
|
+
// Build context
|
|
129
|
+
const ctx = {
|
|
130
|
+
req,
|
|
131
|
+
res,
|
|
132
|
+
url,
|
|
133
|
+
method,
|
|
134
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
135
|
+
body,
|
|
136
|
+
params: routeParams,
|
|
137
|
+
};
|
|
138
|
+
// Execute handler
|
|
139
|
+
try {
|
|
140
|
+
const result = await handler(ctx);
|
|
141
|
+
// Handler already sent response
|
|
142
|
+
if (res.writableEnded)
|
|
143
|
+
return true;
|
|
144
|
+
// Handle Response
|
|
145
|
+
if (result instanceof Response) {
|
|
146
|
+
res.statusCode = result.status;
|
|
147
|
+
result.headers.forEach((v, k) => res.setHeader(k, v));
|
|
148
|
+
const buf = Buffer.from(await result.arrayBuffer());
|
|
149
|
+
res.end(buf);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
// Handle string
|
|
153
|
+
if (typeof result === "string") {
|
|
154
|
+
res.statusCode = 200;
|
|
155
|
+
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
156
|
+
res.end(result);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
// Handle object (JSON)
|
|
160
|
+
res.statusCode = 200;
|
|
161
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
162
|
+
res.end(JSON.stringify(result ?? null));
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
res.statusCode = 500;
|
|
167
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
168
|
+
res.end(JSON.stringify({ error: "Internal server error", details: err.message }));
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Read request body (shared with old API handler).
|
|
174
|
+
*/
|
|
175
|
+
async function readRequestBody(req) {
|
|
176
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
177
|
+
if (method === "GET" || method === "HEAD")
|
|
178
|
+
return null;
|
|
179
|
+
const chunks = [];
|
|
180
|
+
for await (const chunk of req) {
|
|
181
|
+
chunks.push(Buffer.from(chunk));
|
|
182
|
+
}
|
|
183
|
+
if (chunks.length === 0)
|
|
184
|
+
return null;
|
|
185
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
186
|
+
const ct = (req.headers["content-type"] ?? "").toString();
|
|
187
|
+
if (ct.includes("application/json")) {
|
|
188
|
+
try {
|
|
189
|
+
return JSON.parse(raw);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return { __raw: raw };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return { __raw: raw };
|
|
196
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Jen.js.
|
|
3
|
+
* Copyright (C) 2026 oopsio
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync } from "node:fs";
|
|
19
|
+
import { join, normalize } from "node:path";
|
|
20
|
+
import { pathToFileURL } from "node:url";
|
|
21
|
+
const MAX_BODY_SIZE = 1024 * 1024; // 1MB
|
|
22
|
+
const VALID_ROUTE_PATTERN = /^[a-zA-Z0-9_\-/]+$/; // Only alphanumeric, underscore, hyphen, forward slash
|
|
23
|
+
function isValidRouteName(name) {
|
|
24
|
+
if (!name || name.length > 255)
|
|
25
|
+
return false;
|
|
26
|
+
if (name.includes("..") || name.includes("\\") || name.startsWith("/"))
|
|
27
|
+
return false;
|
|
28
|
+
return VALID_ROUTE_PATTERN.test(name);
|
|
29
|
+
}
|
|
30
|
+
export async function tryHandleApiRoute(opts) {
|
|
31
|
+
const { req, res, siteDir } = opts;
|
|
32
|
+
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
33
|
+
if (!url.pathname.startsWith("/api/"))
|
|
34
|
+
return false;
|
|
35
|
+
// /api/hello -> site/api/(hello).ts
|
|
36
|
+
let name = url.pathname.slice("/api/".length) || "home";
|
|
37
|
+
// Security: Validate route name to prevent path traversal
|
|
38
|
+
if (!isValidRouteName(name)) {
|
|
39
|
+
res.statusCode = 400;
|
|
40
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
41
|
+
res.end(JSON.stringify({ error: "Invalid API route format" }));
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const file = join(process.cwd(), siteDir, "api", `(${name}).ts`);
|
|
45
|
+
// Ensure the resolved path is within the api directory (prevent directory traversal)
|
|
46
|
+
const apiDir = normalize(join(process.cwd(), siteDir, "api"));
|
|
47
|
+
if (!normalize(file).startsWith(apiDir)) {
|
|
48
|
+
res.statusCode = 403;
|
|
49
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
50
|
+
res.end(JSON.stringify({ error: "Forbidden" }));
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (!existsSync(file)) {
|
|
54
|
+
res.statusCode = 404;
|
|
55
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
56
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
// Use pathToFileURL to handle Windows paths correctly
|
|
60
|
+
const mod = await import(pathToFileURL(file).href + `?t=${Date.now()}`);
|
|
61
|
+
const handler = mod?.default;
|
|
62
|
+
if (typeof handler !== "function") {
|
|
63
|
+
res.statusCode = 500;
|
|
64
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
65
|
+
res.end(JSON.stringify({ error: "API route missing default export function" }));
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
const body = await readBody(req);
|
|
69
|
+
const ctx = {
|
|
70
|
+
req,
|
|
71
|
+
res,
|
|
72
|
+
url,
|
|
73
|
+
method: req.method ?? "GET",
|
|
74
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
75
|
+
body,
|
|
76
|
+
};
|
|
77
|
+
const out = await handler(ctx);
|
|
78
|
+
if (res.writableEnded)
|
|
79
|
+
return true;
|
|
80
|
+
if (out instanceof Response) {
|
|
81
|
+
res.statusCode = out.status;
|
|
82
|
+
out.headers.forEach((v, k) => res.setHeader(k, v));
|
|
83
|
+
const buf = Buffer.from(await out.arrayBuffer());
|
|
84
|
+
res.end(buf);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
if (typeof out === "string") {
|
|
88
|
+
res.statusCode = 200;
|
|
89
|
+
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
90
|
+
res.end(out);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
res.statusCode = 200;
|
|
94
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
95
|
+
res.end(JSON.stringify(out ?? null));
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
async function readBody(req) {
|
|
99
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
100
|
+
if (method === "GET" || method === "HEAD")
|
|
101
|
+
return null;
|
|
102
|
+
const chunks = [];
|
|
103
|
+
let totalSize = 0;
|
|
104
|
+
for await (const chunk of req) {
|
|
105
|
+
totalSize += chunk.length;
|
|
106
|
+
if (totalSize > MAX_BODY_SIZE) {
|
|
107
|
+
throw new Error(`Request body exceeds maximum size of ${MAX_BODY_SIZE} bytes`);
|
|
108
|
+
}
|
|
109
|
+
chunks.push(Buffer.from(chunk));
|
|
110
|
+
}
|
|
111
|
+
if (chunks.length === 0)
|
|
112
|
+
return null;
|
|
113
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
114
|
+
const ct = req.headers["content-type"] ?? "";
|
|
115
|
+
if (typeof ct === "string" && ct.includes("application/json")) {
|
|
116
|
+
try {
|
|
117
|
+
return JSON.parse(raw);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return { __raw: raw };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { __raw: raw };
|
|
124
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { FrameworkConfig } from "../core/config.js";
|
|
3
|
+
type AppMode = "dev" | "prod";
|
|
4
|
+
export declare function createApp(opts: {
|
|
5
|
+
config: FrameworkConfig;
|
|
6
|
+
mode: AppMode;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
handle(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
9
|
+
}>;
|
|
10
|
+
export {};
|