@nifrajs/cli 2.9.1 → 2.11.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/README.md +2 -1
- package/dist/check.d.ts +9 -1
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +38 -6
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts +2 -18
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +129 -66
- package/dist/cli.js.map +1 -1
- package/dist/dev-bun-config.d.ts +17 -6
- package/dist/dev-bun-config.d.ts.map +1 -1
- package/dist/dev-bun-config.js +51 -14
- package/dist/dev-bun-config.js.map +1 -1
- package/dist/doctor.d.ts +10 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +17 -1
- package/dist/doctor.js.map +1 -1
- package/dist/introspect.d.ts +26 -6
- package/dist/introspect.d.ts.map +1 -1
- package/dist/introspect.js +92 -2
- package/dist/introspect.js.map +1 -1
- package/dist/load.d.ts +4 -0
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +1 -0
- package/dist/load.js.map +1 -1
- package/dist/mcp-http.js +1 -1
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp.js +2 -2
- package/dist/mcp.js.map +1 -1
- package/dist/pipeline-guard.d.ts +25 -10
- package/dist/pipeline-guard.d.ts.map +1 -1
- package/dist/pipeline-guard.js +35 -15
- package/dist/pipeline-guard.js.map +1 -1
- package/dist/pipeline-report.d.ts +34 -0
- package/dist/pipeline-report.d.ts.map +1 -0
- package/dist/pipeline-report.js +282 -0
- package/dist/pipeline-report.js.map +1 -0
- package/dist/sdk.d.ts +10 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +229 -0
- package/dist/sdk.js.map +1 -0
- package/docs/llms-full.txt +246 -17
- package/docs/types.json +725 -16
- package/package.json +9 -9
- package/src/check.ts +54 -5
- package/src/cli.ts +131 -67
- package/src/dev-bun-config.ts +57 -14
- package/src/doctor.ts +28 -1
- package/src/introspect.ts +124 -4
- package/src/load.ts +5 -0
- package/src/mcp-http.ts +1 -1
- package/src/mcp.ts +2 -2
- package/src/pipeline-guard.ts +44 -14
- package/src/pipeline-report.ts +341 -0
- package/src/sdk.ts +260 -0
package/docs/llms-full.txt
CHANGED
|
@@ -3545,23 +3545,35 @@ Deploy: `wrangler pages deploy dist` (Pages) or `wrangler deploy`
|
|
|
3545
3545
|
`server.ts` to hand-write. (`create-nifra` scaffolds the conventions.)
|
|
3546
3546
|
|
|
3547
3547
|
```ts
|
|
3548
|
-
nifra dev # true-HMR dev server (
|
|
3548
|
+
nifra dev # true-HMR dev server (Bun native HMR + Nifra SSR) - http://localhost:4321
|
|
3549
|
+
nifra dev --vite # the Vite middleware pipeline instead (automatic when vitePlugins are your ONLY transforms)
|
|
3549
3550
|
nifra build # full Bun deploy → dist/server.js + content-hashed dist/assets/ (default target: bun)
|
|
3550
3551
|
nifra start # run dist/server.js on Bun
|
|
3551
3552
|
nifra build --target cf-pages # also: node | deno | vercel | static; add --report for chunk sizes
|
|
3552
3553
|
|
|
3553
3554
|
# dev + start share the default port 4321. Override per run: --port <n> (alias -p) or the PORT env var.
|
|
3554
3555
|
# flags: --port <n> (dev/start) · --out <dir> (build/start) · --target <t> (build) · --poll (dev)
|
|
3556
|
+
# --vite | --bun (dev/build) force the pipeline
|
|
3555
3557
|
```
|
|
3556
3558
|
|
|
3557
3559
|
### The conventions
|
|
3558
3560
|
|
|
3559
|
-
Four conventions at the project root. `nifra dev` runs the
|
|
3561
|
+
Four conventions at the project root. `nifra dev` runs the Bun-native
|
|
3560
3562
|
[HMR dev server](/docs/dev); `nifra build` runs the Bun-native production
|
|
3561
3563
|
build (content-hashed client assets plus a target-specific server); `nifra start`
|
|
3562
3564
|
runs the default Bun output. The generated server serves assets and SSR with matched-route
|
|
3563
3565
|
chunks preloaded and route CSS linked in each `<head>`.
|
|
3564
3566
|
|
|
3567
|
+
**One rule picks the bundler, and it is the same rule in both phases** - so a
|
|
3568
|
+
project can never be bundled by one toolchain in dev and the other in production. Bun runs
|
|
3569
|
+
everything, except an app whose _only_ transforms are `vitePlugins`: the Bun
|
|
3570
|
+
pipeline cannot run those, so that app gets Vite for dev and build alike, and says so.
|
|
3571
|
+
`--vite` / `--bun` force the choice; `--bun` is refused on a
|
|
3572
|
+
Vite-only app rather than dropping its transforms silently. Every `dev` and
|
|
3573
|
+
`build` run prints which bundler it picked and why, and `nifra check`
|
|
3574
|
+
answers the same question without starting a server - see
|
|
3575
|
+
[which pipeline runs, when](/docs/dev) for the full table.
|
|
3576
|
+
|
|
3565
3577
|
```ts
|
|
3566
3578
|
my-app/
|
|
3567
3579
|
routes/ # file-based routes (index.tsx, _layout.tsx, [id].tsx, …)
|
|
@@ -3844,9 +3856,9 @@ distinct.
|
|
|
3844
3856
|
|
|
3845
3857
|
Nifra gives you two local development loops, and the rule between them is that one
|
|
3846
3858
|
toolchain owns a whole phase. **Both** give you React Fast Refresh with state
|
|
3847
|
-
preserved.
|
|
3848
|
-
|
|
3849
|
-
|
|
3859
|
+
preserved. Bun is the default; Vite takes over automatically when your config's only
|
|
3860
|
+
transforms are `vitePlugins`. Both serve your real SSR app locally, and neither
|
|
3861
|
+
mixes the two bundlers in one process.
|
|
3850
3862
|
|
|
3851
3863
|
### Two loops, same app
|
|
3852
3864
|
|
|
@@ -3859,7 +3871,7 @@ use when
|
|
|
3859
3871
|
|
|
3860
3872
|
Bun HMR + Fast Refresh (native)
|
|
3861
3873
|
none (Bun only)
|
|
3862
|
-
one bundler dev+prod
|
|
3874
|
+
one bundler dev+prod, no Vite dep; CSS Modules included
|
|
3863
3875
|
|
|
3864
3876
|
`@nifrajs/web/vite`
|
|
3865
3877
|
|
|
@@ -3869,6 +3881,79 @@ true HMR (Fast Refresh / framework HMR)
|
|
|
3869
3881
|
|
|
3870
3882
|
state-preserving UI iteration
|
|
3871
3883
|
|
|
3884
|
+
### Which pipeline runs, when
|
|
3885
|
+
|
|
3886
|
+
One rule decides the bundler, and it decides it the same way for `nifra dev` and
|
|
3887
|
+
`nifra build` - your dev loop and your production build are never on different
|
|
3888
|
+
toolchains.
|
|
3889
|
+
|
|
3890
|
+
your config
|
|
3891
|
+
command
|
|
3892
|
+
pipeline
|
|
3893
|
+
why
|
|
3894
|
+
|
|
3895
|
+
no plugins at all
|
|
3896
|
+
|
|
3897
|
+
`nifra dev` / `nifra build`
|
|
3898
|
+
|
|
3899
|
+
Bun
|
|
3900
|
+
the default: no Vite dependency, one bundler across dev and prod
|
|
3901
|
+
|
|
3902
|
+
`clientPlugins` and/or `serverPlugins`
|
|
3903
|
+
|
|
3904
|
+
`nifra dev` / `nifra build`
|
|
3905
|
+
|
|
3906
|
+
Bun
|
|
3907
|
+
those slots are Bun.build plugins; Vite would never call them
|
|
3908
|
+
|
|
3909
|
+
`vitePlugins` only
|
|
3910
|
+
|
|
3911
|
+
`nifra dev` / `nifra build`
|
|
3912
|
+
|
|
3913
|
+
Vite (automatic)
|
|
3914
|
+
the Bun build cannot run them, so staying on Bun would silently drop your transforms
|
|
3915
|
+
|
|
3916
|
+
`vitePlugins` only
|
|
3917
|
+
|
|
3918
|
+
`--bun`
|
|
3919
|
+
|
|
3920
|
+
error
|
|
3921
|
+
nifra refuses rather than build an app with its compiler switched off
|
|
3922
|
+
|
|
3923
|
+
any
|
|
3924
|
+
|
|
3925
|
+
`--vite`
|
|
3926
|
+
|
|
3927
|
+
Vite (forced)
|
|
3928
|
+
|
|
3929
|
+
exact dev/prod client resolution for `conditions`, or a Vite-only plugin
|
|
3930
|
+
|
|
3931
|
+
any
|
|
3932
|
+
|
|
3933
|
+
`--bun`
|
|
3934
|
+
|
|
3935
|
+
Bun (forced)
|
|
3936
|
+
allowed whenever no transform would be lost
|
|
3937
|
+
|
|
3938
|
+
You never have to work this out from the table. Every `nifra dev` and
|
|
3939
|
+
`nifra build` run prints the answer under its banner, and
|
|
3940
|
+
`nifra check` and `nifra doctor` report it - with the config hazards
|
|
3941
|
+
below - without starting a server:
|
|
3942
|
+
|
|
3943
|
+
```ts
|
|
3944
|
+
# doc-check: skip - fragment: terminal output, not source.
|
|
3945
|
+
$ nifra dev
|
|
3946
|
+
nifra dev (bun) → http://localhost:3000
|
|
3947
|
+
bundler: bun (default; --vite to switch)
|
|
3948
|
+
|
|
3949
|
+
$ nifra build
|
|
3950
|
+
nifra build (node, vite) → dist/server/server.js
|
|
3951
|
+
bundler: vite (auto: this app's only transforms are `vitePlugins` (svelte), which the Bun build cannot run)
|
|
3952
|
+
|
|
3953
|
+
$ nifra check
|
|
3954
|
+
• bundler: vite (auto: this app's only transforms are `vitePlugins` (svelte), which the Bun build cannot run)
|
|
3955
|
+
```
|
|
3956
|
+
|
|
3872
3957
|
### State-preserving HMR
|
|
3873
3958
|
|
|
3874
3959
|
Use `createViteDevServer` when you want component edits to update the browser
|
|
@@ -4012,10 +4097,12 @@ a component-only module swaps its markup with `useState` state intact, no reload
|
|
|
4012
4097
|
boundary rule is the same as Vite's (see below). The real prize is that dev and production use
|
|
4013
4098
|
the _same bundler_, so the dev/prod seam disappears.
|
|
4014
4099
|
|
|
4015
|
-
|
|
4016
|
-
`*.module.css` transform
|
|
4017
|
-
|
|
4018
|
-
|
|
4100
|
+
**CSS Modules included.** Bun's dev-server bundler has no
|
|
4101
|
+
`*.module.css` transform of its own, so the CLI hands it the same one the
|
|
4102
|
+
production `Bun.build` uses - and a class hashes to the same scoped name on every
|
|
4103
|
+
pipeline. Calling `createDevServer` as a library instead of through the CLI, you
|
|
4104
|
+
supply that plugin yourself through your own `bunfig.toml`; plain CSS and Tailwind
|
|
4105
|
+
need nothing either way.
|
|
4019
4106
|
|
|
4020
4107
|
**
|
|
4021
4108
|
Server functions and `*.server` modules work under `--bun`
|
|
@@ -4044,7 +4131,8 @@ source. A divergence between the loops is treated as a bug, not a caveat.
|
|
|
4044
4131
|
import { createDevServer } from "@nifrajs/web/dev"
|
|
4045
4132
|
// Bun.serve bundles + hot-reloads the client; Bun's runtime resolves SSR. An edit reloads the
|
|
4046
4133
|
// changed module graph - with React Fast Refresh (state preserved) applied natively by Bun, no plugin.
|
|
4047
|
-
// CSS + the entry URL come from Bun. Plain CSS/Tailwind work; *.module.css
|
|
4134
|
+
// CSS + the entry URL come from Bun. Plain CSS/Tailwind work as-is; for *.module.css as a library
|
|
4135
|
+
// caller, pass the production CSS Modules plugin through your own bunfig (nifra dev --bun does it for you).
|
|
4048
4136
|
const server = await createDevServer({ routesDir, outDir, clientModule, createApp })
|
|
4049
4137
|
```
|
|
4050
4138
|
|
|
@@ -4161,6 +4249,105 @@ own stylesheet. Pass `manifest.routeStyles` to `createWebApp` alongside
|
|
|
4161
4249
|
`styles`, and Nifra links the matched route's CSS during SSR. In
|
|
4162
4250
|
**dev**, Vite injects per-module CSS.
|
|
4163
4251
|
|
|
4252
|
+
### Gotchas
|
|
4253
|
+
|
|
4254
|
+
The rule "one toolchain owns a whole phase" is what keeps the two loops honest, and most of
|
|
4255
|
+
what follows is a consequence of it. None of these are things you have to memorise before you
|
|
4256
|
+
start - they are the edges you can hit later, collected in one place.
|
|
4257
|
+
|
|
4258
|
+
#### Keep the adapter out of your config file
|
|
4259
|
+
|
|
4260
|
+
Split `framework.ts` (the adapter, imported by your server and edge entries) from
|
|
4261
|
+
`nifra.config.ts` (the CLI's config, where the Vite plugins and SFC compilers live).
|
|
4262
|
+
If your server entry reaches the adapter _through_ the config, everything the config
|
|
4263
|
+
imports is bundled into your production server - the Vite plugin, the framework compiler, and
|
|
4264
|
+
their native bindings. It builds without complaint and then fails at startup with a missing
|
|
4265
|
+
native binding, which reads like a broken install rather than a config-shape problem.
|
|
4266
|
+
|
|
4267
|
+
```ts
|
|
4268
|
+
// doc-check: skip - fragment: two files from one app, shown together.
|
|
4269
|
+
// framework.ts - imported by your SERVER and edge entries. Adapter only, nothing else.
|
|
4270
|
+
import { svelteAdapter } from "@nifrajs/web-svelte"
|
|
4271
|
+
export const adapter = svelteAdapter
|
|
4272
|
+
|
|
4273
|
+
// nifra.config.ts - imported ONLY by the CLI, which runs on Bun. Compilers and Vite plugins
|
|
4274
|
+
// belong here. Re-export the adapter; never define it here, or the dev toolchain it pulls in
|
|
4275
|
+
// (Vite, the SFC compiler, their native bindings) is bundled into your production server.
|
|
4276
|
+
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
|
4277
|
+
export { adapter } from "./framework"
|
|
4278
|
+
export const clientModule = "@nifrajs/web-svelte/client"
|
|
4279
|
+
export const vitePlugins = [svelte()]
|
|
4280
|
+
```
|
|
4281
|
+
|
|
4282
|
+
#### Plugins go in the slot that matches the pipeline
|
|
4283
|
+
|
|
4284
|
+
`vitePlugins` run on the Vite pipeline; `clientPlugins` and
|
|
4285
|
+
`serverPlugins` run on the Bun one. A plugin in the wrong slot is not an error, it
|
|
4286
|
+
is a _no-op_ - your transform silently does not run. Nifra classifies each plugin by its
|
|
4287
|
+
hook shape and refuses a mismatch rather than letting the build succeed without it. The same
|
|
4288
|
+
check is why `--bun` throws for an app whose only transforms are
|
|
4289
|
+
`vitePlugins`, instead of building without them.
|
|
4290
|
+
|
|
4291
|
+
#### `conditions` does not reach the Bun dev client bundle
|
|
4292
|
+
|
|
4293
|
+
On the Bun pipeline, `conditions` governs SSR - `nifra dev` passes them
|
|
4294
|
+
to the runtime when it re-execs - and it governs the production client bundle. It cannot govern
|
|
4295
|
+
the client bundle the dev server serves: Bun's dev-server bundler accepts no resolve
|
|
4296
|
+
conditions, and there is no `bunfig.toml` key for them either (a top-level
|
|
4297
|
+
`conditions`, or one under `[run]`, `[serve.static]` or
|
|
4298
|
+
`[bundle]`, parses and is ignored). So a package with an `exports` map
|
|
4299
|
+
can resolve to one file in dev and another in `nifra build`. Nifra says so once at
|
|
4300
|
+
startup rather than letting you find out in production. If your app depends on exact dev/prod
|
|
4301
|
+
client resolution, run `nifra dev --vite`.
|
|
4302
|
+
|
|
4303
|
+
Related, if you ever pass the flag to `bun` yourself: it takes
|
|
4304
|
+
**one condition per flag**. The comma form is accepted and matches nothing,
|
|
4305
|
+
because Bun reads the whole string as a single condition name.
|
|
4306
|
+
|
|
4307
|
+
```ts
|
|
4308
|
+
# Resolve conditions on the Bun dev pipeline.
|
|
4309
|
+
# SSR honours `conditions` - nifra passes them to the runtime when it re-execs.
|
|
4310
|
+
# The CLIENT bundle does not: Bun's dev-server bundler takes no resolve conditions,
|
|
4311
|
+
# from bunfig.toml or anywhere else. nifra warns once at startup when it matters.
|
|
4312
|
+
nifra dev --vite # exact dev/prod client resolution, if your app needs it
|
|
4313
|
+
|
|
4314
|
+
# If you invoke bun yourself: ONE FLAG PER CONDITION.
|
|
4315
|
+
bun --conditions=browser --conditions=development ./app.ts # correct
|
|
4316
|
+
bun --conditions=browser,development ./app.ts # ONE condition named "browser,development"
|
|
4317
|
+
```
|
|
4318
|
+
|
|
4319
|
+
#### Editing a non-route file updates SSR too
|
|
4320
|
+
|
|
4321
|
+
On the Bun pipeline the dev server tracks the module graph your routes import, so editing a
|
|
4322
|
+
component, a helper, or a server module several levels down is reflected in the next SSR
|
|
4323
|
+
render - not just in the browser bundle. Modules you did _not_ touch keep their
|
|
4324
|
+
identity, so a module-level singleton stays single across the reload. Two limits are
|
|
4325
|
+
deliberate: files under `node_modules` are not tracked (they are dependencies, not
|
|
4326
|
+
your source), and a specifier only participates if it is relative and written literally - a
|
|
4327
|
+
computed or aliased specifier is invisible to a static graph. A third-party Bun plugin that
|
|
4328
|
+
rewrites imports needs to call `rewriteSsrImports` for its output to stay tracked.
|
|
4329
|
+
|
|
4330
|
+
#### An adapter with a compiled asset needs the dev server's loader
|
|
4331
|
+
|
|
4332
|
+
This one matters only if you are writing a render adapter. On the Vite pipeline Vite owns SSR
|
|
4333
|
+
resolution, which is what lets `resolve.dedupe` reach the server and keeps your app
|
|
4334
|
+
on one copy of the framework. Adapter packages themselves stay external to that graph, because
|
|
4335
|
+
the adapter's context object has to be the one instance your app imported. If such an adapter
|
|
4336
|
+
must load a _compiled_ asset on the server - Svelte's chain component is one - a plain
|
|
4337
|
+
`import` reaches a runtime with no compiler for it, and registering a second
|
|
4338
|
+
compiler in the runtime is worse: the tree then holds two copies of the framework runtime, and
|
|
4339
|
+
context written by one half is invisible to the other. Load it through
|
|
4340
|
+
`ssrModuleLoader()` instead, and take the framework's _server renderer_ from
|
|
4341
|
+
there as well - a component compiled by one toolchain has to render through the renderer that
|
|
4342
|
+
toolchain resolved.
|
|
4343
|
+
|
|
4344
|
+
#### Scoped class names are identical across pipelines
|
|
4345
|
+
|
|
4346
|
+
A CSS Modules class hashes to the same scoped name whichever pipeline produced it, and across
|
|
4347
|
+
machines - the hash is keyed on the class name plus the module's _package-relative_
|
|
4348
|
+
path, never an absolute one. A selector written against a generated name behaves the same under
|
|
4349
|
+
`nifra dev`, `nifra dev --bun`, and `nifra build`.
|
|
4350
|
+
|
|
4164
4351
|
## Nifra - Troubleshooting
|
|
4165
4352
|
|
|
4166
4353
|
> Fixes keyed on the literal error strings Nifra prints: `reached the client bundle` (a node:/native import in the browser bundle), `server-only module reached the client bundle` (the server-only marker), and `resolveDispatcher` / `Invalid hook call` (duplicate React).
|
|
@@ -6680,6 +6867,9 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
6680
6867
|
|
|
6681
6868
|
Session primitives for nifra - signed-cookie + server-store sessions, CSRF, and route guards. Bring your own identity (Better Auth / Lucia / OAuth); nifra owns the session.
|
|
6682
6869
|
|
|
6870
|
+
`Authorizer`/`requireAuthorization` provide a small public policy seam. The application or data layer
|
|
6871
|
+
must decide ownership and permissions; Nifra stores no policy, tenant, or subject data.
|
|
6872
|
+
|
|
6683
6873
|
Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
|
|
6684
6874
|
|
|
6685
6875
|
## Install
|
|
@@ -6874,7 +7064,7 @@ The `nifra` CLI - zero-config dev/build/start for a nifra app, plus the agent su
|
|
|
6874
7064
|
`routes/`).
|
|
6875
7065
|
|
|
6876
7066
|
```
|
|
6877
|
-
nifra dev [--port <n>] [--poll] True-HMR dev server (
|
|
7067
|
+
nifra dev [--port <n>] [--poll] True-HMR dev server (Bun + nifra SSR; Vite for a Vite-only app).
|
|
6878
7068
|
nifra build [--out <dir>] [--target <t>] Complete deploy directory; target defaults to Bun.
|
|
6879
7069
|
nifra start [--port <n>] [--out <dir>] Run the generated Bun server at <out>/server.js.
|
|
6880
7070
|
nifra context Print this project's API + page routes + conventions.
|
|
@@ -6884,6 +7074,7 @@ nifra assure [--config <file>] [--json] Gate reflected routes against enforcem
|
|
|
6884
7074
|
nifra capabilities check [--json] Gate effect provenance + the reviewed capability lockfile.
|
|
6885
7075
|
nifra manifest emit [--sign <key-ref>] Emit the hash-verified route trust artifact after assurance.
|
|
6886
7076
|
nifra manifest diff <before> <after> Block promotion on contract/governance regressions.
|
|
7077
|
+
nifra sdk --lang <python|go> Generate a deterministic non-TypeScript SDK from `backend.ts`.
|
|
6887
7078
|
nifra doctor [--json] [--auto-fix] Catch undeclared imports and duplicate Nifra/React installs.
|
|
6888
7079
|
```
|
|
6889
7080
|
|
|
@@ -7094,6 +7285,11 @@ The Bun-native, contract-first HTTP framework at the heart of [nifra](../../READ
|
|
|
7094
7285
|
a radix router, a fully type-inferred server, versionable contracts, lifecycle
|
|
7095
7286
|
middleware, and production hardening.
|
|
7096
7287
|
|
|
7288
|
+
The Web-standard app can be wrapped for Vercel Edge with `toVercelHandler`, Netlify Functions with
|
|
7289
|
+
`toNetlifyHandler`, or API Gateway v1/v2 with `toLambdaHandler` from `@nifrajs/core/server`. These are
|
|
7290
|
+
thin event-envelope adapters; application policy, persistence, and platform credentials stay outside
|
|
7291
|
+
the core.
|
|
7292
|
+
|
|
7097
7293
|
```sh
|
|
7098
7294
|
bun add @nifrajs/core
|
|
7099
7295
|
```
|
|
@@ -7116,6 +7312,8 @@ available only from their explicit subpaths, so an ordinary HTTP server never ev
|
|
|
7116
7312
|
import { defineContract, implement } from "@nifrajs/core/contract"
|
|
7117
7313
|
import { startCausality } from "@nifrajs/core/causality"
|
|
7118
7314
|
import { defineAssurancePolicy } from "@nifrajs/core/assurance"
|
|
7315
|
+
import { createDataPort, defineDataContract, diffDataContract } from "@nifrajs/core/data"
|
|
7316
|
+
import { defineChannel, memoryChannelHub } from "@nifrajs/core/channel"
|
|
7119
7317
|
```
|
|
7120
7318
|
|
|
7121
7319
|
- **Inline or contract-first.** Write routes inline (types inferred from the
|
|
@@ -7165,6 +7363,16 @@ import { defineAssurancePolicy } from "@nifrajs/core/assurance"
|
|
|
7165
7363
|
bounded HTTP representations and supplies the same frame/loader adapters for WebSockets and
|
|
7166
7364
|
deferred data. Import `richWireCodec()` from `@nifrajs/core/transport-codec-rich`; the separate
|
|
7167
7365
|
subpath keeps rich-wire code out of plain JSON bundles.
|
|
7366
|
+
- **Typed data seam (opt in).** `@nifrajs/core/data` defines token-only operation contracts,
|
|
7367
|
+
`db.read`/`db.write` capability names, an opaque request-local `RlsScope`, typed adapter requests,
|
|
7368
|
+
drift snapshots, and `createDataPort(contract, adapter, { beacon: useCapability })`, which emits the
|
|
7369
|
+
operation's capability evidence - derived from the contract, never from the request - before the
|
|
7370
|
+
private adapter runs. It contains no database driver, tenant identity, policy, row values, or durable
|
|
7371
|
+
store; those belong in the adapter layer.
|
|
7372
|
+
- **Typed channels (opt in).** `@nifrajs/core/channel` defines typed message contracts, bounded
|
|
7373
|
+
subscriptions, cancellation, per-channel resume cursors, bounded local replay, and a process-local
|
|
7374
|
+
in-memory hub for tests. Durable replay, presence, rooms, and multi-instance fan-out remain adapter
|
|
7375
|
+
concerns.
|
|
7168
7376
|
|
|
7169
7377
|
```ts
|
|
7170
7378
|
import { defineAssurancePolicy, evaluateRouteAssurance, NIFRA_ASSURANCE } from "@nifrajs/core/assurance"
|
|
@@ -7454,10 +7662,21 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
7454
7662
|
|
|
7455
7663
|
## @nifrajs/image
|
|
7456
7664
|
|
|
7457
|
-
Image optimization for nifra - a CLS-safe responsive <Image> + pluggable loaders (CDN or self-hosted) + pure-JS dimension reading.
|
|
7665
|
+
Image optimization for nifra - a CLS-safe responsive <Image> + pluggable loaders (CDN or self-hosted) + pure-JS dimension reading. The zero-dependency core also includes safe, cacheable Open Graph SVG generation at `@nifrajs/image/og` - useful where you control the consumer, but no major crawler renders SVG for `og:image`, so a social card needs an injected PNG/JPEG rasterizer. The optional Bun.Image-backed resize endpoint lives at `@nifrajs/image/server`.
|
|
7458
7666
|
|
|
7459
7667
|
Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
|
|
7460
7668
|
|
|
7669
|
+
For crawler-compatible cards, adapt the renderer you choose to the public PNG seam:
|
|
7670
|
+
|
|
7671
|
+
```ts
|
|
7672
|
+
import { createResvgRasterizer } from "@nifrajs/image/og-png"
|
|
7673
|
+
import { Resvg } from "@resvg/resvg-js"
|
|
7674
|
+
|
|
7675
|
+
const rasterizer = createResvgRasterizer(Resvg)
|
|
7676
|
+
```
|
|
7677
|
+
|
|
7678
|
+
The codec remains an application dependency; the package's default stays explicit SVG output.
|
|
7679
|
+
|
|
7461
7680
|
## Install
|
|
7462
7681
|
|
|
7463
7682
|
```sh
|
|
@@ -7720,6 +7939,7 @@ import {
|
|
|
7720
7939
|
bodyLimit,
|
|
7721
7940
|
cors,
|
|
7722
7941
|
MemoryStore,
|
|
7942
|
+
problemDetails,
|
|
7723
7943
|
rateLimit,
|
|
7724
7944
|
securityHeaders,
|
|
7725
7945
|
timing,
|
|
@@ -7727,6 +7947,7 @@ import {
|
|
|
7727
7947
|
|
|
7728
7948
|
const app = server()
|
|
7729
7949
|
.use(securityHeaders())
|
|
7950
|
+
.use(problemDetails())
|
|
7730
7951
|
.use(cors({ origin: ["https://app.example.com"], credentials: true }))
|
|
7731
7952
|
.use(bodyLimit({ maxBytes: 1_000_000 }))
|
|
7732
7953
|
.use(rateLimit({
|
|
@@ -7766,6 +7987,14 @@ const app = server()
|
|
|
7766
7987
|
store, `Vary`-aware keys, `Age`, byte caps, and `Cache-Control` / `Set-Cookie` safety defaults.
|
|
7767
7988
|
`MemoryResponseCache` is dev/single-instance only unless explicitly allowed in production.
|
|
7768
7989
|
- **`timing()`** - `Server-Timing` plus typed `c.timing.metric/mark/measure` controls.
|
|
7990
|
+
- **`problemDetails()`** - opt-in RFC 9457 `application/problem+json` responses for framework
|
|
7991
|
+
errors. The default `{ ok: false, error }` envelope remains unchanged unless installed; validation
|
|
7992
|
+
issues are preserved, and `includeInstance` includes only the request pathname.
|
|
7993
|
+
- **`rangeResponse()` / `parseByteRange()`** - bounded byte-range responses with 206/416,
|
|
7994
|
+
`If-Range`, multipart ranges, and conditional validators.
|
|
7995
|
+
- **`conditionalResponse()`** - reusable ETag/Last-Modified handling that emits a bodyless 304.
|
|
7996
|
+
- **`negotiateContentType()`** - RFC-style `Accept` matching with q-values, wildcards, and q=0.
|
|
7997
|
+
- **`multipartResponse()`** - cancellable streaming multipart output without buffering all parts.
|
|
7769
7998
|
- **`prettyJson()`** - capped, JSON-only pretty printing for debugging and developer-facing APIs.
|
|
7770
7999
|
- **`methodOverride()`** - header/query method tunneling for clients that can only send `POST`.
|
|
7771
8000
|
Header override is on by default; query override is opt-in.
|
|
@@ -8801,7 +9030,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
8801
9030
|
|
|
8802
9031
|
## @nifrajs/auth
|
|
8803
9032
|
|
|
8804
|
-
`createSessions`, `csrf`, `CsrfOptions`, `GuardOptions`, `KVNamespaceLike`, `KVSessionStore`, `MemorySessionStore`, `MemorySessionStoreOptions`, `requireSession`, `requireUser`, `Session`, `SessionContext`, `SessionCookieOptions`, `SessionManager`, `SessionOptions`, `SessionRecord`, `SessionStore`
|
|
9033
|
+
`AuthorizationRequest`, `Authorizer`, `createSessions`, `csrf`, `CsrfOptions`, `GuardOptions`, `isAuthorized`, `KVNamespaceLike`, `KVSessionStore`, `MemorySessionStore`, `MemorySessionStoreOptions`, `requireAuthorization`, `requireSession`, `requireUser`, `Session`, `SessionContext`, `SessionCookieOptions`, `SessionManager`, `SessionOptions`, `SessionRecord`, `SessionStore`
|
|
8805
9034
|
|
|
8806
9035
|
## @nifrajs/better-auth
|
|
8807
9036
|
|
|
@@ -8849,7 +9078,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
8849
9078
|
|
|
8850
9079
|
## @nifrajs/image
|
|
8851
9080
|
|
|
8852
|
-
`cloudflareLoader`, `CloudflareLoaderOptions`, `HtmlImageAttrs`, `identityLoader`, `imageDimensions`, `ImageFormat`, `ImageInfo`, `ImageLoader`, `ImageProps`, `readImageDimensions`, `ResolvedImage`, `resolveImage`, `selfHostedLoader`, `SelfHostedLoaderOptions`, `signImageUrl`, `SignImageUrlOptions`, `toHtmlAttrs`
|
|
9081
|
+
`cloudflareLoader`, `CloudflareLoaderOptions`, `createPngRasterizer`, `createResvgRasterizer`, `HtmlImageAttrs`, `identityLoader`, `imageDimensions`, `ImageFormat`, `ImageInfo`, `ImageLoader`, `ImageProps`, `OgImageOptions`, `OgImageRasterized`, `OgImageRasterizer`, `ogImageResponse`, `PngRenderer`, `readImageDimensions`, `renderOgImage`, `ResolvedImage`, `resolveImage`, `ResvgConstructor`, `ResvgRenderer`, `selfHostedLoader`, `SelfHostedLoaderOptions`, `signImageUrl`, `SignImageUrlOptions`, `toHtmlAttrs`
|
|
8853
9082
|
|
|
8854
9083
|
## @nifrajs/islets
|
|
8855
9084
|
|
|
@@ -8869,7 +9098,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
8869
9098
|
|
|
8870
9099
|
## @nifrajs/middleware
|
|
8871
9100
|
|
|
8872
|
-
`AdmissionControllerHandle`, `AdmissionEvidence`, `AdmissionOptions`, `AdmissionPolicy`, `AdmissionSnapshot`, `apiKey`, `ApiKeyStaticOptions`, `ApiKeyVerifyOptions`, `appendTrailingSlash`, `AuthPlugin`, `basicAuth`, `BasicAuthPlugin`, `BasicAuthStaticOptions`, `BasicAuthVerifyOptions`, `bearer`, `BearerOptions`, `bodyLimit`, `BodyLimitOptions`, `buildOpenApiDocument`, `cache`, `cacheControl`, `CacheControlOptions`, `CachedResponse`, `CacheOptions`, `combine`, `Composable`, `compression`, `CompressionOptions`, `cors`, `CorsOptions`, `createAdmissionController`, `createCsrfToken`, `createEventLoopLagSampler`, `csrf`, `CsrfOptions`, `durableCommand`, `DurableCommandOptions`, `etag`, `ETagOptions`, `healthcheck`, `HealthcheckOptions`, `idempotency`, `IdempotencyClaim`, `IdempotencyOptions`, `IdempotencyRecord`, `IdempotencyStore`, `IpMatcher`, `ipRestriction`, `IpRestrictionOptions`, `jwk`, `JwkKey`, `jwks`, `JwksOptions`, `jwt`, `JwtAlgorithm`, `JwtClaims`, `JwtHeader`, `JwtKeyResolver`, `JwtOptions`, `JwtPlugin`, `JwtVerificationKey`, `language`, `LanguageMatch`, `LanguageOptions`, `logger`, `LoggerOptions`, `LoopDelayHistogram`, `LoopDelayMonitor`, `MemoryIdempotencyStore`, `MemoryIdempotencyStoreOptions`, `MemoryResponseCache`, `MemoryResponseCacheOptions`, `MemoryStore`, `MemoryStoreOptions`, `methodOverride`, `MethodOverrideOptions`, `namedCombine`, `openapi`, `OpenApiInfo`, `OpenApiOptions`, `OpenApiServer`, `OpenApiTag`, `OpenApiUiOptions`, `pickLanguage`, `poweredBy`, `PoweredByOptions`, `prettyJson`, `PrettyJsonOptions`, `rateLimit`, `RateLimitOptions`, `RateLimitResult`, `RateLimitStore`, `requestId`, `RequestIdOptions`, `RequestLogFields`, `responseCache`, `ResponseCacheStore`, `RouteLike`, `securityHeaders`, `SecurityHeadersOptions`, `SecurityRequirement`, `ShedReason`, `timing`, `TimingControls`, `TimingMetric`, `TimingOptions`, `TrailingSlashOptions`, `trimTrailingSlash`, `tryVerifyJwt`, `VerifiedJwt`, `verifyCsrfToken`, `verifyJwt`, `VerifyJwtOptions`, `VerifyJwtResult`
|
|
9101
|
+
`AdmissionControllerHandle`, `AdmissionEvidence`, `AdmissionOptions`, `AdmissionPolicy`, `AdmissionSnapshot`, `apiKey`, `ApiKeyStaticOptions`, `ApiKeyVerifyOptions`, `appendTrailingSlash`, `AuthPlugin`, `basicAuth`, `BasicAuthPlugin`, `BasicAuthStaticOptions`, `BasicAuthVerifyOptions`, `bearer`, `BearerOptions`, `bodyLimit`, `BodyLimitOptions`, `buildOpenApiDocument`, `ByteRange`, `ByteRangeResult`, `cache`, `cacheControl`, `CacheControlOptions`, `CachedResponse`, `CacheOptions`, `combine`, `Composable`, `compression`, `CompressionOptions`, `conditionalResponse`, `ConditionalResponseOptions`, `ContentPreference`, `cors`, `CorsOptions`, `createAdmissionController`, `createCsrfToken`, `createEventLoopLagSampler`, `csrf`, `CsrfOptions`, `durableCommand`, `DurableCommandOptions`, `etag`, `ETagOptions`, `healthcheck`, `HealthcheckOptions`, `idempotency`, `IdempotencyClaim`, `IdempotencyOptions`, `IdempotencyRecord`, `IdempotencyStore`, `IpMatcher`, `ipRestriction`, `IpRestrictionOptions`, `jwk`, `JwkKey`, `jwks`, `JwksOptions`, `jwt`, `JwtAlgorithm`, `JwtClaims`, `JwtHeader`, `JwtKeyResolver`, `JwtOptions`, `JwtPlugin`, `JwtVerificationKey`, `language`, `LanguageMatch`, `LanguageOptions`, `logger`, `LoggerOptions`, `LoopDelayHistogram`, `LoopDelayMonitor`, `MemoryIdempotencyStore`, `MemoryIdempotencyStoreOptions`, `MemoryResponseCache`, `MemoryResponseCacheOptions`, `MemoryStore`, `MemoryStoreOptions`, `methodOverride`, `MethodOverrideOptions`, `MultipartBody`, `MultipartHeadersInit`, `MultipartPart`, `multipartResponse`, `MultipartResponseOptions`, `namedCombine`, `negotiateContentType`, `openapi`, `OpenApiInfo`, `OpenApiOptions`, `OpenApiServer`, `OpenApiTag`, `OpenApiUiOptions`, `parseAcceptHeader`, `parseByteRange`, `pickLanguage`, `poweredBy`, `PoweredByOptions`, `prettyJson`, `PrettyJsonOptions`, `problemDetails`, `ProblemDetailsOptions`, `rangeResponse`, `RangeResponseOptions`, `rateLimit`, `RateLimitOptions`, `RateLimitResult`, `RateLimitStore`, `requestId`, `RequestIdOptions`, `RequestLogFields`, `responseCache`, `ResponseCacheStore`, `RouteLike`, `securityHeaders`, `SecurityHeadersOptions`, `SecurityRequirement`, `ShedReason`, `timing`, `TimingControls`, `TimingMetric`, `TimingOptions`, `TrailingSlashOptions`, `trimTrailingSlash`, `tryVerifyJwt`, `VerifiedJwt`, `verifyCsrfToken`, `verifyJwt`, `VerifyJwtOptions`, `VerifyJwtResult`
|
|
8873
9102
|
|
|
8874
9103
|
## @nifrajs/mock
|
|
8875
9104
|
|
|
@@ -8913,7 +9142,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
8913
9142
|
|
|
8914
9143
|
## @nifrajs/web
|
|
8915
9144
|
|
|
8916
|
-
`Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `Blocker`, `BlockerController`, `BlockerFunction`, `BlockerLocation`, `BlockerState`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `gate`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateRouteSearchTypes`, `GenerateRouteSearchTypesOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `gone`, `hashQueryKey`, `IDLE_BLOCKER`, `InertScriptType`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LAYOUT_DATA_GLOBAL`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NAV_FROM_HEADER`, `NavigateFunction`, `NavigateOptions`, `NavigateSearchOf`, `NavigateTargetInput`, `notFound`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `previewEndpoint`, `PreviewEndpointOptions`, `PublicDirCache`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `registerBlocker`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderAssemblyCache`, `RenderedPage`, `renderPage`, `RenderPageInput`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `resolveNavigate`, `resolvePublicPath`, `RETAIN_HEADER`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROOT_ATTRIBUTE`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `RouteSearch`, `routeStyles`, `ScriptDescriptor`, `searchOf`, `SearchOf`, `searchOfChain`, `serializeData`, `serializeSearch`, `servePublicDir`, `ServePublicDirOptions`, `SERVER_FN_MODULE`, `SERVER_ONLY_MODULE`, `ServerOnly`, `setBlockerController`, `setBrowserNavigate`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `STATUS_HEADER`, `statusPage`, `StatusPageOptions`, `styles`, `Submission`, `SubmitOptions`, `unsafeInlineScript`, `UnsafeScriptDescriptor`, `withISR`
|
|
9145
|
+
`Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `Blocker`, `BlockerController`, `BlockerFunction`, `BlockerLocation`, `BlockerState`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `gate`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateRouteSearchTypes`, `GenerateRouteSearchTypesOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `gone`, `hashQueryKey`, `IDLE_BLOCKER`, `InertScriptType`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_REVALIDATE_TAGS_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LAYOUT_DATA_GLOBAL`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NAV_FROM_HEADER`, `NavigateFunction`, `NavigateOptions`, `NavigateSearchOf`, `NavigateTargetInput`, `notFound`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `previewEndpoint`, `PreviewEndpointOptions`, `PublicDirCache`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `registerBlocker`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderAssemblyCache`, `RenderedPage`, `renderPage`, `RenderPageInput`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `resolveNavigate`, `resolvePublicPath`, `RETAIN_HEADER`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROOT_ATTRIBUTE`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `RouteSearch`, `routeStyles`, `ScriptDescriptor`, `searchOf`, `SearchOf`, `searchOfChain`, `serializeData`, `serializeSearch`, `servePublicDir`, `ServePublicDirOptions`, `SERVER_FN_MODULE`, `SERVER_ONLY_MODULE`, `ServerOnly`, `setBlockerController`, `setBrowserNavigate`, `setSsrModuleLoader`, `ssrModuleLoader`, `SsrModuleLoader`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `STATUS_HEADER`, `statusPage`, `StatusPageOptions`, `styles`, `Submission`, `SubmitOptions`, `unsafeInlineScript`, `UnsafeScriptDescriptor`, `withISR`
|
|
8917
9146
|
|
|
8918
9147
|
## @nifrajs/web-preact
|
|
8919
9148
|
|