@tanstack/devtools-vite 0.2.5 → 0.2.6
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/esm/editor.d.ts +1 -2
- package/dist/esm/editor.js +5 -38
- package/dist/esm/editor.js.map +1 -1
- package/dist/esm/plugin.d.ts +0 -2
- package/dist/esm/plugin.js +3 -5
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/utils.d.ts +0 -7
- package/dist/esm/utils.js +5 -17
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/editor.ts +4 -47
- package/src/plugin.ts +5 -8
- package/src/utils.ts +6 -27
package/dist/esm/editor.d.ts
CHANGED
|
@@ -18,9 +18,8 @@ export type EditorConfig = {
|
|
|
18
18
|
open: (path: string, lineNumber: string | undefined, columnNumber?: string) => Promise<void>;
|
|
19
19
|
};
|
|
20
20
|
export declare const DEFAULT_EDITOR_CONFIG: EditorConfig;
|
|
21
|
-
export declare const handleOpenSource: ({ data, openInEditor,
|
|
21
|
+
export declare const handleOpenSource: ({ data, openInEditor, }: {
|
|
22
22
|
data: OpenSourceData;
|
|
23
|
-
appDir: string;
|
|
24
23
|
openInEditor: EditorConfig["open"];
|
|
25
24
|
}) => Promise<void>;
|
|
26
25
|
export {};
|
package/dist/esm/editor.js
CHANGED
|
@@ -1,54 +1,21 @@
|
|
|
1
|
-
import { normalizePath } from "vite";
|
|
2
|
-
import { checkPath } from "./utils.js";
|
|
3
1
|
const DEFAULT_EDITOR_CONFIG = {
|
|
4
2
|
name: "VSCode",
|
|
5
3
|
open: async (path, lineNumber, columnNumber) => {
|
|
6
4
|
const { exec } = await import("node:child_process");
|
|
7
5
|
exec(
|
|
8
|
-
`code -g "${
|
|
6
|
+
`code -g "${path.replaceAll("$", "\\$")}${lineNumber ? `:${lineNumber}` : ""}${columnNumber ? `:${columnNumber}` : ""}"`
|
|
9
7
|
);
|
|
10
8
|
}
|
|
11
9
|
};
|
|
12
10
|
const handleOpenSource = async ({
|
|
13
11
|
data,
|
|
14
|
-
openInEditor
|
|
15
|
-
appDir
|
|
12
|
+
openInEditor
|
|
16
13
|
}) => {
|
|
17
|
-
const { source, line,
|
|
14
|
+
const { source, line, column } = data.data;
|
|
18
15
|
const lineNum = line ? `${line}` : void 0;
|
|
19
|
-
const
|
|
20
|
-
const path = await import("node:path");
|
|
16
|
+
const columnNum = column ? `${column}` : void 0;
|
|
21
17
|
if (source) {
|
|
22
|
-
return openInEditor(source, lineNum);
|
|
23
|
-
}
|
|
24
|
-
if (routeID) {
|
|
25
|
-
const routePath = path.join(appDir, routeID);
|
|
26
|
-
const checkedPath = await checkPath(routePath);
|
|
27
|
-
if (!checkedPath) return;
|
|
28
|
-
const { type, validPath } = checkedPath;
|
|
29
|
-
const reactExtensions = ["tsx", "jsx"];
|
|
30
|
-
const allExtensions = ["ts", "js", ...reactExtensions];
|
|
31
|
-
const isRoot = routeID === "root";
|
|
32
|
-
const findFileByExtension = (prefix, filePaths) => {
|
|
33
|
-
const file = filePaths.find(
|
|
34
|
-
(file2) => allExtensions.some((ext) => file2 === `${prefix}.${ext}`)
|
|
35
|
-
);
|
|
36
|
-
return file;
|
|
37
|
-
};
|
|
38
|
-
if (isRoot) {
|
|
39
|
-
if (!fs.existsSync(appDir)) return;
|
|
40
|
-
const filesInReactRouterPath = fs.readdirSync(appDir);
|
|
41
|
-
const rootFile = findFileByExtension("root", filesInReactRouterPath);
|
|
42
|
-
rootFile && openInEditor(path.join(appDir, rootFile), lineNum);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (type === "directory") {
|
|
46
|
-
const filesInFolderRoute = fs.readdirSync(validPath);
|
|
47
|
-
const routeFile = findFileByExtension("route", filesInFolderRoute);
|
|
48
|
-
routeFile && openInEditor(path.join(appDir, routeID, routeFile), lineNum);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
return openInEditor(validPath, lineNum);
|
|
18
|
+
return openInEditor(source, lineNum, columnNum);
|
|
52
19
|
}
|
|
53
20
|
};
|
|
54
21
|
export {
|
package/dist/esm/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sources":["../../src/editor.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"editor.js","sources":["../../src/editor.ts"],"sourcesContent":["type OpenSourceData = {\n type: 'open-source'\n data: {\n /** The source file to open */\n source?: string\n /** The react router route ID, usually discovered via the hook useMatches */\n routeID?: string\n /** The line number in the source file */\n line?: number\n /** The column number in the source file */\n column?: number\n }\n}\n\nexport type EditorConfig = {\n /** The name of the editor, used for debugging purposes */\n name: string\n /** Callback to open a file in the editor */\n open: (\n path: string,\n lineNumber: string | undefined,\n columnNumber?: string,\n ) => Promise<void>\n}\n\nexport const DEFAULT_EDITOR_CONFIG: EditorConfig = {\n name: 'VSCode',\n open: async (path, lineNumber, columnNumber) => {\n const { exec } = await import('node:child_process')\n exec(\n `code -g \"${path.replaceAll('$', '\\\\$')}${lineNumber ? `:${lineNumber}` : ''}${columnNumber ? `:${columnNumber}` : ''}\"`,\n )\n },\n}\n\nexport const handleOpenSource = async ({\n data,\n openInEditor,\n}: {\n data: OpenSourceData\n openInEditor: EditorConfig['open']\n}) => {\n const { source, line, column } = data.data\n const lineNum = line ? `${line}` : undefined\n const columnNum = column ? `${column}` : undefined\n if (source) {\n return openInEditor(source, lineNum, columnNum)\n }\n}\n"],"names":[],"mappings":"AAyBO,MAAM,wBAAsC;AAAA,EACjD,MAAM;AAAA,EACN,MAAM,OAAO,MAAM,YAAY,iBAAiB;AAC9C,UAAM,EAAE,KAAA,IAAS,MAAM,OAAO,oBAAoB;AAClD;AAAA,MACE,YAAY,KAAK,WAAW,KAAK,KAAK,CAAC,GAAG,aAAa,IAAI,UAAU,KAAK,EAAE,GAAG,eAAe,IAAI,YAAY,KAAK,EAAE;AAAA,IAAA;AAAA,EAEzH;AACF;AAEO,MAAM,mBAAmB,OAAO;AAAA,EACrC;AAAA,EACA;AACF,MAGM;AACJ,QAAM,EAAE,QAAQ,MAAM,OAAA,IAAW,KAAK;AACtC,QAAM,UAAU,OAAO,GAAG,IAAI,KAAK;AACnC,QAAM,YAAY,SAAS,GAAG,MAAM,KAAK;AACzC,MAAI,QAAQ;AACV,WAAO,aAAa,QAAQ,SAAS,SAAS;AAAA,EAChD;AACF;"}
|
package/dist/esm/plugin.d.ts
CHANGED
|
@@ -2,8 +2,6 @@ import { EditorConfig } from './editor.js';
|
|
|
2
2
|
import { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server';
|
|
3
3
|
import { Plugin } from 'vite';
|
|
4
4
|
export type TanStackDevtoolsViteConfig = {
|
|
5
|
-
/** The directory where the react router app is located. Defaults to the "./src" relative to where vite.config is being defined. */
|
|
6
|
-
appDir?: string;
|
|
7
5
|
/**
|
|
8
6
|
* Configuration for the editor integration. Defaults to opening in VS code
|
|
9
7
|
*/
|
package/dist/esm/plugin.js
CHANGED
|
@@ -7,7 +7,6 @@ import { addSourceToJsx } from "./inject-source.js";
|
|
|
7
7
|
const defineDevtoolsConfig = (config) => config;
|
|
8
8
|
const devtools = (args) => {
|
|
9
9
|
let port = 5173;
|
|
10
|
-
const appDir = args?.appDir || "./src";
|
|
11
10
|
const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true };
|
|
12
11
|
const injectSourceConfig = args?.injectSource ?? { enabled: true };
|
|
13
12
|
const bus = new ServerEventBus(args?.eventBusConfig);
|
|
@@ -45,11 +44,11 @@ const devtools = (args) => {
|
|
|
45
44
|
port = server.config.server.port;
|
|
46
45
|
});
|
|
47
46
|
const editor = args?.editor ?? DEFAULT_EDITOR_CONFIG;
|
|
48
|
-
const openInEditor = async (path, lineNum) => {
|
|
47
|
+
const openInEditor = async (path, lineNum, columnNum) => {
|
|
49
48
|
if (!path) {
|
|
50
49
|
return;
|
|
51
50
|
}
|
|
52
|
-
await editor.open(path, lineNum);
|
|
51
|
+
await editor.open(path, lineNum, columnNum);
|
|
53
52
|
};
|
|
54
53
|
server.middlewares.use(
|
|
55
54
|
(req, res, next) => handleDevToolsViteRequest(req, res, next, (parsedData) => {
|
|
@@ -57,8 +56,7 @@ const devtools = (args) => {
|
|
|
57
56
|
if (routine === "open-source") {
|
|
58
57
|
return handleOpenSource({
|
|
59
58
|
data: { type: data.type, data },
|
|
60
|
-
openInEditor
|
|
61
|
-
appDir
|
|
59
|
+
openInEditor
|
|
62
60
|
});
|
|
63
61
|
}
|
|
64
62
|
return;
|
package/dist/esm/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { normalizePath } from 'vite'\nimport chalk from 'chalk'\nimport { ServerEventBus } from '@tanstack/devtools-event-bus/server'\nimport { handleDevToolsViteRequest } from './utils'\nimport { DEFAULT_EDITOR_CONFIG, handleOpenSource } from './editor'\nimport { addSourceToJsx } from './inject-source'\nimport type { EditorConfig } from './editor'\nimport type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server'\nimport type { Plugin } from 'vite'\n\nexport type TanStackDevtoolsViteConfig = {\n
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { normalizePath } from 'vite'\nimport chalk from 'chalk'\nimport { ServerEventBus } from '@tanstack/devtools-event-bus/server'\nimport { handleDevToolsViteRequest } from './utils'\nimport { DEFAULT_EDITOR_CONFIG, handleOpenSource } from './editor'\nimport { addSourceToJsx } from './inject-source'\nimport type { EditorConfig } from './editor'\nimport type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server'\nimport type { Plugin } from 'vite'\n\nexport type TanStackDevtoolsViteConfig = {\n /**\n * Configuration for the editor integration. Defaults to opening in VS code\n */\n editor?: EditorConfig\n /**\n * The configuration options for the server event bus\n */\n eventBusConfig?: ServerEventBusConfig\n /**\n * Configuration for enhanced logging.\n */\n enhancedLogs?: {\n /**\n * Whether to enable enhanced logging.\n * @default true\n */\n enabled: boolean\n }\n /**\n * Configuration for source injection.\n */\n injectSource: {\n /**\n * Whether to enable source injection via data-tsd-source.\n * @default true\n */\n enabled: boolean\n }\n}\n\nexport const defineDevtoolsConfig = (config: TanStackDevtoolsViteConfig) =>\n config\n\nexport const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {\n let port = 5173\n const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true }\n const injectSourceConfig = args?.injectSource ?? { enabled: true }\n const bus = new ServerEventBus(args?.eventBusConfig)\n\n return [\n {\n enforce: 'pre',\n name: '@tanstack/devtools:inject-source',\n apply(config) {\n return config.mode === 'development' && injectSourceConfig.enabled\n },\n transform(code, id) {\n if (\n id.includes('node_modules') ||\n id.includes('?raw') ||\n id.includes('dist') ||\n id.includes('build')\n )\n return code\n\n return addSourceToJsx(code, id)\n },\n },\n {\n enforce: 'pre',\n name: '@tanstack/devtools:custom-server',\n apply(config) {\n // Custom server is only needed in development for piping events to the client\n return config.mode === 'development'\n },\n configureServer(server) {\n bus.start()\n server.middlewares.use((req, _res, next) => {\n if (req.socket.localPort && req.socket.localPort !== port) {\n port = req.socket.localPort\n }\n next()\n })\n if (server.config.server.port) {\n port = server.config.server.port\n }\n\n server.httpServer?.on('listening', () => {\n port = server.config.server.port\n })\n\n const editor = args?.editor ?? DEFAULT_EDITOR_CONFIG\n const openInEditor: EditorConfig['open'] = async (\n path,\n lineNum,\n columnNum,\n ) => {\n if (!path) {\n return\n }\n await editor.open(path, lineNum, columnNum)\n }\n server.middlewares.use((req, res, next) =>\n handleDevToolsViteRequest(req, res, next, (parsedData) => {\n const { data, routine } = parsedData\n if (routine === 'open-source') {\n return handleOpenSource({\n data: { type: data.type, data },\n openInEditor,\n })\n }\n return\n }),\n )\n },\n transform(code) {\n if (code.includes('__TSD_PORT__')) {\n code = code.replace('__TSD_PORT__', String(port))\n }\n return code\n },\n },\n {\n name: '@tanstack/devtools:better-console-logs',\n enforce: 'pre',\n apply(config) {\n return config.mode === 'development' && enhancedLogsConfig.enabled\n },\n transform(code, id) {\n // Ignore anything external\n if (\n id.includes('node_modules') ||\n id.includes('?raw') ||\n id.includes('dist') ||\n id.includes('build')\n )\n return code\n\n if (!code.includes('console.')) {\n return code\n }\n const lines = code.split('\\n')\n return lines\n .map((line, lineNumber) => {\n if (\n line.trim().startsWith('//') ||\n line.trim().startsWith('/**') ||\n line.trim().startsWith('*')\n ) {\n return line\n }\n // Do not add for arrow functions or return statements\n if (\n line.replaceAll(' ', '').includes('=>console.') ||\n line.includes('return console.')\n ) {\n return line\n }\n\n const column = line.indexOf('console.')\n const location = `${id.replace(normalizePath(process.cwd()), '')}:${lineNumber + 1}:${column + 1}`\n const logMessage = `'${chalk.magenta('LOG')} ${chalk.blueBright(`${location} - http://localhost:${port}/__tsd/open-source?source=${encodeURIComponent(id.replace(normalizePath(process.cwd()), ''))}&line=${lineNumber + 1}&column=${column + 1}`)}\\\\n → '`\n if (line.includes('console.log(')) {\n const newLine = `console.log(${logMessage},`\n return line.replace('console.log(', newLine)\n }\n if (line.includes('console.error(')) {\n const newLine = `console.error(${logMessage},`\n return line.replace('console.error(', newLine)\n }\n return line\n })\n .join('\\n')\n },\n },\n ]\n}\n"],"names":[],"mappings":"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"}
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
import { Connect } from 'vite';
|
|
2
2
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
3
|
export declare const handleDevToolsViteRequest: (req: Connect.IncomingMessage, res: ServerResponse<IncomingMessage>, next: Connect.NextFunction, cb: (data: any) => void) => void;
|
|
4
|
-
export declare function checkPath(routePath: string, extensions?: string[]): Promise<{
|
|
5
|
-
readonly validPath: string;
|
|
6
|
-
readonly type: "directory";
|
|
7
|
-
} | {
|
|
8
|
-
readonly validPath: string;
|
|
9
|
-
readonly type: "file";
|
|
10
|
-
} | null>;
|
package/dist/esm/utils.js
CHANGED
|
@@ -3,13 +3,15 @@ const handleDevToolsViteRequest = (req, res, next, cb) => {
|
|
|
3
3
|
if (req.url?.includes("__tsd/open-source")) {
|
|
4
4
|
const searchParams = new URLSearchParams(req.url.split("?")[1]);
|
|
5
5
|
const source = searchParams.get("source");
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
if (!source) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const [file, line, column] = source.split(":");
|
|
8
10
|
cb({
|
|
9
11
|
type: "open-source",
|
|
10
12
|
routine: "open-source",
|
|
11
13
|
data: {
|
|
12
|
-
source:
|
|
14
|
+
source: file ? normalizePath(`${process.cwd()}/${file}`) : void 0,
|
|
13
15
|
line,
|
|
14
16
|
column
|
|
15
17
|
}
|
|
@@ -36,21 +38,7 @@ const handleDevToolsViteRequest = (req, res, next, cb) => {
|
|
|
36
38
|
res.write("OK");
|
|
37
39
|
});
|
|
38
40
|
};
|
|
39
|
-
async function checkPath(routePath, extensions = [".tsx", ".jsx", ".ts", ".js"]) {
|
|
40
|
-
const fs = await import("node:fs");
|
|
41
|
-
if (fs.existsSync(routePath) && fs.lstatSync(routePath).isDirectory()) {
|
|
42
|
-
return { validPath: routePath, type: "directory" };
|
|
43
|
-
}
|
|
44
|
-
for (const ext of extensions) {
|
|
45
|
-
const filePath = `${routePath}${ext}`;
|
|
46
|
-
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
47
|
-
return { validPath: filePath, type: "file" };
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
41
|
export {
|
|
53
|
-
checkPath,
|
|
54
42
|
handleDevToolsViteRequest
|
|
55
43
|
};
|
|
56
44
|
//# sourceMappingURL=utils.js.map
|
package/dist/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import { normalizePath } from 'vite'\nimport type { Connect } from 'vite'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nexport const handleDevToolsViteRequest = (\n req: Connect.IncomingMessage,\n res: ServerResponse<IncomingMessage>,\n next: Connect.NextFunction,\n cb: (data: any) => void,\n) => {\n if (req.url?.includes('__tsd/open-source')) {\n const searchParams = new URLSearchParams(req.url.split('?')[1])\n const source = searchParams.get('source')\n
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import { normalizePath } from 'vite'\nimport type { Connect } from 'vite'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nexport const handleDevToolsViteRequest = (\n req: Connect.IncomingMessage,\n res: ServerResponse<IncomingMessage>,\n next: Connect.NextFunction,\n cb: (data: any) => void,\n) => {\n if (req.url?.includes('__tsd/open-source')) {\n const searchParams = new URLSearchParams(req.url.split('?')[1])\n const source = searchParams.get('source')\n if (!source) {\n return\n }\n const [file, line, column] = source.split(':')\n\n cb({\n type: 'open-source',\n routine: 'open-source',\n data: {\n source: file ? normalizePath(`${process.cwd()}/${file}`) : undefined,\n line,\n column,\n },\n })\n res.setHeader('Content-Type', 'text/html')\n res.write(`<script> window.close(); </script>`)\n res.end()\n return\n }\n if (!req.url?.includes('__tsd')) {\n return next()\n }\n\n const chunks: Array<any> = []\n req.on('data', (chunk) => {\n chunks.push(chunk)\n })\n req.on('end', () => {\n const dataToParse = Buffer.concat(chunks)\n try {\n const parsedData = JSON.parse(dataToParse.toString())\n cb(parsedData)\n } catch (e) {}\n res.write('OK')\n })\n}\n"],"names":[],"mappings":";AAIO,MAAM,4BAA4B,CACvC,KACA,KACA,MACA,OACG;AACH,MAAI,IAAI,KAAK,SAAS,mBAAmB,GAAG;AAC1C,UAAM,eAAe,IAAI,gBAAgB,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AAC9D,UAAM,SAAS,aAAa,IAAI,QAAQ;AACxC,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AACA,UAAM,CAAC,MAAM,MAAM,MAAM,IAAI,OAAO,MAAM,GAAG;AAE7C,OAAG;AAAA,MACD,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,QAAQ,OAAO,cAAc,GAAG,QAAQ,KAAK,IAAI,IAAI,EAAE,IAAI;AAAA,QAC3D;AAAA,QACA;AAAA,MAAA;AAAA,IACF,CACD;AACD,QAAI,UAAU,gBAAgB,WAAW;AACzC,QAAI,MAAM,qCAAoC;AAC9C,QAAI,IAAA;AACJ;AAAA,EACF;AACA,MAAI,CAAC,IAAI,KAAK,SAAS,OAAO,GAAG;AAC/B,WAAO,KAAA;AAAA,EACT;AAEA,QAAM,SAAqB,CAAA;AAC3B,MAAI,GAAG,QAAQ,CAAC,UAAU;AACxB,WAAO,KAAK,KAAK;AAAA,EACnB,CAAC;AACD,MAAI,GAAG,OAAO,MAAM;AAClB,UAAM,cAAc,OAAO,OAAO,MAAM;AACxC,QAAI;AACF,YAAM,aAAa,KAAK,MAAM,YAAY,UAAU;AACpD,SAAG,UAAU;AAAA,IACf,SAAS,GAAG;AAAA,IAAC;AACb,QAAI,MAAM,IAAI;AAAA,EAChB,CAAC;AACH;"}
|
package/package.json
CHANGED
package/src/editor.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { normalizePath } from 'vite'
|
|
2
|
-
import { checkPath } from './utils.js'
|
|
3
|
-
|
|
4
1
|
type OpenSourceData = {
|
|
5
2
|
type: 'open-source'
|
|
6
3
|
data: {
|
|
@@ -31,7 +28,7 @@ export const DEFAULT_EDITOR_CONFIG: EditorConfig = {
|
|
|
31
28
|
open: async (path, lineNumber, columnNumber) => {
|
|
32
29
|
const { exec } = await import('node:child_process')
|
|
33
30
|
exec(
|
|
34
|
-
`code -g "${
|
|
31
|
+
`code -g "${path.replaceAll('$', '\\$')}${lineNumber ? `:${lineNumber}` : ''}${columnNumber ? `:${columnNumber}` : ''}"`,
|
|
35
32
|
)
|
|
36
33
|
},
|
|
37
34
|
}
|
|
@@ -39,54 +36,14 @@ export const DEFAULT_EDITOR_CONFIG: EditorConfig = {
|
|
|
39
36
|
export const handleOpenSource = async ({
|
|
40
37
|
data,
|
|
41
38
|
openInEditor,
|
|
42
|
-
appDir,
|
|
43
39
|
}: {
|
|
44
40
|
data: OpenSourceData
|
|
45
|
-
appDir: string
|
|
46
41
|
openInEditor: EditorConfig['open']
|
|
47
42
|
}) => {
|
|
48
|
-
const { source, line,
|
|
43
|
+
const { source, line, column } = data.data
|
|
49
44
|
const lineNum = line ? `${line}` : undefined
|
|
50
|
-
const
|
|
51
|
-
const path = await import('node:path')
|
|
45
|
+
const columnNum = column ? `${column}` : undefined
|
|
52
46
|
if (source) {
|
|
53
|
-
return openInEditor(source, lineNum)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (routeID) {
|
|
57
|
-
const routePath = path.join(appDir, routeID)
|
|
58
|
-
const checkedPath = await checkPath(routePath)
|
|
59
|
-
|
|
60
|
-
if (!checkedPath) return
|
|
61
|
-
const { type, validPath } = checkedPath
|
|
62
|
-
|
|
63
|
-
const reactExtensions = ['tsx', 'jsx']
|
|
64
|
-
const allExtensions = ['ts', 'js', ...reactExtensions]
|
|
65
|
-
const isRoot = routeID === 'root'
|
|
66
|
-
const findFileByExtension = (prefix: string, filePaths: Array<string>) => {
|
|
67
|
-
const file = filePaths.find((file) =>
|
|
68
|
-
allExtensions.some((ext) => file === `${prefix}.${ext}`),
|
|
69
|
-
)
|
|
70
|
-
return file
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (isRoot) {
|
|
74
|
-
if (!fs.existsSync(appDir)) return
|
|
75
|
-
const filesInReactRouterPath = fs.readdirSync(appDir)
|
|
76
|
-
const rootFile = findFileByExtension('root', filesInReactRouterPath)
|
|
77
|
-
rootFile && openInEditor(path.join(appDir, rootFile), lineNum)
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// If its not the root route, then we find the file or folder in the routes folder
|
|
82
|
-
// We know that the route ID is in the form of "routes/contact" or "routes/user.profile" when is not root
|
|
83
|
-
// so the ID already contains the "routes" segment, so we just need to find the file or folder in the routes folder
|
|
84
|
-
if (type === 'directory') {
|
|
85
|
-
const filesInFolderRoute = fs.readdirSync(validPath)
|
|
86
|
-
const routeFile = findFileByExtension('route', filesInFolderRoute)
|
|
87
|
-
routeFile && openInEditor(path.join(appDir, routeID, routeFile), lineNum)
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
return openInEditor(validPath, lineNum)
|
|
47
|
+
return openInEditor(source, lineNum, columnNum)
|
|
91
48
|
}
|
|
92
49
|
}
|
package/src/plugin.ts
CHANGED
|
@@ -9,8 +9,6 @@ import type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server'
|
|
|
9
9
|
import type { Plugin } from 'vite'
|
|
10
10
|
|
|
11
11
|
export type TanStackDevtoolsViteConfig = {
|
|
12
|
-
/** The directory where the react router app is located. Defaults to the "./src" relative to where vite.config is being defined. */
|
|
13
|
-
appDir?: string
|
|
14
12
|
/**
|
|
15
13
|
* Configuration for the editor integration. Defaults to opening in VS code
|
|
16
14
|
*/
|
|
@@ -46,7 +44,6 @@ export const defineDevtoolsConfig = (config: TanStackDevtoolsViteConfig) =>
|
|
|
46
44
|
|
|
47
45
|
export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
|
|
48
46
|
let port = 5173
|
|
49
|
-
const appDir = args?.appDir || './src'
|
|
50
47
|
const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true }
|
|
51
48
|
const injectSourceConfig = args?.injectSource ?? { enabled: true }
|
|
52
49
|
const bus = new ServerEventBus(args?.eventBusConfig)
|
|
@@ -94,14 +91,15 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
|
|
|
94
91
|
})
|
|
95
92
|
|
|
96
93
|
const editor = args?.editor ?? DEFAULT_EDITOR_CONFIG
|
|
97
|
-
const openInEditor = async (
|
|
98
|
-
path
|
|
99
|
-
lineNum
|
|
94
|
+
const openInEditor: EditorConfig['open'] = async (
|
|
95
|
+
path,
|
|
96
|
+
lineNum,
|
|
97
|
+
columnNum,
|
|
100
98
|
) => {
|
|
101
99
|
if (!path) {
|
|
102
100
|
return
|
|
103
101
|
}
|
|
104
|
-
await editor.open(path, lineNum)
|
|
102
|
+
await editor.open(path, lineNum, columnNum)
|
|
105
103
|
}
|
|
106
104
|
server.middlewares.use((req, res, next) =>
|
|
107
105
|
handleDevToolsViteRequest(req, res, next, (parsedData) => {
|
|
@@ -110,7 +108,6 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
|
|
|
110
108
|
return handleOpenSource({
|
|
111
109
|
data: { type: data.type, data },
|
|
112
110
|
openInEditor,
|
|
113
|
-
appDir,
|
|
114
111
|
})
|
|
115
112
|
}
|
|
116
113
|
return
|
package/src/utils.ts
CHANGED
|
@@ -11,15 +11,16 @@ export const handleDevToolsViteRequest = (
|
|
|
11
11
|
if (req.url?.includes('__tsd/open-source')) {
|
|
12
12
|
const searchParams = new URLSearchParams(req.url.split('?')[1])
|
|
13
13
|
const source = searchParams.get('source')
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (!source) {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
const [file, line, column] = source.split(':')
|
|
18
|
+
|
|
16
19
|
cb({
|
|
17
20
|
type: 'open-source',
|
|
18
21
|
routine: 'open-source',
|
|
19
22
|
data: {
|
|
20
|
-
source:
|
|
21
|
-
? normalizePath(`${process.cwd()}/${source}`)
|
|
22
|
-
: undefined,
|
|
23
|
+
source: file ? normalizePath(`${process.cwd()}/${file}`) : undefined,
|
|
23
24
|
line,
|
|
24
25
|
column,
|
|
25
26
|
},
|
|
@@ -46,25 +47,3 @@ export const handleDevToolsViteRequest = (
|
|
|
46
47
|
res.write('OK')
|
|
47
48
|
})
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
export async function checkPath(
|
|
51
|
-
routePath: string,
|
|
52
|
-
extensions = ['.tsx', '.jsx', '.ts', '.js'],
|
|
53
|
-
) {
|
|
54
|
-
const fs = await import('node:fs')
|
|
55
|
-
// Check if the path exists as a directory
|
|
56
|
-
if (fs.existsSync(routePath) && fs.lstatSync(routePath).isDirectory()) {
|
|
57
|
-
return { validPath: routePath, type: 'directory' } as const
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Check if the path exists as a file with one of the given extensions
|
|
61
|
-
for (const ext of extensions) {
|
|
62
|
-
const filePath = `${routePath}${ext}`
|
|
63
|
-
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
|
|
64
|
-
return { validPath: filePath, type: 'file' } as const
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// If neither a file nor a directory is found
|
|
69
|
-
return null
|
|
70
|
-
}
|