@nifrajs/ts-plugin 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.cjs +16 -6
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +14 -6
- package/dist/resolve.js.map +1 -1
- package/dist/zones.d.ts.map +1 -1
- package/dist/zones.js +9 -3
- package/dist/zones.js.map +1 -1
- package/package.json +3 -3
- package/src/resolve.ts +13 -6
- package/src/zones.ts +9 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nifra Authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -50,13 +50,20 @@ var import_fs = require("@nifrajs/web/fs");
|
|
|
50
50
|
|
|
51
51
|
// src/resolve.ts
|
|
52
52
|
var import_pattern = require("@nifrajs/core/pattern");
|
|
53
|
-
var compiledRouteCache = new
|
|
53
|
+
var compiledRouteCache = new Map;
|
|
54
|
+
var MAX_CACHED_ROUTE_SETS = 8;
|
|
54
55
|
function compiledRoutes(routes) {
|
|
55
|
-
const
|
|
56
|
+
const key = JSON.stringify(routes.map((route) => [route.pattern, route.file]));
|
|
57
|
+
const cached = compiledRouteCache.get(key);
|
|
56
58
|
if (cached !== undefined)
|
|
57
59
|
return cached;
|
|
58
60
|
const compiled = import_pattern.sortRoutesBySpecificity(routes.map((route) => ({ route, pattern: import_pattern.compileRoutePattern(route.pattern) })));
|
|
59
|
-
compiledRouteCache.
|
|
61
|
+
if (compiledRouteCache.size >= MAX_CACHED_ROUTE_SETS) {
|
|
62
|
+
const oldest = compiledRouteCache.keys().next();
|
|
63
|
+
if (oldest.done !== true)
|
|
64
|
+
compiledRouteCache.delete(oldest.value);
|
|
65
|
+
}
|
|
66
|
+
compiledRouteCache.set(key, compiled);
|
|
60
67
|
return compiled;
|
|
61
68
|
}
|
|
62
69
|
function resolveRouteFile(path, routes) {
|
|
@@ -113,7 +120,10 @@ function valueImports(tsm, source) {
|
|
|
113
120
|
return edges;
|
|
114
121
|
}
|
|
115
122
|
function resolveImport(tsm, source, edge, options) {
|
|
116
|
-
const
|
|
123
|
+
const query = edge.specifier.indexOf("?", 1);
|
|
124
|
+
const hash = edge.specifier.indexOf("#", 1);
|
|
125
|
+
const cut = query === -1 ? hash : hash === -1 ? query : Math.min(query, hash);
|
|
126
|
+
const specifier = cut === -1 ? edge.specifier : edge.specifier.slice(0, cut);
|
|
117
127
|
const mode = tsm.getModeForUsageLocation(source, edge.literal, options);
|
|
118
128
|
const resolved = tsm.resolveModuleName(specifier, source.fileName, options, tsm.sys, undefined, undefined, mode).resolvedModule?.resolvedFileName;
|
|
119
129
|
if (resolved !== undefined)
|
|
@@ -131,7 +141,7 @@ var real = (file) => {
|
|
|
131
141
|
}
|
|
132
142
|
};
|
|
133
143
|
function libraryAsImported(target, specifier) {
|
|
134
|
-
if (target.zone !== "library")
|
|
144
|
+
if (target.zone !== "library" || target.entry !== undefined)
|
|
135
145
|
return target;
|
|
136
146
|
const named = import_zones.specifierPackage(specifier);
|
|
137
147
|
if (named === undefined || named === target.packageName)
|
|
@@ -148,7 +158,7 @@ function edgeProblem(classifier, display, fileName, from, specifier, target) {
|
|
|
148
158
|
}
|
|
149
159
|
if (target === undefined)
|
|
150
160
|
return;
|
|
151
|
-
const to = classifier.classify(target);
|
|
161
|
+
const to = classifier.classify(target, specifier);
|
|
152
162
|
if (to.zone === "error")
|
|
153
163
|
return `${display(fileName)} imports ${display(target)}: ${to.reason}`;
|
|
154
164
|
if (to.zone === "library") {
|
package/dist/resolve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAYA,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAYA,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AA6BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,MAAM,GAAG,SAAS,CASpB"}
|
package/dist/resolve.js
CHANGED
|
@@ -5,16 +5,24 @@
|
|
|
5
5
|
* it would at runtime - the plugin never re-derives the file-based routing rules.
|
|
6
6
|
*/
|
|
7
7
|
import { compileRoutePattern, matchRoutePattern, sortRoutesBySpecificity, } from "@nifrajs/core/pattern";
|
|
8
|
-
// The language service asks for definitions repeatedly while the cursor moves
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
const compiledRouteCache = new
|
|
8
|
+
// The language service asks for definitions repeatedly while the cursor moves, and route discovery
|
|
9
|
+
// hands over a new array each time. So the compilation/specificity sort is cached by what the routes
|
|
10
|
+
// are, not by the array: each query then only matches, and a changed route set compiles afresh.
|
|
11
|
+
const compiledRouteCache = new Map();
|
|
12
|
+
/** Route sets kept compiled at once: a workspace's apps, plus the sets an edit just replaced. */
|
|
13
|
+
const MAX_CACHED_ROUTE_SETS = 8;
|
|
12
14
|
function compiledRoutes(routes) {
|
|
13
|
-
const
|
|
15
|
+
const key = JSON.stringify(routes.map((route) => [route.pattern, route.file]));
|
|
16
|
+
const cached = compiledRouteCache.get(key);
|
|
14
17
|
if (cached !== undefined)
|
|
15
18
|
return cached;
|
|
16
19
|
const compiled = sortRoutesBySpecificity(routes.map((route) => ({ route, pattern: compileRoutePattern(route.pattern) })));
|
|
17
|
-
compiledRouteCache.
|
|
20
|
+
if (compiledRouteCache.size >= MAX_CACHED_ROUTE_SETS) {
|
|
21
|
+
const oldest = compiledRouteCache.keys().next();
|
|
22
|
+
if (oldest.done !== true)
|
|
23
|
+
compiledRouteCache.delete(oldest.value);
|
|
24
|
+
}
|
|
25
|
+
compiledRouteCache.set(key, compiled);
|
|
18
26
|
return compiled;
|
|
19
27
|
}
|
|
20
28
|
/**
|
package/dist/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,uBAAuB,CAAA;AAa9B,mGAAmG;AACnG,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,uBAAuB,CAAA;AAa9B,mGAAmG;AACnG,qGAAqG;AACrG,gGAAgG;AAChG,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA4C,CAAA;AAC9E,iGAAiG;AACjG,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAE/B,SAAS,cAAc,CAAC,MAAgC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9E,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAA;IACvC,MAAM,QAAQ,GAAG,uBAAuB,CACtC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAChF,CAAA;IACD,IAAI,kBAAkB,CAAC,IAAI,IAAI,qBAAqB,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;QAC/C,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;YAAE,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACnE,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IACrC,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,MAAgC;IAEhC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;IACjD,6FAA6F;IAC7F,sDAAsD;IACtD,KAAK,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,IAAI,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC,IAAI,CAAA;IACrE,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
package/dist/zones.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zones.d.ts","sourceRoot":"","sources":["../src/zones.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AAErC,yGAAyG;AACzG,eAAO,MAAM,oBAAoB,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"zones.d.ts","sourceRoot":"","sources":["../src/zones.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AAErC,yGAAyG;AACzG,eAAO,MAAM,oBAAoB,SAAS,CAAA;AAyI1C;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,OAAO,EAAE,EACd,MAAM,EAAE,EAAE,CAAC,UAAU,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,EAAE,CAAC,eAAe,GAC1B,EAAE,CAAC,UAAU,EAAE,CA+BjB"}
|
package/dist/zones.js
CHANGED
|
@@ -62,7 +62,12 @@ function valueImports(tsm, source) {
|
|
|
62
62
|
/** Where an import lands: TypeScript's resolution (tsconfig `paths` included), else a relative path
|
|
63
63
|
* that exists on disk (an `.svelte` or `.vue` file TypeScript only knows through a shim). */
|
|
64
64
|
function resolveImport(tsm, source, edge, options) {
|
|
65
|
-
|
|
65
|
+
// Cut by index: `/[?#].*$/` retries from every `#` and is quadratic on a long run of them. The
|
|
66
|
+
// search starts past a leading `#`, which names a package.json import rather than a hash.
|
|
67
|
+
const query = edge.specifier.indexOf("?", 1);
|
|
68
|
+
const hash = edge.specifier.indexOf("#", 1);
|
|
69
|
+
const cut = query === -1 ? hash : hash === -1 ? query : Math.min(query, hash);
|
|
70
|
+
const specifier = cut === -1 ? edge.specifier : edge.specifier.slice(0, cut);
|
|
66
71
|
const mode = tsm.getModeForUsageLocation(source, edge.literal, options);
|
|
67
72
|
const resolved = tsm.resolveModuleName(specifier, source.fileName, options, tsm.sys, undefined, undefined, mode).resolvedModule?.resolvedFileName;
|
|
68
73
|
if (resolved !== undefined)
|
|
@@ -83,7 +88,7 @@ const real = (file) => {
|
|
|
83
88
|
/** A third-party target as the specifier names it: TypeScript resolves `pg` to `@types/pg`, and the
|
|
84
89
|
* server-package list knows `pg`. */
|
|
85
90
|
function libraryAsImported(target, specifier) {
|
|
86
|
-
if (target.zone !== "library")
|
|
91
|
+
if (target.zone !== "library" || target.entry !== undefined)
|
|
87
92
|
return target;
|
|
88
93
|
const named = specifierPackage(specifier);
|
|
89
94
|
if (named === undefined || named === target.packageName)
|
|
@@ -101,7 +106,8 @@ function edgeProblem(classifier, display, fileName, from, specifier, target) {
|
|
|
101
106
|
}
|
|
102
107
|
if (target === undefined)
|
|
103
108
|
return undefined;
|
|
104
|
-
|
|
109
|
+
// A package that gives each entry its own side is judged by the entry the import names.
|
|
110
|
+
const to = classifier.classify(target, specifier);
|
|
105
111
|
if (to.zone === "error")
|
|
106
112
|
return `${display(fileName)} imports ${display(target)}: ${to.reason}`;
|
|
107
113
|
if (to.zone === "library") {
|
package/dist/zones.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zones.js","sourceRoot":"","sources":["../src/zones.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"zones.js","sourceRoot":"","sources":["../src/zones.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/ts-plugin",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "TypeScript language-service plugin for nifra - go-to-definition from a route-path string literal to the routes/ file that serves it, and the frontend/backend zone rules as editor errors.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"build": "bun run build.ts"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@nifrajs/core": "5.
|
|
51
|
-
"@nifrajs/web": "5.
|
|
50
|
+
"@nifrajs/core": "5.1.0",
|
|
51
|
+
"@nifrajs/web": "5.1.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"typescript": ">=5.5.0"
|
package/src/resolve.ts
CHANGED
|
@@ -21,18 +21,25 @@ type CompiledRouteLocation = {
|
|
|
21
21
|
readonly pattern: ReturnType<typeof compileRoutePattern>
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
// The language service asks for definitions repeatedly while the cursor moves
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
const compiledRouteCache = new
|
|
24
|
+
// The language service asks for definitions repeatedly while the cursor moves, and route discovery
|
|
25
|
+
// hands over a new array each time. So the compilation/specificity sort is cached by what the routes
|
|
26
|
+
// are, not by the array: each query then only matches, and a changed route set compiles afresh.
|
|
27
|
+
const compiledRouteCache = new Map<string, readonly CompiledRouteLocation[]>()
|
|
28
|
+
/** Route sets kept compiled at once: a workspace's apps, plus the sets an edit just replaced. */
|
|
29
|
+
const MAX_CACHED_ROUTE_SETS = 8
|
|
28
30
|
|
|
29
31
|
function compiledRoutes(routes: readonly RouteLocation[]): readonly CompiledRouteLocation[] {
|
|
30
|
-
const
|
|
32
|
+
const key = JSON.stringify(routes.map((route) => [route.pattern, route.file]))
|
|
33
|
+
const cached = compiledRouteCache.get(key)
|
|
31
34
|
if (cached !== undefined) return cached
|
|
32
35
|
const compiled = sortRoutesBySpecificity(
|
|
33
36
|
routes.map((route) => ({ route, pattern: compileRoutePattern(route.pattern) })),
|
|
34
37
|
)
|
|
35
|
-
compiledRouteCache.
|
|
38
|
+
if (compiledRouteCache.size >= MAX_CACHED_ROUTE_SETS) {
|
|
39
|
+
const oldest = compiledRouteCache.keys().next()
|
|
40
|
+
if (oldest.done !== true) compiledRouteCache.delete(oldest.value)
|
|
41
|
+
}
|
|
42
|
+
compiledRouteCache.set(key, compiled)
|
|
36
43
|
return compiled
|
|
37
44
|
}
|
|
38
45
|
|
package/src/zones.ts
CHANGED
|
@@ -91,7 +91,12 @@ function resolveImport(
|
|
|
91
91
|
edge: ImportEdge,
|
|
92
92
|
options: ts.CompilerOptions,
|
|
93
93
|
): string | undefined {
|
|
94
|
-
|
|
94
|
+
// Cut by index: `/[?#].*$/` retries from every `#` and is quadratic on a long run of them. The
|
|
95
|
+
// search starts past a leading `#`, which names a package.json import rather than a hash.
|
|
96
|
+
const query = edge.specifier.indexOf("?", 1)
|
|
97
|
+
const hash = edge.specifier.indexOf("#", 1)
|
|
98
|
+
const cut = query === -1 ? hash : hash === -1 ? query : Math.min(query, hash)
|
|
99
|
+
const specifier = cut === -1 ? edge.specifier : edge.specifier.slice(0, cut)
|
|
95
100
|
const mode = tsm.getModeForUsageLocation(source, edge.literal, options)
|
|
96
101
|
const resolved = tsm.resolveModuleName(
|
|
97
102
|
specifier,
|
|
@@ -119,7 +124,7 @@ const real = (file: string): string => {
|
|
|
119
124
|
/** A third-party target as the specifier names it: TypeScript resolves `pg` to `@types/pg`, and the
|
|
120
125
|
* server-package list knows `pg`. */
|
|
121
126
|
function libraryAsImported(target: Classification, specifier: string): Classification {
|
|
122
|
-
if (target.zone !== "library") return target
|
|
127
|
+
if (target.zone !== "library" || target.entry !== undefined) return target
|
|
123
128
|
const named = specifierPackage(specifier)
|
|
124
129
|
if (named === undefined || named === target.packageName) return target
|
|
125
130
|
return { zone: "library", packageName: named }
|
|
@@ -142,7 +147,8 @@ function edgeProblem(
|
|
|
142
147
|
return `"${BACKEND_ONLY_MARKER}" marks a module backend-only, but ${display(fileName)} reaches the browser. Move it under backend/ or into a route's backend half`
|
|
143
148
|
}
|
|
144
149
|
if (target === undefined) return undefined
|
|
145
|
-
|
|
150
|
+
// A package that gives each entry its own side is judged by the entry the import names.
|
|
151
|
+
const to = classifier.classify(target, specifier)
|
|
146
152
|
if (to.zone === "error") return `${display(fileName)} imports ${display(target)}: ${to.reason}`
|
|
147
153
|
if (to.zone === "library") {
|
|
148
154
|
const reason = browser ? browserDenial(libraryAsImported(to, specifier), specifier) : undefined
|