From 902ef8db9bf4722311c6f2dfcbb7c89f4e1c141a Mon Sep 17 00:00:00 2001 From: Hajime-san <41257923+Hajime-san@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:27:21 +0900 Subject: [PATCH 1/5] fix: move to `bin.ts` --- bin.ts | 206 +++++++++++++++++++++++++++++++++++++++++++- src/bin_internal.ts | 201 ------------------------------------------ 2 files changed, 204 insertions(+), 203 deletions(-) delete mode 100644 src/bin_internal.ts diff --git a/bin.ts b/bin.ts index 25268b2..f65481f 100644 --- a/bin.ts +++ b/bin.ts @@ -1,3 +1,205 @@ -import { main } from "./src/bin_internal.ts"; +import { cli, io, path, ts, walk } from './src/deps.ts'; +import { + hasShouldResolveImportedFiles, + resolvedModules, +} from './src/resolve_util.ts'; +import { preserveNewLine, restoreNewLine } from './src/str.ts'; +import { transform } from './src/transform.ts'; -await main(); +const flags = cli.parse(Deno.args, { + string: ['b', 'c'], + boolean: ['d', 'r'], +}); + +const main = async (args: { + basePath?: string; + options?: { + tsConfigPath?: string; + dryRun?: boolean; + repl?: boolean; + }; +} = { + basePath: flags.b, + options: { + tsConfigPath: flags.c, + dryRun: flags.d ?? false, + repl: flags.r ?? false, + }, +}) => { + const { basePath, options } = args; + const _basePath = basePath ?? '.'; + const tsConfigPath = options?.tsConfigPath ?? './tsconfig.json'; + const match = [/\.ts$/, /\.mts$/, /\.jsx$/, /\.tsx$/]; + const skip = [/node_modules/]; + const decoder = new TextDecoder('utf-8'); + const tsConfigJson = await Deno.readFile(tsConfigPath); + const tsConfigObject = ts.parseJsonConfigFileContent( + JSON.parse(decoder.decode(tsConfigJson)), + ts.sys, + _basePath, + ); + const printer = ts.createPrinter(); + + const transformedList: Array<{ + path: string; + result: string; + }> = []; + + console.log('processing...'); + + for await (const entry of walk(_basePath, { match, skip })) { + if (entry.isFile) { + const targetPath = entry.path; + const targetFileAbsPath = path.resolve(targetPath); + const fileContent = preserveNewLine(decoder.decode( + await Deno.readFile(targetFileAbsPath), + )); + + const { importedFiles } = ts.preProcessFile(fileContent, true, true); + + if ( + !hasShouldResolveImportedFiles({ + importedFiles, + targetFileAbsPath, + tsConfigObject, + }) + ) continue; + + const imports = resolvedModules({ + importedFiles, + targetFileAbsPath, + tsConfigObject, + }); + + const sourceFile = ts.createSourceFile( + targetFileAbsPath, + fileContent, + ts.ScriptTarget.ESNext, + true, + ); + + const result = restoreNewLine( + // It seems like ts.Printer.printNode doesn't keep original source newline.🤔 + transform({ + sourceFile, + imports, + tsConfigObject, + printer, + }), + tsConfigObject.options.newLine, + ); + transformedList.push({ + path: targetFileAbsPath, + result, + }); + } + } + + if (transformedList.length === 0) { + console.log( + `%cThere're no transform target files.`, + 'color: green', + ); + Deno.exit(); + } + console.log( + `%ctransform target ${transformedList.length} files found.`, + 'color: yellow', + ); + const encoder = new TextEncoder(); + + const writeFiles = async (): Promise => { + await Promise.all(transformedList.map((transformed) => { + return new Promise((resolve, reject) => { + const { path, result } = transformed; + try { + resolve( + Deno.writeFile( + path, + encoder.encode(result), + ).then(), + ); + } catch (error) { + reject(error); + } + }); + })).then(() => { + console.log( + `%cupdate ${transformedList.length} files, finished.`, + 'color: green', + ); + }).catch((error) => { + throw new Error(error); + }); + }; + + const LOG_FILE_NAME = 'module-specifier-resolver.log'; + + const writeLog = async (): Promise => { + // try remove log file if it exsist or not + try { + await Deno.remove(LOG_FILE_NAME); + } catch (_) { /* noop */ } + await Promise.all(transformedList.map((transformed) => { + return new Promise((resolve, reject) => { + const { path, result } = transformed; + try { + resolve( + Deno.writeFile( + LOG_FILE_NAME, + encoder.encode( + `file: ${path} +${result} + +`, + ), + { + append: true, + }, + ).then(), + ); + } catch (error) { + reject(error); + } + }); + })).then(() => { + console.log( + `%cDry run: ${transformedList.length} files, finished.`, + 'color: green', + ); + console.log( + `%cInfo: ${LOG_FILE_NAME}`, + 'color: blue', + ); + }).catch((error) => { + throw new Error(error); + }); + }; + + if (options?.dryRun) { + await writeLog(); + Deno.exit(); + } + + if (options?.repl) { + console.log( + `%cAre you sure complement the extension of module specifier to files? (y/n)`, + 'color: yellow', + ); + for await (const line of io.readLines(Deno.stdin)) { + if (line.trim().toLowerCase() === 'y') { + await writeFiles(); + Deno.exit(); + } else { + Deno.exit(); + } + } + } else { + await writeFiles(); + Deno.exit(); + } +}; + +if(import.meta.main) { + await main(); +} \ No newline at end of file diff --git a/src/bin_internal.ts b/src/bin_internal.ts deleted file mode 100644 index a0c6a3f..0000000 --- a/src/bin_internal.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { cli, io, path, ts, walk } from './deps.ts'; -import { - hasShouldResolveImportedFiles, - resolvedModules, -} from './resolve_util.ts'; -import { preserveNewLine, restoreNewLine } from './str.ts'; -import { transform } from './transform.ts'; - -const flags = cli.parse(Deno.args, { - string: ['b', 'c'], - boolean: ['d', 'r'], -}); - -export const main = async (args: { - basePath?: string; - options?: { - tsConfigPath?: string; - dryRun?: boolean; - repl?: boolean; - }; -} = { - basePath: flags.b, - options: { - tsConfigPath: flags.c, - dryRun: flags.d ?? false, - repl: flags.r ?? false, - }, -}) => { - const { basePath, options } = args; - const _basePath = basePath ?? '.'; - const tsConfigPath = options?.tsConfigPath ?? './tsconfig.json'; - const match = [/\.ts$/, /\.mts$/, /\.jsx$/, /\.tsx$/]; - const skip = [/node_modules/]; - const decoder = new TextDecoder('utf-8'); - const tsConfigJson = await Deno.readFile(tsConfigPath); - const tsConfigObject = ts.parseJsonConfigFileContent( - JSON.parse(decoder.decode(tsConfigJson)), - ts.sys, - _basePath, - ); - const printer = ts.createPrinter(); - - const transformedList: Array<{ - path: string; - result: string; - }> = []; - - console.log('processing...'); - - for await (const entry of walk(_basePath, { match, skip })) { - if (entry.isFile) { - const targetPath = entry.path; - const targetFileAbsPath = path.resolve(targetPath); - const fileContent = preserveNewLine(decoder.decode( - await Deno.readFile(targetFileAbsPath), - )); - - const { importedFiles } = ts.preProcessFile(fileContent, true, true); - - if ( - !hasShouldResolveImportedFiles({ - importedFiles, - targetFileAbsPath, - tsConfigObject, - }) - ) continue; - - const imports = resolvedModules({ - importedFiles, - targetFileAbsPath, - tsConfigObject, - }); - - const sourceFile = ts.createSourceFile( - targetFileAbsPath, - fileContent, - ts.ScriptTarget.ESNext, - true, - ); - - const result = restoreNewLine( - // It seems like ts.Printer.printNode doesn't keep original source newline.🤔 - transform({ - sourceFile, - imports, - tsConfigObject, - printer, - }), - tsConfigObject.options.newLine, - ); - transformedList.push({ - path: targetFileAbsPath, - result, - }); - } - } - - if (transformedList.length === 0) { - console.log( - `%cThere're no transform target files.`, - 'color: green', - ); - Deno.exit(); - } - console.log( - `%ctransform target ${transformedList.length} files found.`, - 'color: yellow', - ); - const encoder = new TextEncoder(); - - const writeFiles = async (): Promise => { - await Promise.all(transformedList.map((transformed) => { - return new Promise((resolve, reject) => { - const { path, result } = transformed; - try { - resolve( - Deno.writeFile( - path, - encoder.encode(result), - ).then(), - ); - } catch (error) { - reject(error); - } - }); - })).then(() => { - console.log( - `%cupdate ${transformedList.length} files, finished.`, - 'color: green', - ); - }).catch((error) => { - throw new Error(error); - }); - }; - - const LOG_FILE_NAME = 'module-specifier-resolver.log'; - - const writeLog = async (): Promise => { - // try remove log file if it exsist or not - try { - await Deno.remove(LOG_FILE_NAME); - } catch (_) { /* noop */ } - await Promise.all(transformedList.map((transformed) => { - return new Promise((resolve, reject) => { - const { path, result } = transformed; - try { - resolve( - Deno.writeFile( - LOG_FILE_NAME, - encoder.encode( - `file: ${path} -${result} - -`, - ), - { - append: true, - }, - ).then(), - ); - } catch (error) { - reject(error); - } - }); - })).then(() => { - console.log( - `%cDry run: ${transformedList.length} files, finished.`, - 'color: green', - ); - console.log( - `%cInfo: ${LOG_FILE_NAME}`, - 'color: blue', - ); - }).catch((error) => { - throw new Error(error); - }); - }; - - if (options?.dryRun) { - await writeLog(); - Deno.exit(); - } - - if (options?.repl) { - console.log( - `%cAre you sure complement the extension of module specifier to files? (y/n)`, - 'color: yellow', - ); - for await (const line of io.readLines(Deno.stdin)) { - if (line.trim().toLowerCase() === 'y') { - await writeFiles(); - Deno.exit(); - } else { - Deno.exit(); - } - } - } else { - await writeFiles(); - Deno.exit(); - } -}; From d5de6095a4e61df4da53dcb3ec0a0e9b79cfd757 Mon Sep 17 00:00:00 2001 From: Hajime-san <41257923+Hajime-san@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:27:44 +0900 Subject: [PATCH 2/5] feat: add package definition --- deno.jsonc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deno.jsonc b/deno.jsonc index 0ecc50c..2ee1b23 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,4 +1,7 @@ { + "name": "@hajime-san/module-specifier-resolver", + "version": "1.0.20", + "exports": "./bin.ts", "tasks": { "run-dry": "deno run --allow-env --allow-read --allow-write bin.ts -b=./examples/repo/src -c=./examples/repo/tsconfig.json -d", "run": "deno run --allow-env --allow-read --allow-write bin.ts -b=./examples/repo/src -c=./examples/repo/tsconfig.json -r", From aede0004de65585cc8a1f605a7aa62dd6e3f2bb3 Mon Sep 17 00:00:00 2001 From: Hajime-san <41257923+Hajime-san@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:30:13 +0900 Subject: [PATCH 3/5] feat(action): update deps --- .github/workflows/ci.yaml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ec0557c..1a2e643 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,24 +6,24 @@ on: - main env: - DENO_VERSION: "1.31.1" - NODE_VERSION: "18.15.0" + DENO_VERSION: "1.41.0" + NODE_VERSION: "20.11.1" jobs: test: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: setup node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: cache node_modules id: node_modules_cache_id - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.npm key: node-v${{ env.NODE_VERSION }}-deps-${{ hashFiles('**/package-lock.json') }} @@ -41,11 +41,9 @@ jobs: deno-version: ${{ env.DENO_VERSION }} - name: Cache Deno dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: - path: | - /home/runner/.deno - /home/runner/.cache/deno + path: ~/.cache/deno key: deno-v${{ env.DENO_VERSION }}-${{ hashFiles('**/deno.lock') }} restore-keys: | deno-v${{ env.DENO_VERSION }}- From 3a9ec699ebf31d7c5a36d7ef2ef563d0b895794c Mon Sep 17 00:00:00 2001 From: Hajime-san <41257923+Hajime-san@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:34:40 +0900 Subject: [PATCH 4/5] feat(action): add publish workflow --- .github/workflows/publish.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..767dcd5 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,16 @@ +name: Publish to jsr + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read # need for checkout + id-token: write # The OIDC ID token is used for authentication with JSR. + steps: + - uses: actions/checkout@v4 + - uses: denoland/setup-deno@v1 + - run: deno publish From 20a5d2391926d6ccccb55da53893ac4fa7dd631d Mon Sep 17 00:00:00 2001 From: Hajime-san <41257923+Hajime-san@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:36:02 +0900 Subject: [PATCH 5/5] feat: to `1.0.20` --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5446844..ff31acb 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,9 @@ Please install [Deno](https://deno.land/manual@v1.30.3/getting_started/installat ## command ### remote - dry run - - `deno run --allow-env --allow-read --allow-write https://deno.land/x/module_specifier_resolver@v1.0.19/bin.ts -b=./src -c=./tsconfig.json -d` + - `deno run --allow-env --allow-read --allow-write https://deno.land/x/module_specifier_resolver@v1.0.20/bin.ts -b=./src -c=./tsconfig.json -d` - transform - - `deno run --allow-env --allow-read --allow-write https://deno.land/x/module_specifier_resolver@v1.0.19/bin.ts -b=./src -c=./tsconfig.json -r` + - `deno run --allow-env --allow-read --allow-write https://deno.land/x/module_specifier_resolver@v1.0.20/bin.ts -b=./src -c=./tsconfig.json -r` ### local - `deno task run-dry` - `deno task run`