From 2220c6bcdde028159fde6aff90d505cf1af0f8e5 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Fri, 16 Jun 2023 17:58:42 +0300 Subject: [PATCH 01/20] Experimental auto JSDoc extraction --- src/utils.ts | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index e5f3afd6..27cb5e99 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -140,14 +140,51 @@ export function toExports (imports: Import[], fileDir?: string) { }) .join('\n') } +export function extractJSDoc(modulePath: string, functionName: string) { + try{ + if(modulePath.indexOf("../../")!==-1){ + modulePath=modulePath.slice(6) + modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" + } + if(modulePath.indexOf("vue-router")!==-1){ + modulePath=".nuxt/vue-router.d.ts" + } + if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ + modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') + } + if(modulePath.indexOf("/node_modules")!==-1){ + modulePath=modulePath.slice(modulePath.indexOf("/node_modules")+1) + modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" + } + const sourceCode = fs.readFileSync(modulePath, 'utf8'); + + const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); + + let jsDoc; + function visit(node) { + if (ts.isFunctionDeclaration(node) && node.name && node.name.text === functionName) { + + if (node.jsDoc && node.jsDoc.length > 0) { + const comment = node.jsDoc[0].getText(sourceFile); + jsDoc = comment; + } + } + + ts.forEachChild(node, visit); + } + visit(sourceFile); + return jsDoc; + } + catch (err){ + return console.error("Error encountered while obtaining the JSDoc: "+err) + } +} export function toTypeDeclarationItems (imports: Import[], options?: TypeDeclarationOptions) { - return imports - .map((i) => { - const from = (options?.resolvePath?.(i) || i.from).replace(/\.ts$/, '') - return `const ${i.as}: typeof import('${from}')${i.name !== '*' ? `['${i.name}']` : ''}` - }) - .sort() + return imports.map((i) => { + const from = (options?.resolvePath?.(i) || i.from).replace(/\.ts$/, ""); + return `${extractJSDoc(from, i.as)}\n\tconst ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; + }).sort(); } export function toTypeDeclarationFile (imports: Import[], options?: TypeDeclarationOptions) { From a7dfea9a7c576fa054d6541a5a198792a9f05400 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Fri, 16 Jun 2023 18:18:26 +0300 Subject: [PATCH 02/20] Missing imports --- src/utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 27cb5e99..7beae6aa 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,7 +4,8 @@ import { findStaticImports, parseStaticImport, StaticImport, resolvePath } from import MagicString from 'magic-string' import { stripLiteral } from 'strip-literal' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' - +import fs from "fs" +import ts from "typescript" export const excludeRE = [ // imported/exported from other module /\b(import|export)\b([\s\w_$*{},]+)\sfrom\b/gs, From d0e468774a6a90ae21593b6dbed41b1103d912fc Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Fri, 16 Jun 2023 18:20:01 +0300 Subject: [PATCH 03/20] Destructuring --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 7beae6aa..90cd5f89 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,8 +4,8 @@ import { findStaticImports, parseStaticImport, StaticImport, resolvePath } from import MagicString from 'magic-string' import { stripLiteral } from 'strip-literal' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' -import fs from "fs" import ts from "typescript" +import {existsSync, readFileSync} from "fs"; export const excludeRE = [ // imported/exported from other module /\b(import|export)\b([\s\w_$*{},]+)\sfrom\b/gs, From dd1ac239d0df316d71bde8b621909fcbd4b36fa1 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Fri, 16 Jun 2023 18:23:12 +0300 Subject: [PATCH 04/20] Removal of 'undefined' in non-existent JSDoc --- src/utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 90cd5f89..369e779a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -184,7 +184,8 @@ export function extractJSDoc(modulePath: string, functionName: string) { export function toTypeDeclarationItems (imports: Import[], options?: TypeDeclarationOptions) { return imports.map((i) => { const from = (options?.resolvePath?.(i) || i.from).replace(/\.ts$/, ""); - return `${extractJSDoc(from, i.as)}\n\tconst ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; + const jsDoc=extractJSDoc(from, i.as) + return `${jsDoc===undefined ? '' : jsDoc+"\n\t"}const ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; }).sort(); } From 666d4e210c950644dcbe6cfa06a2797896beb95c Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Fri, 16 Jun 2023 23:22:53 +0300 Subject: [PATCH 05/20] Non-Nuxt-locked vue-router handling --- src/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 369e779a..90f4f01f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -147,9 +147,6 @@ export function extractJSDoc(modulePath: string, functionName: string) { modulePath=modulePath.slice(6) modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } - if(modulePath.indexOf("vue-router")!==-1){ - modulePath=".nuxt/vue-router.d.ts" - } if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') } @@ -157,6 +154,9 @@ export function extractJSDoc(modulePath: string, functionName: string) { modulePath=modulePath.slice(modulePath.indexOf("/node_modules")+1) modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } + if(modulePath.indexOf("vue-router")!==-1){ + modulePath="node_modules/vue-router/dist/vue-router.d.ts" + } const sourceCode = fs.readFileSync(modulePath, 'utf8'); const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); From 8d40bc5f18c3eca71419d7a85f48808a5c37149f Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Sat, 17 Jun 2023 18:10:42 +0300 Subject: [PATCH 06/20] Proper error handling --- src/utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 90f4f01f..3da65cc5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -143,6 +143,7 @@ export function toExports (imports: Import[], fileDir?: string) { } export function extractJSDoc(modulePath: string, functionName: string) { try{ + //Relative paths if(modulePath.indexOf("../../")!==-1){ modulePath=modulePath.slice(6) modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" @@ -177,7 +178,7 @@ export function extractJSDoc(modulePath: string, functionName: string) { return jsDoc; } catch (err){ - return console.error("Error encountered while obtaining the JSDoc: "+err) + throw new Error(err) } } From d3b5c0a69f6f6892e1ccdde8edbb1de05dcf82f6 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Sat, 17 Jun 2023 18:17:38 +0300 Subject: [PATCH 07/20] Fixing up after destructuring, comments, Nuxt-compatible non-locked vue-router --- src/utils.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 3da65cc5..42db894a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -143,35 +143,40 @@ export function toExports (imports: Import[], fileDir?: string) { } export function extractJSDoc(modulePath: string, functionName: string) { try{ + //Relative paths if(modulePath.indexOf("../../")!==-1){ modulePath=modulePath.slice(6) - modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" + modulePath=existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } + + //NPM packages (including scoped ones) (with proper handling for i18n, tested on Nuxt only, needs proper testing on other tools) if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') } + + //Absolute paths if(modulePath.indexOf("/node_modules")!==-1){ modulePath=modulePath.slice(modulePath.indexOf("/node_modules")+1) - modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" + modulePath=existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } + + //Vue-router (non-Nuxt locked) if(modulePath.indexOf("vue-router")!==-1){ - modulePath="node_modules/vue-router/dist/vue-router.d.ts" + modulePath=existsSync(".nuxt") ? ".nuxt/vue-router.d.ts" : "node_modules/vue-router/dist/vue-router.d.ts" } - const sourceCode = fs.readFileSync(modulePath, 'utf8'); - + + const sourceCode = readFileSync(modulePath, 'utf8'); const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); let jsDoc; function visit(node) { if (ts.isFunctionDeclaration(node) && node.name && node.name.text === functionName) { - if (node.jsDoc && node.jsDoc.length > 0) { const comment = node.jsDoc[0].getText(sourceFile); jsDoc = comment; } } - ts.forEachChild(node, visit); } visit(sourceFile); From 0d55c6d5a8b77f804c255950e959a8025e50ac7c Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Sat, 17 Jun 2023 18:19:48 +0300 Subject: [PATCH 08/20] Update utils.ts --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 42db894a..402f1347 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -150,7 +150,7 @@ export function extractJSDoc(modulePath: string, functionName: string) { modulePath=existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } - //NPM packages (including scoped ones) (with proper handling for i18n, tested on Nuxt only, needs proper testing on other tools) + //NPM packages (including scoped ones) (with handling for i18n, tested on Nuxt only, needs proper testing on other tools) if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') } From 4a0a2c731ca8ec4ab4ecce896cdc0ff74f1b95e3 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Sat, 17 Jun 2023 18:25:47 +0300 Subject: [PATCH 09/20] TS destructuring --- src/utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 402f1347..f737b09d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,7 +4,7 @@ import { findStaticImports, parseStaticImport, StaticImport, resolvePath } from import MagicString from 'magic-string' import { stripLiteral } from 'strip-literal' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' -import ts from "typescript" +import {createSourceFile, ScriptTarget, isFunctionDeclaration, forEachChild} from "typescript" import {existsSync, readFileSync} from "fs"; export const excludeRE = [ // imported/exported from other module @@ -167,17 +167,17 @@ export function extractJSDoc(modulePath: string, functionName: string) { } const sourceCode = readFileSync(modulePath, 'utf8'); - const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); + const sourceFile = createSourceFile("temp.ts", sourceCode, ScriptTarget.ES2015, true); let jsDoc; function visit(node) { - if (ts.isFunctionDeclaration(node) && node.name && node.name.text === functionName) { + if (isFunctionDeclaration(node) && node.name && node.name.text === functionName) { if (node.jsDoc && node.jsDoc.length > 0) { const comment = node.jsDoc[0].getText(sourceFile); jsDoc = comment; } } - ts.forEachChild(node, visit); + forEachChild(node, visit); } visit(sourceFile); return jsDoc; From 4a62c05f66e46a802cee81ec951879dbcf9215af Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Tue, 20 Jun 2023 18:39:54 +0300 Subject: [PATCH 10/20] Reverting broken destructuring --- src/utils.ts | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index f737b09d..d11c875f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,8 +4,8 @@ import { findStaticImports, parseStaticImport, StaticImport, resolvePath } from import MagicString from 'magic-string' import { stripLiteral } from 'strip-literal' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' -import {createSourceFile, ScriptTarget, isFunctionDeclaration, forEachChild} from "typescript" -import {existsSync, readFileSync} from "fs"; +import ts from "typescript" +import fs from "fs"; export const excludeRE = [ // imported/exported from other module /\b(import|export)\b([\s\w_$*{},]+)\sfrom\b/gs, @@ -143,41 +143,35 @@ export function toExports (imports: Import[], fileDir?: string) { } export function extractJSDoc(modulePath: string, functionName: string) { try{ - - //Relative paths if(modulePath.indexOf("../../")!==-1){ modulePath=modulePath.slice(6) - modulePath=existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" + modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" + } + if(modulePath.indexOf("vue-router")!==-1){ + modulePath=".nuxt/vue-router.d.ts" } - - //NPM packages (including scoped ones) (with handling for i18n, tested on Nuxt only, needs proper testing on other tools) if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') } - - //Absolute paths if(modulePath.indexOf("/node_modules")!==-1){ modulePath=modulePath.slice(modulePath.indexOf("/node_modules")+1) - modulePath=existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" - } - - //Vue-router (non-Nuxt locked) - if(modulePath.indexOf("vue-router")!==-1){ - modulePath=existsSync(".nuxt") ? ".nuxt/vue-router.d.ts" : "node_modules/vue-router/dist/vue-router.d.ts" + modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } - - const sourceCode = readFileSync(modulePath, 'utf8'); - const sourceFile = createSourceFile("temp.ts", sourceCode, ScriptTarget.ES2015, true); + const sourceCode = fs.readFileSync(modulePath, 'utf8'); + + const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); let jsDoc; function visit(node) { - if (isFunctionDeclaration(node) && node.name && node.name.text === functionName) { + if (ts.isFunctionDeclaration(node) && node.name && node.name.text === functionName) { + if (node.jsDoc && node.jsDoc.length > 0) { const comment = node.jsDoc[0].getText(sourceFile); jsDoc = comment; } } - forEachChild(node, visit); + + ts.forEachChild(node, visit); } visit(sourceFile); return jsDoc; From 220d63e1d80370397daa6d7b6a0fa128a912c331 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Tue, 20 Jun 2023 18:45:14 +0300 Subject: [PATCH 11/20] Returning comments --- src/utils.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index d11c875f..a7d91c51 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -143,22 +143,30 @@ export function toExports (imports: Import[], fileDir?: string) { } export function extractJSDoc(modulePath: string, functionName: string) { try{ + + //Relative paths if(modulePath.indexOf("../../")!==-1){ modulePath=modulePath.slice(6) modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } - if(modulePath.indexOf("vue-router")!==-1){ - modulePath=".nuxt/vue-router.d.ts" - } + + //NPM packages (including scoped ones) (with handling for i18n, tested on Nuxt only, needs proper testing on other tools) if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') } + + //Absolute paths if(modulePath.indexOf("/node_modules")!==-1){ modulePath=modulePath.slice(modulePath.indexOf("/node_modules")+1) modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" } - const sourceCode = fs.readFileSync(modulePath, 'utf8'); + //Vue-router (non-Nuxt locked) + if(modulePath.indexOf("vue-router")!==-1){ + modulePath=".nuxt/vue-router.d.ts" + } + + const sourceCode = fs.readFileSync(modulePath, 'utf8'); const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); let jsDoc; From 60def88092f43588e5742acfd48f340aba135ddb Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Sat, 1 Jul 2023 21:04:15 +0300 Subject: [PATCH 12/20] FIxing non-nuxt-locked vue-router, migrating to patterns in stead of TS --- src/utils.ts | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 48b18947..358c1c4e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,8 +4,8 @@ import { findStaticImports, parseStaticImport, StaticImport, resolvePath } from import MagicString from 'magic-string' import { stripLiteral } from 'strip-literal' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' -import ts from "typescript" -import fs from "fs"; +import fs from "fs" +const files={} export const excludeRE = [ // imported/exported from other module /\b(import|export)\b([\s\w_$*{},]+)\sfrom\b/gs, @@ -163,25 +163,13 @@ export function extractJSDoc(modulePath: string, functionName: string) { //Vue-router (non-Nuxt locked) if(modulePath.indexOf("vue-router")!==-1){ - modulePath=".nuxt/vue-router.d.ts" + modulePath=fs.existsSync(".nuxt") ? ".nuxt/vue-router.d.ts" : "node_modules/vue-router/dist/vue-router.d.ts" } - - const sourceCode = fs.readFileSync(modulePath, 'utf8'); - const sourceFile = ts.createSourceFile("temp.ts", sourceCode, ts.ScriptTarget.ES2015, true); - - let jsDoc; - function visit(node) { - if (ts.isFunctionDeclaration(node) && node.name && node.name.text === functionName) { - - if (node.jsDoc && node.jsDoc.length > 0) { - const comment = node.jsDoc[0].getText(sourceFile); - jsDoc = comment; - } - } - - ts.forEachChild(node, visit); + if(!files[modulePath]){ + files[modulePath]=fs.readFileSync(modulePath, 'utf8'); } - visit(sourceFile); + const jsDocRE=new RegExp(`(\\/\\*\\*[?;,.:\/@\\-\\s\\w\\{\\}\\[\\]\\(\\)\\<\\>\\"\`\|*]*\\*\\/)(?:\nexport d?e?c?l?a?r?e? (?:function|const) ${functionName})`,'i') + const jsDoc= files[modulePath].match(jsDocRE) return jsDoc; } catch (err){ @@ -193,7 +181,7 @@ export function toTypeDeclarationItems (imports: Import[], options?: TypeDeclara return imports.map((i) => { const from = (options?.resolvePath?.(i) || i.from).replace(/\.ts$/, ""); const jsDoc=extractJSDoc(from, i.as) - return `${jsDoc===undefined ? '' : jsDoc+"\n\t"}const ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; + return `${jsDoc===null ? '' : jsDoc[0].slice(0,jsDoc[0].indexOf("*/\nexport")+3)+"\n\t"}const ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; }).sort(); } From 9676362adb7c1f3c30f473b3a776c15ac10130f2 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Tue, 29 Aug 2023 20:02:22 +0300 Subject: [PATCH 13/20] Update utils.ts --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 9a013d9e..b99a76c4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,7 +5,7 @@ import MagicString from 'magic-string' import { stripLiteral, StripLiteralOptions } from 'strip-literal' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' import fs from "fs" -const files={} +export const files={} export const excludeRE = [ // imported/exported from other module /\b(import|export)\b([\s\w_$*{},]+)\sfrom\b/gs, From c768dd2154cb84dfac3dc72831b672e43477fd95 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Mon, 22 Jan 2024 23:05:12 +0200 Subject: [PATCH 14/20] refactor: use map with readSync to get the main entry --- src/utils.ts | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 26a30b85..da4e7a17 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { isAbsolute, relative } from 'pathe' +import { isAbsolute, relative, resolve } from 'pathe' import type { StaticImport } from 'mlly' import { findStaticImports, parseStaticImport, resolvePath } from 'mlly' import MagicString from 'magic-string' @@ -149,32 +149,25 @@ export function toExports(imports: Import[], fileDir?: string, includeType = fal } export function extractJSDoc(modulePath: string, functionName: string) { try{ - //Relative paths - if(modulePath.indexOf("../../")!==-1){ - modulePath=modulePath.slice(6) - modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" - } - - //NPM packages (including scoped ones) (with handling for i18n, tested on Nuxt only, needs proper testing on other tools) - if(modulePath.indexOf("/")===-1 || modulePath.indexOf("@")!==-1){ - modulePath=(modulePath.indexOf("node_modules")===-1?"node_modules/":"")+modulePath+(modulePath.indexOf("i18n")===-1? "/dist/"+( modulePath==="vue" ? modulePath+".d.ts": "index.d.ts"): '') - } - - //Absolute paths - if(modulePath.indexOf("/node_modules")!==-1){ - modulePath=modulePath.slice(modulePath.indexOf("/node_modules")+1) - modulePath=fs.existsSync(modulePath+".d.ts") ? modulePath+".d.ts" : modulePath+"/index.d.ts" - } - - //Vue-router (non-Nuxt locked) - if(modulePath.indexOf("vue-router")!==-1){ - modulePath=fs.existsSync(".nuxt") ? ".nuxt/vue-router.d.ts" : "node_modules/vue-router/dist/vue-router.d.ts" - } - if(!files[modulePath]){ - files[modulePath]=fs.readFileSync(modulePath, 'utf8'); - } const jsDocRE=new RegExp(`(\\/\\*\\*[?;,.:\/@\\-\\s\\w\\{\\}\\[\\]\\(\\)\\<\\>\\"\`\|*]*\\*\\/)(?:\nexport d?e?c?l?a?r?e? (?:function|const) ${functionName})`,'i') - const jsDoc= files[modulePath].match(jsDocRE) + modulePath=resolve(modulePath.slice(6)) + if(!files.has(modulePath)){ + if(fs.existsSync(modulePath+"/package.json")){ + const pkg = JSON.parse(fs.readFileSync(modulePath+"/package.json","utf8")) + files.set(modulePath,readFileSync(modulePath+"/"+pkg.main,"utf8")) + } + else{ + if(!files[modulePath]){ + for(const ext of [".ts",".js",".mjs",".cjs"]){ + if(fs.existsSync(modulePath+ext)){ + files.set(modulePath,fs.readFileSync(modulePath+ext,"utf8")) + break + } + } + } + } + } + const jsDoc= files.get(modulePath)?.match(jsDocRE) return jsDoc; } catch (err){ From 4ed29d28c22d7546351ac0d9cf06060b957554d3 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Mon, 22 Jan 2024 23:09:04 +0200 Subject: [PATCH 15/20] Update the map --- src/utils.ts | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index da4e7a17..5c22f24c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,34 +5,7 @@ import MagicString from 'magic-string' import type { Import, InlinePreset, MagicStringResult, TypeDeclarationOptions } from './types' import { stripCommentsAndStrings } from './regexp' import fs from "fs" -export const files={} -export const excludeRE = [ - // imported/exported from other module - /\b(import|export)\b([\s\w_$*{},]+)\sfrom\b/gs, - // defined as function - /\bfunction\s*([\w_$]+?)\s*\(/gs, - // defined as class - /\bclass\s*([\w_$]+?)\s*{/gs, - // defined as local variable - /\b(?:const|let|var)\s+?(\[.*?\]|\{.*?\}|.+?)\s*?[=;\n]/gs, -] - -export const importAsRE = /^.*\sas\s+/ -export const separatorRE = /[,[\]{}\n]|\bimport\b/g - -/** - * | | - * destructing case&ternary non-call inheritance | id | - * ↓ ↓ ↓ ↓ | | - */ -export const matchRE = /(^|\.\.\.|(?:\bcase|\?)\s+|[^\w_$\/)]|(?:\bextends)\s+)([\w_$]+)\s*(?=[.()[\]}}:;?+\-*&|`<>,\n]|\b(?:instanceof|in)\b|$|(?<=extends\s+\w+)\s+{)/g - -const regexRE = /\/[^\s]*?(? Date: Mon, 22 Jan 2024 23:10:08 +0200 Subject: [PATCH 16/20] Update utils.ts --- src/utils.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 5c22f24c..2a1e90c3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -148,6 +148,9 @@ export function extractJSDoc(modulePath: string, functionName: string) { } } +export function stripFileExtension(path: string) { + return path.replace(/\.[a-zA-Z]+$/, '') +} export function toTypeDeclarationItems (imports: Import[], options?: TypeDeclarationOptions) { return imports.map((i) => { @@ -155,10 +158,6 @@ export function toTypeDeclarationItems (imports: Import[], options?: TypeDeclara const jsDoc=extractJSDoc(from, i.as) return `${jsDoc===null ? '' : jsDoc[0].slice(0,jsDoc[0].indexOf("*/\nexport")+3)+"\n\t"}const ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; }).sort(); -export function stripFileExtension(path: string) { - return path.replace(/\.[a-zA-Z]+$/, '') -} - } export function toTypeDeclarationFile(imports: Import[], options?: TypeDeclarationOptions) { From e579e889a47319b5cb288e70884ae3f5da27795b Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Mon, 22 Jan 2024 23:12:07 +0200 Subject: [PATCH 17/20] chore: remove redundant check --- src/utils.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 2a1e90c3..70300813 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -130,12 +130,10 @@ export function extractJSDoc(modulePath: string, functionName: string) { files.set(modulePath,readFileSync(modulePath+"/"+pkg.main,"utf8")) } else{ - if(!files[modulePath]){ - for(const ext of [".ts",".js",".mjs",".cjs"]){ - if(fs.existsSync(modulePath+ext)){ - files.set(modulePath,fs.readFileSync(modulePath+ext,"utf8")) - break - } + for(const ext of [".ts",".js",".mjs",".cjs"]){ + if(fs.existsSync(modulePath+ext)){ + files.set(modulePath,fs.readFileSync(modulePath+ext,"utf8")) + break } } } From f7031e2feae3ef92260a06f03c3175c796f4de5f Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Mon, 22 Jan 2024 23:14:20 +0200 Subject: [PATCH 18/20] style: lint --- src/utils.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 70300813..02bfcd10 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -122,23 +122,23 @@ export function toExports(imports: Import[], fileDir?: string, includeType = fal } export function extractJSDoc(modulePath: string, functionName: string) { try{ - const jsDocRE=new RegExp(`(\\/\\*\\*[?;,.:\/@\\-\\s\\w\\{\\}\\[\\]\\(\\)\\<\\>\\"\`\|*]*\\*\\/)(?:\nexport d?e?c?l?a?r?e? (?:function|const) ${functionName})`,'i') - modulePath=resolve(modulePath.slice(6)) + const jsDocRE = new RegExp(`(\\/\\*\\*[?;,.:\/@\\-\\s\\w\\{\\}\\[\\]\\(\\)\\<\\>\\"\`\|*]*\\*\\/)(?:\nexport d?e?c?l?a?r?e? (?:function|const) ${functionName})`,'i') + modulePath = resolve(modulePath.slice(6)) if(!files.has(modulePath)){ - if(fs.existsSync(modulePath+"/package.json")){ - const pkg = JSON.parse(fs.readFileSync(modulePath+"/package.json","utf8")) - files.set(modulePath,readFileSync(modulePath+"/"+pkg.main,"utf8")) + if(fs.existsSync(modulePath + "/package.json")){ + const pkg = JSON.parse(fs.readFileSync(modulePath + "/package.json","utf8")) + files.set(modulePath, readFileSync(modulePath + "/" + pkg.main,"utf8")) } else{ for(const ext of [".ts",".js",".mjs",".cjs"]){ if(fs.existsSync(modulePath+ext)){ - files.set(modulePath,fs.readFileSync(modulePath+ext,"utf8")) + files.set(modulePath, fs.readFileSync(modulePath+ext,"utf8")) break } } } } - const jsDoc= files.get(modulePath)?.match(jsDocRE) + const jsDoc = files.get(modulePath)?.match(jsDocRE) return jsDoc; } catch (err){ @@ -153,8 +153,8 @@ export function stripFileExtension(path: string) { export function toTypeDeclarationItems (imports: Import[], options?: TypeDeclarationOptions) { return imports.map((i) => { const from = options?.resolvePath?.(i) || stripFileExtension(i.typeFrom || i.from) - const jsDoc=extractJSDoc(from, i.as) - return `${jsDoc===null ? '' : jsDoc[0].slice(0,jsDoc[0].indexOf("*/\nexport")+3)+"\n\t"}const ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; + const jsDoc = extractJSDoc(from, i.as) + return `${jsDoc === null || jsDoc === undefined ? '' : jsDoc[0].slice(0, jsDoc[0].indexOf("*/\nexport")+3) + "\n\t"}const ${i.as}: typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}`; }).sort(); } From 4bf2eef7f0a9b7cf821fbd0bbfd831aad9696e30 Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Mon, 22 Jan 2024 23:25:52 +0200 Subject: [PATCH 19/20] chore: space --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 02bfcd10..6a1e5f04 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -121,7 +121,7 @@ export function toExports(imports: Import[], fileDir?: string, includeType = fal .join('\n') } export function extractJSDoc(modulePath: string, functionName: string) { - try{ + try { const jsDocRE = new RegExp(`(\\/\\*\\*[?;,.:\/@\\-\\s\\w\\{\\}\\[\\]\\(\\)\\<\\>\\"\`\|*]*\\*\\/)(?:\nexport d?e?c?l?a?r?e? (?:function|const) ${functionName})`,'i') modulePath = resolve(modulePath.slice(6)) if(!files.has(modulePath)){ From c0fe713f6f6fe4ce4101861b136cce1ca1bb3f1e Mon Sep 17 00:00:00 2001 From: Michael Brevard Date: Wed, 24 Jan 2024 11:05:49 +0200 Subject: [PATCH 20/20] style: lint --- src/utils.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 6a1e5f04..8e730c9d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -124,15 +124,15 @@ export function extractJSDoc(modulePath: string, functionName: string) { try { const jsDocRE = new RegExp(`(\\/\\*\\*[?;,.:\/@\\-\\s\\w\\{\\}\\[\\]\\(\\)\\<\\>\\"\`\|*]*\\*\\/)(?:\nexport d?e?c?l?a?r?e? (?:function|const) ${functionName})`,'i') modulePath = resolve(modulePath.slice(6)) - if(!files.has(modulePath)){ - if(fs.existsSync(modulePath + "/package.json")){ - const pkg = JSON.parse(fs.readFileSync(modulePath + "/package.json","utf8")) - files.set(modulePath, readFileSync(modulePath + "/" + pkg.main,"utf8")) + if (!files.has(modulePath)) { + if (fs.existsSync(modulePath + "/package.json")) { + const pkg = JSON.parse(fs.readFileSync(modulePath + "/package.json", "utf8")) + files.set(modulePath, readFileSync(modulePath + "/" + pkg.main, "utf8")) } - else{ - for(const ext of [".ts",".js",".mjs",".cjs"]){ - if(fs.existsSync(modulePath+ext)){ - files.set(modulePath, fs.readFileSync(modulePath+ext,"utf8")) + else { + for (const ext of [".ts",".js",".mjs",".cjs"]) { + if (fs.existsSync(modulePath + ext)) { + files.set(modulePath, fs.readFileSync(modulePath+ext, "utf8")) break } } @@ -141,7 +141,7 @@ export function extractJSDoc(modulePath: string, functionName: string) { const jsDoc = files.get(modulePath)?.match(jsDocRE) return jsDoc; } - catch (err){ + catch (err) { throw new Error(err) } }