@react-router/dev 0.0.0-experimental-312bddb22 → 0.0.0-experimental-2d5e406e4
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/commands.js +1 -1
- package/dist/cli/detectPackageManager.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/run.js +1 -1
- package/dist/cli/useJavascript.js +1 -1
- package/dist/colors.js +1 -1
- package/dist/config/format.js +1 -1
- package/dist/config/routes.js +2 -2
- package/dist/invariant.js +2 -4
- package/dist/routes.js +1 -1
- package/dist/typescript/ast.d.ts +8 -0
- package/dist/typescript/ast.js +98 -0
- package/dist/typescript/autotype/api.completions.d.ts +5 -0
- package/dist/typescript/autotype/api.completions.js +75 -0
- package/dist/typescript/autotype/api.definitions.d.ts +4 -0
- package/dist/typescript/autotype/api.definitions.js +55 -0
- package/dist/typescript/autotype/api.diagnostics.d.ts +5 -0
- package/dist/typescript/autotype/api.diagnostics.js +60 -0
- package/dist/typescript/autotype/api.hover.d.ts +3 -0
- package/dist/typescript/autotype/api.hover.js +33 -0
- package/dist/typescript/autotype/api.inlay-hints.d.ts +3 -0
- package/dist/typescript/autotype/api.inlay-hints.js +31 -0
- package/dist/typescript/autotype/index.d.ts +5 -0
- package/dist/typescript/autotype/language-service.d.ts +35 -0
- package/dist/typescript/autotype/language-service.js +290 -0
- package/dist/typescript/context.d.ts +15 -0
- package/dist/typescript/decorate.d.ts +2 -0
- package/dist/typescript/decorate.js +233 -0
- package/dist/typescript/plugin.d.ts +6 -0
- package/dist/typescript/plugin.js +67 -0
- package/dist/typescript/routes.d.ts +10 -0
- package/dist/typescript/routes.js +102 -0
- package/dist/typescript/typecheck.d.ts +1 -0
- package/dist/typescript/typegen.d.ts +5 -0
- package/dist/typescript/typegen.js +165 -0
- package/dist/vite/babel.js +1 -1
- package/dist/vite/build.js +3 -3
- package/dist/vite/cloudflare-dev-proxy.js +1 -1
- package/dist/vite/cloudflare.js +1 -1
- package/dist/vite/combine-urls.js +1 -1
- package/dist/vite/config.d.ts +3 -3
- package/dist/vite/config.js +3 -3
- package/dist/vite/dev.js +1 -1
- package/dist/vite/import-vite-esm-sync.js +2 -2
- package/dist/vite/node-adapter.js +2 -2
- package/dist/vite/plugin.d.ts +1 -1
- package/dist/vite/plugin.js +24 -50
- package/dist/vite/profiler.js +1 -1
- package/dist/vite/remove-exports.js +1 -1
- package/dist/vite/resolve-file-url.js +1 -1
- package/dist/vite/styles.js +1 -1
- package/dist/vite/vite-node.d.ts +9 -0
- package/dist/vite/vite-node.js +57 -0
- package/dist/vite/vmod.js +1 -1
- package/dist/vite/with-props.js +1 -1
- package/dist/vite.js +1 -1
- package/package.json +11 -7
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-2d5e406e4
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var path = require('node:path');
|
|
16
|
+
var typegen = require('../typegen.js');
|
|
17
|
+
var ast = require('../ast.js');
|
|
18
|
+
var routes = require('../routes.js');
|
|
19
|
+
|
|
20
|
+
function _interopNamespace(e) {
|
|
21
|
+
if (e && e.__esModule) return e;
|
|
22
|
+
var n = Object.create(null);
|
|
23
|
+
if (e) {
|
|
24
|
+
Object.keys(e).forEach(function (k) {
|
|
25
|
+
if (k !== 'default') {
|
|
26
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
27
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return e[k]; }
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
n["default"] = e;
|
|
35
|
+
return Object.freeze(n);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
39
|
+
|
|
40
|
+
// Adapted from https://github.com/sveltejs/language-tools/blob/master/packages/typescript-plugin/src/language-service/sveltekit.ts
|
|
41
|
+
const FORCE_UPDATE_VERSION = "FORCE_UPDATE_VERSION";
|
|
42
|
+
// TODO: cache by rootDirectory!
|
|
43
|
+
let CACHED;
|
|
44
|
+
function getAutotypeLanguageService(ctx) {
|
|
45
|
+
if (CACHED) return CACHED;
|
|
46
|
+
const host = ctx.languageServiceHost;
|
|
47
|
+
class AutotypeLanguageServiceHost {
|
|
48
|
+
routes = {};
|
|
49
|
+
// TODO: Q: are these needed? do they just "silence" the autotype host?
|
|
50
|
+
// log() {}
|
|
51
|
+
// trace() {}
|
|
52
|
+
// error() {}
|
|
53
|
+
getCompilationSettings() {
|
|
54
|
+
return host.getCompilationSettings();
|
|
55
|
+
}
|
|
56
|
+
getCurrentDirectory() {
|
|
57
|
+
return host.getCurrentDirectory();
|
|
58
|
+
}
|
|
59
|
+
getDefaultLibFileName(o) {
|
|
60
|
+
return host.getDefaultLibFileName(o);
|
|
61
|
+
}
|
|
62
|
+
getScriptFileNames() {
|
|
63
|
+
const names = new Set(Object.keys(this.routes));
|
|
64
|
+
const files = host.getScriptFileNames();
|
|
65
|
+
for (const file of files) {
|
|
66
|
+
names.add(file);
|
|
67
|
+
}
|
|
68
|
+
return [...names];
|
|
69
|
+
}
|
|
70
|
+
getScriptVersion(fileName) {
|
|
71
|
+
const route = this.routes[fileName];
|
|
72
|
+
if (!route) return host.getScriptVersion(fileName);
|
|
73
|
+
return route.version.toString();
|
|
74
|
+
}
|
|
75
|
+
getScriptSnapshot(fileName) {
|
|
76
|
+
const route = this.routes[fileName];
|
|
77
|
+
if (!route) return host.getScriptSnapshot(fileName);
|
|
78
|
+
return route.snapshot;
|
|
79
|
+
}
|
|
80
|
+
readFile(fileName) {
|
|
81
|
+
const route = this.routes[fileName];
|
|
82
|
+
return route ? route.snapshot.getText(0, route.snapshot.getLength()) : host.readFile(fileName);
|
|
83
|
+
}
|
|
84
|
+
fileExists(fileName) {
|
|
85
|
+
return this.routes[fileName] !== undefined || host.fileExists(fileName);
|
|
86
|
+
}
|
|
87
|
+
getRouteIfUpToDate(fileName) {
|
|
88
|
+
const scriptVersion = this.getScriptVersion(fileName);
|
|
89
|
+
const route = this.routes[fileName];
|
|
90
|
+
if (!route || scriptVersion !== host.getScriptVersion(fileName) || scriptVersion === FORCE_UPDATE_VERSION) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return route;
|
|
94
|
+
}
|
|
95
|
+
upsertRouteFile(fileName) {
|
|
96
|
+
var _ctx$languageService$;
|
|
97
|
+
const route = routes.get(ctx, fileName);
|
|
98
|
+
if (!route) return;
|
|
99
|
+
const sourceFile = (_ctx$languageService$ = ctx.languageService.getProgram()) === null || _ctx$languageService$ === void 0 ? void 0 : _ctx$languageService$.getSourceFile(fileName);
|
|
100
|
+
if (!sourceFile) return;
|
|
101
|
+
const {
|
|
102
|
+
text: code
|
|
103
|
+
} = sourceFile;
|
|
104
|
+
const autotyped = autotypeRoute(ctx, fileName, code);
|
|
105
|
+
const snapshot = ctx.ts.ScriptSnapshot.fromString(autotyped.code());
|
|
106
|
+
snapshot.getChangeRange = _ => undefined;
|
|
107
|
+
this.routes[fileName] = {
|
|
108
|
+
version: this.routes[fileName] === undefined ? FORCE_UPDATE_VERSION : host.getScriptVersion(fileName),
|
|
109
|
+
snapshot,
|
|
110
|
+
autotyped
|
|
111
|
+
};
|
|
112
|
+
return this.routes[fileName];
|
|
113
|
+
}
|
|
114
|
+
// needed for path auto completions
|
|
115
|
+
readDirectory = host.readDirectory ? (...args) => {
|
|
116
|
+
return host.readDirectory(...args);
|
|
117
|
+
} : undefined;
|
|
118
|
+
}
|
|
119
|
+
const autotypeHost = new AutotypeLanguageServiceHost();
|
|
120
|
+
function getRoute(fileName) {
|
|
121
|
+
const route = autotypeHost.getRouteIfUpToDate(fileName) ?? autotypeHost.upsertRouteFile(fileName);
|
|
122
|
+
return route;
|
|
123
|
+
}
|
|
124
|
+
const languageService = ctx.ts.createLanguageService(autotypeHost);
|
|
125
|
+
CACHED = {
|
|
126
|
+
...languageService,
|
|
127
|
+
getRoute
|
|
128
|
+
};
|
|
129
|
+
return CACHED;
|
|
130
|
+
}
|
|
131
|
+
function autotypeRoute(ctx, filepath, code) {
|
|
132
|
+
const sourceFile = ctx.ts.createSourceFile(filepath, code, ctx.ts.ScriptTarget.Latest, true);
|
|
133
|
+
const route = {
|
|
134
|
+
file: path__namespace.relative(ctx.config.appDirectory, filepath)
|
|
135
|
+
};
|
|
136
|
+
const typesSource = "./" + path__namespace.parse(typegen.getPath(ctx, route)).name;
|
|
137
|
+
const splices = [...sourceFile.statements.flatMap(stmt => [...annotateDefaultExportFunctionDeclaration(ctx, stmt, typesSource), ...annotateDefaultExportExpression(ctx, stmt, typesSource), ...annotateNamedExportFunctionDeclaration(ctx, stmt, typesSource), ...annotateNamedExportVariableStatement(ctx, stmt, typesSource)])];
|
|
138
|
+
return new AutotypedRoute(code, splices);
|
|
139
|
+
}
|
|
140
|
+
function annotateDefaultExportFunctionDeclaration(ctx, stmt, typesSource) {
|
|
141
|
+
var _stmt$name, _stmt$name2;
|
|
142
|
+
if (!ctx.ts.isFunctionDeclaration(stmt)) return [];
|
|
143
|
+
if (!ast.exported(ctx.ts, stmt)) return [];
|
|
144
|
+
const _default = ast.defaulted(ctx.ts, stmt);
|
|
145
|
+
if (!_default) return [];
|
|
146
|
+
return annotateFunction(ctx, stmt, {
|
|
147
|
+
typesSource,
|
|
148
|
+
name: "default",
|
|
149
|
+
remapDiagnostics: {
|
|
150
|
+
start: ((_stmt$name = stmt.name) === null || _stmt$name === void 0 ? void 0 : _stmt$name.getStart()) ?? _default.getStart(),
|
|
151
|
+
length: ((_stmt$name2 = stmt.name) === null || _stmt$name2 === void 0 ? void 0 : _stmt$name2.getWidth()) ?? _default.getWidth()
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function annotateDefaultExportExpression(ctx, stmt, typesSource) {
|
|
156
|
+
if (!ctx.ts.isExportAssignment(stmt)) return [];
|
|
157
|
+
if (stmt.isExportEquals) return [];
|
|
158
|
+
if (!ctx.ts.isArrowFunction(stmt.expression)) return [];
|
|
159
|
+
const regex = /^export\s+/;
|
|
160
|
+
const matches = stmt.getText().match(regex);
|
|
161
|
+
if (!matches) {
|
|
162
|
+
throw Error(`expected ${regex} at ${stmt.getSourceFile().fileName}:${stmt.getStart()}`);
|
|
163
|
+
}
|
|
164
|
+
return annotateFunction(ctx, stmt.expression, {
|
|
165
|
+
typesSource,
|
|
166
|
+
name: "default",
|
|
167
|
+
remapDiagnostics: {
|
|
168
|
+
start: stmt.getStart() + matches[0].length,
|
|
169
|
+
length: 7
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function annotateNamedExportFunctionDeclaration(ctx, stmt, typesSource) {
|
|
174
|
+
if (!ctx.ts.isFunctionDeclaration(stmt)) return [];
|
|
175
|
+
if (!ast.exported(ctx.ts, stmt)) return [];
|
|
176
|
+
if (ast.defaulted(ctx.ts, stmt)) return [];
|
|
177
|
+
if (!stmt.name) return [];
|
|
178
|
+
return annotateFunction(ctx, stmt, {
|
|
179
|
+
typesSource,
|
|
180
|
+
name: stmt.name.text,
|
|
181
|
+
remapDiagnostics: {
|
|
182
|
+
start: stmt.name.getStart(),
|
|
183
|
+
length: stmt.name.getWidth()
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function annotateNamedExportVariableStatement(ctx, stmt, typesSource) {
|
|
188
|
+
if (!ctx.ts.isVariableStatement(stmt)) return [];
|
|
189
|
+
if (!ast.exported(ctx.ts, stmt)) return [];
|
|
190
|
+
return stmt.declarationList.declarations.flatMap(decl => {
|
|
191
|
+
if (!ctx.ts.isIdentifier(decl.name)) return [];
|
|
192
|
+
if (decl.initializer === undefined) return [];
|
|
193
|
+
if (ctx.ts.isFunctionExpression(decl.initializer) || ctx.ts.isArrowFunction(decl.initializer)) {
|
|
194
|
+
return annotateFunction(ctx, decl.initializer, {
|
|
195
|
+
typesSource,
|
|
196
|
+
name: decl.name.text,
|
|
197
|
+
remapDiagnostics: {
|
|
198
|
+
start: decl.name.getStart(),
|
|
199
|
+
length: decl.name.getWidth()
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return [];
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
function annotateFunction(ctx, fn, {
|
|
207
|
+
typesSource,
|
|
208
|
+
name,
|
|
209
|
+
remapDiagnostics
|
|
210
|
+
}) {
|
|
211
|
+
var _fn$body, _Route$exports$name;
|
|
212
|
+
const param = fn.parameters[0];
|
|
213
|
+
const returnTypeIndex = ctx.ts.isArrowFunction(fn) ? fn.equalsGreaterThanToken.getStart() : (_fn$body = fn.body) === null || _fn$body === void 0 ? void 0 : _fn$body.getStart();
|
|
214
|
+
const annotateReturnType = (_Route$exports$name = routes.exports[name]) === null || _Route$exports$name === void 0 ? void 0 : _Route$exports$name.annotateReturnType;
|
|
215
|
+
name = name === "default" ? "Default" : name;
|
|
216
|
+
return [param && param.type === undefined ? {
|
|
217
|
+
index: param.getEnd(),
|
|
218
|
+
content: `: import("${typesSource}").${name}["args"]`,
|
|
219
|
+
remapDiagnostics
|
|
220
|
+
} : null, returnTypeIndex && annotateReturnType && fn.type === undefined ? {
|
|
221
|
+
index: returnTypeIndex,
|
|
222
|
+
content: `: import("${typesSource}").${name}["return"]`,
|
|
223
|
+
remapDiagnostics
|
|
224
|
+
} : null].filter(x => x !== null);
|
|
225
|
+
}
|
|
226
|
+
class AutotypedRoute {
|
|
227
|
+
_code = undefined;
|
|
228
|
+
constructor(code, splices) {
|
|
229
|
+
this._originalCode = code;
|
|
230
|
+
this._splices = splices;
|
|
231
|
+
}
|
|
232
|
+
code() {
|
|
233
|
+
if (!this._code) {
|
|
234
|
+
const chars = Array.from(this._originalCode);
|
|
235
|
+
// iterate over splices in reverse so that splicing doesn't mess up other indices
|
|
236
|
+
for (let {
|
|
237
|
+
index,
|
|
238
|
+
content
|
|
239
|
+
} of reverse(this._splices)) {
|
|
240
|
+
chars.splice(index, 0, content);
|
|
241
|
+
}
|
|
242
|
+
this._code = chars.join("");
|
|
243
|
+
}
|
|
244
|
+
return this._code;
|
|
245
|
+
}
|
|
246
|
+
toSplicedIndex(originalIndex) {
|
|
247
|
+
let spliceOffset = 0;
|
|
248
|
+
for (let {
|
|
249
|
+
index,
|
|
250
|
+
content
|
|
251
|
+
} of this._splices) {
|
|
252
|
+
if (index > originalIndex) break;
|
|
253
|
+
spliceOffset += content.length;
|
|
254
|
+
}
|
|
255
|
+
return originalIndex + spliceOffset;
|
|
256
|
+
}
|
|
257
|
+
toOriginalIndex(splicedIndex) {
|
|
258
|
+
let spliceOffset = 0;
|
|
259
|
+
for (let {
|
|
260
|
+
index,
|
|
261
|
+
content,
|
|
262
|
+
remapDiagnostics
|
|
263
|
+
} of this._splices) {
|
|
264
|
+
// before this splice
|
|
265
|
+
if (splicedIndex < index + spliceOffset) break;
|
|
266
|
+
// within this splice
|
|
267
|
+
if (splicedIndex < index + spliceOffset + content.length) {
|
|
268
|
+
return {
|
|
269
|
+
index,
|
|
270
|
+
remapDiagnostics
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
// after this splice
|
|
274
|
+
spliceOffset += content.length;
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
index: Math.max(0, splicedIndex - spliceOffset)
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function* reverse(array) {
|
|
282
|
+
let i = array.length - 1;
|
|
283
|
+
while (i >= 0) {
|
|
284
|
+
yield array[i];
|
|
285
|
+
i--;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
exports.AutotypedRoute = AutotypedRoute;
|
|
290
|
+
exports.getAutotypeLanguageService = getAutotypeLanguageService;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type ts from "typescript/lib/tsserverlibrary";
|
|
2
|
+
import type { RouteManifest } from "../config/routes";
|
|
3
|
+
export type Context = {
|
|
4
|
+
config: {
|
|
5
|
+
rootDirectory: string;
|
|
6
|
+
appDirectory: string;
|
|
7
|
+
};
|
|
8
|
+
routes: RouteManifest;
|
|
9
|
+
languageService: ts.LanguageService;
|
|
10
|
+
languageServiceHost: ts.LanguageServiceHost;
|
|
11
|
+
ts: typeof ts;
|
|
12
|
+
logger?: {
|
|
13
|
+
info: (message: string) => void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-2d5e406e4
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
|
+
|
|
15
|
+
var api_completions = require('./autotype/api.completions.js');
|
|
16
|
+
var api_definitions = require('./autotype/api.definitions.js');
|
|
17
|
+
var api_diagnostics = require('./autotype/api.diagnostics.js');
|
|
18
|
+
var api_hover = require('./autotype/api.hover.js');
|
|
19
|
+
var api_inlayHints = require('./autotype/api.inlay-hints.js');
|
|
20
|
+
var ast = require('./ast.js');
|
|
21
|
+
var routes = require('./routes.js');
|
|
22
|
+
|
|
23
|
+
function decorateLanguageService(ctx) {
|
|
24
|
+
const ls = ctx.languageService;
|
|
25
|
+
// completions
|
|
26
|
+
// --------------------------------------------------------------------------
|
|
27
|
+
const {
|
|
28
|
+
getCompletionsAtPosition
|
|
29
|
+
} = ls;
|
|
30
|
+
ls.getCompletionsAtPosition = (fileName, position, ...rest) => {
|
|
31
|
+
var _ctx$languageService$;
|
|
32
|
+
if (!routes.get(ctx, fileName)) {
|
|
33
|
+
return getCompletionsAtPosition(fileName, position, ...rest);
|
|
34
|
+
}
|
|
35
|
+
const completions = api_completions.getCompletionsAtPosition(ctx)(fileName, position, ...rest);
|
|
36
|
+
const sourceFile = (_ctx$languageService$ = ctx.languageService.getProgram()) === null || _ctx$languageService$ === void 0 ? void 0 : _ctx$languageService$.getSourceFile(fileName);
|
|
37
|
+
if (!sourceFile) return completions;
|
|
38
|
+
const node = ast.findNodeAtPosition(sourceFile, position);
|
|
39
|
+
if (!node) return completions;
|
|
40
|
+
const isTopLevel = ctx.ts.isSourceFile(node.parent) || ctx.ts.isStatement(node.parent) && ctx.ts.isSourceFile(node.parent.parent);
|
|
41
|
+
if (!isTopLevel) return completions;
|
|
42
|
+
const {
|
|
43
|
+
line
|
|
44
|
+
} = sourceFile.getLineAndCharacterOfPosition(position);
|
|
45
|
+
const lineStart = sourceFile.getPositionOfLineAndCharacter(line, 0);
|
|
46
|
+
const normalizedLine = sourceFile.text.slice(lineStart, position).trim().replace(/\s+g/, " ");
|
|
47
|
+
const exports = ast.getExportNames(ctx.ts, sourceFile);
|
|
48
|
+
const routeExportCompletions = Object.keys(routes.exports).map(key => {
|
|
49
|
+
if (exports.has(key)) return null;
|
|
50
|
+
const insertText = key === "default" ? `export default function Component() {}` : `export function ${key}() {}`;
|
|
51
|
+
if (!fzf(normalizedLine, insertText)) return null;
|
|
52
|
+
const completion = {
|
|
53
|
+
name: key,
|
|
54
|
+
insertText,
|
|
55
|
+
kind: ctx.ts.ScriptElementKind.functionElement,
|
|
56
|
+
kindModifiers: ctx.ts.ScriptElementKindModifier.exportedModifier,
|
|
57
|
+
sortText: "0",
|
|
58
|
+
labelDetails: {
|
|
59
|
+
description: "React Router Export"
|
|
60
|
+
},
|
|
61
|
+
data: {
|
|
62
|
+
exportName: key,
|
|
63
|
+
// TS needs this
|
|
64
|
+
__reactRouter: key
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
...completion,
|
|
69
|
+
replacementSpan: {
|
|
70
|
+
start: lineStart,
|
|
71
|
+
length: position - lineStart
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}).filter(x => x !== null);
|
|
75
|
+
if (!completions) {
|
|
76
|
+
return routeExportCompletions.length > 0 ? {
|
|
77
|
+
isGlobalCompletion: false,
|
|
78
|
+
isMemberCompletion: false,
|
|
79
|
+
isNewIdentifierLocation: false,
|
|
80
|
+
isIncomplete: true,
|
|
81
|
+
entries: routeExportCompletions
|
|
82
|
+
} : undefined;
|
|
83
|
+
}
|
|
84
|
+
return routeExportCompletions.length > 0 ? {
|
|
85
|
+
...completions,
|
|
86
|
+
entries: [...routeExportCompletions, ...completions.entries]
|
|
87
|
+
} : completions;
|
|
88
|
+
};
|
|
89
|
+
const {
|
|
90
|
+
getCompletionEntryDetails
|
|
91
|
+
} = ls;
|
|
92
|
+
ls.getCompletionEntryDetails = (...args) => {
|
|
93
|
+
const data = args[6];
|
|
94
|
+
if (data.__reactRouter) {
|
|
95
|
+
var _Route$exports$key;
|
|
96
|
+
const key = data.__reactRouter;
|
|
97
|
+
return {
|
|
98
|
+
name: key,
|
|
99
|
+
kind: ctx.ts.ScriptElementKind.functionElement,
|
|
100
|
+
kindModifiers: ctx.ts.ScriptElementKindModifier.exportedModifier,
|
|
101
|
+
documentation: ((_Route$exports$key = routes.exports[key]) === null || _Route$exports$key === void 0 ? void 0 : _Route$exports$key.documentation) ?? [],
|
|
102
|
+
displayParts: []
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return routes.get(ctx, args[0]) ? api_completions.getCompletionEntryDetails(ctx)(...args) : getCompletionEntryDetails(...args);
|
|
106
|
+
};
|
|
107
|
+
const {
|
|
108
|
+
getSignatureHelpItems
|
|
109
|
+
} = ls;
|
|
110
|
+
ls.getSignatureHelpItems = (...args) => routes.get(ctx, args[0]) ? api_completions.getSignatureHelpItems(ctx)(...args) : getSignatureHelpItems(...args);
|
|
111
|
+
// definitions
|
|
112
|
+
// --------------------------------------------------------------------------
|
|
113
|
+
const {
|
|
114
|
+
getDefinitionAndBoundSpan
|
|
115
|
+
} = ls;
|
|
116
|
+
ls.getDefinitionAndBoundSpan = (...args) => routes.get(ctx, args[0]) ? api_definitions.getDefinitionAndBoundSpan(ctx)(...args) : getDefinitionAndBoundSpan(...args);
|
|
117
|
+
const {
|
|
118
|
+
getTypeDefinitionAtPosition
|
|
119
|
+
} = ls;
|
|
120
|
+
ls.getTypeDefinitionAtPosition = (...args) => routes.get(ctx, args[0]) ? api_definitions.getTypeDefinitionAtPosition(ctx)(...args) : getTypeDefinitionAtPosition(...args);
|
|
121
|
+
// diagnostics
|
|
122
|
+
// --------------------------------------------------------------------------
|
|
123
|
+
const {
|
|
124
|
+
getSyntacticDiagnostics
|
|
125
|
+
} = ls;
|
|
126
|
+
ls.getSyntacticDiagnostics = (...args) => routes.get(ctx, args[0]) ? api_diagnostics.getSyntacticDiagnostics(ctx)(...args) : getSyntacticDiagnostics(...args);
|
|
127
|
+
const {
|
|
128
|
+
getSemanticDiagnostics
|
|
129
|
+
} = ls;
|
|
130
|
+
ls.getSemanticDiagnostics = fileName => {
|
|
131
|
+
var _ls$getProgram;
|
|
132
|
+
if (!routes.get(ctx, fileName)) return getSemanticDiagnostics(fileName);
|
|
133
|
+
const diagnostics = api_diagnostics.getSemanticDiagnostics(ctx)(fileName);
|
|
134
|
+
const sourceFile = (_ls$getProgram = ls.getProgram()) === null || _ls$getProgram === void 0 ? void 0 : _ls$getProgram.getSourceFile(fileName);
|
|
135
|
+
if (!sourceFile) return diagnostics;
|
|
136
|
+
const exportStarDiagnostics = sourceFile.statements
|
|
137
|
+
// eslint-disable-next-line array-callback-return
|
|
138
|
+
.map(stmt => {
|
|
139
|
+
if (!ctx.ts.isExportDeclaration(stmt)) return undefined;
|
|
140
|
+
if (stmt.exportClause === undefined ||
|
|
141
|
+
// export * as stuff from "..."
|
|
142
|
+
ctx.ts.isNamespaceExportDeclaration(stmt) // export * as stuff from "..."
|
|
143
|
+
) {
|
|
144
|
+
const diagnostic = {
|
|
145
|
+
file: sourceFile,
|
|
146
|
+
category: ctx.ts.DiagnosticCategory.Warning,
|
|
147
|
+
start: stmt.getStart(),
|
|
148
|
+
length: stmt.getWidth(),
|
|
149
|
+
messageText: "React Router cannot typecheck route exports from `*` exports",
|
|
150
|
+
code: 100
|
|
151
|
+
};
|
|
152
|
+
return diagnostic;
|
|
153
|
+
}
|
|
154
|
+
}).filter(x => x !== undefined);
|
|
155
|
+
const hmrNamedFunctionsDiagnostics = sourceFile.statements
|
|
156
|
+
// eslint-disable-next-line array-callback-return
|
|
157
|
+
.map(stmt => {
|
|
158
|
+
if (ctx.ts.isFunctionDeclaration(stmt)) {
|
|
159
|
+
// export default function ...
|
|
160
|
+
if (!ast.exported(ctx.ts, stmt)) return undefined;
|
|
161
|
+
if (!ast.defaulted(ctx.ts, stmt)) return undefined;
|
|
162
|
+
if (!stmt.name) {
|
|
163
|
+
return {
|
|
164
|
+
file: sourceFile,
|
|
165
|
+
category: ctx.ts.DiagnosticCategory.Warning,
|
|
166
|
+
start: stmt.getStart(),
|
|
167
|
+
length: stmt.getWidth(),
|
|
168
|
+
messageText: "For HMR to work, React Router default export must be named\n\nhttps://remix.run/docs/en/main/discussion/hot-module-replacement#named-function-components",
|
|
169
|
+
code: 101
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (ctx.ts.isExportAssignment(stmt)) {
|
|
174
|
+
if (stmt.isExportEquals) return undefined;
|
|
175
|
+
// export default expr
|
|
176
|
+
return {
|
|
177
|
+
file: sourceFile,
|
|
178
|
+
category: ctx.ts.DiagnosticCategory.Warning,
|
|
179
|
+
start: stmt.getStart(),
|
|
180
|
+
length: stmt.getWidth(),
|
|
181
|
+
messageText: "For HMR to work, React Router default export must be named\n\nhttps://remix.run/docs/en/main/discussion/hot-module-replacement#named-function-components",
|
|
182
|
+
code: 101
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}).filter(x => x !== undefined);
|
|
186
|
+
return [...hmrNamedFunctionsDiagnostics, ...exportStarDiagnostics, ...diagnostics];
|
|
187
|
+
};
|
|
188
|
+
const {
|
|
189
|
+
getSuggestionDiagnostics
|
|
190
|
+
} = ls;
|
|
191
|
+
ls.getSuggestionDiagnostics = (...args) => routes.get(ctx, args[0]) ? api_diagnostics.getSuggestionDiagnostics(ctx)(...args) : getSuggestionDiagnostics(...args);
|
|
192
|
+
// diagnostics
|
|
193
|
+
// --------------------------------------------------------------------------
|
|
194
|
+
const {
|
|
195
|
+
getQuickInfoAtPosition
|
|
196
|
+
} = ls;
|
|
197
|
+
ls.getQuickInfoAtPosition = (fileName, position) => {
|
|
198
|
+
var _ctx$languageService$2, _Route$exports$export;
|
|
199
|
+
const route = routes.get(ctx, fileName);
|
|
200
|
+
if (!route) return getQuickInfoAtPosition(fileName, position);
|
|
201
|
+
const quickinfo = routes.get(ctx, fileName) ? api_hover.getQuickInfoAtPosition(ctx)(fileName, position) : getQuickInfoAtPosition(fileName, position);
|
|
202
|
+
if (!quickinfo) return;
|
|
203
|
+
const sourceFile = (_ctx$languageService$2 = ctx.languageService.getProgram()) === null || _ctx$languageService$2 === void 0 ? void 0 : _ctx$languageService$2.getSourceFile(fileName);
|
|
204
|
+
const node = sourceFile && ast.findNodeAtPosition(sourceFile, position);
|
|
205
|
+
const exportName = node && ast.getRouteExportName(ctx, node);
|
|
206
|
+
const routeExportDocs = exportName ? (_Route$exports$export = routes.exports[exportName]) === null || _Route$exports$export === void 0 ? void 0 : _Route$exports$export.documentation : undefined;
|
|
207
|
+
const documentation = [...(quickinfo.documentation ?? []), ...(routeExportDocs ?? [])];
|
|
208
|
+
return {
|
|
209
|
+
...quickinfo,
|
|
210
|
+
documentation: documentation.length > 0 ? documentation : undefined
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
// inlay hints
|
|
214
|
+
// --------------------------------------------------------------------------
|
|
215
|
+
const {
|
|
216
|
+
provideInlayHints
|
|
217
|
+
} = ls;
|
|
218
|
+
ls.provideInlayHints = (...args) => routes.get(ctx, args[0]) ? api_inlayHints.provideInlayHints(ctx)(...args) : provideInlayHints(...args);
|
|
219
|
+
}
|
|
220
|
+
function fzf(pattern, target) {
|
|
221
|
+
let patternIndex = 0;
|
|
222
|
+
let targetIndex = 0;
|
|
223
|
+
while (patternIndex < pattern.length && targetIndex < target.length) {
|
|
224
|
+
var _pattern$patternIndex, _target$targetIndex;
|
|
225
|
+
if (((_pattern$patternIndex = pattern[patternIndex]) === null || _pattern$patternIndex === void 0 ? void 0 : _pattern$patternIndex.toLowerCase()) === ((_target$targetIndex = target[targetIndex]) === null || _target$targetIndex === void 0 ? void 0 : _target$targetIndex.toLowerCase())) {
|
|
226
|
+
patternIndex += 1;
|
|
227
|
+
}
|
|
228
|
+
targetIndex += 1;
|
|
229
|
+
}
|
|
230
|
+
return patternIndex === pattern.length;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
exports.decorateLanguageService = decorateLanguageService;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-2d5e406e4
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Remix Software Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
* @license MIT
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
var Path = require('pathe');
|
|
14
|
+
var typegen = require('./typegen.js');
|
|
15
|
+
var decorate = require('./decorate.js');
|
|
16
|
+
|
|
17
|
+
function _interopNamespace(e) {
|
|
18
|
+
if (e && e.__esModule) return e;
|
|
19
|
+
var n = Object.create(null);
|
|
20
|
+
if (e) {
|
|
21
|
+
Object.keys(e).forEach(function (k) {
|
|
22
|
+
if (k !== 'default') {
|
|
23
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
24
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return e[k]; }
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
n["default"] = e;
|
|
32
|
+
return Object.freeze(n);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var Path__namespace = /*#__PURE__*/_interopNamespace(Path);
|
|
36
|
+
|
|
37
|
+
// For compatibility with the TS language service plugin API, this entrypoint:
|
|
38
|
+
function init(modules) {
|
|
39
|
+
function create(info) {
|
|
40
|
+
const {
|
|
41
|
+
logger
|
|
42
|
+
} = info.project.projectService;
|
|
43
|
+
logger.info("[react-router] setup");
|
|
44
|
+
const rootDirectory = Path__namespace.normalize(info.project.getCurrentDirectory());
|
|
45
|
+
const config = {
|
|
46
|
+
rootDirectory,
|
|
47
|
+
appDirectory: Path__namespace.join(rootDirectory, "app")
|
|
48
|
+
};
|
|
49
|
+
const ctx = {
|
|
50
|
+
config,
|
|
51
|
+
routes: {},
|
|
52
|
+
// will be updated by `Typegen.watch`
|
|
53
|
+
languageService: info.languageService,
|
|
54
|
+
languageServiceHost: info.languageServiceHost,
|
|
55
|
+
ts: modules.typescript,
|
|
56
|
+
logger
|
|
57
|
+
};
|
|
58
|
+
typegen.watch(ctx);
|
|
59
|
+
decorate.decorateLanguageService(ctx);
|
|
60
|
+
return info.languageService;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
create
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = init;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type ts from "typescript/lib/tsserverlibrary";
|
|
2
|
+
import type { Context } from "./context";
|
|
3
|
+
import type { RouteManifestEntry } from "../config/routes";
|
|
4
|
+
export declare function get(ctx: Context, fileName: string): RouteManifestEntry | undefined;
|
|
5
|
+
type RouteExportInfo = {
|
|
6
|
+
annotateReturnType: boolean;
|
|
7
|
+
documentation: ts.SymbolDisplayPart[];
|
|
8
|
+
};
|
|
9
|
+
export declare const exports: Record<string, RouteExportInfo>;
|
|
10
|
+
export {};
|