@nifrajs/cli 2.14.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/assure-hydration.d.ts.map +1 -1
- package/dist/assure-hydration.js +6 -1
- package/dist/assure-hydration.js.map +1 -1
- package/dist/assure.d.ts.map +1 -1
- package/dist/assure.js +3 -2
- package/dist/assure.js.map +1 -1
- package/dist/check-diagnostics.d.ts +165 -0
- package/dist/check-diagnostics.d.ts.map +1 -0
- package/dist/check-diagnostics.js +1009 -0
- package/dist/check-diagnostics.js.map +1 -0
- package/dist/check-scan.d.ts +245 -0
- package/dist/check-scan.d.ts.map +1 -0
- package/dist/check-scan.js +1599 -0
- package/dist/check-scan.js.map +1 -0
- package/dist/check.d.ts +4 -324
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +8 -2346
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +285 -10
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.d.ts +27 -1
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +142 -2
- package/dist/command-catalog.js.map +1 -1
- package/dist/doctor.d.ts +42 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +64 -7
- package/dist/doctor.js.map +1 -1
- package/dist/env-file.d.ts +17 -0
- package/dist/env-file.d.ts.map +1 -0
- package/dist/env-file.js +113 -0
- package/dist/env-file.js.map +1 -0
- package/dist/fix-recipes.d.ts.map +1 -1
- package/dist/fix-recipes.js +91 -15
- package/dist/fix-recipes.js.map +1 -1
- package/dist/frontend-guidance.d.ts +57 -0
- package/dist/frontend-guidance.d.ts.map +1 -0
- package/dist/frontend-guidance.js +195 -0
- package/dist/frontend-guidance.js.map +1 -0
- package/dist/internal/reserved-segment-codemod.d.ts +36 -0
- package/dist/internal/reserved-segment-codemod.d.ts.map +1 -0
- package/dist/internal/reserved-segment-codemod.js +134 -0
- package/dist/internal/reserved-segment-codemod.js.map +1 -0
- package/dist/internal/typescript-import.d.ts +1 -1
- package/dist/internal/typescript-import.d.ts.map +1 -1
- package/dist/internal/typescript-import.js +62 -11
- package/dist/internal/typescript-import.js.map +1 -1
- package/dist/introspect.d.ts +26 -1
- package/dist/introspect.d.ts.map +1 -1
- package/dist/introspect.js +74 -24
- package/dist/introspect.js.map +1 -1
- package/dist/levels-tool.d.ts.map +1 -1
- package/dist/levels-tool.js +6 -0
- package/dist/levels-tool.js.map +1 -1
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +4 -1
- package/dist/load.js.map +1 -1
- package/dist/mcp-context.d.ts +48 -0
- package/dist/mcp-context.d.ts.map +1 -0
- package/dist/mcp-context.js +215 -0
- package/dist/mcp-context.js.map +1 -0
- package/dist/mcp-docs-tools.d.ts.map +1 -1
- package/dist/mcp-docs-tools.js +31 -0
- package/dist/mcp-docs-tools.js.map +1 -1
- package/dist/mcp-exec.d.ts +74 -0
- package/dist/mcp-exec.d.ts.map +1 -0
- package/dist/mcp-exec.js +844 -0
- package/dist/mcp-exec.js.map +1 -0
- package/dist/mcp-http.js +1 -1
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp-io.d.ts +26 -0
- package/dist/mcp-io.d.ts.map +1 -0
- package/dist/mcp-io.js +100 -0
- package/dist/mcp-io.js.map +1 -0
- package/dist/mcp-reflect.d.ts +16 -0
- package/dist/mcp-reflect.d.ts.map +1 -0
- package/dist/mcp-reflect.js +101 -0
- package/dist/mcp-reflect.js.map +1 -0
- package/dist/mcp-root.d.ts +7 -0
- package/dist/mcp-root.d.ts.map +1 -1
- package/dist/mcp-root.js +51 -3
- package/dist/mcp-root.js.map +1 -1
- package/dist/mcp.d.ts +10 -84
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +13 -1170
- package/dist/mcp.js.map +1 -1
- package/dist/openapi-tool.d.ts +5 -10
- package/dist/openapi-tool.d.ts.map +1 -1
- package/dist/openapi-tool.js +21 -2
- package/dist/openapi-tool.js.map +1 -1
- package/dist/openapi-types.d.ts +21 -0
- package/dist/openapi-types.d.ts.map +1 -0
- package/dist/openapi-types.js +214 -0
- package/dist/openapi-types.js.map +1 -0
- package/dist/port.d.ts.map +1 -1
- package/dist/port.js +2 -1
- package/dist/port.js.map +1 -1
- package/dist/project-facts.d.ts +2 -1
- package/dist/project-facts.d.ts.map +1 -1
- package/dist/project-facts.js.map +1 -1
- package/dist/recipes/3.0.0.d.ts +10 -0
- package/dist/recipes/3.0.0.d.ts.map +1 -0
- package/dist/recipes/3.0.0.js +23 -0
- package/dist/recipes/3.0.0.js.map +1 -0
- package/dist/recipes/index.d.ts.map +1 -1
- package/dist/recipes/index.js +2 -0
- package/dist/recipes/index.js.map +1 -1
- package/dist/release-verification.d.ts +4 -1
- package/dist/release-verification.d.ts.map +1 -1
- package/dist/release-verification.js +6 -123
- package/dist/release-verification.js.map +1 -1
- package/dist/rules/codes.d.ts +4 -0
- package/dist/rules/codes.d.ts.map +1 -1
- package/dist/rules/codes.js +4 -0
- package/dist/rules/codes.js.map +1 -1
- package/dist/rules/islands.d.ts +4 -0
- package/dist/rules/islands.d.ts.map +1 -0
- package/dist/rules/islands.js +155 -0
- package/dist/rules/islands.js.map +1 -0
- package/dist/rules/nano.d.ts +6 -0
- package/dist/rules/nano.d.ts.map +1 -0
- package/dist/rules/nano.js +264 -0
- package/dist/rules/nano.js.map +1 -0
- package/dist/rules/routes.d.ts.map +1 -1
- package/dist/rules/routes.js +17 -30
- package/dist/rules/routes.js.map +1 -1
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +38 -4
- package/dist/rules/security.js.map +1 -1
- package/dist/scaffold.d.ts +12 -6
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +149 -10
- package/dist/scaffold.js.map +1 -1
- package/dist/search-terms.d.ts.map +1 -1
- package/dist/search-terms.js +5 -3
- package/dist/search-terms.js.map +1 -1
- package/dist/stylex-migrate.d.ts +38 -0
- package/dist/stylex-migrate.d.ts.map +1 -0
- package/dist/stylex-migrate.js +1052 -0
- package/dist/stylex-migrate.js.map +1 -0
- package/dist/sync-manifest.d.ts.map +1 -1
- package/dist/sync-manifest.js +2 -1
- package/dist/sync-manifest.js.map +1 -1
- package/dist/verification-plan.d.ts +24 -0
- package/dist/verification-plan.d.ts.map +1 -0
- package/dist/verification-plan.js +116 -0
- package/dist/verification-plan.js.map +1 -0
- package/dist/work-graph.d.ts.map +1 -1
- package/dist/work-graph.js +6 -3
- package/dist/work-graph.js.map +1 -1
- package/dist/workspace-link.d.ts +37 -0
- package/dist/workspace-link.d.ts.map +1 -0
- package/dist/workspace-link.js +72 -0
- package/dist/workspace-link.js.map +1 -0
- package/docs/examples.json +37 -1
- package/docs/llms-full.txt +1598 -44
- package/docs/types.json +5157 -172
- package/package.json +9 -9
- package/src/assure-hydration.ts +6 -1
- package/src/assure.ts +4 -2
- package/src/check-diagnostics.ts +1219 -0
- package/src/check-scan.ts +1825 -0
- package/src/check.ts +47 -2731
- package/src/cli.ts +291 -10
- package/src/command-catalog.ts +177 -2
- package/src/doctor.ts +99 -8
- package/src/env-file.ts +121 -0
- package/src/fix-recipes.ts +101 -15
- package/src/frontend-guidance.ts +259 -0
- package/src/internal/reserved-segment-codemod.ts +150 -0
- package/src/internal/typescript-import.ts +61 -11
- package/src/introspect.ts +82 -21
- package/src/levels-tool.ts +6 -0
- package/src/load.ts +4 -1
- package/src/mcp-context.ts +266 -0
- package/src/mcp-docs-tools.ts +37 -0
- package/src/mcp-exec.ts +1040 -0
- package/src/mcp-http.ts +1 -1
- package/src/mcp-io.ts +118 -0
- package/src/mcp-reflect.ts +140 -0
- package/src/mcp-root.ts +62 -4
- package/src/mcp.ts +61 -1436
- package/src/openapi-tool.ts +32 -2
- package/src/openapi-types.ts +261 -0
- package/src/port.ts +2 -1
- package/src/project-facts.ts +2 -4
- package/src/recipes/3.0.0.ts +24 -0
- package/src/recipes/index.ts +2 -0
- package/src/release-verification.ts +22 -147
- package/src/rules/codes.ts +4 -0
- package/src/rules/islands.ts +171 -0
- package/src/rules/nano.ts +295 -0
- package/src/rules/routes.ts +17 -30
- package/src/rules/security.ts +40 -4
- package/src/scaffold.ts +169 -9
- package/src/search-terms.ts +7 -3
- package/src/stylex-migrate.ts +1139 -0
- package/src/sync-manifest.ts +2 -1
- package/src/verification-plan.ts +242 -0
- package/src/work-graph.ts +6 -3
- package/src/workspace-link.ts +80 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-facts.js","sourceRoot":"","sources":["../src/project-facts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-facts.js","sourceRoot":"","sources":["../src/project-facts.ts"],"names":[],"mappings":"AA6CA,SAAS,cAAc,CAAmB,QAAsB;IAC9D,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;AAChF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAsB,EACtB,iBAA6C;IAE7C,MAAM,cAAc,GAA0B,MAAM,CAAC,MAAM,CAAC;QAC1D,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;QACpD,cAAc,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;QAClE,cAAc,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;QAClE,cAAc,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;QAClE,eAAe,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;KACrE,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,GAAG,IAAI,CAAC,QAAQ;QAChB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;KACvD,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,IAAI;QACP,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QACnC,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;QAC7C,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;YACtB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC5B,aAAa,EAAE,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;SAC3D,CAAC;QACF,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClF,QAAQ;QACR,cAAc;QACd,iBAAiB,EAAE,cAAc,CAAC,iBAAiB,CAAC;KACrD,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { UpgradeRecipe } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Upgrade recipe for the Nifra 3.0 fixed-group cutover.
|
|
4
|
+
*
|
|
5
|
+
* No package is removed and no import specifier moves this release, so the runner only pins the
|
|
6
|
+
* fixed version group. The two breaking changes are structural - a redirect return value and the
|
|
7
|
+
* reserved typed-client segment types - and stay as explicit notes, one of which points at a codemod.
|
|
8
|
+
*/
|
|
9
|
+
export declare const recipe: UpgradeRecipe;
|
|
10
|
+
//# sourceMappingURL=3.0.0.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"3.0.0.d.ts","sourceRoot":"","sources":["../../src/recipes/3.0.0.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,EAAE,aAcpB,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade recipe for the Nifra 3.0 fixed-group cutover.
|
|
3
|
+
*
|
|
4
|
+
* No package is removed and no import specifier moves this release, so the runner only pins the
|
|
5
|
+
* fixed version group. The two breaking changes are structural - a redirect return value and the
|
|
6
|
+
* reserved typed-client segment types - and stay as explicit notes, one of which points at a codemod.
|
|
7
|
+
*/
|
|
8
|
+
export const recipe = {
|
|
9
|
+
version: "3.0.0",
|
|
10
|
+
pins: [
|
|
11
|
+
{ match: "@nifrajs/", to: "3.0.0" },
|
|
12
|
+
{ match: "create-nifra", to: "3.0.0" },
|
|
13
|
+
{ match: "nifra", to: "3.0.0" },
|
|
14
|
+
],
|
|
15
|
+
importMoves: [],
|
|
16
|
+
notes: [
|
|
17
|
+
"Read the 2.x → 3.0 migration guide: https://nifra.dev/docs/migrate-3.",
|
|
18
|
+
"`redirect(...)` now returns plain render data, not a `Response`. Read it with `.plain` (`{ status, headers, body }`) or `toResponse()`, add headers with the second argument, and assert on `.plain` in tests. `return redirect()` / `throw redirect()` are unchanged, and cookies still apply.",
|
|
19
|
+
"Reserved typed-client segment keys are a frozen contract: a property or bracket access on a reserved-named route segment no longer type-checks. Run `nifra fix --code NF-C018` to rewrite the affected call sites; `nifra routes` annotates a colliding route with the spelling that reaches it.",
|
|
20
|
+
"On Node, `@nifrajs/proxy` defaults to the undici transport. Pass an explicit `transport` to `createProxy` to override it.",
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=3.0.0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"3.0.0.js","sourceRoot":"","sources":["../../src/recipes/3.0.0.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAkB;IACnC,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE;QACnC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,OAAO,EAAE;QACtC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE;KAChC;IACD,WAAW,EAAE,EAAE;IACf,KAAK,EAAE;QACL,uEAAuE;QACvE,iSAAiS;QACjS,kSAAkS;QAClS,2HAA2H;KAC5H;CACF,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipes/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipes/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,0FAA0F;AAC1F,MAAM,WAAW,OAAO;IACtB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACpB;AAED,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,CAAA;IACpD,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAA;IAC3C,qGAAqG;IACrG,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC;AAQD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEpE;AAED,4CAA4C;AAC5C,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C"}
|
package/dist/recipes/index.js
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { recipe as v1_8_0 } from "./1.8.0.js";
|
|
7
7
|
import { recipe as v2_0_0 } from "./2.0.0.js";
|
|
8
|
+
import { recipe as v3_0_0 } from "./3.0.0.js";
|
|
8
9
|
const RECIPES = {
|
|
9
10
|
[v1_8_0.version]: v1_8_0,
|
|
10
11
|
[v2_0_0.version]: v2_0_0,
|
|
12
|
+
[v3_0_0.version]: v3_0_0,
|
|
11
13
|
};
|
|
12
14
|
export function getRecipe(version) {
|
|
13
15
|
return RECIPES[version];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recipes/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AAgC7C,MAAM,OAAO,GAAkC;IAC7C,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM;IACxB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM;CACzB,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;AACzB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACnE,CAAC;AAED,SAAS,eAAe,CAAC,CAAS,EAAE,CAAS;IAC3C,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QACxC,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;IAC7B,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recipes/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AAgC7C,MAAM,OAAO,GAAkC;IAC7C,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM;IACxB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM;IACxB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM;CACzB,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;AACzB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACnE,CAAC;AAED,SAAS,eAAe,CAAC,CAAS,EAAE,CAAS;IAC3C,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QACxC,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;IAC7B,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* This module is intentionally independent from app loading. The root package scripts and the
|
|
5
5
|
* `nifra verify` command both call this runner, so the local and CI paths share one gate plan.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
import { type VerificationPlanMode } from "./verification-plan.js";
|
|
8
|
+
export type ReleaseVerificationMode = VerificationPlanMode;
|
|
8
9
|
export type ReleaseGateStatus = "pass" | "fail" | "skipped";
|
|
9
10
|
export interface ReleaseGateResult {
|
|
10
11
|
readonly id: string;
|
|
@@ -18,6 +19,8 @@ export interface ReleaseVerificationResult {
|
|
|
18
19
|
readonly ok: boolean;
|
|
19
20
|
readonly mode: ReleaseVerificationMode;
|
|
20
21
|
readonly gates: readonly ReleaseGateResult[];
|
|
22
|
+
/** Release gates intentionally absent from the selected shorter plan. */
|
|
23
|
+
readonly omittedReleaseGateIds: readonly string[];
|
|
21
24
|
}
|
|
22
25
|
export interface ReleaseCommandResult {
|
|
23
26
|
readonly exitCode: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-verification.d.ts","sourceRoot":"","sources":["../src/release-verification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"release-verification.d.ts","sourceRoot":"","sources":["../src/release-verification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAGL,KAAK,oBAAoB,EAE1B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAA;AAC1D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;AAE3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAA;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAC5C,yEAAyE;IACzE,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAA;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CACjD;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,CAAC,EAAE,uBAAuB,CAAA;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAA;CAClF;AA8DD,uFAAuF;AACvF,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa5E;AAsDD,uFAAuF;AACvF,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,yBAAyB,CAAC,CA0BpC;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAiBnF;AAED,yEAAyE;AACzE,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,0BAA0B,GAAG;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GACrE,OAAO,CAAC,OAAO,CAAC,CAKlB"}
|
|
@@ -7,128 +7,7 @@
|
|
|
7
7
|
import { mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
9
9
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
10
|
-
|
|
11
|
-
{
|
|
12
|
-
id: "lint",
|
|
13
|
-
commands: [["run", "lint"]],
|
|
14
|
-
remediation: "Run `bun run lint` and fix the reported lint findings.",
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
id: "typecheck",
|
|
18
|
-
commands: [["run", "typecheck"]],
|
|
19
|
-
remediation: "Run `bun run typecheck` and fix the reported TypeScript errors.",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
id: "tests",
|
|
23
|
-
commands: [["run", "test"]],
|
|
24
|
-
remediation: "Run `bun run test` and fix the first failing test.",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: "docs",
|
|
28
|
-
commands: [["run", "check:docs"]],
|
|
29
|
-
remediation: "Run `bun run check:docs` and update the failing documentation example.",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: "api-corpus",
|
|
33
|
-
commands: [["run", "check:api"]],
|
|
34
|
-
remediation: "Run `bun run gen:api` and review the generated API reference.",
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: "cards-corpus",
|
|
38
|
-
commands: [["run", "check:cards"]],
|
|
39
|
-
remediation: "Run `bun run gen:cards` and review the generated package cards.",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
id: "node-outcome-corpus",
|
|
43
|
-
commands: [["run", "check:node-outcome"]],
|
|
44
|
-
remediation: "Run `bun run gen:node-outcome` and review the generated Node outcome contract.",
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: "sitemap",
|
|
48
|
-
commands: [["run", "check:sitemap"]],
|
|
49
|
-
remediation: "Run `bun run gen:sitemap` and review the generated sitemap.",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
id: "public-boundary",
|
|
53
|
-
commands: [["run", "check:public-boundary"]],
|
|
54
|
-
remediation: "Run `bun run check:public-boundary` and remove the reported public-boundary violation.",
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
id: "size",
|
|
58
|
-
commands: [["run", "check:size"]],
|
|
59
|
-
remediation: "Run `bun run check:size` and either reduce the bundle or update the reviewed budget.",
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
const RELEASE_GATES = [
|
|
63
|
-
{
|
|
64
|
-
id: "build",
|
|
65
|
-
commands: [["run", "build"]],
|
|
66
|
-
remediation: "Run `bun run build` and fix the first package build failure.",
|
|
67
|
-
},
|
|
68
|
-
...DEFAULT_GATES.slice(0, 3),
|
|
69
|
-
{
|
|
70
|
-
id: "coverage",
|
|
71
|
-
commands: [
|
|
72
|
-
["run", "test:coverage"],
|
|
73
|
-
["run", "check:coverage"],
|
|
74
|
-
],
|
|
75
|
-
remediation: "Run `bun run test:coverage` first, then `bun run check:coverage`, and fix the reported coverage regression.",
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
id: "corpus",
|
|
79
|
-
commands: [["run", "check:corpus"]],
|
|
80
|
-
remediation: "Run `bun run gen:llms`, `bun run gen:api`, and `bun run gen:cards`, then rerun the corpus gate.",
|
|
81
|
-
},
|
|
82
|
-
DEFAULT_GATES[3],
|
|
83
|
-
{
|
|
84
|
-
id: "public-boundary",
|
|
85
|
-
commands: [["run", "check:public-boundary"]],
|
|
86
|
-
remediation: "Run `bun run check:public-boundary` and remove the reported public-boundary violation.",
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
id: "size",
|
|
90
|
-
commands: [["run", "check:size"]],
|
|
91
|
-
remediation: "Run `bun run check:size` and either reduce the bundle or update the reviewed budget.",
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
id: "core-performance",
|
|
95
|
-
commands: [["run", "check:core-performance"]],
|
|
96
|
-
remediation: "Run `bun run check:core-performance` and investigate the measured performance regression.",
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
id: "publish",
|
|
100
|
-
commands: [["run", "check:publish"]],
|
|
101
|
-
remediation: "Run `bun run check:publish` and fix the publish-consumer metadata or type-surface failure.",
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
id: "consumer",
|
|
105
|
-
commands: [["run", "check:consumers"]],
|
|
106
|
-
remediation: "Run `bun run check:consumers` and fix the isolated consumer failure.",
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
id: "cold-start",
|
|
110
|
-
commands: [["run", "check:cold-start"]],
|
|
111
|
-
remediation: "Run `bun run check:cold-start` and fix the fresh scaffold install or build failure.",
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: "cross-runtime-deno",
|
|
115
|
-
commands: [
|
|
116
|
-
["run", "test:deno"],
|
|
117
|
-
["run", "check:deno-tarball"],
|
|
118
|
-
],
|
|
119
|
-
remediation: "Run `bun run test:deno` and `bun run check:deno-tarball`, then fix the first Deno compatibility failure.",
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
id: "cross-runtime-node",
|
|
123
|
-
commands: [["run", "test:node"]],
|
|
124
|
-
remediation: "Run `bun run test:node` and fix the Node runtime adapter failure.",
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
id: "pipeline-parity",
|
|
128
|
-
commands: [["run", "check:pipeline-parity"]],
|
|
129
|
-
remediation: "Run `bun run check:pipeline-parity` and fix the development and production manifest drift.",
|
|
130
|
-
},
|
|
131
|
-
];
|
|
10
|
+
import { omittedVerificationGateIds, verificationPlan, } from "./verification-plan.js";
|
|
132
11
|
const runBunCommand = async (spec) => {
|
|
133
12
|
const child = Bun.spawn([process.execPath, ...spec.args], {
|
|
134
13
|
cwd: spec.cwd,
|
|
@@ -198,7 +77,7 @@ export async function resolveVerificationRoot(start) {
|
|
|
198
77
|
current = parent;
|
|
199
78
|
}
|
|
200
79
|
}
|
|
201
|
-
const gatePlan = (mode) => mode
|
|
80
|
+
const gatePlan = (mode) => verificationPlan(mode);
|
|
202
81
|
const commandLabel = (args) => `bun ${args.join(" ")}`;
|
|
203
82
|
const runGate = async (root, gate, runCommand, fixtureRoot) => {
|
|
204
83
|
let lastExitCode;
|
|
@@ -267,6 +146,7 @@ export async function collectReleaseVerification(start, options = {}) {
|
|
|
267
146
|
ok: gates.every((gate) => gate.status === "pass"),
|
|
268
147
|
mode,
|
|
269
148
|
gates,
|
|
149
|
+
omittedReleaseGateIds: omittedVerificationGateIds(mode),
|
|
270
150
|
};
|
|
271
151
|
}
|
|
272
152
|
export function renderReleaseVerification(result) {
|
|
@@ -279,6 +159,9 @@ export function renderReleaseVerification(result) {
|
|
|
279
159
|
if (gate.status !== "pass")
|
|
280
160
|
lines.push(` fix: ${gate.remediation}`);
|
|
281
161
|
}
|
|
162
|
+
if (result.omittedReleaseGateIds.length > 0) {
|
|
163
|
+
lines.push("", `note: default verification omits release gates: ${result.omittedReleaseGateIds.join(", ")}`, " run `bun run check:release` for the full release gate.");
|
|
164
|
+
}
|
|
282
165
|
lines.push("", result.ok ? "✓ verification passed" : "✗ verification failed");
|
|
283
166
|
return lines.join("\n");
|
|
284
167
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-verification.js","sourceRoot":"","sources":["../src/release-verification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"release-verification.js","sourceRoot":"","sources":["../src/release-verification.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/codes.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export declare const RULE_CODES: Readonly<{
|
|
|
19
19
|
readonly "NF-C017": "Rule pack validation";
|
|
20
20
|
readonly "NF-C018": "Reserved client segment check";
|
|
21
21
|
readonly "NF-C019": "Duplicate route registration check";
|
|
22
|
+
readonly "NF-C020": "Island enhancer cleanup check";
|
|
23
|
+
readonly "NF-C021": "nano binding cleanup check";
|
|
24
|
+
readonly "NF-C022": "nano bindList key check";
|
|
25
|
+
readonly "NF-C023": "nano computed deps check";
|
|
22
26
|
readonly "NF-D001": "Doctor check";
|
|
23
27
|
readonly "NF-A001": "Assurance bundle check";
|
|
24
28
|
readonly "NF-H001": "Hydration mismatch";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../src/rules/codes.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAE/F,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../src/rules/codes.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAE/F,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCZ,CAAA;AAEX,6DAA6D;AAC7D,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAAa,CAAA;AAE3D,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,UAAU,CAAA;AAEjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,WAAW,CAE/D;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAO5C"}
|
package/dist/rules/codes.js
CHANGED
|
@@ -19,6 +19,10 @@ export const RULE_CODES = Object.freeze({
|
|
|
19
19
|
"NF-C017": "Rule pack validation",
|
|
20
20
|
"NF-C018": "Reserved client segment check",
|
|
21
21
|
"NF-C019": "Duplicate route registration check",
|
|
22
|
+
"NF-C020": "Island enhancer cleanup check",
|
|
23
|
+
"NF-C021": "nano binding cleanup check",
|
|
24
|
+
"NF-C022": "nano bindList key check",
|
|
25
|
+
"NF-C023": "nano computed deps check",
|
|
22
26
|
"NF-D001": "Doctor check",
|
|
23
27
|
"NF-A001": "Assurance bundle check",
|
|
24
28
|
"NF-H001": "Hydration mismatch",
|
package/dist/rules/codes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codes.js","sourceRoot":"","sources":["../../src/rules/codes.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAE/F,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,SAAS,EAAE,2BAA2B;IACtC,SAAS,EAAE,oBAAoB;IAC/B,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,0BAA0B;IACrC,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,wBAAwB;IACnC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,yBAAyB;IACpC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,4BAA4B;IACvC,SAAS,EAAE,4BAA4B;IACvC,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,2BAA2B;IACtC,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,oCAAoC;IAC/C,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,wBAAwB;IACnC,SAAS,EAAE,oBAAoB;IAC/B,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,oBAAoB;IAC/B,SAAS,EAAE,uBAAuB;IAClC,SAAS,EAAE,yBAAyB;IACpC,SAAS,EAAE,gBAAgB;IAC3B,SAAS,EAAE,qCAAqC;IAChD,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,0CAA0C;IACrD,SAAS,EAAE,2BAA2B;IACtC,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,kDAAkD;CACrD,CAAC,CAAA;AAEX,6DAA6D;AAC7D,MAAM,CAAC,MAAM,aAAa,GAAwB,IAAI,GAAG,EAAE,CAAA;AAI3D,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,IAAI,UAAU,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM;QACtC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAA;IACjG,CAAC;AACH,CAAC;AAED,qBAAqB,EAAE,CAAA"}
|
|
1
|
+
{"version":3,"file":"codes.js","sourceRoot":"","sources":["../../src/rules/codes.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAE/F,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,SAAS,EAAE,2BAA2B;IACtC,SAAS,EAAE,oBAAoB;IAC/B,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,0BAA0B;IACrC,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,wBAAwB;IACnC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,yBAAyB;IACpC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,4BAA4B;IACvC,SAAS,EAAE,4BAA4B;IACvC,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,2BAA2B;IACtC,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,oCAAoC;IAC/C,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,4BAA4B;IACvC,SAAS,EAAE,yBAAyB;IACpC,SAAS,EAAE,0BAA0B;IACrC,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,wBAAwB;IACnC,SAAS,EAAE,oBAAoB;IAC/B,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,oBAAoB;IAC/B,SAAS,EAAE,uBAAuB;IAClC,SAAS,EAAE,yBAAyB;IACpC,SAAS,EAAE,gBAAgB;IAC3B,SAAS,EAAE,qCAAqC;IAChD,SAAS,EAAE,6BAA6B;IACxC,SAAS,EAAE,0CAA0C;IACrD,SAAS,EAAE,2BAA2B;IACtC,SAAS,EAAE,+BAA+B;IAC1C,SAAS,EAAE,kDAAkD;CACrD,CAAC,CAAA;AAEX,6DAA6D;AAC7D,MAAM,CAAC,MAAM,aAAa,GAAwB,IAAI,GAAG,EAAE,CAAA;AAI3D,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,IAAI,UAAU,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM;QACtC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAA;IACjG,CAAC;AACH,CAAC;AAED,qBAAqB,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"islands.d.ts","sourceRoot":"","sources":["../../src/rules/islands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,YAAY,CAAA;AAyHxD,eAAO,MAAM,iBAAiB,EAAE,SA4C/B,CAAA;AAED,eAAO,MAAM,WAAW,sBAAqC,CAAA"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { diagnostic } from "../diagnostics.js";
|
|
2
|
+
import { importProjectTypeScript } from "../internal/typescript-import.js";
|
|
3
|
+
/**
|
|
4
|
+
* NF-C020 - the island cleanup lint. An island enhancer (`@nifrajs/web/islands`) runs once and must
|
|
5
|
+
* hand back a teardown for anything it wires: `mountIslands`'s disposer calls it on soft-nav, and
|
|
6
|
+
* without it every navigation leaks the listener. This is the single mistake an agent writing
|
|
7
|
+
* imperative island code makes most - it adds `el.addEventListener(...)` and forgets the `return`.
|
|
8
|
+
* The lint watches the two authoring shapes and warns (never blocks) when a block-body enhancer adds
|
|
9
|
+
* a listener but returns no cleanup:
|
|
10
|
+
*
|
|
11
|
+
* defineIsland((el) => { el.addEventListener("click", f) }) // ← flagged: no cleanup
|
|
12
|
+
* defineIsland((el) => { el.addEventListener("click", f); return () => el.removeEventListener("click", f) }) // ok
|
|
13
|
+
* mountIslands({ x: (el) => { el.addEventListener("click", f) } }) // ← flagged
|
|
14
|
+
*
|
|
15
|
+
* Deliberately conservative to stay false-positive-free: a concise-body arrow (`(el) => bus.on(...)`)
|
|
16
|
+
* already IS a returned value, so it is never flagged; a block that returns anything is trusted as
|
|
17
|
+
* cleanup; only an inline function literal is inspected (a `defineIsland(...)` result referenced by
|
|
18
|
+
* name is caught at its definition site, never twice).
|
|
19
|
+
*/
|
|
20
|
+
const parseCache = new WeakMap();
|
|
21
|
+
function parsedTree(ts, sources, file) {
|
|
22
|
+
let files = parseCache.get(sources);
|
|
23
|
+
if (files === undefined) {
|
|
24
|
+
files = new Map();
|
|
25
|
+
parseCache.set(sources, files);
|
|
26
|
+
}
|
|
27
|
+
const cached = files.get(file);
|
|
28
|
+
if (cached !== undefined)
|
|
29
|
+
return cached?.tree;
|
|
30
|
+
const source = sources.read(file);
|
|
31
|
+
if (source === undefined) {
|
|
32
|
+
files.set(file, null);
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const kind = /\.tsx?$/.test(file) ? ts.ScriptKind.TSX : ts.ScriptKind.JS;
|
|
36
|
+
const tree = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true, kind);
|
|
37
|
+
files.set(file, { tree });
|
|
38
|
+
return tree;
|
|
39
|
+
}
|
|
40
|
+
function isEnhancerFn(ts, node) {
|
|
41
|
+
return ts.isArrowFunction(node) || ts.isFunctionExpression(node);
|
|
42
|
+
}
|
|
43
|
+
/** Any `<expr>.addEventListener(...)` reachable inside the enhancer (nested handlers included - the
|
|
44
|
+
* presence of the wiring is what matters, not its depth). */
|
|
45
|
+
function addsListener(ts, fn) {
|
|
46
|
+
let found = false;
|
|
47
|
+
const walk = (node) => {
|
|
48
|
+
if (found)
|
|
49
|
+
return;
|
|
50
|
+
if (ts.isCallExpression(node) &&
|
|
51
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
52
|
+
node.expression.name.text === "addEventListener") {
|
|
53
|
+
found = true;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
ts.forEachChild(node, walk);
|
|
57
|
+
};
|
|
58
|
+
ts.forEachChild(fn, walk);
|
|
59
|
+
return found;
|
|
60
|
+
}
|
|
61
|
+
/** Does the enhancer hand back a value? A concise-body arrow always does. A block body counts only a
|
|
62
|
+
* `return <expr>` that is NOT inside a nested function (a nested handler's return is not the
|
|
63
|
+
* enhancer's cleanup). */
|
|
64
|
+
function returnsCleanup(ts, fn) {
|
|
65
|
+
if (ts.isArrowFunction(fn) && !ts.isBlock(fn.body))
|
|
66
|
+
return true; // concise body IS the return value
|
|
67
|
+
let found = false;
|
|
68
|
+
const walk = (node) => {
|
|
69
|
+
if (found)
|
|
70
|
+
return;
|
|
71
|
+
if (isEnhancerFn(ts, node) || ts.isFunctionDeclaration(node))
|
|
72
|
+
return; // don't descend into nested fns
|
|
73
|
+
if (ts.isReturnStatement(node) && node.expression !== undefined) {
|
|
74
|
+
found = true;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
ts.forEachChild(node, walk);
|
|
78
|
+
};
|
|
79
|
+
ts.forEachChild(fn, walk);
|
|
80
|
+
return found;
|
|
81
|
+
}
|
|
82
|
+
/** The inline enhancer functions authored in `file`: the argument to `defineIsland(...)` and every
|
|
83
|
+
* function-typed value of a `mountIslands({ ... })` object literal. */
|
|
84
|
+
function enhancerFns(ts, tree) {
|
|
85
|
+
const out = [];
|
|
86
|
+
const visit = (node) => {
|
|
87
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
|
|
88
|
+
const callee = node.expression.text;
|
|
89
|
+
if (callee === "defineIsland") {
|
|
90
|
+
const arg = node.arguments[0];
|
|
91
|
+
if (arg !== undefined && isEnhancerFn(ts, arg))
|
|
92
|
+
out.push(arg);
|
|
93
|
+
}
|
|
94
|
+
else if (callee === "mountIslands") {
|
|
95
|
+
const arg = node.arguments[0];
|
|
96
|
+
if (arg !== undefined && ts.isObjectLiteralExpression(arg)) {
|
|
97
|
+
for (const prop of arg.properties) {
|
|
98
|
+
// Only inline function literals `{ x: (el) => {…} }` are inspected. A shorthand method
|
|
99
|
+
// `{ x(el) {…} }` or a named reference `{ x: counter }` is left to its definition site.
|
|
100
|
+
if (ts.isPropertyAssignment(prop) && isEnhancerFn(ts, prop.initializer))
|
|
101
|
+
out.push(prop.initializer);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
ts.forEachChild(node, visit);
|
|
107
|
+
};
|
|
108
|
+
visit(tree);
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
export const islandCleanupRule = {
|
|
112
|
+
code: "NF-C020",
|
|
113
|
+
title: "Island enhancer cleanup check",
|
|
114
|
+
async scan(ctx) {
|
|
115
|
+
const ts = await importProjectTypeScript(ctx.root);
|
|
116
|
+
if (ts === undefined) {
|
|
117
|
+
return [
|
|
118
|
+
diagnostic({
|
|
119
|
+
code: "NF-C020",
|
|
120
|
+
severity: "warn",
|
|
121
|
+
message: "Island enhancer cleanup check (NF-C020) did NOT run - TypeScript is not installed, so this report says nothing about it",
|
|
122
|
+
fix: { recipe: "toolchain.install-typescript", command: "bun add -d typescript" },
|
|
123
|
+
verify: "nifra check --lints-only",
|
|
124
|
+
}),
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
const findings = [];
|
|
128
|
+
for (const file of ctx.project.source.files) {
|
|
129
|
+
const tree = parsedTree(ts, ctx.project.source, file);
|
|
130
|
+
if (tree === undefined)
|
|
131
|
+
continue;
|
|
132
|
+
for (const fn of enhancerFns(ts, tree)) {
|
|
133
|
+
if (!addsListener(ts, fn) || returnsCleanup(ts, fn))
|
|
134
|
+
continue;
|
|
135
|
+
const line = tree.getLineAndCharacterOfPosition(fn.getStart(tree)).line + 1;
|
|
136
|
+
findings.push(diagnostic({
|
|
137
|
+
code: "NF-C020",
|
|
138
|
+
severity: "warn",
|
|
139
|
+
file,
|
|
140
|
+
line,
|
|
141
|
+
message: "island enhancer adds an event listener but returns no cleanup - it leaks on soft-nav teardown",
|
|
142
|
+
evidence: ["addEventListener without a returned cleanup"],
|
|
143
|
+
fix: {
|
|
144
|
+
recipe: "islands.return-cleanup",
|
|
145
|
+
command: "nifra_docs islands",
|
|
146
|
+
},
|
|
147
|
+
verify: "nifra check --lints-only",
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return findings;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
export const islandRules = Object.freeze([islandCleanupRule]);
|
|
155
|
+
//# sourceMappingURL=islands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"islands.js","sourceRoot":"","sources":["../../src/rules/islands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CheckRule } from "./index.js";
|
|
2
|
+
export declare const nanoBindCleanupRule: CheckRule;
|
|
3
|
+
export declare const nanoListKeyRule: CheckRule;
|
|
4
|
+
export declare const nanoComputedDepsRule: CheckRule;
|
|
5
|
+
export declare const nanoRules: readonly CheckRule[];
|
|
6
|
+
//# sourceMappingURL=nano.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nano.d.ts","sourceRoot":"","sources":["../../src/rules/nano.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,YAAY,CAAA;AAgKxD,eAAO,MAAM,mBAAmB,EAAE,SAsCjC,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,SAuC7B,CAAA;AAED,eAAO,MAAM,oBAAoB,EAAE,SAgDlC,CAAA;AAED,eAAO,MAAM,SAAS,sBAA8E,CAAA"}
|