diff --git a/README.md b/README.md index 6577682..47e4e02 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ This tool transforms your local TypeScript code that gives you to rewrite file e ## transform examples ```ts export { foo } from "./foo" -transform to +// transform to export { foo } from "./foo.(ts|tsx|d.ts)" ``` ```ts import { bar } from "./bar" -transform to +// transform to import { bar } from "./bar.(ts|tsx|d.ts)" ``` @@ -18,13 +18,14 @@ import { bar } from "./bar.(ts|tsx|d.ts)" - Can't resolve `paths` alias of TypeScript compiler options. - Can't resolve `import()` syntax, commonly called `dynamic import`. - Can't keep `newline` of original source code. +- Can't keep `single quatation` or `duble quatation` and `semicolon` of original source code. ## command ### remote - dry run - - `deno run --unstable --allow-env --allow-read https://deno.land/x/module_specifier_resolver@v1.0.5/bin.ts -b=./src -c=./tsconfig.json -d` + - `deno run --unstable --allow-env --allow-read https://deno.land/x/module_specifier_resolver@v1.0.6/bin.ts -b=./src -c=./tsconfig.json -d` - transform - - `deno run --unstable --allow-env --allow-read --allow-write https://deno.land/x/module_specifier_resolver@v1.0.5/bin.ts -b=./src -c=./tsconfig.json -r` + - `deno run --unstable --allow-env --allow-read --allow-write https://deno.land/x/module_specifier_resolver@v1.0.6/bin.ts -b=./src -c=./tsconfig.json -r` ### local - `deno task run-dry` - `deno task run` @@ -32,7 +33,7 @@ import { bar } from "./bar.(ts|tsx|d.ts)" ### arguments | key | description | type | default | |-----|-----|-----|-----| -| -b | local of base directory | `string` | `./` | +| -b | local of base directory | `string` | `.` | | -c | local of base `tsconfig.json` | `string` | `./tsconfig.json` | | -d | dry run | `boolean` | `false` | | -r | enable repl interface | `boolean` | `false` | @@ -40,15 +41,15 @@ import { bar } from "./bar.(ts|tsx|d.ts)" ## tips After you ran `bin.ts`, you should run `npx tsc --noEmit` due to check correctness of transformation by this tool. - `tsconfig.json` example -```json -{ - "compilerOptions": { - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "noEmit": true + ```json + { + "compilerOptions": { + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "noEmit": true + } } -} -``` + ``` ## License - MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) diff --git a/examples/repo/src/App.tsx b/examples/repo/src/App.tsx index f6ee8e9..603d565 100644 --- a/examples/repo/src/App.tsx +++ b/examples/repo/src/App.tsx @@ -7,6 +7,8 @@ import { ComponentC } from './ComponentC'; import style from './style.css'; import './sideEffect'; +const str = '😎'; + // a comment createRoot(document.getElementById('root') as HTMLElement) .render( @@ -14,5 +16,6 @@ createRoot(document.getElementById('root') as HTMLElement) +

{str}

, ); diff --git a/examples/repo/src/Main/App.tsx b/examples/repo/src/Main/App.tsx deleted file mode 100644 index bfdf157..0000000 --- a/examples/repo/src/Main/App.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { ComponentA } from '../ComponentA'; -import { ComponentB } from '../ComponentB'; -import { ComponentC } from '../ComponentC'; - -createRoot(document.getElementById('root') as HTMLElement) - .render( - - - - - , - ); diff --git a/src/mod.ts b/src/mod.ts index 8913425..8f7c658 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -1,5 +1,6 @@ import { cli, io, path, ts, walk } from './dev_deps.ts'; import { relativeFilePath } from './path.ts'; +import { hasUnicodeStr, unescapeUnicodeStr } from './str.ts'; type NodeLike = ts.Node | ts.Expression; @@ -147,11 +148,13 @@ export const transform = (args: { transformeModuleSpecifier(imports), ], tsConfigObject.options); - return printer.printNode( + const result = printer.printNode( ts.EmitHint.Unspecified, transformationResult.transformed[0], ts.createSourceFile('', '', ts.ScriptTarget.ESNext), ); + // unescape unicode text + return hasUnicodeStr(result) ? unescapeUnicodeStr(result) : result; }; const flags = cli.parse(Deno.args, { @@ -175,9 +178,10 @@ export const main = async (args: { }, }) => { const { basePath, options } = args; - const _basePath = basePath ?? './'; + const _basePath = basePath ?? '.'; const tsConfigPath = options?.tsConfigPath ?? './tsconfig.json'; const match = [/\.js$/, /\.mjs$/, /\.ts$/, /\.mts$/, /\.jsx$/, /\.tsx$/]; + const skip = [/node_modules/]; const decoder = new TextDecoder('utf-8'); const tsConfigJson = await Deno.readFile(tsConfigPath); const tsConfigObject = ts.parseJsonConfigFileContent( @@ -192,7 +196,7 @@ export const main = async (args: { result: string; }> = []; - for await (const entry of walk(_basePath, { match })) { + for await (const entry of walk(_basePath, { match, skip })) { if (entry.isFile) { const targetPath = entry.path; const currentFileAbsPath = path.resolve(targetPath); diff --git a/src/mod_test.ts b/src/mod_test.ts index b77d383..d4ebf2b 100644 --- a/src/mod_test.ts +++ b/src/mod_test.ts @@ -50,7 +50,8 @@ Deno.test('transform', async (t) => { transform({ sourceFile: ts.createSourceFile( './src/App.tsx', - `import { ComponentA } from './ComponentA';`, + `import { ComponentA } from './ComponentA';\n` + + `const str = '😎';\n`, ts.ScriptTarget.ESNext, ), imports: [ @@ -59,7 +60,8 @@ Deno.test('transform', async (t) => { tsConfigObject: tsConfigMockObject, printer: ts.createPrinter(), }), - `import { ComponentA } from "./ComponentA.tsx";\n`, + `import { ComponentA } from "./ComponentA.tsx";\n` + + `const str = "😎";\n`, ); }); }); diff --git a/src/str.ts b/src/str.ts new file mode 100644 index 0000000..dec9e36 --- /dev/null +++ b/src/str.ts @@ -0,0 +1,7 @@ +export const hasUnicodeStr = (str: string): boolean => { + return /\\u.{4}/gi.test(str); +}; + +export const unescapeUnicodeStr = (str: string): string => { + return unescape(str.replace(/\\u/g, '%u')); +}; diff --git a/src/str_test.ts b/src/str_test.ts new file mode 100644 index 0000000..b051174 --- /dev/null +++ b/src/str_test.ts @@ -0,0 +1,12 @@ +import { asserts } from './dev_deps.ts'; +import { hasUnicodeStr, unescapeUnicodeStr } from './str.ts'; +const { assertEquals } = asserts; + +Deno.test('hasUnicodeStr', () => { + // \uD83D\uDE0E is 😎 + assertEquals(hasUnicodeStr('\\uD83D\\uDE0E'), true); +}); + +Deno.test('unescapeUnicodeStr', () => { + assertEquals(unescapeUnicodeStr('\uD83D\uDE0E'), '😎'); +});