@tanstack/devtools-vite 0.3.2 → 0.3.3

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.
@@ -1,3 +1 @@
1
- export declare function enhanceConsoleLog(code: string, id: string, port: number): import('@babel/generator').GeneratorResult | {
2
- code: string;
3
- };
1
+ export declare function enhanceConsoleLog(code: string, id: string, port: number): import('@babel/generator').GeneratorResult | undefined;
@@ -40,7 +40,7 @@ function enhanceConsoleLog(code, id, port) {
40
40
  });
41
41
  const didTransform = transform(ast, location, port);
42
42
  if (!didTransform) {
43
- return { code };
43
+ return;
44
44
  }
45
45
  return gen(ast, {
46
46
  sourceMaps: true,
@@ -49,7 +49,7 @@ function enhanceConsoleLog(code, id, port) {
49
49
  sourceFileName: filePath
50
50
  });
51
51
  } catch (e) {
52
- return { code };
52
+ return;
53
53
  }
54
54
  }
55
55
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"enhance-logs.js","sources":["../../src/enhance-logs.ts"],"sourcesContent":["import chalk from 'chalk'\nimport { normalizePath } from 'vite'\nimport { gen, parse, t, trav } from './babel'\nimport type { types as Babel } from '@babel/core'\nimport type { ParseResult } from '@babel/parser'\n\nconst transform = (\n ast: ParseResult<Babel.File>,\n filePath: string,\n port: number,\n) => {\n let didTransform = false\n\n trav(ast, {\n CallExpression(path) {\n const callee = path.node.callee\n // Match console.log(...) or console.error(...)\n if (\n callee.type === 'MemberExpression' &&\n callee.object.type === 'Identifier' &&\n callee.object.name === 'console' &&\n callee.property.type === 'Identifier' &&\n (callee.property.name === 'log' || callee.property.name === 'error')\n ) {\n const location = path.node.loc\n if (!location) {\n return\n }\n const [lineNumber, column] = [\n location.start.line,\n location.start.column,\n ]\n const finalPath = `${filePath}:${lineNumber}:${column + 1}`\n path.node.arguments.unshift(\n t.stringLiteral(\n `${chalk.magenta('LOG')} ${chalk.blueBright(`${finalPath} - http://localhost:${port}/__tsd/open-source?source=${encodeURIComponent(finalPath)}`)}\\n → `,\n ),\n )\n didTransform = true\n }\n },\n })\n\n return didTransform\n}\n\nexport function enhanceConsoleLog(code: string, id: string, port: number) {\n const [filePath] = id.split('?')\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n const location = filePath?.replace(normalizePath(process.cwd()), '')!\n\n try {\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n })\n const didTransform = transform(ast, location, port)\n if (!didTransform) {\n return { code }\n }\n return gen(ast, {\n sourceMaps: true,\n retainLines: true,\n filename: id,\n sourceFileName: filePath,\n })\n } catch (e) {\n return { code }\n }\n}\n"],"names":[],"mappings":";;;;;AAMA,MAAM,YAAY,CAChB,KACA,UACA,SACG;AACH,MAAI,eAAe;AAEnB,OAAK,KAAK;AAAA,IACR,eAAe,MAAM;AACnB,YAAM,SAAS,KAAK,KAAK;AAEzB,UACE,OAAO,SAAS,sBAChB,OAAO,OAAO,SAAS,gBACvB,OAAO,OAAO,SAAS,aACvB,OAAO,SAAS,SAAS,iBACxB,OAAO,SAAS,SAAS,SAAS,OAAO,SAAS,SAAS,UAC5D;AACA,cAAM,WAAW,KAAK,KAAK;AAC3B,YAAI,CAAC,UAAU;AACb;AAAA,QACF;AACA,cAAM,CAAC,YAAY,MAAM,IAAI;AAAA,UAC3B,SAAS,MAAM;AAAA,UACf,SAAS,MAAM;AAAA,QAAA;AAEjB,cAAM,YAAY,GAAG,QAAQ,IAAI,UAAU,IAAI,SAAS,CAAC;AACzD,aAAK,KAAK,UAAU;AAAA,UAClB,EAAE;AAAA,YACA,GAAG,MAAM,QAAQ,KAAK,CAAC,IAAI,MAAM,WAAW,GAAG,SAAS,uBAAuB,IAAI,6BAA6B,mBAAmB,SAAS,CAAC,EAAE,CAAC;AAAA;AAAA,UAAA;AAAA,QAClJ;AAEF,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,EAAA,CACD;AAED,SAAO;AACT;AAEO,SAAS,kBAAkB,MAAc,IAAY,MAAc;AACxE,QAAM,CAAC,QAAQ,IAAI,GAAG,MAAM,GAAG;AAE/B,QAAM,WAAW,UAAU,QAAQ,cAAc,QAAQ,IAAA,CAAK,GAAG,EAAE;AAEnE,MAAI;AACF,UAAM,MAAM,MAAM,MAAM;AAAA,MACtB,YAAY;AAAA,MACZ,SAAS,CAAC,OAAO,YAAY;AAAA,IAAA,CAC9B;AACD,UAAM,eAAe,UAAU,KAAK,UAAU,IAAI;AAClD,QAAI,CAAC,cAAc;AACjB,aAAO,EAAE,KAAA;AAAA,IACX;AACA,WAAO,IAAI,KAAK;AAAA,MACd,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,UAAU;AAAA,MACV,gBAAgB;AAAA,IAAA,CACjB;AAAA,EACH,SAAS,GAAG;AACV,WAAO,EAAE,KAAA;AAAA,EACX;AACF;"}
1
+ {"version":3,"file":"enhance-logs.js","sources":["../../src/enhance-logs.ts"],"sourcesContent":["import chalk from 'chalk'\nimport { normalizePath } from 'vite'\nimport { gen, parse, t, trav } from './babel'\nimport type { types as Babel } from '@babel/core'\nimport type { ParseResult } from '@babel/parser'\n\nconst transform = (\n ast: ParseResult<Babel.File>,\n filePath: string,\n port: number,\n) => {\n let didTransform = false\n\n trav(ast, {\n CallExpression(path) {\n const callee = path.node.callee\n // Match console.log(...) or console.error(...)\n if (\n callee.type === 'MemberExpression' &&\n callee.object.type === 'Identifier' &&\n callee.object.name === 'console' &&\n callee.property.type === 'Identifier' &&\n (callee.property.name === 'log' || callee.property.name === 'error')\n ) {\n const location = path.node.loc\n if (!location) {\n return\n }\n const [lineNumber, column] = [\n location.start.line,\n location.start.column,\n ]\n const finalPath = `${filePath}:${lineNumber}:${column + 1}`\n path.node.arguments.unshift(\n t.stringLiteral(\n `${chalk.magenta('LOG')} ${chalk.blueBright(`${finalPath} - http://localhost:${port}/__tsd/open-source?source=${encodeURIComponent(finalPath)}`)}\\n → `,\n ),\n )\n didTransform = true\n }\n },\n })\n\n return didTransform\n}\n\nexport function enhanceConsoleLog(code: string, id: string, port: number) {\n const [filePath] = id.split('?')\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n const location = filePath?.replace(normalizePath(process.cwd()), '')!\n\n try {\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n })\n const didTransform = transform(ast, location, port)\n if (!didTransform) {\n return\n }\n return gen(ast, {\n sourceMaps: true,\n retainLines: true,\n filename: id,\n sourceFileName: filePath,\n })\n } catch (e) {\n return\n }\n}\n"],"names":[],"mappings":";;;;;AAMA,MAAM,YAAY,CAChB,KACA,UACA,SACG;AACH,MAAI,eAAe;AAEnB,OAAK,KAAK;AAAA,IACR,eAAe,MAAM;AACnB,YAAM,SAAS,KAAK,KAAK;AAEzB,UACE,OAAO,SAAS,sBAChB,OAAO,OAAO,SAAS,gBACvB,OAAO,OAAO,SAAS,aACvB,OAAO,SAAS,SAAS,iBACxB,OAAO,SAAS,SAAS,SAAS,OAAO,SAAS,SAAS,UAC5D;AACA,cAAM,WAAW,KAAK,KAAK;AAC3B,YAAI,CAAC,UAAU;AACb;AAAA,QACF;AACA,cAAM,CAAC,YAAY,MAAM,IAAI;AAAA,UAC3B,SAAS,MAAM;AAAA,UACf,SAAS,MAAM;AAAA,QAAA;AAEjB,cAAM,YAAY,GAAG,QAAQ,IAAI,UAAU,IAAI,SAAS,CAAC;AACzD,aAAK,KAAK,UAAU;AAAA,UAClB,EAAE;AAAA,YACA,GAAG,MAAM,QAAQ,KAAK,CAAC,IAAI,MAAM,WAAW,GAAG,SAAS,uBAAuB,IAAI,6BAA6B,mBAAmB,SAAS,CAAC,EAAE,CAAC;AAAA;AAAA,UAAA;AAAA,QAClJ;AAEF,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,EAAA,CACD;AAED,SAAO;AACT;AAEO,SAAS,kBAAkB,MAAc,IAAY,MAAc;AACxE,QAAM,CAAC,QAAQ,IAAI,GAAG,MAAM,GAAG;AAE/B,QAAM,WAAW,UAAU,QAAQ,cAAc,QAAQ,IAAA,CAAK,GAAG,EAAE;AAEnE,MAAI;AACF,UAAM,MAAM,MAAM,MAAM;AAAA,MACtB,YAAY;AAAA,MACZ,SAAS,CAAC,OAAO,YAAY;AAAA,IAAA,CAC9B;AACD,UAAM,eAAe,UAAU,KAAK,UAAU,IAAI;AAClD,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AACA,WAAO,IAAI,KAAK;AAAA,MACd,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,UAAU;AAAA,MACV,gBAAgB;AAAA,IAAA,CACjB;AAAA,EACH,SAAS,GAAG;AACV;AAAA,EACF;AACF;"}
@@ -1,3 +1 @@
1
- export declare function addSourceToJsx(code: string, id: string): import('@babel/generator').GeneratorResult | {
2
- code: string;
3
- };
1
+ export declare function addSourceToJsx(code: string, id: string): import('@babel/generator').GeneratorResult | undefined;
@@ -164,7 +164,7 @@ function addSourceToJsx(code, id) {
164
164
  });
