@nifrajs/cli 1.4.0 → 1.6.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +42 -1
- package/dist/cli.js.map +1 -1
- package/dist/diff-tool.d.ts +35 -0
- package/dist/diff-tool.d.ts.map +1 -0
- package/dist/diff-tool.js +107 -0
- package/dist/diff-tool.js.map +1 -0
- package/dist/mcp-http.js +1 -1
- package/docs/llms-full.txt +10 -2
- package/docs/types.json +229 -10
- package/package.json +8 -8
- package/src/cli.ts +40 -1
- package/src/diff-tool.ts +130 -0
- package/src/mcp-http.ts +1 -1
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAoBA,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB;8FAC0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAoBA,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB;8FAC0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AA6ND,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAqBzD"}
|
package/dist/cli.js
CHANGED
|
@@ -52,6 +52,13 @@ Usage:
|
|
|
52
52
|
nifra check [--json] [--lints-only] Gate: typecheck + lints (hand-rolled fetch(), untyped client("…"),
|
|
53
53
|
server-only imports in routes/). Run as "done"; --json for agents;
|
|
54
54
|
--lints-only skips tsc for a near-instant inner-loop pass.
|
|
55
|
+
nifra snapshot [--out <file>] Write the backend's API contract (routes + schemas) as plain
|
|
56
|
+
JSON — the baseline for \`nifra diff\`. Default api-snapshot.json.
|
|
57
|
+
nifra diff [<baseline>] [--json] Breaking-change gate: re-snapshot the contract and compare
|
|
58
|
+
against the committed baseline. Direction-aware (a new required
|
|
59
|
+
request field or a removed response field breaks; widening a
|
|
60
|
+
request enum or adding a response field doesn't) and fails
|
|
61
|
+
closed. Exits non-zero on any breaking change — run it in CI.
|
|
55
62
|
nifra doctor [--json] [--auto-fix] Flag packages imported in source but missing from package.json
|
|
56
63
|
(resolve at Bun runtime, break tsc + standalone install);
|
|
57
64
|
--auto-fix writes safe local-version dependency fixes.
|
|
@@ -68,7 +75,7 @@ routes/ from the current directory. Run from your project root.
|
|
|
68
75
|
Port: \`dev\` and \`start\` share the default ${DEFAULT_DEV_PORT}. Override with \`--port <n>\` (alias \`-p\`) or the
|
|
69
76
|
\`PORT\` env var (\`--port\` wins over \`PORT\`, which wins over the default).`;
|
|
70
77
|
// Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
|
|
71
|
-
const CLI_VERSION = "1.
|
|
78
|
+
const CLI_VERSION = "1.6.0";
|
|
72
79
|
// A render adapter + nifra server are opaque to the CLI (it just forwards them); cast at the seam.
|
|
73
80
|
const asAdapter = (v) => v;
|
|
74
81
|
const asBunPlugins = (v) => v;
|
|
@@ -302,6 +309,40 @@ async function main() {
|
|
|
302
309
|
process.exitCode = 1;
|
|
303
310
|
return;
|
|
304
311
|
}
|
|
312
|
+
// `snapshot` / `diff` load ONLY backend.ts (the API contract) — like `check`, they must run on an
|
|
313
|
+
// API-only project, so they dispatch before the eager `loadApp`.
|
|
314
|
+
if (command === "snapshot") {
|
|
315
|
+
const { runSnapshot } = await import("./diff-tool.js");
|
|
316
|
+
const outIdx = argv.indexOf("--out");
|
|
317
|
+
const out = outIdx !== -1 ? argv[outIdx + 1] : undefined;
|
|
318
|
+
if (outIdx !== -1 && (out === undefined || out.startsWith("-"))) {
|
|
319
|
+
console.error("[nifra] --out needs a file path");
|
|
320
|
+
process.exitCode = 1;
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
await runSnapshot(process.cwd(), out !== undefined ? { out } : {});
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
328
|
+
process.exitCode = 1;
|
|
329
|
+
}
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (command === "diff") {
|
|
333
|
+
const { runDiff, DEFAULT_SNAPSHOT_FILE } = await import("./diff-tool.js");
|
|
334
|
+
const baseline = argv.slice(1).find((arg) => !arg.startsWith("-")) ?? DEFAULT_SNAPSHOT_FILE;
|
|
335
|
+
try {
|
|
336
|
+
if (!(await runDiff(process.cwd(), baseline, { json: argv.includes("--json") }))) {
|
|
337
|
+
process.exitCode = 1;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
342
|
+
process.exitCode = 1;
|
|
343
|
+
}
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
305
346
|
// `port` is a pure cwd-based portability linter (scans source, doesn't run the app) — like `check`/
|
|
306
347
|
// `doctor`, dispatch before the eager `loadApp` so it runs on an API-only / not-yet-built project.
|
|
307
348
|
if (command === "port") {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nifra snapshot` / `nifra diff` — the API breaking-change gate.
|
|
3
|
+
*
|
|
4
|
+
* nifra snapshot [--out api-snapshot.json] Write the backend's route contract as plain JSON.
|
|
5
|
+
* nifra diff <baseline.json> [--json] Re-snapshot and compare against the committed
|
|
6
|
+
* baseline; exit non-zero on any breaking change.
|
|
7
|
+
*
|
|
8
|
+
* The CI loop: commit a snapshot on main, run `nifra diff api-snapshot.json` on every PR, and an
|
|
9
|
+
* accidental contract break (removed route, new required field, retyped response) fails the build
|
|
10
|
+
* before it ships. Classification lives in `@nifrajs/core/diff` (direction-aware, fails closed);
|
|
11
|
+
* this module only loads `backend.ts` and renders the result.
|
|
12
|
+
*
|
|
13
|
+
* Loads ONLY `backend.ts` — the API contract — so it works on an API-only project with no
|
|
14
|
+
* framework config or routes/ directory (unlike the eager `loadApp`).
|
|
15
|
+
*/
|
|
16
|
+
import { type RouteSnapshot, type RoutesDiff } from "@nifrajs/core/diff";
|
|
17
|
+
/** Snapshot file envelope — versioned so a future format change can migrate instead of misparse. */
|
|
18
|
+
export interface SnapshotFile {
|
|
19
|
+
readonly nifraSnapshot: 1;
|
|
20
|
+
readonly routes: readonly RouteSnapshot[];
|
|
21
|
+
}
|
|
22
|
+
export declare const DEFAULT_SNAPSHOT_FILE = "api-snapshot.json";
|
|
23
|
+
/** Parse + validate a snapshot file's content. Throws with an actionable message on any mismatch. */
|
|
24
|
+
export declare function parseSnapshotFile(content: string, sourcePath: string): SnapshotFile;
|
|
25
|
+
/** Render a diff for terminals: breaking first, then info, then compatible. */
|
|
26
|
+
export declare function formatDiff(diff: RoutesDiff): string;
|
|
27
|
+
/** `nifra snapshot`: write the current contract as the CI baseline. */
|
|
28
|
+
export declare function runSnapshot(cwd: string, options: {
|
|
29
|
+
out?: string;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
/** `nifra diff`: compare the current contract against a baseline. Returns false on breaking changes. */
|
|
32
|
+
export declare function runDiff(cwd: string, baselinePath: string, options: {
|
|
33
|
+
json?: boolean;
|
|
34
|
+
}): Promise<boolean>;
|
|
35
|
+
//# sourceMappingURL=diff-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-tool.d.ts","sourceRoot":"","sources":["../src/diff-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAA;AAE3B,oGAAoG;AACpG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;CAC1C;AAED,eAAO,MAAM,qBAAqB,sBAAsB,CAAA;AAExD,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAqBnF;AAaD,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAWnD;AAiBD,uEAAuE;AACvE,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvF;AAED,wGAAwG;AACxG,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nifra snapshot` / `nifra diff` — the API breaking-change gate.
|
|
3
|
+
*
|
|
4
|
+
* nifra snapshot [--out api-snapshot.json] Write the backend's route contract as plain JSON.
|
|
5
|
+
* nifra diff <baseline.json> [--json] Re-snapshot and compare against the committed
|
|
6
|
+
* baseline; exit non-zero on any breaking change.
|
|
7
|
+
*
|
|
8
|
+
* The CI loop: commit a snapshot on main, run `nifra diff api-snapshot.json` on every PR, and an
|
|
9
|
+
* accidental contract break (removed route, new required field, retyped response) fails the build
|
|
10
|
+
* before it ships. Classification lives in `@nifrajs/core/diff` (direction-aware, fails closed);
|
|
11
|
+
* this module only loads `backend.ts` and renders the result.
|
|
12
|
+
*
|
|
13
|
+
* Loads ONLY `backend.ts` — the API contract — so it works on an API-only project with no
|
|
14
|
+
* framework config or routes/ directory (unlike the eager `loadApp`).
|
|
15
|
+
*/
|
|
16
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
17
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
18
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
19
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return path;
|
|
23
|
+
};
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { resolve } from "node:path";
|
|
26
|
+
import { diffRouteSnapshots, snapshotRoutes, } from "@nifrajs/core/diff";
|
|
27
|
+
export const DEFAULT_SNAPSHOT_FILE = "api-snapshot.json";
|
|
28
|
+
/** Parse + validate a snapshot file's content. Throws with an actionable message on any mismatch. */
|
|
29
|
+
export function parseSnapshotFile(content, sourcePath) {
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = JSON.parse(content);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw new Error(`[nifra] ${sourcePath} is not valid JSON — regenerate it with \`nifra snapshot\`.`);
|
|
36
|
+
}
|
|
37
|
+
const record = parsed;
|
|
38
|
+
if (record === null ||
|
|
39
|
+
typeof record !== "object" ||
|
|
40
|
+
record.nifraSnapshot !== 1 ||
|
|
41
|
+
!Array.isArray(record.routes)) {
|
|
42
|
+
throw new Error(`[nifra] ${sourcePath} is not a nifra API snapshot — expected { "nifraSnapshot": 1, "routes": [...] }.`);
|
|
43
|
+
}
|
|
44
|
+
return record;
|
|
45
|
+
}
|
|
46
|
+
const SEVERITY_MARK = {
|
|
47
|
+
breaking: "✖ breaking",
|
|
48
|
+
compatible: "✓ compatible",
|
|
49
|
+
info: "ℹ info",
|
|
50
|
+
};
|
|
51
|
+
const describeChange = (change) => {
|
|
52
|
+
const where = change.section === "route" ? "" : ` ${change.section}`;
|
|
53
|
+
return `${SEVERITY_MARK[change.severity]} ${change.method} ${change.path}${where}: ${change.message}`;
|
|
54
|
+
};
|
|
55
|
+
/** Render a diff for terminals: breaking first, then info, then compatible. */
|
|
56
|
+
export function formatDiff(diff) {
|
|
57
|
+
if (diff.changes.length === 0)
|
|
58
|
+
return "No API contract changes.";
|
|
59
|
+
const order = { breaking: 0, info: 1, compatible: 2 };
|
|
60
|
+
const lines = [...diff.changes]
|
|
61
|
+
.sort((a, b) => order[a.severity] - order[b.severity])
|
|
62
|
+
.map(describeChange);
|
|
63
|
+
const breaking = diff.changes.filter((change) => change.severity === "breaking").length;
|
|
64
|
+
const summary = diff.hasBreaking
|
|
65
|
+
? `${breaking} breaking change${breaking === 1 ? "" : "s"} — existing clients will fail.`
|
|
66
|
+
: "No breaking changes.";
|
|
67
|
+
return `${lines.join("\n")}\n\n${summary}`;
|
|
68
|
+
}
|
|
69
|
+
/** Import `backend.ts` from `cwd` and snapshot its routes. */
|
|
70
|
+
async function snapshotBackend(cwd) {
|
|
71
|
+
const backendPath = resolve(cwd, "backend.ts");
|
|
72
|
+
if (!existsSync(backendPath)) {
|
|
73
|
+
throw new Error(`[nifra] no backend.ts in ${cwd} — \`nifra snapshot\`/\`nifra diff\` compare the API contract, which lives in backend.ts.`);
|
|
74
|
+
}
|
|
75
|
+
const backend = (await import(__rewriteRelativeImportExtension(backendPath))).backend;
|
|
76
|
+
if (backend === undefined) {
|
|
77
|
+
throw new Error(`[nifra] ${backendPath} does not export \`backend\`.`);
|
|
78
|
+
}
|
|
79
|
+
return snapshotRoutes(backend);
|
|
80
|
+
}
|
|
81
|
+
/** `nifra snapshot`: write the current contract as the CI baseline. */
|
|
82
|
+
export async function runSnapshot(cwd, options) {
|
|
83
|
+
const routes = await snapshotBackend(cwd);
|
|
84
|
+
const file = { nifraSnapshot: 1, routes };
|
|
85
|
+
const outPath = resolve(cwd, options.out ?? DEFAULT_SNAPSHOT_FILE);
|
|
86
|
+
await Bun.write(outPath, `${JSON.stringify(file, null, 2)}\n`);
|
|
87
|
+
console.log(`[nifra] wrote ${routes.length} route${routes.length === 1 ? "" : "s"} to ${outPath}`);
|
|
88
|
+
}
|
|
89
|
+
/** `nifra diff`: compare the current contract against a baseline. Returns false on breaking changes. */
|
|
90
|
+
export async function runDiff(cwd, baselinePath, options) {
|
|
91
|
+
const resolved = resolve(cwd, baselinePath);
|
|
92
|
+
const baselineFile = Bun.file(resolved);
|
|
93
|
+
if (!(await baselineFile.exists())) {
|
|
94
|
+
throw new Error(`[nifra] baseline not found: ${resolved} — create it on your main branch with \`nifra snapshot\`.`);
|
|
95
|
+
}
|
|
96
|
+
const baseline = parseSnapshotFile(await baselineFile.text(), baselinePath);
|
|
97
|
+
const current = await snapshotBackend(cwd);
|
|
98
|
+
const diff = diffRouteSnapshots(baseline.routes, current);
|
|
99
|
+
if (options.json === true) {
|
|
100
|
+
console.log(JSON.stringify({ hasBreaking: diff.hasBreaking, changes: diff.changes }, null, 2));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log(formatDiff(diff));
|
|
104
|
+
}
|
|
105
|
+
return !diff.hasBreaking;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=diff-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-tool.js","sourceRoot":"","sources":["../src/diff-tool.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-http.js
CHANGED
|
@@ -19,7 +19,7 @@ import { loadTypesCorpus } from "./types-search.js";
|
|
|
19
19
|
// tool factory + the transport core from one entry: `import { respondMcpHttp, docsTools } from "@nifrajs/cli/mcp"`.
|
|
20
20
|
export { docsTools } from "./mcp-docs-tools.js";
|
|
21
21
|
// Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
|
|
22
|
-
const VERSION = "1.
|
|
22
|
+
const VERSION = "1.6.0";
|
|
23
23
|
const SERVER_INFO = { name: "nifra-docs", version: VERSION };
|
|
24
24
|
const DOCS_HEALTH = "nifra docs MCP — POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call). Tools: nifra_docs, nifra_example.";
|
|
25
25
|
/** The two project-independent tools, reading the package's bundled corpus from disk (CLI use). */
|
package/docs/llms-full.txt
CHANGED
|
@@ -5841,7 +5841,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
5841
5841
|
|
|
5842
5842
|
## @nifrajs/client
|
|
5843
5843
|
|
|
5844
|
-
`ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `FetchFn`, `inProcessClient`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `Result`, `testClient`, `Treaty`, `TreatyFromRegistry`
|
|
5844
|
+
`ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `FetchFn`, `inProcessClient`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `Result`, `SubscribeOptions`, `Subscription`, `testClient`, `Treaty`, `TreatyFromRegistry`
|
|
5845
5845
|
|
|
5846
5846
|
## @nifrajs/content
|
|
5847
5847
|
|
|
@@ -5849,7 +5849,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
5849
5849
|
|
|
5850
5850
|
## @nifrajs/core
|
|
5851
5851
|
|
|
5852
|
-
`AnyServer`, `attachWebSocket`, `commonSecretPatterns`, `Context`, `ContextForOp`, `ContractShape`, `CookieOptions`, `defineContract`, `defineIdentityPlugin`, `definePlugin`, `defineRouterPlugin`, `DurableObjectNamespaceLike`, `ExecutionContext`, `FRAMEWORK_NAME`, `FrameworkError`, `FrameworkName`, `Handler`, `HandlersFor`, `IdentityPlugin`, `implement`, `InferInput`, `InferOutput`, `jsonLogger`, `LogFields`, `Logger`, `McpPromptDescriptor`, `McpResourceDescriptor`, `Method`, `METHODS`, `Middleware`, `NifraPlugin`, `NifraWebSocket`, `NodeServeOutcome`, `OnRequestResult`, `OperationDef`, `Params`, `parseCookies`, `Platform`, `Prettify`, `PromptArgument`, `PromptMessage`, `redactLogFields`, `RedactOptions`, `Registry`, `RegistryFor`, `RegistryFromImpl`, `ResponseControls`, `ResponseDef`, `robots`, `RobotsOptions`, `RobotsRule`, `RouteConfigError`, `RouteConfigErrorCode`, `RouteDescriptor`, `RouteInfo`, `Router`, `RouterMatch`, `RouteSchema`, `RunningServer`, `ScheduledController`, `ScheduledHandler`, `serializeCookie`, `server`, `Server`, `ServerOptions`, `SignatureEncoding`, `signValue`, `silentLogger`, `sitemap`, `SitemapChangeFreq`, `SitemapEntry`, `SitemapOptions`, `sse`, `SSEContext`, `SSEInit`, `SSEMessage`, `SSEStream`, `StandardIssue`, `StandardResult`, `StandardSchemaV1`, `StandardTypes`, `StandardWebSocket`, `toFetchHandler`, `ToolAnnotations`, `TopicRegistry`, `unsignValue`, `validateStandard`, `ValidationOutcome`, `verifyWebhook`, `VerifyWebhookOptions`, `Version`, `VERSION`, `WebhookFailureReason`, `WebhookProvider`, `WebhookResult`, `WebSocketContext`, `WebSocketData`, `WebSocketHandler`, `WebSocketUpgradeOutcome`
|
|
5852
|
+
`AnyServer`, `attachWebSocket`, `commonSecretPatterns`, `Context`, `ContextForOp`, `ContractShape`, `CookieOptions`, `defineContract`, `defineIdentityPlugin`, `definePlugin`, `defineRouterPlugin`, `DurableObjectNamespaceLike`, `ExecutionContext`, `FRAMEWORK_NAME`, `FrameworkError`, `FrameworkName`, `Handler`, `HandlersFor`, `IdentityPlugin`, `implement`, `InferInput`, `InferOutput`, `jsonLogger`, `LogFields`, `Logger`, `McpPromptDescriptor`, `McpResourceDescriptor`, `Method`, `METHODS`, `Middleware`, `NifraPlugin`, `NifraWebSocket`, `NodeServeOutcome`, `OnRequestResult`, `OperationDef`, `Params`, `parseCookies`, `Platform`, `Prettify`, `PromptArgument`, `PromptMessage`, `redactLogFields`, `RedactOptions`, `Registry`, `RegistryFor`, `RegistryFromImpl`, `ResponseControls`, `ResponseDef`, `ResponseFinalization`, `robots`, `RobotsOptions`, `RobotsRule`, `RouteConfigError`, `RouteConfigErrorCode`, `RouteDescriptor`, `RouteInfo`, `Router`, `RouterMatch`, `RouteSchema`, `RunningServer`, `ScheduledController`, `ScheduledHandler`, `serializeCookie`, `server`, `Server`, `ServerOptions`, `SignatureEncoding`, `signValue`, `silentLogger`, `sitemap`, `SitemapChangeFreq`, `SitemapEntry`, `SitemapOptions`, `sse`, `SSEContext`, `SSEInit`, `SSEMessage`, `SSEStream`, `StandardIssue`, `StandardResult`, `StandardSchemaV1`, `StandardTypes`, `StandardWebSocket`, `toFetchHandler`, `ToolAnnotations`, `TopicRegistry`, `typedSSEStream`, `TypedSSEStream`, `unsignValue`, `validateStandard`, `ValidationOutcome`, `verifyWebhook`, `VerifyWebhookOptions`, `Version`, `VERSION`, `WebhookFailureReason`, `WebhookProvider`, `WebhookResult`, `WebSocketContext`, `WebSocketData`, `WebSocketHandler`, `WebSocketUpgradeOutcome`
|
|
5853
5853
|
|
|
5854
5854
|
## @nifrajs/cron
|
|
5855
5855
|
|
|
@@ -5887,6 +5887,10 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
5887
5887
|
|
|
5888
5888
|
`bridgeScript`, `createMcpServer`, `CreateMcpServerOptions`, `defineMcpTool`, `DefineMcpToolOptions`, `defineMcpWidget`, `DefineMcpWidgetOptions`, `McpAppBridge`, `McpHttpOptions`, `McpServer`, `McpToolHandlerResult`, `McpUiIntent`, `McpWidget`, `respondMcpHttp`, `uiResourceMeta`, `widgetDocument`
|
|
5889
5889
|
|
|
5890
|
+
## @nifrajs/mcp-db
|
|
5891
|
+
|
|
5892
|
+
`McpDbAuthorizeContext`, `McpDbConfigError`, `RunQueryOptions`, `serveDatabaseAsMcp`, `ServeDatabaseAsMcpOptions`, `SqliteDatabaseLike`
|
|
5893
|
+
|
|
5890
5894
|
## @nifrajs/middleware
|
|
5891
5895
|
|
|
5892
5896
|
`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`, `createCsrfToken`, `csrf`, `CsrfOptions`, `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`, `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`, `timing`, `TimingControls`, `TimingMetric`, `TimingOptions`, `TrailingSlashOptions`, `trimTrailingSlash`, `tryVerifyJwt`, `VerifiedJwt`, `verifyCsrfToken`, `verifyJwt`, `VerifyJwtOptions`, `VerifyJwtResult`
|
|
@@ -5903,6 +5907,10 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
5903
5907
|
|
|
5904
5908
|
`ActiveObservation`, `AttributeValue`, `combineObservationAdapters`, `consoleSpanExporter`, `createObservationLifecycle`, `EndObservation`, `formatTraceparent`, `generateSpanId`, `generateTraceId`, `NifraSpan`, `ObservationAdapter`, `ObservationClock`, `ObservationContext`, `ObservationLifecycle`, `ObservationLifecycleOptions`, `ObservationParent`, `ParsedTraceparent`, `parseTraceparent`, `SpanExporter`, `SpanStatus`, `StartObservation`, `TraceContext`, `traceHeaders`, `tracing`, `TracingOptions`
|
|
5905
5909
|
|
|
5910
|
+
## @nifrajs/prompt
|
|
5911
|
+
|
|
5912
|
+
`prompt`, `Prompt`, `PromptInputError`, `PromptMessage`, `PromptOutputError`, `PromptRequest`, `PromptResponseFormat`, `RunOptions`
|
|
5913
|
+
|
|
5906
5914
|
## @nifrajs/runner
|
|
5907
5915
|
|
|
5908
5916
|
`AppLike`, `RequestSpec`, `runApp`, `RunOptions`, `runRequest`, `RunResult`
|
package/docs/types.json
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"name": "ActiveObservation",
|
|
32
32
|
"kind": "interface",
|
|
33
33
|
"package": "@nifrajs/otel",
|
|
34
|
-
"signature": "export interface ActiveObservation {\n readonly span: NifraSpan;\n readonly context: ObservationContext;\n /** Adds a sink to this in-flight span. Re-adding the same adapter is idempotent. */\n addAdapter(adapter: ObservationAdapter): void;\n /** Starts a child that inherits this span's trace identity and sampling decision. */\n startChild(input: Omit<StartObservation, \"parent\" | \"traceparent\">, additionalAdapters?: readonly ObservationAdapter[]): ActiveObservation;\n /** Records failure evidence without deciding the final status until the response is known. */\n recordError(error: unknown): void;\n /** Ends and exports once. Repeated calls return the same completed span without notifying again. */\n end(input?: EndObservation): NifraSpan;\n}"
|
|
34
|
+
"signature": "export interface ActiveObservation {\n readonly span: NifraSpan;\n readonly context: ObservationContext;\n /** Adds a sink to this in-flight span. Re-adding the same adapter is idempotent. */\n addAdapter(adapter: ObservationAdapter): void;\n /** Starts a child that inherits this span's trace identity and sampling decision. */\n startChild(input: Omit<StartObservation, \"parent\" | \"traceparent\">, additionalAdapters?: readonly ObservationAdapter[]): ActiveObservation;\n /**\n * Merge attributes onto the in-flight span — the seam for plugins that learn something mid-request\n * (an authenticated principal, a feature-flag bucket, a cache verdict) after the span opened.\n * Silently ignored once the observation has ended (the exported span is immutable).\n */\n setAttributes(attributes: Readonly<Record<string, AttributeValue>>): void;\n /** Records failure evidence without deciding the final status until the response is known. */\n recordError(error: unknown): void;\n /** Ends and exports once. Repeated calls return the same completed span without notifying again. */\n end(input?: EndObservation): NifraSpan;\n}"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"name": "AddRoute",
|
|
@@ -1357,6 +1357,12 @@
|
|
|
1357
1357
|
"signature": "export declare const DEFAULT_DEV_PORT = 4321;",
|
|
1358
1358
|
"doc": "/**\n * The single default port for the dev server (`@nifrajs/web/dev`, `@nifrajs/web/vite`) **and**\n * `nifra start`. Deliberately uncommon: `3000`/`5173`/`8080` collide with whatever else is running\n * (Next, Vite, a stray Node API). `4321` rarely is — and being the *same* constant across `nifra dev`\n * and `nifra start` means a project's URL doesn't change between commands. Override per-run with\n * `--port <n>` or the `PORT` env var. */"
|
|
1359
1359
|
},
|
|
1360
|
+
{
|
|
1361
|
+
"name": "DEFAULT_SNAPSHOT_FILE",
|
|
1362
|
+
"kind": "const",
|
|
1363
|
+
"package": "@nifrajs/cli",
|
|
1364
|
+
"signature": "export declare const DEFAULT_SNAPSHOT_FILE = \"api-snapshot.json\";"
|
|
1365
|
+
},
|
|
1360
1366
|
{
|
|
1361
1367
|
"name": "defer",
|
|
1362
1368
|
"kind": "function",
|
|
@@ -1558,6 +1564,19 @@
|
|
|
1558
1564
|
"signature": "export declare function diffManifestRoutes(manifestFiles: readonly string[], discoveredFiles: readonly string[]): ManifestDrift;",
|
|
1559
1565
|
"doc": "/**\n * Diff the route files a committed server-manifest imports against the files freshly discovered in\n * `routes/`. Returns the `missing` (in routes/, not in manifest — stale manifest) and `extra` (in\n * manifest, gone from routes/ — dangling import) sets. Empty arrays ⇒ in sync. Pure — the caller\n * supplies both file lists (the committed source is parsed via {@link parseManifestRouteFiles}; the\n * fresh list comes from `discoverRoutes`). Lists need not be pre-sorted; the result is sorted.\n */"
|
|
1560
1566
|
},
|
|
1567
|
+
{
|
|
1568
|
+
"name": "diffRouteSnapshots",
|
|
1569
|
+
"kind": "function",
|
|
1570
|
+
"package": "@nifrajs/core",
|
|
1571
|
+
"signature": "export declare function diffRouteSnapshots(before: readonly RouteSnapshot[], after: readonly RouteSnapshot[]): RoutesDiff;",
|
|
1572
|
+
"doc": "/**\n * Diff two route snapshots (`snapshotRoutes` output, possibly restored from JSON). Every change is\n * classified breaking/compatible/info; `hasBreaking` is the CI-gate bit.\n */"
|
|
1573
|
+
},
|
|
1574
|
+
{
|
|
1575
|
+
"name": "DiffSeverity",
|
|
1576
|
+
"kind": "type",
|
|
1577
|
+
"package": "@nifrajs/core",
|
|
1578
|
+
"signature": "export type DiffSeverity = \"breaking\" | \"compatible\" | \"info\";"
|
|
1579
|
+
},
|
|
1561
1580
|
{
|
|
1562
1581
|
"name": "directSinkSpecifier",
|
|
1563
1582
|
"kind": "function",
|
|
@@ -1992,7 +2011,7 @@
|
|
|
1992
2011
|
"name": "FileStorage",
|
|
1993
2012
|
"kind": "class",
|
|
1994
2013
|
"package": "@nifrajs/storage",
|
|
1995
|
-
"signature": "export declare class FileStorage implements StorageAdapter {\n private readonly root;\n private readonly metadataRoot;\n constructor(root: string);\n private metadataPathFor;\n /** Resolve `key` to an absolute path, asserting it stays inside `root` (defense-in-depth on top of `assertSafeKey`). */\n private pathFor;\n put(key: string, data: StorageData, options?: PutOptions): Promise<void>;\n get(key: string): Promise<StorageObject | null>;\n delete(key: string): Promise<void>;\n exists(key: string): Promise<boolean>;\n list(options?: ListOptions): Promise<string[]>;\n private walk;\n}"
|
|
2014
|
+
"signature": "export declare class FileStorage implements StorageAdapter {\n private readonly root;\n private readonly metadataRoot;\n constructor(root: string);\n private metadataPathFor;\n /** Resolve `key` to an absolute path, asserting it stays inside `root` (defense-in-depth on top of `assertSafeKey`). */\n private pathFor;\n private symlinkError;\n /** Reject existing symbolic links below `base`; missing suffixes are safe for later creation. */\n private assertNoSymlinkPath;\n /** Create parents, re-check them, and refuse a final-component symlink at open time. */\n private writeContained;\n put(key: string, data: StorageData, options?: PutOptions): Promise<void>;\n get(key: string): Promise<StorageObject | null>;\n delete(key: string): Promise<void>;\n exists(key: string): Promise<boolean>;\n list(options?: ListOptions): Promise<string[]>;\n private walk;\n}"
|
|
1996
2015
|
},
|
|
1997
2016
|
{
|
|
1998
2017
|
"name": "FileType",
|
|
@@ -2074,6 +2093,13 @@
|
|
|
2074
2093
|
"signature": "export declare function formatBytes(bytes: number): string;",
|
|
2075
2094
|
"doc": "/** Human-readable byte count: `B`/`KB`/`MB` with one decimal above 1 KB (e.g. `12.3 KB`). Pure. */"
|
|
2076
2095
|
},
|
|
2096
|
+
{
|
|
2097
|
+
"name": "formatDiff",
|
|
2098
|
+
"kind": "function",
|
|
2099
|
+
"package": "@nifrajs/cli",
|
|
2100
|
+
"signature": "export declare function formatDiff(diff: RoutesDiff): string;",
|
|
2101
|
+
"doc": "/** Render a diff for terminals: breaking first, then info, then compatible. */"
|
|
2102
|
+
},
|
|
2077
2103
|
{
|
|
2078
2104
|
"name": "formatManifestDrift",
|
|
2079
2105
|
"kind": "function",
|
|
@@ -3371,6 +3397,19 @@
|
|
|
3371
3397
|
"signature": "export interface McpContentBlock {\n readonly type: \"text\";\n readonly text: string;\n}",
|
|
3372
3398
|
"doc": "/** A single content block in a tool result. Today only text — the model-facing representation. */"
|
|
3373
3399
|
},
|
|
3400
|
+
{
|
|
3401
|
+
"name": "McpDbAuthorizeContext",
|
|
3402
|
+
"kind": "interface",
|
|
3403
|
+
"package": "@nifrajs/mcp-db",
|
|
3404
|
+
"signature": "export interface McpDbAuthorizeContext {\n readonly toolName: \"run_query\";\n readonly request: Request;\n}",
|
|
3405
|
+
"doc": "/** Context forwarded to `authorize` — the inbound HTTP Request carrying the `run_query` call. */"
|
|
3406
|
+
},
|
|
3407
|
+
{
|
|
3408
|
+
"name": "McpDbConfigError",
|
|
3409
|
+
"kind": "class",
|
|
3410
|
+
"package": "@nifrajs/mcp-db",
|
|
3411
|
+
"signature": "export declare class McpDbConfigError extends Error {\n constructor(message: string);\n}"
|
|
3412
|
+
},
|
|
3374
3413
|
{
|
|
3375
3414
|
"name": "McpHttpOptions",
|
|
3376
3415
|
"kind": "interface",
|
|
@@ -3648,7 +3687,7 @@
|
|
|
3648
3687
|
"name": "Middleware",
|
|
3649
3688
|
"kind": "interface",
|
|
3650
3689
|
"package": "@nifrajs/core",
|
|
3651
|
-
"signature": "export interface Middleware {\n readonly name?: string;\n readonly onRequest?: (req: Request) => MaybePromise<OnRequestResult>;\n readonly around?: <T>(context: Context, next: () => MaybePromise<T>) => MaybePromise<T>;\n readonly beforeHandle?: (context: Context) => MaybePromise<unknown>;\n readonly afterHandle?: (result: unknown, context: Context) => MaybePromise<unknown>;\n readonly onResponse?: (response: Response, req: Request) => MaybePromise<Response>;\n readonly onError?: (error: unknown, context: Context) => MaybePromise<unknown>;\n}",
|
|
3690
|
+
"signature": "export interface Middleware {\n readonly name?: string;\n readonly onRequest?: (req: Request) => MaybePromise<OnRequestResult>;\n readonly around?: <T>(context: Context, next: () => MaybePromise<T>) => MaybePromise<T>;\n readonly beforeHandle?: (context: Context) => MaybePromise<unknown>;\n readonly afterHandle?: (result: unknown, context: Context) => MaybePromise<unknown>;\n readonly onResponse?: (response: Response, req: Request) => MaybePromise<Response>;\n readonly onResponseFinalized?: (outcome: ResponseFinalization, req: Request) => MaybePromise<void>;\n readonly onError?: (error: unknown, context: Context) => MaybePromise<unknown>;\n}",
|
|
3652
3691
|
"doc": "/**\n * A bundle of lifecycle hooks applied together via {@link Server.use} — the unit\n * `@nifrajs/middleware` ships (cors, security headers, rate-limit). Every hook is\n * optional and wired to its lifecycle point. Middleware is context-agnostic (sees\n * the base `Context`); `use` does no context-type merging — the full type-merging\n * plugin system is deferred, and `.use` is reserved as its future entry point.\n */"
|
|
3653
3692
|
},
|
|
3654
3693
|
{
|
|
@@ -4161,6 +4200,13 @@
|
|
|
4161
4200
|
"signature": "export declare function parseNdjsonData(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): Promise<unknown>;",
|
|
4162
4201
|
"doc": "/**\n * Client side of {@link ndjsonStream} (used by the router's `defaultFetchData` on a soft nav): read\n * the NDJSON body into a data object whose deferred markers settle as resolution lines arrive.\n * Returns after **line 1** so the router can apply the critical data + render immediately; the\n * markers' promises settle/reject in the background. If the stream ends (or `signal` aborts) with\n * markers unsettled, they reject — so `<Await>` never hangs.\n */"
|
|
4163
4202
|
},
|
|
4203
|
+
{
|
|
4204
|
+
"name": "parseSnapshotFile",
|
|
4205
|
+
"kind": "function",
|
|
4206
|
+
"package": "@nifrajs/cli",
|
|
4207
|
+
"signature": "export declare function parseSnapshotFile(content: string, sourcePath: string): SnapshotFile;",
|
|
4208
|
+
"doc": "/** Parse + validate a snapshot file's content. Throws with an actionable message on any mismatch. */"
|
|
4209
|
+
},
|
|
4164
4210
|
{
|
|
4165
4211
|
"name": "parseStaticImports",
|
|
4166
4212
|
"kind": "function",
|
|
@@ -4416,6 +4462,19 @@
|
|
|
4416
4462
|
"signature": "export declare function projectTools(cwd: string, loadAppCached?: (outDirName?: string) => Promise<LoadedApp>): McpTool[];",
|
|
4417
4463
|
"doc": "/** Build the project-scoped tools for `cwd`. */"
|
|
4418
4464
|
},
|
|
4465
|
+
{
|
|
4466
|
+
"name": "prompt",
|
|
4467
|
+
"kind": "function",
|
|
4468
|
+
"package": "@nifrajs/prompt",
|
|
4469
|
+
"signature": "export declare function prompt(instruction: string): Prompt<undefined, string>;",
|
|
4470
|
+
"doc": "/**\n * Define a type-safe prompt. Chain `.input()` / `.output()` with Standard Schemas, then `.run()`\n * with a provider `complete` fn. Immutable — each chain step returns a new prompt.\n */"
|
|
4471
|
+
},
|
|
4472
|
+
{
|
|
4473
|
+
"name": "Prompt",
|
|
4474
|
+
"kind": "interface",
|
|
4475
|
+
"package": "@nifrajs/prompt",
|
|
4476
|
+
"signature": "export interface Prompt<Input, Output> {\n readonly instruction: string;\n /** Declare the variables the prompt needs. Validated on every run. */\n input<Schema extends StandardSchemaV1>(schema: Schema): Prompt<InferOutput<Schema>, Output>;\n /** Declare the shape the model must return. Sent as the provider's structured-output format. */\n output<Schema extends StandardSchemaV1>(schema: Schema): Prompt<Input, InferOutput<Schema>>;\n /** Build the provider request without executing it (for inspection, logging, tests). */\n request(input: Input, extraMessages?: readonly PromptMessage[]): Promise<PromptRequest>;\n /** Execute via the given provider `complete` fn and return the validated, typed output. */\n run(input: Input, options: RunOptions): Promise<Output>;\n}"
|
|
4477
|
+
},
|
|
4419
4478
|
{
|
|
4420
4479
|
"name": "PromptArgument",
|
|
4421
4480
|
"kind": "interface",
|
|
@@ -4423,6 +4482,13 @@
|
|
|
4423
4482
|
"signature": "export interface PromptArgument {\n readonly name: string;\n readonly description?: string;\n readonly required?: boolean;\n}",
|
|
4424
4483
|
"doc": "/** One declared argument of an MCP prompt, surfaced in `prompts/list`. */"
|
|
4425
4484
|
},
|
|
4485
|
+
{
|
|
4486
|
+
"name": "PromptInputError",
|
|
4487
|
+
"kind": "class",
|
|
4488
|
+
"package": "@nifrajs/prompt",
|
|
4489
|
+
"signature": "export declare class PromptInputError extends Error {\n readonly issues: ReadonlyArray<StandardIssue>;\n constructor(issues: ReadonlyArray<StandardIssue>);\n}",
|
|
4490
|
+
"doc": "/** A failed prompt input — the caller's variables did not satisfy the input schema. */"
|
|
4491
|
+
},
|
|
4426
4492
|
{
|
|
4427
4493
|
"name": "PromptMessage",
|
|
4428
4494
|
"kind": "interface",
|
|
@@ -4430,6 +4496,34 @@
|
|
|
4430
4496
|
"signature": "export interface PromptMessage {\n readonly role: \"user\" | \"assistant\";\n readonly content: {\n readonly type: \"text\";\n readonly text: string;\n };\n}",
|
|
4431
4497
|
"doc": "/** A message in an MCP prompt's rendered output (see {@link Server.prompt}). */"
|
|
4432
4498
|
},
|
|
4499
|
+
{
|
|
4500
|
+
"name": "PromptMessage",
|
|
4501
|
+
"kind": "interface",
|
|
4502
|
+
"package": "@nifrajs/prompt",
|
|
4503
|
+
"signature": "export interface PromptMessage {\n readonly role: \"system\" | \"user\" | \"assistant\";\n readonly content: string;\n}",
|
|
4504
|
+
"doc": "/** One chat message. The union every provider API accepts. */"
|
|
4505
|
+
},
|
|
4506
|
+
{
|
|
4507
|
+
"name": "PromptOutputError",
|
|
4508
|
+
"kind": "class",
|
|
4509
|
+
"package": "@nifrajs/prompt",
|
|
4510
|
+
"signature": "export declare class PromptOutputError extends Error {\n readonly issues: ReadonlyArray<StandardIssue>;\n /** The raw model reply that failed, for logging/debugging. */\n readonly raw: string;\n constructor(issues: ReadonlyArray<StandardIssue>, \n /** The raw model reply that failed, for logging/debugging. */\n raw: string);\n}",
|
|
4511
|
+
"doc": "/** The model's reply did not satisfy the output schema (after any heal attempts). */"
|
|
4512
|
+
},
|
|
4513
|
+
{
|
|
4514
|
+
"name": "PromptRequest",
|
|
4515
|
+
"kind": "interface",
|
|
4516
|
+
"package": "@nifrajs/prompt",
|
|
4517
|
+
"signature": "export interface PromptRequest {\n readonly messages: readonly PromptMessage[];\n /** Present when the prompt declares `.output()` — pass it as the provider's structured-output format. */\n readonly responseFormat?: PromptResponseFormat;\n}",
|
|
4518
|
+
"doc": "/** Everything a provider adapter needs to execute one prompt call. */"
|
|
4519
|
+
},
|
|
4520
|
+
{
|
|
4521
|
+
"name": "PromptResponseFormat",
|
|
4522
|
+
"kind": "interface",
|
|
4523
|
+
"package": "@nifrajs/prompt",
|
|
4524
|
+
"signature": "export interface PromptResponseFormat {\n readonly name: string;\n readonly strict: true;\n readonly schema: JsonSchema;\n}",
|
|
4525
|
+
"doc": "/** The structured-output format handed to the provider (OpenAI `json_schema` shape; trivially\n * adaptable to Anthropic tool-input or Gemini `responseSchema`). */"
|
|
4526
|
+
},
|
|
4433
4527
|
{
|
|
4434
4528
|
"name": "PROTOCOL_VERSION",
|
|
4435
4529
|
"kind": "const",
|
|
@@ -4700,7 +4794,7 @@
|
|
|
4700
4794
|
"name": "ReflectedRouteSchema",
|
|
4701
4795
|
"kind": "interface",
|
|
4702
4796
|
"package": "@nifrajs/core",
|
|
4703
|
-
"signature": "export interface ReflectedRouteSchema {\n readonly body?: SchemaReflection;\n readonly query?: SchemaReflection;\n readonly response?: SchemaReflection;\n readonly errors?: Readonly<Record<string, SchemaReflection>>;\n}"
|
|
4797
|
+
"signature": "export interface ReflectedRouteSchema {\n readonly body?: SchemaReflection;\n readonly query?: SchemaReflection;\n readonly response?: SchemaReflection;\n readonly errors?: Readonly<Record<string, SchemaReflection>>;\n /** The SSE event-payload schema of a typed streaming route (`app.sse()`). */\n readonly sse?: SchemaReflection;\n}"
|
|
4704
4798
|
},
|
|
4705
4799
|
{
|
|
4706
4800
|
"name": "ReflectedSchemaField",
|
|
@@ -4748,7 +4842,7 @@
|
|
|
4748
4842
|
"name": "RegistryFromImpl",
|
|
4749
4843
|
"kind": "type",
|
|
4750
4844
|
"package": "@nifrajs/core",
|
|
4751
|
-
"signature": "export type RegistryFromImpl<C extends ContractShape, H extends HandlersFor<C>> = {\n [P in C[keyof C][\"path\"]]: {\n [K in keyof C as C[K][\"path\"] extends P ? C[K][\"method\"] : never]: {\n readonly params: Params<C[K][\"path\"]>;\n readonly query: OpQuery<C[K]>;\n readonly body: OpBody<C[K]>;\n readonly output: C[K] extends {\n response: infer R extends StandardSchemaV1;\n } ? InferOutput<R> : H[K] extends AnyFn ? OutputOf<H[K]> : unknown;\n readonly errors: OpErrors<C[K]>;\n };\n };\n};",
|
|
4845
|
+
"signature": "export type RegistryFromImpl<C extends ContractShape, H extends HandlersFor<C>> = {\n [P in C[keyof C][\"path\"]]: {\n [K in keyof C as C[K][\"path\"] extends P ? C[K][\"method\"] : never]: {\n readonly params: Params<C[K][\"path\"]>;\n readonly query: OpQuery<C[K]>;\n readonly body: OpBody<C[K]>;\n readonly output: C[K] extends {\n response: infer R extends StandardSchemaV1;\n } ? InferOutput<R> : H[K] extends AnyFn ? OutputOf<H[K]> : unknown;\n readonly errors: OpErrors<C[K]>;\n readonly sse: never;\n };\n };\n};",
|
|
4752
4846
|
"doc": "/**\n * The registry produced by `implement`: input from the contract op; `output` is the declared `response`\n * contract when present (it wins — exactly as in the inline path), else the bound HANDLER's return — so\n * the implemented server stays route-for-route identical to the equivalent inline server (the\n * mode-conformance guarantee), and a contract-typed client and a `typeof app`-typed client agree.\n */"
|
|
4753
4847
|
},
|
|
4754
4848
|
{
|
|
@@ -5089,6 +5183,13 @@
|
|
|
5089
5183
|
"signature": "export interface ResponseDef {\n readonly description?: string;\n /** Response body schema (any Standard Schema; a `t` schema yields full JSON Schema in OpenAPI). */\n readonly schema?: StandardSchemaV1;\n /** Content type. Default `application/json`. */\n readonly contentType?: string;\n}",
|
|
5090
5184
|
"doc": "/** An additional (non-success) response a contract operation can document, e.g. a `404`. */"
|
|
5091
5185
|
},
|
|
5186
|
+
{
|
|
5187
|
+
"name": "ResponseFinalization",
|
|
5188
|
+
"kind": "interface",
|
|
5189
|
+
"package": "@nifrajs/core",
|
|
5190
|
+
"signature": "export interface ResponseFinalization {\n /** The final response, or the last response available when a transformation failed. */\n readonly response: Response;\n /** A response-hook failure. Terminal observers run fail-open before the error is rethrown. */\n readonly error?: unknown;\n}",
|
|
5191
|
+
"doc": "/** The terminal response-pipeline outcome observed after every transforming `onResponse` hook. */"
|
|
5192
|
+
},
|
|
5092
5193
|
{
|
|
5093
5194
|
"name": "Result",
|
|
5094
5195
|
"kind": "type",
|
|
@@ -5169,6 +5270,12 @@
|
|
|
5169
5270
|
"signature": "export type RouteBody<App, Path extends string, Method extends string> = Path extends keyof RegistryOf<App> ? Uppercase<Method> extends keyof RegistryOf<App>[Path] ? (RegistryOf<App>[Path][Uppercase<Method>] & RouteInfo)[\"body\"] : never : never;",
|
|
5170
5271
|
"doc": "/** The body object type of `App`'s `Method Path` route (`never` when the route declares no body). */"
|
|
5171
5272
|
},
|
|
5273
|
+
{
|
|
5274
|
+
"name": "RouteChange",
|
|
5275
|
+
"kind": "interface",
|
|
5276
|
+
"package": "@nifrajs/core",
|
|
5277
|
+
"signature": "export interface RouteChange {\n readonly severity: DiffSeverity;\n readonly method: string;\n readonly path: string;\n /** Which part of the contract changed; \"route\" for add/remove of the whole route. */\n readonly section: \"route\" | \"body\" | \"query\" | \"response\" | \"sse\" | \"errors\";\n /** The top-level field (or error status) the change is about, when field-granular. */\n readonly field?: string;\n readonly message: string;\n}"
|
|
5278
|
+
},
|
|
5172
5279
|
{
|
|
5173
5280
|
"name": "RouteConfigError",
|
|
5174
5281
|
"kind": "class",
|
|
@@ -5201,14 +5308,14 @@
|
|
|
5201
5308
|
"name": "RouteInfo",
|
|
5202
5309
|
"kind": "interface",
|
|
5203
5310
|
"package": "@nifrajs/core",
|
|
5204
|
-
"signature": "export interface RouteInfo {\n readonly params: object;\n readonly query: unknown;\n readonly body: unknown;\n readonly output: unknown;\n /** Union of the route's declared error-response body types (from `schema.errors`); `unknown` when the\n * route declares none. Surfaced by the typed client as the failure `errorData`. */\n readonly errors?: unknown;\n}",
|
|
5311
|
+
"signature": "export interface RouteInfo {\n readonly params: object;\n readonly query: unknown;\n readonly body: unknown;\n readonly output: unknown;\n /** Union of the route's declared error-response body types (from `schema.errors`); `unknown` when the\n * route declares none. Surfaced by the typed client as the failure `errorData`. */\n readonly errors?: unknown;\n /** The SSE event payload type (from `schema.sse`, declared via `app.sse()`); `never` for ordinary\n * routes. The typed client keys `.subscribe()` availability and its event type off this. */\n readonly sse?: unknown;\n}",
|
|
5205
5312
|
"doc": "/**\n * One route's input/output shape as the **client** will consume it. `query`/`body`\n * are `never` when the route declares no schema for them, so the client can detect\n * \"this route takes no body\" via `[body] extends [never]`. `output` is the\n * handler's raw return type (the client applies `Jsonify` when reading it).\n */"
|
|
5206
5313
|
},
|
|
5207
5314
|
{
|
|
5208
5315
|
"name": "RouteInfoFor",
|
|
5209
5316
|
"kind": "type",
|
|
5210
5317
|
"package": "@nifrajs/core",
|
|
5211
|
-
"signature": "export type RouteInfoFor<Path extends string, S extends RouteSchema, Output> = {\n readonly params: Params<Path>;\n readonly query: RegistryQuery<S>;\n readonly body: RegistryBody<S>;\n readonly output: RegistryOutput<S, Output>;\n readonly errors: RegistryErrors<S>;\n};",
|
|
5318
|
+
"signature": "export type RouteInfoFor<Path extends string, S extends RouteSchema, Output> = {\n readonly params: Params<Path>;\n readonly query: RegistryQuery<S>;\n readonly body: RegistryBody<S>;\n readonly output: RegistryOutput<S, Output>;\n readonly errors: RegistryErrors<S>;\n readonly sse: RegistrySse<S>;\n};",
|
|
5212
5319
|
"doc": "/** Build a {@link RouteInfo} from a route's path, schema, and handler output type. */"
|
|
5213
5320
|
},
|
|
5214
5321
|
{
|
|
@@ -5299,9 +5406,28 @@
|
|
|
5299
5406
|
"name": "RouteSchema",
|
|
5300
5407
|
"kind": "interface",
|
|
5301
5408
|
"package": "@nifrajs/core",
|
|
5302
|
-
"signature": "export interface RouteSchema {\n readonly body?: StandardSchemaV1;\n readonly query?: StandardSchemaV1;\n /** Optional **response contract**. When declared: the handler's return is type-checked against it\n * (the implementation can't drift from the contract), the typed client sees THIS as the response type\n * (the contract — not the handler's incidental return), and it's emitted into OpenAPI/JSON-Schema so\n * tooling and coding agents can read the exact shape. It is **not** validated at runtime (zero\n * hot-path cost) — purely a compile-time + introspection contract. */\n readonly response?: StandardSchemaV1;\n /**\n * Optional **error-response contract**: a map of HTTP status code → the Standard Schema of that error's\n * body. Declares a route's failure modes so they flow into OpenAPI (as non-2xx `responses`), the\n * `/llms.txt` context, and other introspection — the whole contract, not just the happy path, is legible\n * to tooling and coding agents. Like `response`, it is **not** validated at runtime (zero hot-path cost);\n * it's a compile-time + introspection contract. Example: `{ 404: NotFound, 409: Conflict }`. */\n readonly errors?: Readonly<Record<number, StandardSchemaV1>>;\n /**\n * Hook fired when the request fails `body`/`query` validation, before the handler runs. `kind` says\n * which input failed (`\"body\"` | `\"query\"`). Its return value selects one of three outcomes (may be async):\n * - a **`Response`** → returned as-is, short-circuiting the route (custom error envelope, redirect, …).\n * - **any other value** → treated as a repaired payload and **re-validated once** against the same\n * schema. If it now passes, the handler runs with it; if it still fails, the original `422` stands.\n * Re-validation means a bad return can't bypass the schema — the trust boundary holds.\n * - **`undefined`** → give up; the original validation `422` is returned unchanged.\n * A route hook **overrides** the app-wide default set via `server({ onValidationError })`; return\n * `undefined` to fall through to the plain `422` even when an app default exists. Typical uses: a custom\n * error envelope, coercing the input, or prompting an LLM to repair the payload (re-validated, so it can't\n * bypass the schema).\n */\n readonly onValidationError?: (issues: ReadonlyArray<StandardIssue>, ctx: Context, kind: \"body\" | \"query\") => Response | unknown | Promise<Response | unknown>;\n}",
|
|
5409
|
+
"signature": "export interface RouteSchema {\n readonly body?: StandardSchemaV1;\n readonly query?: StandardSchemaV1;\n /** Optional **response contract**. When declared: the handler's return is type-checked against it\n * (the implementation can't drift from the contract), the typed client sees THIS as the response type\n * (the contract — not the handler's incidental return), and it's emitted into OpenAPI/JSON-Schema so\n * tooling and coding agents can read the exact shape. It is **not** validated at runtime (zero\n * hot-path cost) — purely a compile-time + introspection contract. */\n readonly response?: StandardSchemaV1;\n /**\n * Optional **error-response contract**: a map of HTTP status code → the Standard Schema of that error's\n * body. Declares a route's failure modes so they flow into OpenAPI (as non-2xx `responses`), the\n * `/llms.txt` context, and other introspection — the whole contract, not just the happy path, is legible\n * to tooling and coding agents. Like `response`, it is **not** validated at runtime (zero hot-path cost);\n * it's a compile-time + introspection contract. Example: `{ 404: NotFound, 409: Conflict }`. */\n readonly errors?: Readonly<Record<number, StandardSchemaV1>>;\n /**\n * Optional **SSE event contract**: the Standard Schema of each event's `data` payload on a\n * streaming route (declared via `app.sse()`). Marks the route as a typed event stream — the\n * typed client grows a `.subscribe()` for it, and the schema flows into reflection. Like\n * `response`, it is **not** validated at runtime (zero hot-path cost); the server-side\n * `stream.send()` is compile-time-checked against it instead.\n */\n readonly sse?: StandardSchemaV1;\n /**\n * Hook fired when the request fails `body`/`query` validation, before the handler runs. `kind` says\n * which input failed (`\"body\"` | `\"query\"`). Its return value selects one of three outcomes (may be async):\n * - a **`Response`** → returned as-is, short-circuiting the route (custom error envelope, redirect, …).\n * - **any other value** → treated as a repaired payload and **re-validated once** against the same\n * schema. If it now passes, the handler runs with it; if it still fails, the original `422` stands.\n * Re-validation means a bad return can't bypass the schema — the trust boundary holds.\n * - **`undefined`** → give up; the original validation `422` is returned unchanged.\n * A route hook **overrides** the app-wide default set via `server({ onValidationError })`; return\n * `undefined` to fall through to the plain `422` even when an app default exists. Typical uses: a custom\n * error envelope, coercing the input, or prompting an LLM to repair the payload (re-validated, so it can't\n * bypass the schema).\n */\n readonly onValidationError?: (issues: ReadonlyArray<StandardIssue>, ctx: Context, kind: \"body\" | \"query\") => Response | unknown | Promise<Response | unknown>;\n}",
|
|
5303
5410
|
"doc": "/** Per-route input schemas. Each is any Standard Schema (zod/valibot/arktype/…). */"
|
|
5304
5411
|
},
|
|
5412
|
+
{
|
|
5413
|
+
"name": "RoutesDiff",
|
|
5414
|
+
"kind": "interface",
|
|
5415
|
+
"package": "@nifrajs/core",
|
|
5416
|
+
"signature": "export interface RoutesDiff {\n readonly changes: readonly RouteChange[];\n /** True when any change is `breaking` — the CI-gate signal. */\n readonly hasBreaking: boolean;\n}"
|
|
5417
|
+
},
|
|
5418
|
+
{
|
|
5419
|
+
"name": "RouteSnapshot",
|
|
5420
|
+
"kind": "interface",
|
|
5421
|
+
"package": "@nifrajs/core",
|
|
5422
|
+
"signature": "export interface RouteSnapshot {\n readonly method: string;\n readonly path: string;\n readonly schema?: RouteSnapshotSchema;\n}",
|
|
5423
|
+
"doc": "/** One route in a snapshot — plain JSON, safe to persist as a CI baseline. */"
|
|
5424
|
+
},
|
|
5425
|
+
{
|
|
5426
|
+
"name": "RouteSnapshotSchema",
|
|
5427
|
+
"kind": "interface",
|
|
5428
|
+
"package": "@nifrajs/core",
|
|
5429
|
+
"signature": "export interface RouteSnapshotSchema {\n readonly body?: SchemaSnapshot;\n readonly query?: SchemaSnapshot;\n readonly response?: SchemaSnapshot;\n readonly sse?: SchemaSnapshot;\n readonly errors?: Readonly<Record<string, SchemaSnapshot>>;\n}"
|
|
5430
|
+
},
|
|
5305
5431
|
{
|
|
5306
5432
|
"name": "routesToJson",
|
|
5307
5433
|
"kind": "function",
|
|
@@ -5369,6 +5495,13 @@
|
|
|
5369
5495
|
"signature": "export declare function runCheck(cwd: string, opts?: {\n readonly json?: boolean;\n readonly lintsOnly?: boolean;\n}): Promise<boolean>;",
|
|
5370
5496
|
"doc": "/** Run the full check; print a report (`--json` for machine output) and return whether it passed. */"
|
|
5371
5497
|
},
|
|
5498
|
+
{
|
|
5499
|
+
"name": "runDiff",
|
|
5500
|
+
"kind": "function",
|
|
5501
|
+
"package": "@nifrajs/cli",
|
|
5502
|
+
"signature": "export declare function runDiff(cwd: string, baselinePath: string, options: {\n json?: boolean;\n}): Promise<boolean>;",
|
|
5503
|
+
"doc": "/** `nifra diff`: compare the current contract against a baseline. Returns false on breaking changes. */"
|
|
5504
|
+
},
|
|
5372
5505
|
{
|
|
5373
5506
|
"name": "runDoctor",
|
|
5374
5507
|
"kind": "function",
|
|
@@ -5397,6 +5530,12 @@
|
|
|
5397
5530
|
"signature": "export interface RunningServer {\n readonly port: number;\n readonly hostname: string;\n readonly pendingRequests: number;\n stop(closeActiveConnections?: boolean): void;\n}",
|
|
5398
5531
|
"doc": "/**\n * The handle `listen()` returns — the slice of Bun's server nifra holds and exposes.\n * Declared explicitly (rather than `ReturnType<typeof Bun.serve>`) so the public type\n * surface doesn't leak the ambient `Bun` global into consumers' `.d.ts` resolution.\n */"
|
|
5399
5532
|
},
|
|
5533
|
+
{
|
|
5534
|
+
"name": "RunOptions",
|
|
5535
|
+
"kind": "interface",
|
|
5536
|
+
"package": "@nifrajs/prompt",
|
|
5537
|
+
"signature": "export interface RunOptions {\n /** Execute the LLM call and return the raw text of the model's reply. */\n readonly complete: (request: PromptRequest) => string | Promise<string>;\n /**\n * Repair hook: called when the reply fails output validation, with the raw reply and the issues.\n * Return a corrected raw reply (e.g. by re-asking the model) — it is validated again. Runs at most\n * `healAttempts` times (default 1). Omit to fail fast.\n */\n readonly heal?: (context: {\n readonly raw: string;\n readonly issues: ReadonlyArray<StandardIssue>;\n readonly request: PromptRequest;\n }) => string | Promise<string>;\n /** Max heal retries after the first failed validation (default 1). */\n readonly healAttempts?: number;\n /** Extra messages appended after the instruction (few-shot examples, prior turns). */\n readonly messages?: readonly PromptMessage[];\n}"
|
|
5538
|
+
},
|
|
5400
5539
|
{
|
|
5401
5540
|
"name": "RunOptions",
|
|
5402
5541
|
"kind": "interface",
|
|
@@ -5416,6 +5555,12 @@
|
|
|
5416
5555
|
"package": "@nifrajs/cli",
|
|
5417
5556
|
"signature": "export interface RunPortOptions {\n readonly target?: string;\n readonly json?: boolean;\n /** Fail (exit non-zero) on a detected unsupported feature for the resolved target. Implied by --target. */\n readonly ci?: boolean;\n /** With --ci, also fail on caveats (not just unsupported). */\n readonly strict?: boolean;\n}"
|
|
5418
5557
|
},
|
|
5558
|
+
{
|
|
5559
|
+
"name": "RunQueryOptions",
|
|
5560
|
+
"kind": "interface",
|
|
5561
|
+
"package": "@nifrajs/mcp-db",
|
|
5562
|
+
"signature": "export interface RunQueryOptions {\n /**\n * REQUIRED. Authorize each `run_query` call at the transport boundary (inspect the inbound\n * Request's auth). Return false to reject with a JSON-RPC error. There is no unauthenticated\n * mode — schema tools are the anonymous surface. Note: `run_query` is therefore HTTP-only;\n * direct `handle()` dispatch rejects it (no Request to authorize — fails closed).\n */\n readonly authorize: (context: McpDbAuthorizeContext) => boolean | Promise<boolean>;\n /** Max rows returned per query (default 100). */\n readonly maxRows?: number;\n /** Max serialized result size in bytes (default 100 KB). */\n readonly maxResultBytes?: number;\n}"
|
|
5563
|
+
},
|
|
5419
5564
|
{
|
|
5420
5565
|
"name": "runRequest",
|
|
5421
5566
|
"kind": "function",
|
|
@@ -5430,6 +5575,13 @@
|
|
|
5430
5575
|
"signature": "export interface RunResult {\n readonly label?: string;\n readonly method: string;\n readonly path: string;\n /** `true` when the app returned a 2xx response. `false` for non-2xx, or when `app.fetch` threw. */\n readonly ok: boolean;\n /** HTTP status — present when the app returned a response (absent when it threw). */\n readonly status?: number;\n readonly statusText?: string;\n readonly headers?: Readonly<Record<string, string>>;\n /** Parsed JSON when the response is JSON; otherwise the (possibly truncated) text. */\n readonly body?: unknown;\n /** The response body as text, truncated to `maxBodyChars`. */\n readonly bodyText?: string;\n /** `true` when `bodyText` was cut to the cap. */\n readonly truncated?: boolean;\n /** Wall-clock time for this request, milliseconds. */\n readonly durationMs: number;\n /** Set when `app.fetch` threw (the app crashed) rather than returning a response. */\n readonly error?: {\n readonly name: string;\n readonly message: string;\n readonly stack?: string;\n };\n}",
|
|
5431
5576
|
"doc": "/** The captured outcome of one request. */"
|
|
5432
5577
|
},
|
|
5578
|
+
{
|
|
5579
|
+
"name": "runSnapshot",
|
|
5580
|
+
"kind": "function",
|
|
5581
|
+
"package": "@nifrajs/cli",
|
|
5582
|
+
"signature": "export declare function runSnapshot(cwd: string, options: {\n out?: string;\n}): Promise<void>;",
|
|
5583
|
+
"doc": "/** `nifra snapshot`: write the current contract as the CI baseline. */"
|
|
5584
|
+
},
|
|
5433
5585
|
{
|
|
5434
5586
|
"name": "runWebSocket",
|
|
5435
5587
|
"kind": "function",
|
|
@@ -5596,6 +5748,13 @@
|
|
|
5596
5748
|
"signature": "export interface SchemaReflection {\n /** The Standard Schema validator, when the value implements Standard Schema v1. */\n readonly standard: StandardSchemaV1 | undefined;\n /** Raw JSON Schema metadata, when the value exposes it or is itself a raw JSON Schema. */\n readonly jsonSchema: JsonSchema | undefined;\n /** Top-level object fields, or `undefined` when the JSON Schema is absent/non-object. */\n readonly fields: readonly ReflectedSchemaField[] | undefined;\n}",
|
|
5597
5749
|
"doc": "/** Validation and introspection capabilities discovered for one schema-like value. */"
|
|
5598
5750
|
},
|
|
5751
|
+
{
|
|
5752
|
+
"name": "SchemaSnapshot",
|
|
5753
|
+
"kind": "interface",
|
|
5754
|
+
"package": "@nifrajs/core",
|
|
5755
|
+
"signature": "export interface SchemaSnapshot {\n readonly jsonSchema?: JsonSchema;\n readonly fields?: readonly ReflectedSchemaField[];\n}",
|
|
5756
|
+
"doc": "/** One schema position in a snapshot: JSON Schema metadata only, no validator. */"
|
|
5757
|
+
},
|
|
5599
5758
|
{
|
|
5600
5759
|
"name": "ScoredExample",
|
|
5601
5760
|
"kind": "interface",
|
|
@@ -5735,6 +5894,19 @@
|
|
|
5735
5894
|
"signature": "export declare function serve(app: FetchHandler, options: ServeOptions): Promise<NodeServer>;",
|
|
5736
5895
|
"doc": "/**\n * Serve a Web-`fetch` app on a Node `http` server. Resolves once bound — Node binds\n * the port asynchronously, so awaiting gives you the real port (matters for `port: 0`).\n */"
|
|
5737
5896
|
},
|
|
5897
|
+
{
|
|
5898
|
+
"name": "serveDatabaseAsMcp",
|
|
5899
|
+
"kind": "function",
|
|
5900
|
+
"package": "@nifrajs/mcp-db",
|
|
5901
|
+
"signature": "export declare function serveDatabaseAsMcp(db: SqliteDatabaseLike, options: ServeDatabaseAsMcpOptions): McpServer;",
|
|
5902
|
+
"doc": "/**\n * Serve `db` as a mountable MCP server (`mcp.fetch` at `POST /mcp`). See module docs for the\n * security model. Throws {@link McpDbConfigError} on any unsafe configuration — always at\n * construction (boot), never at request time.\n */"
|
|
5903
|
+
},
|
|
5904
|
+
{
|
|
5905
|
+
"name": "ServeDatabaseAsMcpOptions",
|
|
5906
|
+
"kind": "interface",
|
|
5907
|
+
"package": "@nifrajs/mcp-db",
|
|
5908
|
+
"signature": "export interface ServeDatabaseAsMcpOptions {\n /**\n * REQUIRED allowlist of tables the MCP surface may see. `list_tables`/`describe_table` are\n * restricted to it and `run_query` plans are verified against it. Empty array → construction\n * throws; expose nothing by accident, ever.\n */\n readonly tables: readonly string[];\n /** Enable the `run_query` tool. Omitted → schema tools only. */\n readonly runQuery?: RunQueryOptions;\n /** MCP server identity (defaults: name `nifra-db`, version `1.0.0`). */\n readonly name?: string;\n readonly version?: string;\n /**\n * Set `PRAGMA query_only = ON` on the connection at construction (default true). Disable ONLY\n * when the same connection must also serve writes elsewhere in the app — with it disabled,\n * `run_query` still gates on SELECT/WITH + plan verification, but the engine-level guarantee is\n * yours to provide (e.g. open a second, read-only connection for the MCP mount — preferred).\n */\n readonly enforceQueryOnly?: boolean;\n}"
|
|
5909
|
+
},
|
|
5738
5910
|
{
|
|
5739
5911
|
"name": "ServeOptions",
|
|
5740
5912
|
"kind": "interface",
|
|
@@ -5752,7 +5924,7 @@
|
|
|
5752
5924
|
"name": "Server",
|
|
5753
5925
|
"kind": "class",
|
|
5754
5926
|
"package": "@nifrajs/core",
|
|
5755
|
-
"signature": "export declare class Server<R extends Registry = EmptyRegistry, Ctx = EmptyContext> {\n private readonly router;\n /** WebSocket routes, matched separately at upgrade time (a GET + `Upgrade: websocket`). */\n private readonly wsRouter;\n private wsRouteCount;\n /** In-process pub/sub backing `ws.subscribe(topic)` + `app.publish(topic, data)` (single-instance).\n * Created by the first `app.ws()` via the `@nifrajs/core/ws` runtime — `undefined` until then, so a\n * no-WebSocket app never constructs (or bundles) it. */\n private topics;\n private readonly routeList;\n private readonly maxBodyBytes;\n private readonly wsMaxPayloadBytes;\n private readonly requestTimeoutMs;\n private readonly gracefulSignals;\n private readonly logger;\n /** App-wide validation-error fallback; a route's own `schema.onValidationError` takes precedence. */\n private readonly defaultOnValidationError?;\n private bunServer;\n private readonly derives;\n private readonly decorations;\n private readonly beforeHandleHooks;\n private readonly afterHandleHooks;\n private readonly onErrorHooks;\n private readonly aroundHooks;\n private readonly onRequestHooks;\n private readonly onResponseHooks;\n private readonly responseRequests;\n /** Names of plugins/middleware already applied via `use` — for idempotent dedupe. */\n private readonly appliedPlugins;\n /** App-declared MCP resources / prompts (via {@link resource} / {@link prompt}), read by `nifra mcp`. */\n private readonly mcpResourceList;\n private readonly mcpPromptList;\n constructor(options?: ServerOptions);\n /** Add a per-request, computed context extension for subsequent routes. */\n derive<D extends object>(fn: (context: Context & Ctx) => MaybePromise<D>): Server<R, Ctx & D>;\n /** Add a static context value for subsequent routes. */\n decorate<const K extends string, V>(key: K, value: V): Server<R, Ctx & Record<K, V>>;\n /**\n * Run before routing on the raw request. Return a `Response` to short-circuit, or a replacement\n * `Request` to continue routing with a rewritten method/URL/headers. Global.\n */\n onRequest(fn: (req: Request) => MaybePromise<OnRequestResult>): this;\n /** Run after validation, before the handler; a non-`undefined` return short-circuits. Order-scoped. */\n beforeHandle(fn: (context: Context & Ctx) => MaybePromise<unknown>): this;\n /**\n * Wrap the matched route lifecycle for subsequent routes. This is intentionally generic over the\n * route output, so wrappers like async context storage do not force Node's direct JSON path through\n * a Web `Response`. The first registered wrapper is outermost.\n */\n around(fn: <T>(context: Context & Ctx, next: () => MaybePromise<T>) => MaybePromise<T>): this;\n /** Transform the handler's result before it is serialized. Order-scoped. */\n afterHandle(fn: (result: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Handle a thrown error; a non-`undefined` return becomes the response (else the default 500). Order-scoped. */\n onError(fn: (error: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Transform every outgoing response — success, error, 404, 405, short-circuit. Global. */\n onResponse(fn: (response: Response, req: Request) => MaybePromise<Response>): this;\n /**\n * Apply a type-**identity** plugin ({@link IdentityPlugin}, from {@link defineIdentityPlugin}) — it\n * registers routes/hooks but doesn't change the types, so this returns `this` with the route registry\n * and context fully intact. This overload exists specifically so a *named* identity plugin (e.g.\n * `@nifrajs/better-auth`) threads the registry: its `& { pluginName }` intersection would otherwise\n * defeat the generic inference of the transforming overload below and collapse the result to `any`.\n */\n use(plugin: IdentityPlugin): this;\n /**\n * Apply a **plugin function** — `(app) => app`, typically built with {@link definePlugin}. It's\n * called with `this` and its result is returned, so an inline plugin's `derive`/`decorate` thread\n * the added context to handlers defined after `use` (the overload is generic over the concrete\n * `this`). A named plugin already applied is skipped (idempotent dedupe).\n */\n use<Out extends AnyServer>(plugin: (app: this) => Out): Out;\n /**\n * Apply a {@link Middleware} bundle — wire each hook it provides to its lifecycle point. Returns\n * `this` (no context-type merging); call it before the routes its `beforeHandle`/`afterHandle`\n * should cover (those are order-scoped; `onRequest`/`onResponse` are global). A named bundle already\n * applied is skipped (idempotent).\n */\n use(mw: Middleware): this;\n get<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n get<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n post<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n post<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n put<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n put<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n patch<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n patch<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n delete<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n delete<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n tool<Name extends string, S extends {\n description: string;\n input: StandardSchemaV1;\n output?: StandardSchemaV1;\n annotations?: ToolAnnotations;\n }, H extends (input: InferOutput<S[\"input\"]>, ctx: Context & Ctx) => MaybePromise<S[\"output\"] extends StandardSchemaV1 ? InferOutput<S[\"output\"]> : unknown>>(name: Name, config: S, handler: H): Server<AddRoute<R, \"POST\", `/_nifra/tool/${Name}`, RouteInfoFor<`/_nifra/tool/${Name}`, S[\"output\"] extends StandardSchemaV1 ? {\n body: S[\"input\"];\n response: S[\"output\"];\n } : {\n body: S[\"input\"];\n }, OutputOf<H>>>, Ctx>;\n /**\n * Declare an MCP **resource** — read-only data an agent can fetch through `nifra mcp` (app config, a\n * generated document, …). `read` runs in the app process, so capture whatever app state it needs in the\n * closure. `uri` is the MCP resource identifier (e.g. `\"myapp://config\"`). The sibling of {@link tool}\n * for the resource half of MCP.\n */\n resource(uri: string, config: {\n readonly name: string;\n readonly description?: string;\n readonly mimeType?: string;\n }, read: McpResourceDescriptor[\"read\"]): Server<R, Ctx>;\n /**\n * Declare an MCP **prompt** — a reusable prompt template an agent can fetch through `nifra mcp`.\n * `handler` receives the caller's arguments and returns the rendered messages.\n */\n prompt(name: string, config: {\n readonly description: string;\n readonly arguments?: readonly PromptArgument[];\n }, handler: McpPromptDescriptor[\"handler\"]): Server<R, Ctx>;\n /** The MCP resources declared via {@link resource} — enumerated by `nifra mcp`. */\n mcpResources(): readonly McpResourceDescriptor[];\n /** The MCP prompts declared via {@link prompt} — enumerated by `nifra mcp`. */\n mcpPrompts(): readonly McpPromptDescriptor[];\n /**\n * Register a **WebSocket** route. The connection upgrades on a `GET` to `path` carrying\n * `Upgrade: websocket`; the optional `handler.upgrade(c)` runs in the request context first and may\n * reject (return a `Response`) or seed per-connection `ws.data`. WebSockets are served by the\n * adapter (`listen()`, `@nifrajs/node`, `@nifrajs/deno`, `toFetchHandler`) — not by bare `app.fetch`, which\n * has no socket (a WS path through `app.fetch` is a normal HTTP response).\n *\n * app.ws(\"/chat\", { open: (ws) => ws.send(\"hi\"), message: (ws, data) => ws.send(data) })\n */\n ws<Data = unknown, Schema extends StandardSchemaV1 | undefined = undefined>(path: string, handler: WebSocketHandler<Data, EnvOf<Ctx>, Schema>): this;\n /**\n * Broadcast `data` to every WebSocket connection subscribed to `topic` (via `ws.subscribe(topic)`).\n * In-process and **single-instance** (see {@link TopicRegistry}) — a multi-instance deploy must bridge\n * an external fan-out (Redis, a Durable Object) to this. A no-op when nobody is subscribed.\n */\n publish(topic: string, data: string | ArrayBufferView | ArrayBuffer): void;\n private route;\n /**\n * Low-level route registration shared by the inline builder and `implement()`.\n * Captures the server's current `derive`/`decorate` chain into the route — this\n * is the \"compiled\", order-scoped per-route chain.\n */\n register(method: Method, path: string, schema: RouteSchema | undefined, handler: (context: never) => unknown): void;\n /**\n * Enumerate the registered routes (method, path, input schemas), in registration\n * order. Powers `toOpenAPI` and other introspection; the router trie itself no\n * longer holds the original patterns.\n */\n routes(): ReadonlyArray<RouteDescriptor>;\n /**\n * Resolve a `Request` to a `Response` — the whole lifecycle, testable without a port. The\n * optional `platform` carries edge inputs (`env`, `waitUntil`); edge adapters pass it, and\n * Bun/Node/Deno omit it (then `c.env` is `undefined` and `c.waitUntil` runs fire-and-forget).\n */\n fetch(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<Response>;\n private fetchSource;\n /**\n * Like {@link fetch}, but renders a plain-data result **without** building a Web `Response` — the\n * `@nifrajs/node` adapter serializes the returned primitives straight to the socket, skipping the undici\n * `Response` build + body drain (the bulk of the Node bridge cost, measured ≈4µs/req). A handler that\n * returns a `Response`, an error/short-circuit, or any registered `onResponse` hook falls back to the\n * full Web path (`{ kind: \"response\" }`), so behavior is identical — only the common JSON-data case is\n * faster. Same lifecycle as {@link fetch} (body cap, validation, hooks all run); only the final\n * render differs.\n */\n resolveNode(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<NodeServeOutcome>;\n resolveNodeSource(source: RequestSource, platform?: Platform<EnvOf<Ctx>>): MaybePromise<NodeServeOutcome>;\n /**\n * Resolve a WebSocket upgrade — the seam every serving adapter uses. Returns `pass` (not a WS\n * upgrade for a registered route → handle as normal HTTP), `reject` (a WS route matched but\n * `upgrade()` rejected, or the path was malformed → return `response`), or `upgrade` (perform the\n * runtime upgrade, then dispatch the native socket's events to `handler`, seeding `ws.data` with\n * `data`). Runs the route's `upgrade(c)` guard in a real request context. Synchronous unless\n * `upgrade()` is async; a throw rejects with a flat 500 (no detail leaked).\n */\n resolveWebSocketUpgrade(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<WebSocketUpgradeOutcome>;\n /** Bun `fetch` when WS routes exist: try a WS upgrade first, else run the normal HTTP lifecycle.\n * `undefined` ⇒ Bun owns the upgraded socket; a `Response` ⇒ a normal reply or a rejected upgrade.\n * (The socket dispatch itself lives in `ws-bun.ts`, loaded via `@nifrajs/core/ws`.) */\n private bunFetchWithWebSocket;\n /**\n * The shared lifecycle, generic over how the final value is rendered: `finalize` turns a handler's\n * result + `set` into the output `T` (`toResponse` → a Web `Response`; `toNodeOutcome` → node-direct\n * primitives), `wrapResponse` lifts an early/error `Response` into that same `T`, and `onTimeout`\n * produces the 503. The Web `fetch` and `resolveNode` are thin callers over this one routing +\n * context + lifecycle implementation — no duplication across the trust boundary.\n */\n private dispatch;\n /**\n * onRequest short-circuit path. Synchronous as long as every hook returns synchronously (the\n * common case — e.g. CORS returning `undefined` for a non-preflight request): an `async` version\n * here put EVERY request of any app with one onRequest hook onto the promise machinery, profiled\n * at ~13% of a realistic request. The first hook that returns a Promise hands the REMAINING\n * hooks to the async continuation; behavior is identical.\n */\n private runWithOnRequest;\n /** Async tail of {@link runWithOnRequest}: applies the first awaited hook's outcome, then runs\n * the remaining hooks (awaiting freely — we're already async here). */\n private continueOnRequest;\n private takeResponseRequest;\n /**\n * Route → build context → run. Synchronous through to the handler for a **bare** route\n * ({@link RouteEntry.bare}), so a sync handler produces its result with zero promise allocations;\n * routes with validation/hooks keep the full async {@link runLifecycle}, unchanged.\n */\n private routeAndRun;\n /** The narrowest bare route: a syntactic `() => ...` handler cannot observe the context argument, so\n * successful requests can skip allocating `RequestContext`. Errors still allocate one for logging. */\n private runContextlessBare;\n private contextlessBareError;\n /**\n * The synchronous fast path for a {@link RouteEntry.bare} route: apply static decorations, call the\n * handler, render the result — **no `await`** unless the handler itself returns a promise. It mirrors\n * the bare slice of {@link runLifecycle} (which a bare route would otherwise no-op through) and shares\n * {@link logRequestError}; a bare route has no `onError` hooks, so error handling is fully synchronous\n * (a thrown `Response` is control flow; anything else is a logged flat 500). This is where nifra skips\n * the per-request async-frame tax — the same win codegen routers get, but without `eval`.\n */\n private runBare;\n /** Bare-route error rendering — identical to {@link runLifecycle}'s catch minus the (absent) onError\n * loop: a thrown `Response` is returned as deliberate control flow; anything else is logged + 500. */\n /**\n * Build a route's fused Web lane (see {@link RouteEntry.fusedWeb}). Composition happens once at\n * registration; the returned closure is what every request to the route runs. Behavior is\n * byte-identical to the generic `runBare`/`runContextlessBare` + `toResponse` pair — same\n * decoration order, same error routing (thrown `Response` = control flow; anything else logs and\n * 500s), same respond semantics (the lifecycle parity suite pins it).\n */\n private buildFusedWeb;\n private bareError;\n private runWithAround;\n private runAround;\n private runBodyOnly;\n /** Validate + run the handler for the bodyOnly path — shared by the inline fast path and the\n * streaming fallback. A method (not per-request closures) so the hot path allocates nothing\n * beyond the one `.then` continuation. */\n private finishBodyOnly;\n private executeHandler;\n private handleValidationErrorRecovery;\n private applyBodyValidation;\n private runQueryOnly;\n /** Validate-result → set `ctx.query` → run handler. A method (not a per-request closure), the\n * query analogue of {@link applyBodyValidation}. */\n private applyQueryValidation;\n /**\n * Thread the response through each global `onResponse` hook. Stays SYNCHRONOUS until a hook\n * actually returns a Promise — an `async` version forced a promise + microtask on EVERY response\n * of any app with an onResponse hook (cors/securityHeaders/etag/timing all use onResponse), the\n * same ~13%/req tax the onRequest walk was de-async'd to avoid. The first async hook hands the\n * rest to {@link continueOnResponse}.\n */\n private applyOnResponse;\n /** Async tail of {@link applyOnResponse}: runs the remaining hooks once one has gone async. */\n private continueOnResponse;\n /**\n * Bound the response time. On timeout we abort `ctx.signal` (so cancellation-aware\n * handlers can bail) and return 503; the in-flight work keeps running but its\n * result is discarded — JS can't forcibly cancel a promise.\n */\n private withTimeout;\n /**\n * The post-match lifecycle: validate → derive → beforeHandle → handler → afterHandle, with onError.\n * Generic over the render: a success value goes through `finalize(result, set)` (a Web `Response`, or\n * node-direct primitives); an early/error `Response` (validation, thrown, 500) through `wrapResponse`.\n */\n private runLifecycle;\n private handleLifecycleError;\n /** Log an unhandled request error to the (redacting) logger — shared by {@link runLifecycle} and the\n * bare fast path ({@link bareError}) so both record the same fields. Never throws; never leaks. */\n private logRequestError;\n private readAndValidateBody;\n /**\n * Read the body as text, capped at `maxBodyBytes`. Rejects (`null`) on a\n * `Content-Length` over the cap *before* buffering, and aborts mid-stream once the\n * running byte count exceeds it — so a lying or absent length can't force us to\n * buffer an oversized payload.\n *\n * Fast path: when a non-chunked request carries a `Content-Length` within the cap,\n * a native `req.json()` is already bounded — under HTTP/1.1 + HTTP/2 framing the\n * runtime delivers at most `Content-Length` bytes — so we skip the manual stream\n * loop and a separate text decode. It trusts the wire\n * *framing*, not the header value: nifra only ever receives framed Requests from the\n * runtime's HTTP server, never a hand-built one with a mismatched length. Chunked or\n * length-less bodies fall through to the streaming byte-cap guard below.\n */\n private readBoundedJson;\n /**\n * Start a `Bun.serve` instance bound to `port` (use `0` for an ephemeral port).\n *\n * `reusePort` sets `SO_REUSEPORT` so **multiple processes can bind the same port** and the kernel\n * load-balances connections across them — the standard way to use every core (Bun is\n * single-threaded per process). Spawn one process per core, each calling\n * `app.listen(PORT, { reusePort: true })`; see `examples/cluster.ts`. Every process must opt in,\n * and all of them must be the same app. Linux balances ~evenly; macOS accepts the flag but may\n * favor one socket (fine for dev, measure on Linux for production numbers).\n */\n listen(port: number, options?: {\n readonly reusePort?: boolean;\n }): RunningServer;\n /**\n * Gracefully stop: wait for in-flight requests to finish (up to `drainMs`), then\n * issue a single terminal stop — graceful if everything drained, forced if\n * stragglers remain. Safe to call when not listening.\n *\n * The Bun semantics: poll `pendingRequests` (awaiting\n * `stop()`'s promise drops in-flight requests), and decide graceful-vs-forced in\n * ONE call (Bun can't escalate an already-graceful `stop()` to a forced close).\n * New connections may be accepted during the drain window; in a real deploy the\n * load balancer has already stopped routing here, and `drainMs` bounds it.\n */\n stop({ drainMs }?: {\n drainMs?: number;\n }): Promise<void>;\n private installSignalHandlers;\n}",
|
|
5927
|
+
"signature": "export declare class Server<R extends Registry = EmptyRegistry, Ctx = EmptyContext> {\n private readonly router;\n /** WebSocket routes, matched separately at upgrade time (a GET + `Upgrade: websocket`). */\n private readonly wsRouter;\n private wsRouteCount;\n /** In-process pub/sub backing `ws.subscribe(topic)` + `app.publish(topic, data)` (single-instance).\n * Created by the first `app.ws()` via the `@nifrajs/core/ws` runtime — `undefined` until then, so a\n * no-WebSocket app never constructs (or bundles) it. */\n private topics;\n private readonly routeList;\n private readonly maxBodyBytes;\n private readonly wsMaxPayloadBytes;\n private readonly requestTimeoutMs;\n private readonly gracefulSignals;\n private readonly logger;\n /** App-wide validation-error fallback; a route's own `schema.onValidationError` takes precedence. */\n private readonly defaultOnValidationError?;\n private bunServer;\n private readonly derives;\n private readonly decorations;\n private readonly beforeHandleHooks;\n private readonly afterHandleHooks;\n private readonly onErrorHooks;\n private readonly aroundHooks;\n private readonly onRequestHooks;\n private readonly onResponseHooks;\n private readonly onResponseFinalizedHooks;\n private readonly responseRequests;\n /** Names of plugins/middleware already applied via `use` — for idempotent dedupe. */\n private readonly appliedPlugins;\n /** App-declared MCP resources / prompts (via {@link resource} / {@link prompt}), read by `nifra mcp`. */\n private readonly mcpResourceList;\n private readonly mcpPromptList;\n constructor(options?: ServerOptions);\n /** Add a per-request, computed context extension for subsequent routes. */\n derive<D extends object>(fn: (context: Context & Ctx) => MaybePromise<D>): Server<R, Ctx & D>;\n /** Add a static context value for subsequent routes. */\n decorate<const K extends string, V>(key: K, value: V): Server<R, Ctx & Record<K, V>>;\n /**\n * Run before routing on the raw request. Return a `Response` to short-circuit, or a replacement\n * `Request` to continue routing with a rewritten method/URL/headers. Global.\n */\n onRequest(fn: (req: Request) => MaybePromise<OnRequestResult>): this;\n /** Run after validation, before the handler; a non-`undefined` return short-circuits. Order-scoped. */\n beforeHandle(fn: (context: Context & Ctx) => MaybePromise<unknown>): this;\n /**\n * Wrap the matched route lifecycle for subsequent routes. This is intentionally generic over the\n * route output, so wrappers like async context storage do not force Node's direct JSON path through\n * a Web `Response`. The first registered wrapper is outermost.\n */\n around(fn: <T>(context: Context & Ctx, next: () => MaybePromise<T>) => MaybePromise<T>): this;\n /** Transform the handler's result before it is serialized. Order-scoped. */\n afterHandle(fn: (result: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Handle a thrown error; a non-`undefined` return becomes the response (else the default 500). Order-scoped. */\n onError(fn: (error: unknown, context: Context & Ctx) => MaybePromise<unknown>): this;\n /** Transform every outgoing response — success, error, 404, 405, short-circuit. Global. */\n onResponse(fn: (response: Response, req: Request) => MaybePromise<Response>): this;\n /** Observe the terminal response after all transformations. Observers are ordered and fail-open. */\n onResponseFinalized(fn: (outcome: ResponseFinalization, req: Request) => MaybePromise<void>): this;\n /**\n * Apply a type-**identity** plugin ({@link IdentityPlugin}, from {@link defineIdentityPlugin}) — it\n * registers routes/hooks but doesn't change the types, so this returns `this` with the route registry\n * and context fully intact. This overload exists specifically so a *named* identity plugin (e.g.\n * `@nifrajs/better-auth`) threads the registry: its `& { pluginName }` intersection would otherwise\n * defeat the generic inference of the transforming overload below and collapse the result to `any`.\n */\n use(plugin: IdentityPlugin): this;\n /**\n * Apply a **plugin function** — `(app) => app`, typically built with {@link definePlugin}. It's\n * called with `this` and its result is returned, so an inline plugin's `derive`/`decorate` thread\n * the added context to handlers defined after `use` (the overload is generic over the concrete\n * `this`). A named plugin already applied is skipped (idempotent dedupe).\n */\n use<Out extends AnyServer>(plugin: (app: this) => Out): Out;\n /**\n * Apply a {@link Middleware} bundle — wire each hook it provides to its lifecycle point. Returns\n * `this` (no context-type merging); call it before the routes its `beforeHandle`/`afterHandle`\n * should cover (those are order-scoped; `onRequest`/`onResponse` are global). A named bundle already\n * applied is skipped (idempotent).\n */\n use(mw: Middleware): this;\n get<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n get<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n /**\n * Register a **typed SSE route** — a GET endpoint streaming `text/event-stream` whose event\n * payloads are contracted by `schema.sse`. The handler receives the validated context plus a\n * {@link TypedSSEStream}: `stream.send(event)` is compile-time-checked against the schema and\n * JSON-serialized into the SSE `data:` field. The typed client sees the marker and grows a\n * `.subscribe(onEvent)` for the route with the same payload type — end-to-end typed streaming.\n *\n * const app = server().sse(\"/feed\", { sse: t.object({ id: t.integer(), title: t.string() }) },\n * async (c, stream) => {\n * stream.send({ id: 1, title: \"hello\" }) // typed\n * await waitForDisconnect(stream.signal)\n * },\n * { keepAlive: 15_000 })\n *\n * // client: const off = api.feed.subscribe((post) => console.log(post.title))\n *\n * `init` passes through to the underlying {@link sse} helper (`keepAlive`, extra headers). The\n * connection closes when the handler resolves, `stream.close()` runs, or the client disconnects\n * (`stream.signal`). Query/body schemas validate exactly as on any other route.\n */\n sse<Path extends string, S extends RouteSchema & {\n sse: StandardSchemaV1;\n }>(path: Path, schema: S, run: (context: Context<Path, S> & Ctx, stream: TypedSSEStream<InferOutput<S[\"sse\"]>>) => void | Promise<void>, init?: SSEInit): Server<AddRoute<R, \"GET\", Path, RouteInfoFor<Path, S, Response>>, Ctx>;\n post<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n post<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"POST\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n put<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n put<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PUT\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n patch<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n patch<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"PATCH\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n delete<Path extends string, S extends RouteSchema, H extends Handler<Path, S, Ctx>>(path: Path, schema: S, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, S, OutputOf<H>>>, Ctx>;\n delete<Path extends string, H extends Handler<Path, RouteSchema, Ctx>>(path: Path, handler: H): Server<AddRoute<R, \"DELETE\", Path, RouteInfoFor<Path, Record<never, never>, OutputOf<H>>>, Ctx>;\n tool<Name extends string, S extends {\n description: string;\n input: StandardSchemaV1;\n output?: StandardSchemaV1;\n annotations?: ToolAnnotations;\n }, H extends (input: InferOutput<S[\"input\"]>, ctx: Context & Ctx) => MaybePromise<S[\"output\"] extends StandardSchemaV1 ? InferOutput<S[\"output\"]> : unknown>>(name: Name, config: S, handler: H): Server<AddRoute<R, \"POST\", `/_nifra/tool/${Name}`, RouteInfoFor<`/_nifra/tool/${Name}`, S[\"output\"] extends StandardSchemaV1 ? {\n body: S[\"input\"];\n response: S[\"output\"];\n } : {\n body: S[\"input\"];\n }, OutputOf<H>>>, Ctx>;\n /**\n * Declare an MCP **resource** — read-only data an agent can fetch through `nifra mcp` (app config, a\n * generated document, …). `read` runs in the app process, so capture whatever app state it needs in the\n * closure. `uri` is the MCP resource identifier (e.g. `\"myapp://config\"`). The sibling of {@link tool}\n * for the resource half of MCP.\n */\n resource(uri: string, config: {\n readonly name: string;\n readonly description?: string;\n readonly mimeType?: string;\n }, read: McpResourceDescriptor[\"read\"]): Server<R, Ctx>;\n /**\n * Declare an MCP **prompt** — a reusable prompt template an agent can fetch through `nifra mcp`.\n * `handler` receives the caller's arguments and returns the rendered messages.\n */\n prompt(name: string, config: {\n readonly description: string;\n readonly arguments?: readonly PromptArgument[];\n }, handler: McpPromptDescriptor[\"handler\"]): Server<R, Ctx>;\n /** The MCP resources declared via {@link resource} — enumerated by `nifra mcp`. */\n mcpResources(): readonly McpResourceDescriptor[];\n /** The MCP prompts declared via {@link prompt} — enumerated by `nifra mcp`. */\n mcpPrompts(): readonly McpPromptDescriptor[];\n /**\n * Register a **WebSocket** route. The connection upgrades on a `GET` to `path` carrying\n * `Upgrade: websocket`; the optional `handler.upgrade(c)` runs in the request context first and may\n * reject (return a `Response`) or seed per-connection `ws.data`. WebSockets are served by the\n * adapter (`listen()`, `@nifrajs/node`, `@nifrajs/deno`, `toFetchHandler`) — not by bare `app.fetch`, which\n * has no socket (a WS path through `app.fetch` is a normal HTTP response).\n *\n * app.ws(\"/chat\", { open: (ws) => ws.send(\"hi\"), message: (ws, data) => ws.send(data) })\n */\n ws<Data = unknown, Schema extends StandardSchemaV1 | undefined = undefined>(path: string, handler: WebSocketHandler<Data, EnvOf<Ctx>, Schema>): this;\n /**\n * Broadcast `data` to every WebSocket connection subscribed to `topic` (via `ws.subscribe(topic)`).\n * In-process and **single-instance** (see {@link TopicRegistry}) — a multi-instance deploy must bridge\n * an external fan-out (Redis, a Durable Object) to this. A no-op when nobody is subscribed.\n */\n publish(topic: string, data: string | ArrayBufferView | ArrayBuffer): void;\n private route;\n /**\n * Low-level route registration shared by the inline builder and `implement()`.\n * Captures the server's current `derive`/`decorate` chain into the route — this\n * is the \"compiled\", order-scoped per-route chain.\n */\n register(method: Method, path: string, schema: RouteSchema | undefined, handler: (context: never) => unknown): void;\n /**\n * Enumerate the registered routes (method, path, input schemas), in registration\n * order. Powers `toOpenAPI` and other introspection; the router trie itself no\n * longer holds the original patterns.\n */\n routes(): ReadonlyArray<RouteDescriptor>;\n /**\n * Resolve a `Request` to a `Response` — the whole lifecycle, testable without a port. The\n * optional `platform` carries edge inputs (`env`, `waitUntil`); edge adapters pass it, and\n * Bun/Node/Deno omit it (then `c.env` is `undefined` and `c.waitUntil` runs fire-and-forget).\n */\n fetch(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<Response>;\n private fetchSource;\n /**\n * Like {@link fetch}, but renders a plain-data result **without** building a Web `Response` — the\n * `@nifrajs/node` adapter serializes the returned primitives straight to the socket, skipping the undici\n * `Response` build + body drain (the bulk of the Node bridge cost, measured ≈4µs/req). A handler that\n * returns a `Response`, an error/short-circuit, or any registered `onResponse` hook falls back to the\n * full Web path (`{ kind: \"response\" }`), so behavior is identical — only the common JSON-data case is\n * faster. Same lifecycle as {@link fetch} (body cap, validation, hooks all run); only the final\n * render differs.\n */\n resolveNode(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<NodeServeOutcome>;\n resolveNodeSource(source: RequestSource, platform?: Platform<EnvOf<Ctx>>): MaybePromise<NodeServeOutcome>;\n /**\n * Resolve a WebSocket upgrade — the seam every serving adapter uses. Returns `pass` (not a WS\n * upgrade for a registered route → handle as normal HTTP), `reject` (a WS route matched but\n * `upgrade()` rejected, or the path was malformed → return `response`), or `upgrade` (perform the\n * runtime upgrade, then dispatch the native socket's events to `handler`, seeding `ws.data` with\n * `data`). Runs the route's `upgrade(c)` guard in a real request context. Synchronous unless\n * `upgrade()` is async; a throw rejects with a flat 500 (no detail leaked).\n */\n resolveWebSocketUpgrade(req: Request, platform?: Platform<EnvOf<Ctx>>): MaybePromise<WebSocketUpgradeOutcome>;\n /** Bun `fetch` when WS routes exist: try a WS upgrade first, else run the normal HTTP lifecycle.\n * `undefined` ⇒ Bun owns the upgraded socket; a `Response` ⇒ a normal reply or a rejected upgrade.\n * (The socket dispatch itself lives in `ws-bun.ts`, loaded via `@nifrajs/core/ws`.) */\n private bunFetchWithWebSocket;\n /**\n * The shared lifecycle, generic over how the final value is rendered: `finalize` turns a handler's\n * result + `set` into the output `T` (`toResponse` → a Web `Response`; `toNodeOutcome` → node-direct\n * primitives), `wrapResponse` lifts an early/error `Response` into that same `T`, and `onTimeout`\n * produces the 503. The Web `fetch` and `resolveNode` are thin callers over this one routing +\n * context + lifecycle implementation — no duplication across the trust boundary.\n */\n private dispatch;\n /**\n * onRequest short-circuit path. Synchronous as long as every hook returns synchronously (the\n * common case — e.g. CORS returning `undefined` for a non-preflight request): an `async` version\n * here put EVERY request of any app with one onRequest hook onto the promise machinery, profiled\n * at ~13% of a realistic request. The first hook that returns a Promise hands the REMAINING\n * hooks to the async continuation; behavior is identical.\n */\n private runWithOnRequest;\n /** Async tail of {@link runWithOnRequest}: applies the first awaited hook's outcome, then runs\n * the remaining hooks (awaiting freely — we're already async here). */\n private continueOnRequest;\n private takeResponseRequest;\n /**\n * Route → build context → run. Synchronous through to the handler for a **bare** route\n * ({@link RouteEntry.bare}), so a sync handler produces its result with zero promise allocations;\n * routes with validation/hooks keep the full async {@link runLifecycle}, unchanged.\n */\n private routeAndRun;\n /** The narrowest bare route: a syntactic `() => ...` handler cannot observe the context argument, so\n * successful requests can skip allocating `RequestContext`. Errors still allocate one for logging. */\n private runContextlessBare;\n private contextlessBareError;\n /**\n * The synchronous fast path for a {@link RouteEntry.bare} route: apply static decorations, call the\n * handler, render the result — **no `await`** unless the handler itself returns a promise. It mirrors\n * the bare slice of {@link runLifecycle} (which a bare route would otherwise no-op through) and shares\n * {@link logRequestError}; a bare route has no `onError` hooks, so error handling is fully synchronous\n * (a thrown `Response` is control flow; anything else is a logged flat 500). This is where nifra skips\n * the per-request async-frame tax — the same win codegen routers get, but without `eval`.\n */\n private runBare;\n /** Bare-route error rendering — identical to {@link runLifecycle}'s catch minus the (absent) onError\n * loop: a thrown `Response` is returned as deliberate control flow; anything else is logged + 500. */\n /**\n * Build a route's fused Web lane (see {@link RouteEntry.fusedWeb}). Composition happens once at\n * registration; the returned closure is what every request to the route runs. Behavior is\n * byte-identical to the generic `runBare`/`runContextlessBare` + `toResponse` pair — same\n * decoration order, same error routing (thrown `Response` = control flow; anything else logs and\n * 500s), same respond semantics (the lifecycle parity suite pins it).\n */\n private buildFusedWeb;\n private bareError;\n private runWithAround;\n private runAround;\n private runBodyOnly;\n /** Validate + run the handler for the bodyOnly path — shared by the inline fast path and the\n * streaming fallback. A method (not per-request closures) so the hot path allocates nothing\n * beyond the one `.then` continuation. */\n private finishBodyOnly;\n private executeHandler;\n private handleValidationErrorRecovery;\n private applyBodyValidation;\n private runQueryOnly;\n /** Validate-result → set `ctx.query` → run handler. A method (not a per-request closure), the\n * query analogue of {@link applyBodyValidation}. */\n private applyQueryValidation;\n /**\n * Thread the response through each global `onResponse` hook. Stays SYNCHRONOUS until a hook\n * actually returns a Promise — an `async` version forced a promise + microtask on EVERY response\n * of any app with an onResponse hook (cors/securityHeaders/etag/timing all use onResponse), the\n * same ~13%/req tax the onRequest walk was de-async'd to avoid. The first async hook hands the\n * rest to {@link continueOnResponse}.\n */\n private applyOnResponse;\n private applyOnResponseAndFinalize;\n private completeResponseFinalization;\n private failResponseFinalization;\n /** Notify terminal observers in order while isolating both sync and async failures. */\n private notifyResponseFinalized;\n /** Async tail of {@link applyOnResponse}: runs the remaining hooks once one has gone async. */\n private continueOnResponse;\n /**\n * Bound the response time. On timeout we abort `ctx.signal` (so cancellation-aware\n * handlers can bail) and return 503; the in-flight work keeps running but its\n * result is discarded — JS can't forcibly cancel a promise.\n */\n private withTimeout;\n /**\n * The post-match lifecycle: validate → derive → beforeHandle → handler → afterHandle, with onError.\n * Generic over the render: a success value goes through `finalize(result, set)` (a Web `Response`, or\n * node-direct primitives); an early/error `Response` (validation, thrown, 500) through `wrapResponse`.\n */\n private runLifecycle;\n private handleLifecycleError;\n /** Log an unhandled request error to the (redacting) logger — shared by {@link runLifecycle} and the\n * bare fast path ({@link bareError}) so both record the same fields. Never throws; never leaks. */\n private logRequestError;\n private readAndValidateBody;\n /**\n * Read the body as text, capped at `maxBodyBytes`. Rejects (`null`) on a\n * `Content-Length` over the cap *before* buffering, and aborts mid-stream once the\n * running byte count exceeds it — so a lying or absent length can't force us to\n * buffer an oversized payload.\n *\n * Fast path: when a non-chunked request carries a `Content-Length` within the cap,\n * a native `req.json()` is already bounded — under HTTP/1.1 + HTTP/2 framing the\n * runtime delivers at most `Content-Length` bytes — so we skip the manual stream\n * loop and a separate text decode. It trusts the wire\n * *framing*, not the header value: nifra only ever receives framed Requests from the\n * runtime's HTTP server, never a hand-built one with a mismatched length. Chunked or\n * length-less bodies fall through to the streaming byte-cap guard below.\n */\n private readBoundedJson;\n /**\n * Start a `Bun.serve` instance bound to `port` (use `0` for an ephemeral port).\n *\n * `reusePort` sets `SO_REUSEPORT` so **multiple processes can bind the same port** and the kernel\n * load-balances connections across them — the standard way to use every core (Bun is\n * single-threaded per process). Spawn one process per core, each calling\n * `app.listen(PORT, { reusePort: true })`; see `examples/cluster.ts`. Every process must opt in,\n * and all of them must be the same app. Linux balances ~evenly; macOS accepts the flag but may\n * favor one socket (fine for dev, measure on Linux for production numbers).\n */\n listen(port: number, options?: {\n readonly reusePort?: boolean;\n }): RunningServer;\n /**\n * Gracefully stop: wait for in-flight requests to finish (up to `drainMs`), then\n * issue a single terminal stop — graceful if everything drained, forced if\n * stragglers remain. Safe to call when not listening.\n *\n * The Bun semantics: poll `pendingRequests` (awaiting\n * `stop()`'s promise drops in-flight requests), and decide graceful-vs-forced in\n * ONE call (Bun can't escalate an already-graceful `stop()` to a forced close).\n * New connections may be accepted during the drain window; in a real deploy the\n * load balancer has already stopped routing here, and `drainMs` bounds it.\n */\n stop({ drainMs }?: {\n drainMs?: number;\n }): Promise<void>;\n private installSignalHandlers;\n}",
|
|
5756
5928
|
"doc": "/**\n * The inline server. Routes are chainable and fully type-inferred. `derive`/\n * `decorate` extend the handler context (`Ctx`) for routes defined *after* them,\n * with full types; `Ctx` is server-only and never touches the client registry.\n *\n * app.decorate(\"db\", db).derive((c) => ({ user: auth(c) }))\n * .get(\"/me\", (c) => c.user) // c.user + c.db are typed\n */"
|
|
5757
5929
|
},
|
|
5758
5930
|
{
|
|
@@ -6039,6 +6211,20 @@
|
|
|
6039
6211
|
"signature": "export interface SizeReport {\n /** Per-chunk sizes, sorted biggest gzip first (the regression you want to see at the top). */\n readonly chunks: readonly ChunkSize[];\n /** Sum of every chunk's raw bytes. */\n readonly totalBytes: number;\n /** Sum of every chunk's gzip bytes. */\n readonly totalGzip: number;\n}",
|
|
6040
6212
|
"doc": "/** A whole build's size report — every chunk (largest first) + the totals. */"
|
|
6041
6213
|
},
|
|
6214
|
+
{
|
|
6215
|
+
"name": "SnapshotFile",
|
|
6216
|
+
"kind": "interface",
|
|
6217
|
+
"package": "@nifrajs/cli",
|
|
6218
|
+
"signature": "export interface SnapshotFile {\n readonly nifraSnapshot: 1;\n readonly routes: readonly RouteSnapshot[];\n}",
|
|
6219
|
+
"doc": "/** Snapshot file envelope — versioned so a future format change can migrate instead of misparse. */"
|
|
6220
|
+
},
|
|
6221
|
+
{
|
|
6222
|
+
"name": "snapshotRoutes",
|
|
6223
|
+
"kind": "function",
|
|
6224
|
+
"package": "@nifrajs/core",
|
|
6225
|
+
"signature": "export declare function snapshotRoutes(source: unknown): readonly RouteSnapshot[];",
|
|
6226
|
+
"doc": "/**\n * Snapshot an app's routes (anything `reflectRoutes` accepts) as plain JSON. Validators are\n * dropped; only introspectable JSON Schema metadata is kept, so the result round-trips through\n * `JSON.stringify` unchanged.\n */"
|
|
6227
|
+
},
|
|
6042
6228
|
{
|
|
6043
6229
|
"name": "solidAdapter",
|
|
6044
6230
|
"kind": "const",
|
|
@@ -6088,6 +6274,13 @@
|
|
|
6088
6274
|
"signature": "export declare function splitSections(markdown: string): DocSection[];",
|
|
6089
6275
|
"doc": "/** Split the generated doc into its `##` sections (the `# title` intro becomes \"Overview\"). */"
|
|
6090
6276
|
},
|
|
6277
|
+
{
|
|
6278
|
+
"name": "SqliteDatabaseLike",
|
|
6279
|
+
"kind": "interface",
|
|
6280
|
+
"package": "@nifrajs/mcp-db",
|
|
6281
|
+
"signature": "export interface SqliteDatabaseLike {\n /** Prepare a statement; `all` runs it and returns row objects. */\n prepare(sql: string): {\n all(...params: unknown[]): unknown[];\n };\n /** Execute a statement for its side effect (used only for `PRAGMA query_only`). */\n run(sql: string): unknown;\n}",
|
|
6282
|
+
"doc": "/** The structural slice of `bun:sqlite`'s `Database` this package needs. */"
|
|
6283
|
+
},
|
|
6091
6284
|
{
|
|
6092
6285
|
"name": "sse",
|
|
6093
6286
|
"kind": "function",
|
|
@@ -6382,6 +6575,18 @@
|
|
|
6382
6575
|
"signature": "export interface SubmitOptions {\n /** Re-run the active route's loader after the action settles (default `true`). Set `false` to\n * keep the current `data` and rely on the action's `actionData` alone. */\n readonly revalidate?: boolean;\n}",
|
|
6383
6576
|
"doc": "/** Per-submit options. `revalidate: false` opts out of the post-action loader re-fetch. */"
|
|
6384
6577
|
},
|
|
6578
|
+
{
|
|
6579
|
+
"name": "SubscribeOptions",
|
|
6580
|
+
"kind": "interface",
|
|
6581
|
+
"package": "@nifrajs/client",
|
|
6582
|
+
"signature": "export interface SubscribeOptions<I extends RouteInfo> {\n query?: [I[\"query\"]] extends [never] ? QueryNotTyped : I[\"query\"];\n headers?: Record<string, string>;\n /** Abort to close the subscription (same effect as calling `close()`). */\n signal?: AbortSignal;\n /**\n * Reconnect after a dropped/errored stream (default true — EventSource semantics, so a proxy\n * closing an idle feed doesn't silently kill it). A FINITE stream should pass `false` so a clean\n * server-side end completes the subscription instead of replaying it. Delays follow exponential\n * backoff with jitter, honoring the server's `retry:` hint when sent.\n */\n reconnect?: boolean | {\n baseDelayMs?: number;\n maxDelayMs?: number;\n };\n /** Stream-level failures (network drop, non-2xx, bad JSON). Reconnection continues regardless. */\n onError?: (error: unknown) => void;\n /** The stream ended and no reconnect will follow (clean end with `reconnect: false`, or closed). */\n onClose?: () => void;\n}"
|
|
6583
|
+
},
|
|
6584
|
+
{
|
|
6585
|
+
"name": "Subscription",
|
|
6586
|
+
"kind": "interface",
|
|
6587
|
+
"package": "@nifrajs/client",
|
|
6588
|
+
"signature": "export interface Subscription {\n /** Stop the subscription: aborts the live stream and cancels any pending reconnect. */\n close(): void;\n}"
|
|
6589
|
+
},
|
|
6385
6590
|
{
|
|
6386
6591
|
"name": "svelteAdapter",
|
|
6387
6592
|
"kind": "const",
|
|
@@ -6677,6 +6882,20 @@
|
|
|
6677
6882
|
"signature": "export declare function tsTypeOf(schema: unknown, depth?: number): string;",
|
|
6678
6883
|
"doc": "/**\n * Render a JSON Schema as a compact TypeScript-like type (`{ id: string, name?: string }`) — the\n * shape agents already think in, at a fraction of the raw JSON Schema's tokens (~70-80% smaller).\n * Anything the renderer doesn't model falls back to the raw JSON for that subtree, so the output\n * is always faithful, just not always minimal.\n */"
|
|
6679
6884
|
},
|
|
6885
|
+
{
|
|
6886
|
+
"name": "typedSSEStream",
|
|
6887
|
+
"kind": "function",
|
|
6888
|
+
"package": "@nifrajs/core",
|
|
6889
|
+
"signature": "export declare function typedSSEStream<Event>(stream: SSEStream): TypedSSEStream<Event>;",
|
|
6890
|
+
"doc": "/** Wrap a raw {@link SSEStream} in the typed, JSON-serializing surface `app.sse()` hands out. */"
|
|
6891
|
+
},
|
|
6892
|
+
{
|
|
6893
|
+
"name": "TypedSSEStream",
|
|
6894
|
+
"kind": "interface",
|
|
6895
|
+
"package": "@nifrajs/core",
|
|
6896
|
+
"signature": "export interface TypedSSEStream<Event> {\n /** Send one typed event. `init` sets the optional SSE frame fields (`event`, `id`, `retry`). */\n send(event: Event, init?: Pick<SSEMessage, \"event\" | \"id\" | \"retry\">): void;\n /** Send a `: comment` line (e.g. an explicit ping). */\n comment(text: string): void;\n /** End the stream now. */\n close(): void;\n /** Aborts when the client disconnects — use it to tear down subscriptions/loops. */\n readonly signal: AbortSignal;\n}",
|
|
6897
|
+
"doc": "/**\n * The stream handed to an `app.sse()` handler: `send` takes the route's TYPED event payload and\n * serializes it (JSON) into the SSE `data:` field — the compile-time half of the `sse` contract.\n */"
|
|
6898
|
+
},
|
|
6680
6899
|
{
|
|
6681
6900
|
"name": "TypeEntry",
|
|
6682
6901
|
"kind": "interface",
|
|
@@ -7054,7 +7273,7 @@
|
|
|
7054
7273
|
"name": "VERSION",
|
|
7055
7274
|
"kind": "const",
|
|
7056
7275
|
"package": "@nifrajs/core",
|
|
7057
|
-
"signature": "export declare const VERSION: \"1.
|
|
7276
|
+
"signature": "export declare const VERSION: \"1.6.0\";",
|
|
7058
7277
|
"doc": "/**\n * Current package version. A hardcoded literal on purpose — core runs on the edge (no fs), so it can't\n * read its own package.json at runtime. `scripts/version.ts` rewrites it on every release bump and\n * `check:publish` asserts it equals `@nifrajs/core`'s package version, so the literal can't go stale\n * (it shipped at \"0.0.0\" through 1.0.0 before those guards existed). Kept narrow (`as const`) so\n * consumers can pin it at the type level — see `test/version.test-d.ts`.\n */"
|
|
7059
7278
|
},
|
|
7060
7279
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "The nifra CLI — zero-config dev/build/start for a nifra app (`nifra dev`, `nifra build`, `nifra start`).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@nifrajs/client": "1.
|
|
45
|
-
"@nifrajs/core": "1.
|
|
46
|
-
"@nifrajs/mcp": "1.
|
|
47
|
-
"@nifrajs/runner": "1.
|
|
48
|
-
"@nifrajs/schema": "1.
|
|
49
|
-
"@nifrajs/web": "1.
|
|
50
|
-
"create-nifra": "1.
|
|
44
|
+
"@nifrajs/client": "1.6.0",
|
|
45
|
+
"@nifrajs/core": "1.6.0",
|
|
46
|
+
"@nifrajs/mcp": "1.6.0",
|
|
47
|
+
"@nifrajs/runner": "1.6.0",
|
|
48
|
+
"@nifrajs/schema": "1.6.0",
|
|
49
|
+
"@nifrajs/web": "1.6.0",
|
|
50
|
+
"create-nifra": "1.6.0"
|
|
51
51
|
},
|
|
52
52
|
"repository": {
|
|
53
53
|
"type": "git",
|
package/src/cli.ts
CHANGED
|
@@ -65,6 +65,13 @@ Usage:
|
|
|
65
65
|
nifra check [--json] [--lints-only] Gate: typecheck + lints (hand-rolled fetch(), untyped client("…"),
|
|
66
66
|
server-only imports in routes/). Run as "done"; --json for agents;
|
|
67
67
|
--lints-only skips tsc for a near-instant inner-loop pass.
|
|
68
|
+
nifra snapshot [--out <file>] Write the backend's API contract (routes + schemas) as plain
|
|
69
|
+
JSON — the baseline for \`nifra diff\`. Default api-snapshot.json.
|
|
70
|
+
nifra diff [<baseline>] [--json] Breaking-change gate: re-snapshot the contract and compare
|
|
71
|
+
against the committed baseline. Direction-aware (a new required
|
|
72
|
+
request field or a removed response field breaks; widening a
|
|
73
|
+
request enum or adding a response field doesn't) and fails
|
|
74
|
+
closed. Exits non-zero on any breaking change — run it in CI.
|
|
68
75
|
nifra doctor [--json] [--auto-fix] Flag packages imported in source but missing from package.json
|
|
69
76
|
(resolve at Bun runtime, break tsc + standalone install);
|
|
70
77
|
--auto-fix writes safe local-version dependency fixes.
|
|
@@ -82,7 +89,7 @@ Port: \`dev\` and \`start\` share the default ${DEFAULT_DEV_PORT}. Override with
|
|
|
82
89
|
\`PORT\` env var (\`--port\` wins over \`PORT\`, which wins over the default).`
|
|
83
90
|
|
|
84
91
|
// Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
|
|
85
|
-
const CLI_VERSION = "1.
|
|
92
|
+
const CLI_VERSION = "1.6.0"
|
|
86
93
|
|
|
87
94
|
// A render adapter + nifra server are opaque to the CLI (it just forwards them); cast at the seam.
|
|
88
95
|
const asAdapter = (v: unknown): RenderAdapter => v as RenderAdapter
|
|
@@ -332,6 +339,38 @@ async function main(): Promise<void> {
|
|
|
332
339
|
process.exitCode = 1
|
|
333
340
|
return
|
|
334
341
|
}
|
|
342
|
+
// `snapshot` / `diff` load ONLY backend.ts (the API contract) — like `check`, they must run on an
|
|
343
|
+
// API-only project, so they dispatch before the eager `loadApp`.
|
|
344
|
+
if (command === "snapshot") {
|
|
345
|
+
const { runSnapshot } = await import("./diff-tool.ts")
|
|
346
|
+
const outIdx = argv.indexOf("--out")
|
|
347
|
+
const out = outIdx !== -1 ? argv[outIdx + 1] : undefined
|
|
348
|
+
if (outIdx !== -1 && (out === undefined || out.startsWith("-"))) {
|
|
349
|
+
console.error("[nifra] --out needs a file path")
|
|
350
|
+
process.exitCode = 1
|
|
351
|
+
return
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
await runSnapshot(process.cwd(), out !== undefined ? { out } : {})
|
|
355
|
+
} catch (err) {
|
|
356
|
+
console.error(err instanceof Error ? err.message : String(err))
|
|
357
|
+
process.exitCode = 1
|
|
358
|
+
}
|
|
359
|
+
return
|
|
360
|
+
}
|
|
361
|
+
if (command === "diff") {
|
|
362
|
+
const { runDiff, DEFAULT_SNAPSHOT_FILE } = await import("./diff-tool.ts")
|
|
363
|
+
const baseline = argv.slice(1).find((arg) => !arg.startsWith("-")) ?? DEFAULT_SNAPSHOT_FILE
|
|
364
|
+
try {
|
|
365
|
+
if (!(await runDiff(process.cwd(), baseline, { json: argv.includes("--json") }))) {
|
|
366
|
+
process.exitCode = 1
|
|
367
|
+
}
|
|
368
|
+
} catch (err) {
|
|
369
|
+
console.error(err instanceof Error ? err.message : String(err))
|
|
370
|
+
process.exitCode = 1
|
|
371
|
+
}
|
|
372
|
+
return
|
|
373
|
+
}
|
|
335
374
|
// `port` is a pure cwd-based portability linter (scans source, doesn't run the app) — like `check`/
|
|
336
375
|
// `doctor`, dispatch before the eager `loadApp` so it runs on an API-only / not-yet-built project.
|
|
337
376
|
if (command === "port") {
|
package/src/diff-tool.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nifra snapshot` / `nifra diff` — the API breaking-change gate.
|
|
3
|
+
*
|
|
4
|
+
* nifra snapshot [--out api-snapshot.json] Write the backend's route contract as plain JSON.
|
|
5
|
+
* nifra diff <baseline.json> [--json] Re-snapshot and compare against the committed
|
|
6
|
+
* baseline; exit non-zero on any breaking change.
|
|
7
|
+
*
|
|
8
|
+
* The CI loop: commit a snapshot on main, run `nifra diff api-snapshot.json` on every PR, and an
|
|
9
|
+
* accidental contract break (removed route, new required field, retyped response) fails the build
|
|
10
|
+
* before it ships. Classification lives in `@nifrajs/core/diff` (direction-aware, fails closed);
|
|
11
|
+
* this module only loads `backend.ts` and renders the result.
|
|
12
|
+
*
|
|
13
|
+
* Loads ONLY `backend.ts` — the API contract — so it works on an API-only project with no
|
|
14
|
+
* framework config or routes/ directory (unlike the eager `loadApp`).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { existsSync } from "node:fs"
|
|
18
|
+
import { resolve } from "node:path"
|
|
19
|
+
import {
|
|
20
|
+
diffRouteSnapshots,
|
|
21
|
+
type RouteChange,
|
|
22
|
+
type RouteSnapshot,
|
|
23
|
+
type RoutesDiff,
|
|
24
|
+
snapshotRoutes,
|
|
25
|
+
} from "@nifrajs/core/diff"
|
|
26
|
+
|
|
27
|
+
/** Snapshot file envelope — versioned so a future format change can migrate instead of misparse. */
|
|
28
|
+
export interface SnapshotFile {
|
|
29
|
+
readonly nifraSnapshot: 1
|
|
30
|
+
readonly routes: readonly RouteSnapshot[]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const DEFAULT_SNAPSHOT_FILE = "api-snapshot.json"
|
|
34
|
+
|
|
35
|
+
/** Parse + validate a snapshot file's content. Throws with an actionable message on any mismatch. */
|
|
36
|
+
export function parseSnapshotFile(content: string, sourcePath: string): SnapshotFile {
|
|
37
|
+
let parsed: unknown
|
|
38
|
+
try {
|
|
39
|
+
parsed = JSON.parse(content)
|
|
40
|
+
} catch {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`[nifra] ${sourcePath} is not valid JSON — regenerate it with \`nifra snapshot\`.`,
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
const record = parsed as Partial<SnapshotFile> | null
|
|
46
|
+
if (
|
|
47
|
+
record === null ||
|
|
48
|
+
typeof record !== "object" ||
|
|
49
|
+
record.nifraSnapshot !== 1 ||
|
|
50
|
+
!Array.isArray(record.routes)
|
|
51
|
+
) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`[nifra] ${sourcePath} is not a nifra API snapshot — expected { "nifraSnapshot": 1, "routes": [...] }.`,
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
return record as SnapshotFile
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const SEVERITY_MARK = {
|
|
60
|
+
breaking: "✖ breaking",
|
|
61
|
+
compatible: "✓ compatible",
|
|
62
|
+
info: "ℹ info",
|
|
63
|
+
} as const
|
|
64
|
+
|
|
65
|
+
const describeChange = (change: RouteChange): string => {
|
|
66
|
+
const where = change.section === "route" ? "" : ` ${change.section}`
|
|
67
|
+
return `${SEVERITY_MARK[change.severity]} ${change.method} ${change.path}${where}: ${change.message}`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Render a diff for terminals: breaking first, then info, then compatible. */
|
|
71
|
+
export function formatDiff(diff: RoutesDiff): string {
|
|
72
|
+
if (diff.changes.length === 0) return "No API contract changes."
|
|
73
|
+
const order: Record<RouteChange["severity"], number> = { breaking: 0, info: 1, compatible: 2 }
|
|
74
|
+
const lines = [...diff.changes]
|
|
75
|
+
.sort((a, b) => order[a.severity] - order[b.severity])
|
|
76
|
+
.map(describeChange)
|
|
77
|
+
const breaking = diff.changes.filter((change) => change.severity === "breaking").length
|
|
78
|
+
const summary = diff.hasBreaking
|
|
79
|
+
? `${breaking} breaking change${breaking === 1 ? "" : "s"} — existing clients will fail.`
|
|
80
|
+
: "No breaking changes."
|
|
81
|
+
return `${lines.join("\n")}\n\n${summary}`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Import `backend.ts` from `cwd` and snapshot its routes. */
|
|
85
|
+
async function snapshotBackend(cwd: string): Promise<readonly RouteSnapshot[]> {
|
|
86
|
+
const backendPath = resolve(cwd, "backend.ts")
|
|
87
|
+
if (!existsSync(backendPath)) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`[nifra] no backend.ts in ${cwd} — \`nifra snapshot\`/\`nifra diff\` compare the API contract, which lives in backend.ts.`,
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
const backend = ((await import(backendPath)) as { backend?: unknown }).backend
|
|
93
|
+
if (backend === undefined) {
|
|
94
|
+
throw new Error(`[nifra] ${backendPath} does not export \`backend\`.`)
|
|
95
|
+
}
|
|
96
|
+
return snapshotRoutes(backend)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** `nifra snapshot`: write the current contract as the CI baseline. */
|
|
100
|
+
export async function runSnapshot(cwd: string, options: { out?: string }): Promise<void> {
|
|
101
|
+
const routes = await snapshotBackend(cwd)
|
|
102
|
+
const file: SnapshotFile = { nifraSnapshot: 1, routes }
|
|
103
|
+
const outPath = resolve(cwd, options.out ?? DEFAULT_SNAPSHOT_FILE)
|
|
104
|
+
await Bun.write(outPath, `${JSON.stringify(file, null, 2)}\n`)
|
|
105
|
+
console.log(`[nifra] wrote ${routes.length} route${routes.length === 1 ? "" : "s"} to ${outPath}`)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** `nifra diff`: compare the current contract against a baseline. Returns false on breaking changes. */
|
|
109
|
+
export async function runDiff(
|
|
110
|
+
cwd: string,
|
|
111
|
+
baselinePath: string,
|
|
112
|
+
options: { json?: boolean },
|
|
113
|
+
): Promise<boolean> {
|
|
114
|
+
const resolved = resolve(cwd, baselinePath)
|
|
115
|
+
const baselineFile = Bun.file(resolved)
|
|
116
|
+
if (!(await baselineFile.exists())) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`[nifra] baseline not found: ${resolved} — create it on your main branch with \`nifra snapshot\`.`,
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
const baseline = parseSnapshotFile(await baselineFile.text(), baselinePath)
|
|
122
|
+
const current = await snapshotBackend(cwd)
|
|
123
|
+
const diff = diffRouteSnapshots(baseline.routes, current)
|
|
124
|
+
if (options.json === true) {
|
|
125
|
+
console.log(JSON.stringify({ hasBreaking: diff.hasBreaking, changes: diff.changes }, null, 2))
|
|
126
|
+
} else {
|
|
127
|
+
console.log(formatDiff(diff))
|
|
128
|
+
}
|
|
129
|
+
return !diff.hasBreaking
|
|
130
|
+
}
|
package/src/mcp-http.ts
CHANGED
|
@@ -26,7 +26,7 @@ export { docsTools } from "./mcp-docs-tools.ts"
|
|
|
26
26
|
export type { TypeEntry } from "./types-search.ts"
|
|
27
27
|
|
|
28
28
|
// Kept in lockstep with packages/cli/package.json by check:publish's version-consistency gate.
|
|
29
|
-
const VERSION = "1.
|
|
29
|
+
const VERSION = "1.6.0"
|
|
30
30
|
const SERVER_INFO = { name: "nifra-docs", version: VERSION }
|
|
31
31
|
const DOCS_HEALTH =
|
|
32
32
|
"nifra docs MCP — POST JSON-RPC 2.0 here (methods: initialize, tools/list, tools/call). Tools: nifra_docs, nifra_example."
|