create-nifra 0.1.0-alpha.1

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.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -0
  3. package/dist/agents.d.ts +22 -0
  4. package/dist/agents.d.ts.map +1 -0
  5. package/dist/agents.js +259 -0
  6. package/dist/agents.js.map +1 -0
  7. package/dist/auth.d.ts +30 -0
  8. package/dist/auth.d.ts.map +1 -0
  9. package/dist/auth.js +90 -0
  10. package/dist/auth.js.map +1 -0
  11. package/dist/cli.d.ts +101 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +450 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/db.d.ts +39 -0
  16. package/dist/db.d.ts.map +1 -0
  17. package/dist/db.js +467 -0
  18. package/dist/db.js.map +1 -0
  19. package/package.json +50 -0
  20. package/template/README.md +24 -0
  21. package/template/gitignore +6 -0
  22. package/template/package.json +20 -0
  23. package/template/src/app.test.ts +8 -0
  24. package/template/src/app.ts +8 -0
  25. package/template/src/index.ts +5 -0
  26. package/template/tsconfig.json +16 -0
  27. package/template-isr/README.md +46 -0
  28. package/template-isr/backend.ts +12 -0
  29. package/template-isr/build.ts +23 -0
  30. package/template-isr/gitignore +7 -0
  31. package/template-isr/package.json +24 -0
  32. package/template-isr/routes/_404.tsx +10 -0
  33. package/template-isr/routes/_layout.tsx +18 -0
  34. package/template-isr/routes/index.tsx +34 -0
  35. package/template-isr/server.ts +56 -0
  36. package/template-isr/tsconfig.json +28 -0
  37. package/template-isr/worker.ts +52 -0
  38. package/template-isr/wrangler.toml +20 -0
  39. package/template-site/.dockerignore +14 -0
  40. package/template-site/Dockerfile +20 -0
  41. package/template-site/README.md +44 -0
  42. package/template-site/_worker.ts +17 -0
  43. package/template-site/backend.ts +12 -0
  44. package/template-site/build-bun.ts +27 -0
  45. package/template-site/build-deno.ts +25 -0
  46. package/template-site/build-node.ts +26 -0
  47. package/template-site/build-vercel.ts +45 -0
  48. package/template-site/build.ts +29 -0
  49. package/template-site/deno.json +7 -0
  50. package/template-site/framework.ts +6 -0
  51. package/template-site/gitignore +16 -0
  52. package/template-site/nifra.config.ts +9 -0
  53. package/template-site/package.json +37 -0
  54. package/template-site/routes/_404.tsx +20 -0
  55. package/template-site/routes/_layout.tsx +40 -0
  56. package/template-site/routes/index.tsx +53 -0
  57. package/template-site/server-bun.ts +35 -0
  58. package/template-site/server-deno.ts +38 -0
  59. package/template-site/server-node.ts +40 -0
  60. package/template-site/server-vercel.ts +17 -0
  61. package/template-site/tsconfig.json +37 -0
  62. package/template-site/wrangler.toml +4 -0
  63. package/template-site-preact/.dockerignore +14 -0
  64. package/template-site-preact/Dockerfile +20 -0
  65. package/template-site-preact/README.md +43 -0
  66. package/template-site-preact/_worker.ts +17 -0
  67. package/template-site-preact/backend.ts +12 -0
  68. package/template-site-preact/build-bun.ts +27 -0
  69. package/template-site-preact/build-deno.ts +25 -0
  70. package/template-site-preact/build-node.ts +26 -0
  71. package/template-site-preact/build-vercel.ts +45 -0
  72. package/template-site-preact/build.ts +29 -0
  73. package/template-site-preact/deno.json +7 -0
  74. package/template-site-preact/framework.ts +6 -0
  75. package/template-site-preact/gitignore +16 -0
  76. package/template-site-preact/nifra.config.ts +9 -0
  77. package/template-site-preact/package.json +34 -0
  78. package/template-site-preact/routes/_404.tsx +20 -0
  79. package/template-site-preact/routes/_layout.tsx +40 -0
  80. package/template-site-preact/routes/index.tsx +53 -0
  81. package/template-site-preact/server-bun.ts +35 -0
  82. package/template-site-preact/server-deno.ts +38 -0
  83. package/template-site-preact/server-node.ts +40 -0
  84. package/template-site-preact/server-vercel.ts +17 -0
  85. package/template-site-preact/tsconfig.json +38 -0
  86. package/template-site-preact/wrangler.toml +4 -0
  87. package/template-site-solid/.dockerignore +14 -0
  88. package/template-site-solid/Dockerfile +20 -0
  89. package/template-site-solid/README.md +43 -0
  90. package/template-site-solid/_worker.ts +17 -0
  91. package/template-site-solid/backend.ts +12 -0
  92. package/template-site-solid/build-bun.ts +33 -0
  93. package/template-site-solid/build-deno.ts +32 -0
  94. package/template-site-solid/build-node.ts +33 -0
  95. package/template-site-solid/build-vercel.ts +47 -0
  96. package/template-site-solid/build.ts +36 -0
  97. package/template-site-solid/deno.json +7 -0
  98. package/template-site-solid/framework.ts +6 -0
  99. package/template-site-solid/gitignore +16 -0
  100. package/template-site-solid/nifra.config.ts +14 -0
  101. package/template-site-solid/package.json +34 -0
  102. package/template-site-solid/routes/_404.tsx +20 -0
  103. package/template-site-solid/routes/_layout.tsx +39 -0
  104. package/template-site-solid/routes/index.tsx +53 -0
  105. package/template-site-solid/server-bun.ts +35 -0
  106. package/template-site-solid/server-deno.ts +38 -0
  107. package/template-site-solid/server-node.ts +40 -0
  108. package/template-site-solid/server-vercel.ts +17 -0
  109. package/template-site-solid/tsconfig.json +38 -0
  110. package/template-site-solid/wrangler.toml +4 -0
  111. package/template-site-svelte/.dockerignore +14 -0
  112. package/template-site-svelte/Dockerfile +20 -0
  113. package/template-site-svelte/README.md +45 -0
  114. package/template-site-svelte/_worker.ts +17 -0
  115. package/template-site-svelte/backend.ts +12 -0
  116. package/template-site-svelte/build-bun.ts +32 -0
  117. package/template-site-svelte/build-deno.ts +31 -0
  118. package/template-site-svelte/build-node.ts +32 -0
  119. package/template-site-svelte/build-vercel.ts +46 -0
  120. package/template-site-svelte/build.ts +35 -0
  121. package/template-site-svelte/deno.json +7 -0
  122. package/template-site-svelte/framework.ts +6 -0
  123. package/template-site-svelte/gitignore +16 -0
  124. package/template-site-svelte/nifra.config.ts +13 -0
  125. package/template-site-svelte/package.json +34 -0
  126. package/template-site-svelte/routes/_404.svelte +16 -0
  127. package/template-site-svelte/routes/_layout.svelte +35 -0
  128. package/template-site-svelte/routes/index.svelte +47 -0
  129. package/template-site-svelte/server-bun.ts +35 -0
  130. package/template-site-svelte/server-deno.ts +38 -0
  131. package/template-site-svelte/server-node.ts +40 -0
  132. package/template-site-svelte/server-vercel.ts +17 -0
  133. package/template-site-svelte/tsconfig.json +37 -0
  134. package/template-site-svelte/wrangler.toml +4 -0
  135. package/template-site-vue/.dockerignore +14 -0
  136. package/template-site-vue/Dockerfile +20 -0
  137. package/template-site-vue/README.md +45 -0
  138. package/template-site-vue/_worker.ts +17 -0
  139. package/template-site-vue/backend.ts +12 -0
  140. package/template-site-vue/build-bun.ts +37 -0
  141. package/template-site-vue/build-deno.ts +36 -0
  142. package/template-site-vue/build-node.ts +37 -0
  143. package/template-site-vue/build-vercel.ts +54 -0
  144. package/template-site-vue/build.ts +40 -0
  145. package/template-site-vue/deno.json +7 -0
  146. package/template-site-vue/framework.ts +6 -0
  147. package/template-site-vue/gitignore +16 -0
  148. package/template-site-vue/nifra.config.ts +19 -0
  149. package/template-site-vue/package.json +35 -0
  150. package/template-site-vue/routes/_404.vue +18 -0
  151. package/template-site-vue/routes/_layout.vue +40 -0
  152. package/template-site-vue/routes/index.vue +56 -0
  153. package/template-site-vue/server-bun.ts +35 -0
  154. package/template-site-vue/server-deno.ts +38 -0
  155. package/template-site-vue/server-node.ts +40 -0
  156. package/template-site-vue/server-vercel.ts +17 -0
  157. package/template-site-vue/tsconfig.json +37 -0
  158. package/template-site-vue/wrangler.toml +4 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "tasks": {
3
+ "build": "bun run build-deno.ts",
4
+ "start": "deno run --allow-net --allow-read --allow-env dist-deno/server-deno.js"
5
+ },
6
+ "//": "Build with Bun (nifra's toolchain), run/deploy the self-contained bundle on Deno. Deploy to Deno Deploy: deployctl deploy --prod --entrypoint=dist-deno/server-deno.js"
7
+ }
@@ -0,0 +1,6 @@
1
+ // The frontend adapter for this app. `create-nifra --framework <react|preact|vue|solid|svelte>` swaps
2
+ // this one line (and the routes + build config); every server entry imports the adapter from here, so
3
+ // they stay framework-agnostic.
4
+ import { vueAdapter } from "@nifrajs/web-vue"
5
+
6
+ export const adapter = vueAdapter
@@ -0,0 +1,16 @@
1
+ node_modules
2
+ dist
3
+ dist-bun
4
+ dist-node
5
+ dist-deno
6
+ .vercel
7
+ .build
8
+ .build-bun
9
+ .build-node
10
+ .build-deno
11
+ .build-vercel
12
+ .wrangler
13
+ # generated by buildServer next to the entry
14
+ server-manifest.ts
15
+ # generated by `nifra dev` (the Vite dev client entry) at the project root
16
+ .nifra-vite-entry.tsx
@@ -0,0 +1,19 @@
1
+ // The nifra CLI's config — read by `nifra dev|build|start`. It's imported ONLY by the CLI (which runs on
2
+ // Bun), so it can eagerly import the Vite plugin + the SFC compiler — keeping them OUT of the edge
3
+ // worker bundle that `framework.ts` (the render-adapter source the entries import) must stay free of.
4
+ import { vueBunPlugin } from "@nifrajs/web-vue/plugin"
5
+ import vue from "@vitejs/plugin-vue"
6
+
7
+ export { adapter } from "./framework"
8
+ export const clientModule = "@nifrajs/web-vue/client"
9
+ // `nifra dev` HMR: Vite + the official Vue plugin compile/HMR the .vue client modules.
10
+ export const vitePlugins = [vue()]
11
+ // `nifra build` (client) + `nifra start`/`nifra dev` (Bun-side SSR) compile .vue via these.
12
+ export const clientPlugins = [vueBunPlugin("dom")]
13
+ export const serverPlugins = [vueBunPlugin("ssr")]
14
+ // Vue feature flags the plugin doesn't inject (mirrors the build scripts' define).
15
+ export const define = {
16
+ __VUE_OPTIONS_API__: "true",
17
+ __VUE_PROD_DEVTOOLS__: "false",
18
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false",
19
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "nifra-site",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "nifra dev",
8
+ "preview": "bunx wrangler pages dev dist",
9
+ "build": "bun run build.ts",
10
+ "build:bun": "bun run build-bun.ts",
11
+ "build:node": "bun run build-node.ts",
12
+ "build:deno": "bun run build-deno.ts",
13
+ "build:vercel": "bun run build-vercel.ts",
14
+ "start": "bun dist-bun/server-bun.js",
15
+ "start:node": "node dist-node/server-node.js",
16
+ "deploy:cf": "wrangler pages deploy dist",
17
+ "deploy:vercel": "vercel deploy --prebuilt"
18
+ },
19
+ "dependencies": {
20
+ "@nifrajs/client": "^0.1.0",
21
+ "@nifrajs/core": "^0.1.0",
22
+ "@nifrajs/deno": "^0.1.0",
23
+ "@nifrajs/node": "^0.1.0",
24
+ "@nifrajs/web": "^0.1.0",
25
+ "@nifrajs/web-vue": "^0.1.0",
26
+ "vue": "^3.5.0"
27
+ },
28
+ "devDependencies": {
29
+ "@nifrajs/cli": "^0.1.0",
30
+ "@vitejs/plugin-vue": "^5.2.0",
31
+ "@vue/compiler-sfc": "^3.5.0",
32
+ "typescript": "^6.0.3",
33
+ "vite": "^8.0.0"
34
+ }
35
+ }
@@ -0,0 +1,18 @@
1
+ <!-- nifra's catch-all renders _404 WITHOUT the layout chain, so it wraps itself in the root Layout. -->
2
+ <script lang="ts">
3
+ export const meta = { title: "Not found" }
4
+ </script>
5
+
6
+ <script setup lang="ts">
7
+ import Layout from "./_layout.vue"
8
+ </script>
9
+
10
+ <template>
11
+ <Layout>
12
+ <section class="hero">
13
+ <h1><span class="grad">404</span></h1>
14
+ <p>That page doesn't exist.</p>
15
+ <a class="btn" href="/">← Back home</a>
16
+ </section>
17
+ </Layout>
18
+ </template>
@@ -0,0 +1,40 @@
1
+ <!--
2
+ Root layout (Vue SFC) — wraps every page; the compose fold passes the page through the default slot.
3
+ The global stylesheet is rendered as a <style> element via <component :is="'style'"> — SFC <style>
4
+ blocks are dropped (nifra has no CSS pipeline), and a dynamic component sidesteps the template
5
+ compiler's special-casing of a literal <style> tag. Keeps the whole template single-file.
6
+ -->
7
+ <script setup lang="ts">
8
+ const css = `
9
+ :root { --bg:#0a0a0f; --panel:#14141c; --border:#26263a; --fg:#e8e8f0; --muted:#9a9ab0; --accent:#7c5cff; --accent2:#00d4ff; }
10
+ * { box-sizing: border-box; } html { color-scheme: dark; }
11
+ body { margin:0; background:var(--bg); color:var(--fg); font:16px/1.6 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif; -webkit-font-smoothing:antialiased; }
12
+ a { color:var(--accent2); text-decoration:none; } a:hover { text-decoration:underline; }
13
+ .wrap { max-width:840px; margin:0 auto; padding:0 24px; }
14
+ header.site { border-bottom:1px solid var(--border); } header.site .wrap { display:flex; align-items:center; justify-content:space-between; height:62px; }
15
+ .logo, .logo b { font-weight:800; font-size:20px; } .logo b { background:linear-gradient(90deg,var(--accent),var(--accent2)); -webkit-background-clip:text; background-clip:text; color:transparent; }
16
+ .hero { text-align:center; padding:80px 0 56px; }
17
+ .hero h1 { font-size:clamp(36px,6vw,56px); line-height:1.05; margin:0 0 16px; letter-spacing:-0.03em; }
18
+ .hero h1 .grad { background:linear-gradient(90deg,var(--accent),var(--accent2)); -webkit-background-clip:text; background-clip:text; color:transparent; }
19
+ .hero p { font-size:19px; color:var(--muted); max-width:560px; margin:0 auto 28px; }
20
+ .card { background:var(--panel); border:1px solid var(--border); border-radius:14px; padding:24px 28px; display:flex; align-items:center; justify-content:space-between; gap:24px; flex-wrap:wrap; }
21
+ .card h3 { margin:0 0 4px; } .card p { margin:0; color:var(--muted); font-size:14px; }
22
+ .count { font-size:34px; font-weight:800; font-variant-numeric:tabular-nums; min-width:44px; text-align:center; background:linear-gradient(90deg,var(--accent),var(--accent2)); -webkit-background-clip:text; background-clip:text; color:transparent; }
23
+ .btn { background:linear-gradient(90deg,var(--accent),var(--accent2)); color:#0a0a0f; font:inherit; font-weight:700; border:none; cursor:pointer; padding:11px 20px; border-radius:10px; }
24
+ footer.site { border-top:1px solid var(--border); color:var(--muted); font-size:14px; } footer.site .wrap { padding:24px; }
25
+ `.trim()
26
+ </script>
27
+
28
+ <template>
29
+ <div id="app">
30
+ <component :is="'style'">{{ css }}</component>
31
+ <header class="site">
32
+ <div class="wrap">
33
+ <a href="/" class="logo"><b>nifra</b></a>
34
+ <a href="https://github.com">GitHub</a>
35
+ </div>
36
+ </header>
37
+ <main class="wrap"><slot /></main>
38
+ <footer class="site"><div class="wrap">Built with nifra</div></footer>
39
+ </div>
40
+ </template>
@@ -0,0 +1,56 @@
1
+ <!--
2
+ Home route (Vue SFC). The plain <script> carries nifra's route convention — loader/action/meta are
3
+ server-only named exports the client codegen tree-shakes out. <script setup> + <template> are the
4
+ component. The form POST is the SSR action path; after a client submit the loader revalidates with
5
+ no full reload (progressive enhancement). Compiled by @nifrajs/web-vue/plugin.
6
+ -->
7
+ <script lang="ts">
8
+ import type { ActionArgs, LoaderArgs } from "@nifrajs/client"
9
+ import type { backend } from "../backend"
10
+
11
+ export const meta = {
12
+ title: "nifra site",
13
+ meta: [{ name: "description", content: "A nifra + Vue SSR site, deployable to every runtime." }],
14
+ }
15
+
16
+ // Loader runs on the server (in-process during SSR). The action handles the form POST.
17
+ export async function loader({ api }: LoaderArgs<typeof backend>) {
18
+ const res = await api.count.get()
19
+ return { count: res.data?.count ?? 0 }
20
+ }
21
+
22
+ export async function action({ api }: ActionArgs<typeof backend>) {
23
+ await api.count.post()
24
+ return { ok: true }
25
+ }
26
+ </script>
27
+
28
+ <script setup lang="ts">
29
+ // compose() spreads data/actionData/pending/submission as props — declare them so they aren't attrs.
30
+ defineProps(["data", "actionData", "pending", "submission"])
31
+ </script>
32
+
33
+ <template>
34
+ <div>
35
+ <section class="hero">
36
+ <h1>Your nifra app,<br /><span class="grad">everywhere.</span></h1>
37
+ <p>
38
+ SSR + hydration, end-to-end types, Vue. One source — deploy to Cloudflare Pages, Node, Deno,
39
+ or Vercel Edge. Edit <code>routes/index.vue</code> to begin.
40
+ </p>
41
+ </section>
42
+ <div class="card">
43
+ <div>
44
+ <h3>Live full-stack loop</h3>
45
+ <p>
46
+ Count is rendered by a typed <code>loader</code>, incremented by an <code>action</code>,
47
+ revalidated with no full reload.
48
+ </p>
49
+ </div>
50
+ <form method="post" style="display: flex; align-items: center; gap: 16px">
51
+ <span class="count">{{ data.count }}</span>
52
+ <button class="btn" type="submit">increment →</button>
53
+ </form>
54
+ </div>
55
+ </div>
56
+ </template>
@@ -0,0 +1,35 @@
1
+ import { inProcessClient } from "@nifrajs/client"
2
+ import { createWebApp } from "@nifrajs/web"
3
+ import { backend } from "./backend"
4
+ import { adapter } from "./framework"
5
+ import { clientEntry, manifest } from "./server-manifest"
6
+
7
+ const app = createWebApp({
8
+ adapter,
9
+ manifest,
10
+ clientEntry,
11
+ api: inProcessClient(backend),
12
+ title: "nifra site",
13
+ })
14
+
15
+ // Bun (nifra's flagship runtime): Bun.serve handles app.fetch; serve the client bundle (/assets/*)
16
+ // from disk with Bun.file. Assets live next to this file in the built dist-bun/ output.
17
+ const ASSETS = new URL("./assets/", import.meta.url)
18
+ const TYPES: Readonly<Record<string, string>> = { js: "text/javascript", css: "text/css" }
19
+
20
+ const server = Bun.serve({
21
+ port: Number(Bun.env.PORT ?? 3000),
22
+ async fetch(req) {
23
+ const { pathname } = new URL(req.url)
24
+ if (pathname.startsWith("/assets/")) {
25
+ const name = pathname.slice("/assets/".length)
26
+ if (!/^[A-Za-z0-9._-]+$/.test(name)) return new Response("bad request", { status: 400 })
27
+ const file = Bun.file(new URL(name, ASSETS))
28
+ if (!(await file.exists())) return new Response("not found", { status: 404 })
29
+ const ext = name.slice(name.lastIndexOf(".") + 1)
30
+ return new Response(file, { headers: { "content-type": TYPES[ext] ?? "application/octet-stream" } })
31
+ }
32
+ return app.fetch(req)
33
+ },
34
+ })
35
+ console.log(`nifra (Bun) → http://localhost:${server.port}`)
@@ -0,0 +1,38 @@
1
+ import { inProcessClient } from "@nifrajs/client"
2
+ import { serve } from "@nifrajs/deno"
3
+ import { createWebApp } from "@nifrajs/web"
4
+ import { backend } from "./backend"
5
+ import { adapter } from "./framework"
6
+ import { clientEntry, manifest } from "./server-manifest"
7
+
8
+ const app = createWebApp({
9
+ adapter,
10
+ manifest,
11
+ clientEntry,
12
+ api: inProcessClient(backend),
13
+ title: "nifra site",
14
+ })
15
+
16
+ const ASSETS = new URL("./assets/", import.meta.url)
17
+ const TYPES: Readonly<Record<string, string>> = { js: "text/javascript", css: "text/css" }
18
+
19
+ await serve(
20
+ {
21
+ async fetch(req) {
22
+ const { pathname } = new URL(req.url)
23
+ if (pathname.startsWith("/assets/")) {
24
+ const name = pathname.slice("/assets/".length)
25
+ if (!/^[A-Za-z0-9._-]+$/.test(name)) return new Response("bad request", { status: 400 })
26
+ try {
27
+ const body = await Deno.readFile(new URL(name, ASSETS))
28
+ const ext = name.slice(name.lastIndexOf(".") + 1)
29
+ return new Response(body, { headers: { "content-type": TYPES[ext] ?? "application/octet-stream" } })
30
+ } catch {
31
+ return new Response("not found", { status: 404 })
32
+ }
33
+ }
34
+ return app.fetch(req)
35
+ },
36
+ },
37
+ { port: Number(Deno.env.get("PORT") ?? "3000") },
38
+ )
@@ -0,0 +1,40 @@
1
+ import { readFile } from "node:fs/promises"
2
+ import { inProcessClient } from "@nifrajs/client"
3
+ import { serve } from "@nifrajs/node"
4
+ import { createWebApp } from "@nifrajs/web"
5
+ import { backend } from "./backend"
6
+ import { adapter } from "./framework"
7
+ import { clientEntry, manifest } from "./server-manifest"
8
+
9
+ const app = createWebApp({
10
+ adapter,
11
+ manifest,
12
+ clientEntry,
13
+ api: inProcessClient(backend),
14
+ title: "nifra site",
15
+ })
16
+
17
+ // @nifrajs/node serves app.fetch only — so serve /assets/* (the client bundle) from disk here.
18
+ const ASSETS = new URL("./assets/", import.meta.url)
19
+ const TYPES: Readonly<Record<string, string>> = { js: "text/javascript", css: "text/css" }
20
+
21
+ await serve(
22
+ {
23
+ async fetch(req) {
24
+ const { pathname } = new URL(req.url)
25
+ if (pathname.startsWith("/assets/")) {
26
+ const name = pathname.slice("/assets/".length)
27
+ if (!/^[A-Za-z0-9._-]+$/.test(name)) return new Response("bad request", { status: 400 })
28
+ try {
29
+ const body = await readFile(new URL(name, ASSETS))
30
+ const ext = name.slice(name.lastIndexOf(".") + 1)
31
+ return new Response(body, { headers: { "content-type": TYPES[ext] ?? "application/octet-stream" } })
32
+ } catch {
33
+ return new Response("not found", { status: 404 })
34
+ }
35
+ }
36
+ return app.fetch(req)
37
+ },
38
+ },
39
+ { port: Number(process.env.PORT ?? 3000) },
40
+ )
@@ -0,0 +1,17 @@
1
+ import { inProcessClient } from "@nifrajs/client"
2
+ import { createWebApp } from "@nifrajs/web"
3
+ import { backend } from "./backend"
4
+ import { adapter } from "./framework"
5
+ import { clientEntry, manifest } from "./server-manifest"
6
+
7
+ const app = createWebApp({
8
+ adapter,
9
+ manifest,
10
+ clientEntry,
11
+ api: inProcessClient(backend),
12
+ title: "nifra site",
13
+ })
14
+
15
+ // Vercel Edge Function — Vercel serves /assets/* from its CDN, so this only SSRs page routes.
16
+ export const config = { runtime: "edge" }
17
+ export default (req: Request): Response | Promise<Response> => app.fetch(req)
@@ -0,0 +1,37 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "jsx": "preserve",
8
+ "strict": true,
9
+ "noUncheckedIndexedAccess": true,
10
+ "skipLibCheck": true,
11
+ "noEmit": true,
12
+ "verbatimModuleSyntax": true
13
+ },
14
+ "include": ["**/*.ts", "**/*.tsx"],
15
+ "exclude": [
16
+ "node_modules",
17
+ "dist",
18
+ "dist-bun",
19
+ "dist-node",
20
+ "dist-deno",
21
+ "dist-vercel",
22
+ ".nifra",
23
+ ".wrangler",
24
+ ".vercel",
25
+ "server-manifest.ts",
26
+ "server-bun.ts",
27
+ "server-node.ts",
28
+ "server-deno.ts",
29
+ "server-vercel.ts",
30
+ "_worker.ts",
31
+ "build.ts",
32
+ "build-bun.ts",
33
+ "build-node.ts",
34
+ "build-deno.ts",
35
+ "build-vercel.ts"
36
+ ]
37
+ }
@@ -0,0 +1,4 @@
1
+ name = "nifra-site"
2
+ pages_build_output_dir = "dist"
3
+ compatibility_date = "2025-01-01"
4
+ compatibility_flags = ["nodejs_compat"]