165
165
  const didTransform = transform(ast, location);
166
166
  if (!didTransform) {
167
- return { code };
167
+ return;
168
168
  }
169
169
  return gen(ast, {
170
170
  sourceMaps: true,
@@ -173,7 +173,7 @@ function addSourceToJsx(code, id) {
173
173
  sourceFileName: filePath
174
174
  });
175
175
  } catch (e) {
176
- return { code };
176
+ return;
177
177
  }
178
178
  }
179
179
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"inject-source.js","sources":["../../src/inject-source.ts"],"sourcesContent":["import { normalizePath } from 'vite'\nimport { gen, parse, t, trav } from './babel'\nimport type { types as Babel, NodePath } from '@babel/core'\nimport type { ParseResult } from '@babel/parser'\n\nconst getPropsNameFromFunctionDeclaration = (\n functionDeclaration:\n | t.VariableDeclarator\n | t.FunctionExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression,\n) => {\n let propsName: string | null = null\n\n if (functionDeclaration.type === 'FunctionExpression') {\n const firstArgument = functionDeclaration.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n return propsName\n }\n if (functionDeclaration.type === 'ArrowFunctionExpression') {\n const firstArgument = functionDeclaration.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n return propsName\n }\n if (functionDeclaration.type === 'FunctionDeclaration') {\n const firstArgument = functionDeclaration.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n return propsName\n }\n // Arrow function case\n if (\n functionDeclaration.init?.type === 'ArrowFunctionExpression' ||\n functionDeclaration.init?.type === 'FunctionExpression'\n ) {\n const firstArgument = functionDeclaration.init.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n }\n return propsName\n}\n\nconst getNameOfElement = (\n element: t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName,\n): string => {\n if (element.type === 'JSXIdentifier') {\n return element.name\n }\n if (element.type === 'JSXMemberExpression') {\n return `${getNameOfElement(element.object)}.${getNameOfElement(element.property)}`\n }\n\n return `${element.namespace.name}:${element.name.name}`\n}\n\nconst transformJSX = (\n element: NodePath<t.JSXOpeningElement>,\n propsName: string | null,\n file: string,\n) => {\n const loc = element.node.loc\n if (!loc) return\n const line = loc.start.line\n const column = loc.start.column\n const nameOfElement = getNameOfElement(element.node.name)\n\n if (nameOfElement === 'Fragment' || nameOfElement === 'React.Fragment') {\n return\n }\n const hasDataSource = element.node.attributes.some(\n (attr) =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === 'data-tsd-source',\n )\n // Check if props are spread\n const hasSpread = element.node.attributes.some(\n (attr) =>\n attr.type === 'JSXSpreadAttribute' &&\n attr.argument.type === 'Identifier' &&\n attr.argument.name === propsName,\n )\n\n if (hasSpread || hasDataSource) {\n // Do not inject if props are spread\n return\n }\n\n // Inject data-source as a string: \"<file>:<line>:<column>\"\n element.node.attributes.push(\n t.jsxAttribute(\n t.jsxIdentifier('data-tsd-source'),\n t.stringLiteral(`${file}:${line}:${column + 1}`),\n ),\n )\n\n return true\n}\n\nconst transform = (ast: ParseResult<Babel.File>, file: string) => {\n let didTransform = false\n\n trav(ast, {\n FunctionDeclaration(functionDeclaration) {\n const propsName = getPropsNameFromFunctionDeclaration(\n functionDeclaration.node,\n )\n functionDeclaration.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n ArrowFunctionExpression(path) {\n const propsName = getPropsNameFromFunctionDeclaration(path.node)\n path.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n FunctionExpression(path) {\n const propsName = getPropsNameFromFunctionDeclaration(path.node)\n path.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n VariableDeclaration(path) {\n const functionDeclaration = path.node.declarations.find((decl) => {\n return (\n decl.init?.type === 'ArrowFunctionExpression' ||\n decl.init?.type === 'FunctionExpression'\n )\n })\n if (!functionDeclaration) {\n return\n }\n const propsName = getPropsNameFromFunctionDeclaration(functionDeclaration)\n\n path.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n })\n\n return didTransform\n}\n\nexport function addSourceToJsx(code: string, id: string) {\n const [filePath] = id.split('?')\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n const location = filePath?.replace(normalizePath(process.cwd()), '')!\n\n try {\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n })\n const didTransform = transform(ast, location)\n if (!didTransform) {\n return { code }\n }\n return gen(ast, {\n sourceMaps: true,\n retainLines: true,\n filename: id,\n sourceFileName: filePath,\n })\n } catch (e) {\n return { code }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inject-source.js","sources":["../../src/inject-source.ts"],"sourcesContent":["import { normalizePath } from 'vite'\nimport { gen, parse, t, trav } from './babel'\nimport type { types as Babel, NodePath } from '@babel/core'\nimport type { ParseResult } from '@babel/parser'\n\nconst getPropsNameFromFunctionDeclaration = (\n functionDeclaration:\n | t.VariableDeclarator\n | t.FunctionExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression,\n) => {\n let propsName: string | null = null\n\n if (functionDeclaration.type === 'FunctionExpression') {\n const firstArgument = functionDeclaration.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n return propsName\n }\n if (functionDeclaration.type === 'ArrowFunctionExpression') {\n const firstArgument = functionDeclaration.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n return propsName\n }\n if (functionDeclaration.type === 'FunctionDeclaration') {\n const firstArgument = functionDeclaration.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n return propsName\n }\n // Arrow function case\n if (\n functionDeclaration.init?.type === 'ArrowFunctionExpression' ||\n functionDeclaration.init?.type === 'FunctionExpression'\n ) {\n const firstArgument = functionDeclaration.init.params[0]\n // handles (props) => {}\n if (firstArgument && firstArgument.type === 'Identifier') {\n propsName = firstArgument.name\n }\n // handles ({ ...props }) => {}\n if (firstArgument && firstArgument.type === 'ObjectPattern') {\n firstArgument.properties.forEach((prop) => {\n if (\n prop.type === 'RestElement' &&\n prop.argument.type === 'Identifier'\n ) {\n propsName = prop.argument.name\n }\n })\n }\n }\n return propsName\n}\n\nconst getNameOfElement = (\n element: t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName,\n): string => {\n if (element.type === 'JSXIdentifier') {\n return element.name\n }\n if (element.type === 'JSXMemberExpression') {\n return `${getNameOfElement(element.object)}.${getNameOfElement(element.property)}`\n }\n\n return `${element.namespace.name}:${element.name.name}`\n}\n\nconst transformJSX = (\n element: NodePath<t.JSXOpeningElement>,\n propsName: string | null,\n file: string,\n) => {\n const loc = element.node.loc\n if (!loc) return\n const line = loc.start.line\n const column = loc.start.column\n const nameOfElement = getNameOfElement(element.node.name)\n\n if (nameOfElement === 'Fragment' || nameOfElement === 'React.Fragment') {\n return\n }\n const hasDataSource = element.node.attributes.some(\n (attr) =>\n attr.type === 'JSXAttribute' &&\n attr.name.type === 'JSXIdentifier' &&\n attr.name.name === 'data-tsd-source',\n )\n // Check if props are spread\n const hasSpread = element.node.attributes.some(\n (attr) =>\n attr.type === 'JSXSpreadAttribute' &&\n attr.argument.type === 'Identifier' &&\n attr.argument.name === propsName,\n )\n\n if (hasSpread || hasDataSource) {\n // Do not inject if props are spread\n return\n }\n\n // Inject data-source as a string: \"<file>:<line>:<column>\"\n element.node.attributes.push(\n t.jsxAttribute(\n t.jsxIdentifier('data-tsd-source'),\n t.stringLiteral(`${file}:${line}:${column + 1}`),\n ),\n )\n\n return true\n}\n\nconst transform = (ast: ParseResult<Babel.File>, file: string) => {\n let didTransform = false\n\n trav(ast, {\n FunctionDeclaration(functionDeclaration) {\n const propsName = getPropsNameFromFunctionDeclaration(\n functionDeclaration.node,\n )\n functionDeclaration.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n ArrowFunctionExpression(path) {\n const propsName = getPropsNameFromFunctionDeclaration(path.node)\n path.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n FunctionExpression(path) {\n const propsName = getPropsNameFromFunctionDeclaration(path.node)\n path.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n VariableDeclaration(path) {\n const functionDeclaration = path.node.declarations.find((decl) => {\n return (\n decl.init?.type === 'ArrowFunctionExpression' ||\n decl.init?.type === 'FunctionExpression'\n )\n })\n if (!functionDeclaration) {\n return\n }\n const propsName = getPropsNameFromFunctionDeclaration(functionDeclaration)\n\n path.traverse({\n JSXOpeningElement(element) {\n const transformed = transformJSX(element, propsName, file)\n if (transformed) {\n didTransform = true\n }\n },\n })\n },\n })\n\n return didTransform\n}\n\nexport function addSourceToJsx(code: string, id: string) {\n const [filePath] = id.split('?')\n // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain\n const location = filePath?.replace(normalizePath(process.cwd()), '')!\n\n try {\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n })\n const didTransform = transform(ast, location)\n if (!didTransform) {\n return\n }\n return gen(ast, {\n sourceMaps: true,\n retainLines: true,\n filename: id,\n sourceFileName: filePath,\n })\n } catch (e) {\n return\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { Plugin } from 'vite';
1
2
  import { EditorConfig } from './editor.js';
2
3
  import { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server';
3
- import { Plugin } from 'vite';
4
4
  export type TanStackDevtoolsViteConfig = {
5
5
  /**
6
6
  * Configuration for the editor integration. Defaults to opening in VS code
@@ -25,6 +25,11 @@ export type TanStackDevtoolsViteConfig = {
25
25
  * @default true
26
26
  */
27
27
  removeDevtoolsOnBuild?: boolean;
28
+ /**
29
+ * Whether to log information to the console.
30
+ * @default true
31
+ */
32
+ logging?: boolean;
28
33
  /**
29
34
  * Configuration for source injection.
30
35
  */
@@ -1,4 +1,6 @@
1
1
  import { ServerEventBus } from "@tanstack/devtools-event-bus/server";
2
+ import { normalizePath } from "vite";
3
+ import chalk from "chalk";
2
4
  import { handleDevToolsViteRequest } from "./utils.js";
3
5
  import { DEFAULT_EDITOR_CONFIG, handleOpenSource } from "./editor.js";
4
6
  import { removeDevtools } from "./remove-devtools.js";
@@ -7,6 +9,7 @@ import { enhanceConsoleLog } from "./enhance-logs.js";
7
9
  const defineDevtoolsConfig = (config) => config;
8
10
  const devtools = (args) => {
9
11
  let port = 5173;
12
+ const logging = args?.logging ?? true;
10
13
  const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true };
11
14
  const injectSourceConfig = args?.injectSource ?? { enabled: true };
12
15
  const removeDevtoolsOnBuild = args?.removeDevtoolsOnBuild ?? true;
@@ -20,7 +23,7 @@ const devtools = (args) => {
20
23
  },
21
24
  transform(code, id) {
22
25
  if (id.includes("node_modules") || id.includes("?raw") || id.includes("dist") || id.includes("build"))
23
- return code;
26
+ return;
24
27
  return addSourceToJsx(code, id);
25
28
  }
26
29
  },
@@ -73,8 +76,17 @@ const devtools = (args) => {
73
76
  enforce: "pre",
74
77
  transform(code, id) {
75
78
  if (id.includes("node_modules") || id.includes("?raw") || id.includes("dist") || id.includes("build"))
76
- return code;
77
- return removeDevtools(code, id);
79
+ return;
80
+ const transform = removeDevtools(code, id);
81
+ if (!transform) return;
82
+ if (logging) {
83
+ console.log(
84
+ `
85
+ ${chalk.greenBright(`[@tanstack/devtools-vite]`)} Removed devtools code from: ${id.replace(normalizePath(process.cwd()), "")}
86
+ `
87
+ );
88
+ }
89
+ return transform;
78
90
  }
79
91
  },
80
92
  {
@@ -84,11 +96,8 @@ const devtools = (args) => {
84
96
  return config.mode === "development" && enhancedLogsConfig.enabled;
85
97
  },
86
98
  transform(code, id) {
87
- if (id.includes("node_modules") || id.includes("?raw") || id.includes("dist") || id.includes("build"))
88
- return code;
89
- if (!code.includes("console.")) {
90
- return code;
91
- }
99
+ if (id.includes("node_modules") || id.includes("?raw") || id.includes("dist") || id.includes("build") || !code.includes("console."))
100
+ return;
92
101
  return enhanceConsoleLog(code, id, port);
93
102
  }
94
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { ServerEventBus } from '@tanstack/devtools-event-bus/server'\nimport { handleDevToolsViteRequest } from './utils'\nimport { DEFAULT_EDITOR_CONFIG, handleOpenSource } from './editor'\nimport { removeDevtools } from './remove-devtools'\nimport { addSourceToJsx } from './inject-source'\nimport { enhanceConsoleLog } from './enhance-logs'\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 * Whether to remove devtools from the production build.\n * @default true\n */\n removeDevtoolsOnBuild?: boolean\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 removeDevtoolsOnBuild = args?.removeDevtoolsOnBuild ?? 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\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 },\n {\n name: '@tanstack/devtools:remove-devtools-on-build',\n apply(_, { command }) {\n return command === 'build' && removeDevtoolsOnBuild\n },\n enforce: 'pre',\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 removeDevtools(code, id)\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 return enhanceConsoleLog(code, id, port)\n },\n },\n ]\n}\n"],"names":[],"mappings":";;;;;;AA8CO,MAAM,uBAAuB,CAAC,WACnC;AAEK,MAAM,WAAW,CAAC,SAAqD;AAC5E,MAAI,OAAO;AACX,QAAM,qBAAqB,MAAM,gBAAgB,EAAE,SAAS,KAAA;AAC5D,QAAM,qBAAqB,MAAM,gBAAgB,EAAE,SAAS,KAAA;AAC5D,QAAM,wBAAwB,MAAM,yBAAyB;AAC7D,QAAM,MAAM,IAAI,eAAe,MAAM,cAAc;AAEnD,SAAO;AAAA,IACL;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM,QAAQ;AACZ,eAAO,OAAO,SAAS,iBAAiB,mBAAmB;AAAA,MAC7D;AAAA,MACA,UAAU,MAAM,IAAI;AAClB,YACE,GAAG,SAAS,cAAc,KAC1B,GAAG,SAAS,MAAM,KAClB,GAAG,SAAS,MAAM,KAClB,GAAG,SAAS,OAAO;AAEnB,iBAAO;AAET,eAAO,eAAe,MAAM,EAAE;AAAA,MAChC;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM,QAAQ;AAEZ,eAAO,OAAO,SAAS;AAAA,MACzB;AAAA,MACA,gBAAgB,QAAQ;AACtB,YAAI,MAAA;AAEJ,eAAO,YAAY,IAAI,CAAC,KAAK,MAAM,SAAS;AAC1C,cAAI,IAAI,OAAO,aAAa,IAAI,OAAO,cAAc,MAAM;AACzD,mBAAO,IAAI,OAAO;AAAA,UACpB;AACA,eAAA;AAAA,QACF,CAAC;AACD,YAAI,OAAO,OAAO,OAAO,MAAM;AAC7B,iBAAO,OAAO,OAAO,OAAO;AAAA,QAC9B;AAEA,eAAO,YAAY,GAAG,aAAa,MAAM;AACvC,iBAAO,OAAO,OAAO,OAAO;AAAA,QAC9B,CAAC;AAED,cAAM,SAAS,MAAM,UAAU;AAC/B,cAAM,eAAqC,OACzC,MACA,SACA,cACG;AACH,cAAI,CAAC,MAAM;AACT;AAAA,UACF;AACA,gBAAM,OAAO,KAAK,MAAM,SAAS,SAAS;AAAA,QAC5C;AACA,eAAO,YAAY;AAAA,UAAI,CAAC,KAAK,KAAK,SAChC,0BAA0B,KAAK,KAAK,MAAM,CAAC,eAAe;AACxD,kBAAM,EAAE,MAAM,QAAA,IAAY;AAC1B,gBAAI,YAAY,eAAe;AAC7B,qBAAO,iBAAiB;AAAA,gBACtB,MAAM,EAAE,MAAM,KAAK,MAAM,KAAA;AAAA,gBACzB;AAAA,cAAA,CACD;AAAA,YACH;AACA;AAAA,UACF,CAAC;AAAA,QAAA;AAAA,MAEL;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,MAAM;AAAA,MACN,MAAM,GAAG,EAAE,WAAW;AACpB,eAAO,YAAY,WAAW;AAAA,MAChC;AAAA,MACA,SAAS;AAAA,MACT,UAAU,MAAM,IAAI;AAClB,YACE,GAAG,SAAS,cAAc,KAC1B,GAAG,SAAS,MAAM,KAClB,GAAG,SAAS,MAAM,KAClB,GAAG,SAAS,OAAO;AAEnB,iBAAO;AAET,eAAO,eAAe,MAAM,EAAE;AAAA,MAChC;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM,QAAQ;AACZ,eAAO,OAAO,SAAS,iBAAiB,mBAAmB;AAAA,MAC7D;AAAA,MACA,UAAU,MAAM,IAAI;AAElB,YACE,GAAG,SAAS,cAAc,KAC1B,GAAG,SAAS,MAAM,KAClB,GAAG,SAAS,MAAM,KAClB,GAAG,SAAS,OAAO;AAEnB,iBAAO;AAET,YAAI,CAAC,KAAK,SAAS,UAAU,GAAG;AAC9B,iBAAO;AAAA,QACT;AACA,eAAO,kBAAkB,MAAM,IAAI,IAAI;AAAA,MACzC;AAAA,IAAA;AAAA,EACF;AAEJ;"}
1
+ {"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { ServerEventBus } from '@tanstack/devtools-event-bus/server'\nimport { normalizePath } from 'vite'\nimport chalk from 'chalk'\nimport { handleDevToolsViteRequest } from './utils'\nimport { DEFAULT_EDITOR_CONFIG, handleOpenSource } from './editor'\nimport { removeDevtools } from './remove-devtools'\nimport { addSourceToJsx } from './inject-source'\nimport { enhanceConsoleLog } from './enhance-logs'\nimport type { Plugin } from 'vite'\nimport type { EditorConfig } from './editor'\nimport type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server'\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 * Whether to remove devtools from the production build.\n * @default true\n */\n removeDevtoolsOnBuild?: boolean\n\n /**\n * Whether to log information to the console.\n * @default true\n */\n logging?: boolean\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 logging = args?.logging ?? true\n const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true }\n const injectSourceConfig = args?.injectSource ?? { enabled: true }\n const removeDevtoolsOnBuild = args?.removeDevtoolsOnBuild ?? 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\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\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 },\n {\n name: '@tanstack/devtools:remove-devtools-on-build',\n apply(_, { command }) {\n return command === 'build' && removeDevtoolsOnBuild\n },\n enforce: 'pre',\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\n const transform = removeDevtools(code, id)\n if (!transform) return\n if (logging) {\n console.log(\n `\\n${chalk.greenBright(`[@tanstack/devtools-vite]`)} Removed devtools code from: ${id.replace(normalizePath(process.cwd()), '')}\\n`,\n )\n }\n return transform\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 !code.includes('console.')\n )\n return\n\n return enhanceConsoleLog(code, id, port)\n },\n },\n ]\n}\n"],"names":[],"mappings":"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"}
@@ -1,3 +1 @@
1
- export declare function removeDevtools(code: string, id: string): import('@babel/generator').GeneratorResult | {
2
- code: string;
3
- };
1
+ export declare function removeDevtools(code: string, id: string): import('@babel/generator').GeneratorResult | undefined;
@@ -118,7 +118,7 @@ function removeDevtools(code, id) {
118
118
  });
119
119
  const didTransform = transform(ast);
120
120
  if (!didTransform) {
121
- return { code };
121
+ return;
122
122
  }
123
123
  return gen(ast, {
124
124
  sourceMaps: true,
@@ -127,7 +127,7 @@ function removeDevtools(code, id) {
127
127
  sourceFileName: filePath
128
128
  });
129
129
  } catch (e) {
130
- return { code };
130
+ return;
131
131
  }
132
132
  }
133
133
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"remove-devtools.js","sources":["../../src/remove-devtools.ts"],"sourcesContent":["import { gen, parse, trav } from './babel'\nimport type { t } from './babel'\nimport type { types as Babel, NodePath } from '@babel/core'\nimport type { ParseResult } from '@babel/parser'\n\nconst isTanStackDevtoolsImport = (source: string) =>\n source === '@tanstack/react-devtools' ||\n source === '@tanstack/devtools' ||\n source === '@tanstack/solid-devtools'\n\nconst getImportedNames = (importDecl: t.ImportDeclaration) => {\n return importDecl.specifiers.map((spec) => spec.local.name)\n}\n\nconst getLeftoverImports = (node: NodePath<t.JSXElement>) => {\n const finalReferences: Array<string> = []\n node.traverse({\n JSXAttribute(path) {\n const node = path.node\n const propName =\n typeof node.name.name === 'string'\n ? node.name.name\n : node.name.name.name\n\n if (\n propName === 'plugins' &&\n node.value?.type === 'JSXExpressionContainer' &&\n node.value.expression.type === 'ArrayExpression'\n ) {\n const elements = node.value.expression.elements\n\n elements.forEach((el) => {\n if (el?.type === 'ObjectExpression') {\n // { name: \"something\", render: ()=> <Component /> }\n const props = el.properties\n const referencesToRemove = props\n .map((prop) => {\n if (\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 'render'\n ) {\n const value = prop.value\n // handle <ReactRouterPanel />\n if (\n value.type === 'JSXElement' &&\n value.openingElement.name.type === 'JSXIdentifier'\n ) {\n const elementName = value.openingElement.name.name\n return elementName\n }\n // handle () => <ReactRouterPanel /> or function() { return <ReactRouterPanel /> }\n if (\n value.type === 'ArrowFunctionExpression' ||\n value.type === 'FunctionExpression'\n ) {\n const body = value.body\n if (\n body.type === 'JSXElement' &&\n body.openingElement.name.type === 'JSXIdentifier'\n ) {\n const elementName = body.openingElement.name.name\n return elementName\n }\n }\n // handle render: SomeComponent\n if (value.type === 'Identifier') {\n const elementName = value.name\n return elementName\n }\n\n // handle render: someFunction()\n if (\n value.type === 'CallExpression' &&\n value.callee.type === 'Identifier'\n ) {\n const elementName = value.callee.name\n return elementName\n }\n\n return ''\n }\n return ''\n })\n .filter(Boolean)\n finalReferences.push(...referencesToRemove)\n }\n })\n }\n },\n })\n return finalReferences\n}\n\nconst transform = (ast: ParseResult<Babel.File>) => {\n let didTransform = false\n const devtoolsComponentNames = new Set()\n const finalReferences: Array<string> = []\n\n const transformations: Array<() => void> = []\n\n trav(ast, {\n ImportDeclaration(path) {\n const importSource = path.node.source.value\n if (isTanStackDevtoolsImport(importSource)) {\n getImportedNames(path.node).forEach((name) =>\n devtoolsComponentNames.add(name),\n )\n\n transformations.push(() => {\n path.remove()\n })\n\n didTransform = true\n }\n },\n JSXElement(path) {\n const opening = path.node.openingElement\n if (\n opening.name.type === 'JSXIdentifier' &&\n devtoolsComponentNames.has(opening.name.name)\n ) {\n const refs = getLeftoverImports(path)\n\n finalReferences.push(...refs)\n transformations.push(() => {\n path.remove()\n })\n didTransform = true\n }\n if (\n opening.name.type === 'JSXMemberExpression' &&\n opening.name.object.type === 'JSXIdentifier' &&\n devtoolsComponentNames.has(opening.name.object.name)\n ) {\n const refs = getLeftoverImports(path)\n finalReferences.push(...refs)\n transformations.push(() => {\n path.remove()\n })\n didTransform = true\n }\n },\n })\n\n trav(ast, {\n ImportDeclaration(path) {\n const imports = path.node.specifiers\n for (const imported of imports) {\n if (imported.type === 'ImportSpecifier') {\n if (finalReferences.includes(imported.local.name)) {\n transformations.push(() => {\n // remove the specifier\n path.node.specifiers = path.node.specifiers.filter(\n (spec) => spec !== imported,\n )\n // remove whole import if nothing is left\n if (path.node.specifiers.length === 0) {\n path.remove()\n }\n })\n }\n }\n }\n },\n })\n\n transformations.forEach((fn) => fn())\n\n return didTransform\n}\n\nexport function removeDevtools(code: string, id: string) {\n const [filePath] = id.split('?')\n\n try {\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n })\n const didTransform = transform(ast)\n if (!didTransform) {\n return { code }\n }\n return gen(ast, {\n sourceMaps: true,\n retainLines: true,\n filename: id,\n sourceFileName: filePath,\n })\n } catch (e) {\n return { code }\n }\n}\n"],"names":["node"],"mappings":"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"}
1
+ {"version":3,"file":"remove-devtools.js","sources":["../../src/remove-devtools.ts"],"sourcesContent":["import { gen, parse, trav } from './babel'\nimport type { t } from './babel'\nimport type { types as Babel, NodePath } from '@babel/core'\nimport type { ParseResult } from '@babel/parser'\n\nconst isTanStackDevtoolsImport = (source: string) =>\n source === '@tanstack/react-devtools' ||\n source === '@tanstack/devtools' ||\n source === '@tanstack/solid-devtools'\n\nconst getImportedNames = (importDecl: t.ImportDeclaration) => {\n return importDecl.specifiers.map((spec) => spec.local.name)\n}\n\nconst getLeftoverImports = (node: NodePath<t.JSXElement>) => {\n const finalReferences: Array<string> = []\n node.traverse({\n JSXAttribute(path) {\n const node = path.node\n const propName =\n typeof node.name.name === 'string'\n ? node.name.name\n : node.name.name.name\n\n if (\n propName === 'plugins' &&\n node.value?.type === 'JSXExpressionContainer' &&\n node.value.expression.type === 'ArrayExpression'\n ) {\n const elements = node.value.expression.elements\n\n elements.forEach((el) => {\n if (el?.type === 'ObjectExpression') {\n // { name: \"something\", render: ()=> <Component /> }\n const props = el.properties\n const referencesToRemove = props\n .map((prop) => {\n if (\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 'render'\n ) {\n const value = prop.value\n // handle <ReactRouterPanel />\n if (\n value.type === 'JSXElement' &&\n value.openingElement.name.type === 'JSXIdentifier'\n ) {\n const elementName = value.openingElement.name.name\n return elementName\n }\n // handle () => <ReactRouterPanel /> or function() { return <ReactRouterPanel /> }\n if (\n value.type === 'ArrowFunctionExpression' ||\n value.type === 'FunctionExpression'\n ) {\n const body = value.body\n if (\n body.type === 'JSXElement' &&\n body.openingElement.name.type === 'JSXIdentifier'\n ) {\n const elementName = body.openingElement.name.name\n return elementName\n }\n }\n // handle render: SomeComponent\n if (value.type === 'Identifier') {\n const elementName = value.name\n return elementName\n }\n\n // handle render: someFunction()\n if (\n value.type === 'CallExpression' &&\n value.callee.type === 'Identifier'\n ) {\n const elementName = value.callee.name\n return elementName\n }\n\n return ''\n }\n return ''\n })\n .filter(Boolean)\n finalReferences.push(...referencesToRemove)\n }\n })\n }\n },\n })\n return finalReferences\n}\n\nconst transform = (ast: ParseResult<Babel.File>) => {\n let didTransform = false\n const devtoolsComponentNames = new Set()\n const finalReferences: Array<string> = []\n\n const transformations: Array<() => void> = []\n\n trav(ast, {\n ImportDeclaration(path) {\n const importSource = path.node.source.value\n if (isTanStackDevtoolsImport(importSource)) {\n getImportedNames(path.node).forEach((name) =>\n devtoolsComponentNames.add(name),\n )\n\n transformations.push(() => {\n path.remove()\n })\n\n didTransform = true\n }\n },\n JSXElement(path) {\n const opening = path.node.openingElement\n if (\n opening.name.type === 'JSXIdentifier' &&\n devtoolsComponentNames.has(opening.name.name)\n ) {\n const refs = getLeftoverImports(path)\n\n finalReferences.push(...refs)\n transformations.push(() => {\n path.remove()\n })\n didTransform = true\n }\n if (\n opening.name.type === 'JSXMemberExpression' &&\n opening.name.object.type === 'JSXIdentifier' &&\n devtoolsComponentNames.has(opening.name.object.name)\n ) {\n const refs = getLeftoverImports(path)\n finalReferences.push(...refs)\n transformations.push(() => {\n path.remove()\n })\n didTransform = true\n }\n },\n })\n\n trav(ast, {\n ImportDeclaration(path) {\n const imports = path.node.specifiers\n for (const imported of imports) {\n if (imported.type === 'ImportSpecifier') {\n if (finalReferences.includes(imported.local.name)) {\n transformations.push(() => {\n // remove the specifier\n path.node.specifiers = path.node.specifiers.filter(\n (spec) => spec !== imported,\n )\n // remove whole import if nothing is left\n if (path.node.specifiers.length === 0) {\n path.remove()\n }\n })\n }\n }\n }\n },\n })\n\n transformations.forEach((fn) => fn())\n\n return didTransform\n}\n\nexport function removeDevtools(code: string, id: string) {\n const [filePath] = id.split('?')\n\n try {\n const ast = parse(code, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n })\n const didTransform = transform(ast)\n if (!didTransform) {\n return\n }\n return gen(ast, {\n sourceMaps: true,\n retainLines: true,\n filename: id,\n sourceFileName: filePath,\n })\n } catch (e) {\n return\n }\n}\n"],"names":["node"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/devtools-vite",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "TanStack Vite plugin used to enhance the core devtools with additional functionalities",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@ describe('remove-devtools', () => {
14
14
  `,
15
15
  'test.jsx',
16
16
  3000,
17
- ).code,
17
+ )!.code,
18
18
  )
19
19
  expect(
20
20
  output.includes(
@@ -26,96 +26,62 @@ describe('remove-devtools', () => {
26
26
  })
27
27
 
28
28
  test('it does not add enhanced console.logs to console.log that is not called', () => {
29
- const output = removeEmptySpace(
30
- enhanceConsoleLog(
31
- `
29
+ const output = enhanceConsoleLog(
30
+ `
32
31
  console.log
33
32
  `,
34
- 'test.jsx',
35
- 3000,
36
- ).code,
37
- )
38
- expect(output).toBe(
39
- removeEmptySpace(`
40
- console.log
41
- `),
33
+ 'test.jsx',
34
+ 3000,
42
35
  )
36
+ expect(output).toBe(undefined)
43
37
  })
44
38
 
45
39
  test('it does not add enhanced console.logs to console.log that is inside a comment', () => {
46
- const output = removeEmptySpace(
47
- enhanceConsoleLog(
48
- `
40
+ const output = enhanceConsoleLog(
41
+ `
49
42
  // console.log('This is a log')
50
43
  `,
51
- 'test.jsx',
52
- 3000,
53
- ).code,
54
- )
55
- expect(output).toBe(
56
- removeEmptySpace(`
57
- // console.log('This is a log')
58
- `),
44
+ 'test.jsx',
45
+ 3000,
59
46
  )
47
+ expect(output).toBe(undefined)
60
48
  })
61
49
 
62
50
  test('it does not add enhanced console.logs to console.log that is inside a multiline comment', () => {
63
- const output = removeEmptySpace(
64
- enhanceConsoleLog(
65
- `
51
+ const output = enhanceConsoleLog(
52
+ `
66
53
  /*
67
54
  console.log('This is a log')
68
55
  */
69
56
  `,
70
- 'test.jsx',
71
- 3000,
72
- ).code,
73
- )
74
- expect(output).toBe(
75
- removeEmptySpace(`
76
- /*
77
- console.log('This is a log')
78
- */
79
- `),
57
+ 'test.jsx',
58
+ 3000,
80
59
  )
60
+ expect(output).toBe(undefined)
81
61
  })
82
62
 
83
63
  test('it does not add enhanced console.error to console.error that is inside a comment', () => {
84
- const output = removeEmptySpace(
85
- enhanceConsoleLog(
86
- `
64
+ const output = enhanceConsoleLog(
65
+ `
87
66
  // console.error('This is a log')
88
67
  `,
89
- 'test.jsx',
90
- 3000,
91
- ).code,
92
- )
93
- expect(output).toBe(
94
- removeEmptySpace(`
95
- // console.error('This is a log')
96
- `),
68
+ 'test.jsx',
69
+ 3000,
97
70
  )
71
+ expect(output).toBe(undefined)
98
72
  })
99
73
 
100
74
  test('it does not add enhanced console.error to console.error that is inside a multiline comment', () => {
101
- const output = removeEmptySpace(
102
- enhanceConsoleLog(
103
- `
75
+ const output = enhanceConsoleLog(
76
+ `
104
77
  /*
105
78
  console.error('This is a log')
106
79
  */
107
80
  `,
108
- 'test.jsx',
109
- 3000,
110
- ).code,
111
- )
112
- expect(output).toBe(
113
- removeEmptySpace(`
114
- /*
115
- console.error('This is a log')
116
- */
117
- `),
81
+ 'test.jsx',
82
+ 3000,
118
83
  )
84
+ expect(output).toBe(undefined)
119
85
  })
120
86
 
121
87
  test('it adds enhanced console.error to console.error()', () => {
@@ -126,7 +92,7 @@ describe('remove-devtools', () => {
126
92
  `,
127
93
  'test.jsx',
128
94
  3000,
129
- ).code,
95
+ )!.code,
130
96
  )
131
97
  console.log('output', output)
132
98
  expect(
@@ -139,19 +105,13 @@ describe('remove-devtools', () => {
139
105
  })
140
106
 
141
107
  test('it does not add enhanced console.error to console.error that is not called', () => {
142
- const output = removeEmptySpace(
143
- enhanceConsoleLog(
144
- `
108
+ const output = enhanceConsoleLog(
109
+ `
145
110
  console.log
146
111
  `,
147
- 'test.jsx',
148
- 3000,
149
- ).code,
150
- )
151
- expect(output).toBe(
152
- removeEmptySpace(`
153
- console.log
154
- `),
112
+ 'test.jsx',
113
+ 3000,
155
114
  )
115
+ expect(output).toBe(undefined)
156
116
  })
157
117
  })
@@ -56,7 +56,7 @@ export function enhanceConsoleLog(code: string, id: string, port: number) {
56
56
  })
57
57
  const didTransform = transform(ast, location, port)
58
58
  if (!didTransform) {
59
- return { code }
59
+ return
60
60
  }
61
61
  return gen(ast, {
62
62
  sourceMaps: true,
@@ -65,6 +65,6 @@ export function enhanceConsoleLog(code: string, id: string, port: number) {
65
65
  sourceFileName: filePath,
66
66
  })
67
67
  } catch (e) {
68
- return { code }
68
+ return
69
69
  }
70
70
  }