Skip to content

Commit

Permalink
feat: allow configure js and ts extensions lists
Browse files Browse the repository at this point in the history
closes #168
  • Loading branch information
antongolub committed Oct 5, 2024
1 parent a964d86 commit 3d2630e
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 39 deletions.
8 changes: 8 additions & 0 deletions src/main/ts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const help = `
--target Specify target/outDir. Suppresses 'tsconfig.compilerOptions.outDir'.
--src Specify src dir for patching. Suppresses '--target' option.
--ext Append extension (like '.mjs') to relative imports/re-exports
--ts-ext Specify TS extensions. Defaults to '.ts,.tsx,.mts,.mtsx,.cts,.ctsx'
--js-ext Specify JS extensions. Defaults to '.js,.jsx,.mjs,.mjsx,.cjs,.cjsx'
--unlink Remove original files if ext changes
--dirnameVar Replace __dirname refs with import.meta
--filenameVar Replace __filename with import.meta
Expand All @@ -32,6 +34,12 @@ const parsed = typeFlag(
ext: {
type: String,
},
tsExt: {
type: String,
},
jsExt: {
type: String,
},
unlink: {
type: Boolean,
default: true,
Expand Down
19 changes: 10 additions & 9 deletions src/main/ts/finder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { dirname, join, resolve } from 'node:path'
import {asArray, glob, readJson, resolveTsConfig} from './util'
import {asArray, extToGlob, glob, readJson, resolveTsConfig} from './util'
import {DEFAULT_FIX_OPTIONS} from "./options";

type TPackageExports = [string, string[]][]

Expand Down Expand Up @@ -30,19 +31,19 @@ export const getTsconfigTargets = (
return targets
}, [])

export const getLocalModules = (sources: string[], targets: string[], cwd: string) => glob(
getPatterns(sources, targets),
export const getLocalModules = (sources: string[], targets: string[], cwd: string, tsExt: string[] = DEFAULT_FIX_OPTIONS.tsExt) => glob(
getPatterns(sources, targets, tsExt),
{
cwd,
onlyFiles: true,
absolute: true,
})

export const getExternalModules = async (cwd: string): Promise<{exportedModules: string[], anyModules: string[], allPackageNames: string[] }> => {
export const getExternalModules = async (cwd: string, jsExt: string[] = DEFAULT_FIX_OPTIONS.jsExt): Promise<{exportedModules: string[], anyModules: string[], allPackageNames: string[] }> => {
const allPackages = await getExternalPackages(cwd)
const allPackageNames = allPackages.map(p => p.name)
const exportedModules = (await Promise.all(allPackages.map(getPackageEntryPoints))).flat()
const anyModules = await getAllModules(cwd)
const anyModules = await getAllModules(cwd, jsExt)

return {
exportedModules,
Expand All @@ -51,12 +52,12 @@ export const getExternalModules = async (cwd: string): Promise<{exportedModules:
}
}

const getAllModules = async (cwd: string): Promise<string[]> => glob(
const getAllModules = async (cwd: string, jsExt: string[] = DEFAULT_FIX_OPTIONS.jsExt): Promise<string[]> => glob(
[
'!node_modules/.cache',
'!node_modules/.bin',
'!node_modules/**/node_modules',
'node_modules/**/*.{js,mjs,cjs}',
`node_modules/${extToGlob(jsExt)}`,
],
{
cwd,
Expand All @@ -65,9 +66,9 @@ const getAllModules = async (cwd: string): Promise<string[]> => glob(
},
)

const getPatterns = (sources: string[], targets: string[]): string[] =>
const getPatterns = (sources: string[], targets: string[], tsExt: string[]): string[] =>
sources.length > 0
? sources.map((src) => src.includes('*') ? src : `${src}/**/*.{ts,tsx}`)
? sources.map((src) => src.includes('*') ? src : `${src}/${extToGlob(tsExt)}`)
: targets.map((target) => target.includes('*') ? target : `${target}/**/*.{js,d.ts}`)

// https://nodejs.org/api/packages.html
Expand Down
16 changes: 7 additions & 9 deletions src/main/ts/fix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
TResourceContext
} from './interface'
import {
asArray,
existsSync,
read,
readJson,
Expand Down Expand Up @@ -40,24 +39,22 @@ export const fix = async (opts?: IFixOptions): Promise<void> => {
await patch(ctx, options)
}

const resolve = async (opts: IFixOptionsNormalized): Promise<TFixContext> => {
const {cwd, target, src, tsconfig, out = cwd, ext, debug, unlink, sourceMap} = opts
const resolve = async (options: IFixOptionsNormalized): Promise<TFixContext> => {
const {cwd, target: _targets, src: sources, tsconfig, out = cwd, ext, debug, tsExt, jsExt} = options
const outDir = path.resolve(cwd, out)
const sources = asArray<string>(src)
const _targets = asArray<string>(target)
const targets = _targets.length > 0 ? _targets : getTsconfigTargets(tsconfig, cwd)
debug('debug:cwd', cwd)
debug('debug:outdir', outDir)
debug('debug:sources', sources)
debug('debug:targets', targets)

const isSource = sources.length > 0
const localModules = await getLocalModules(sources, targets, cwd)
const localModules = await getLocalModules(sources, targets, cwd, tsExt)
const {
exportedModules,
anyModules,
allPackageNames,
} = await getExternalModules(cwd)
} = await getExternalModules(cwd, jsExt)

debug('debug:external-package-names', allPackageNames)
debug('debug:external-exported-modules', exportedModules)
Expand All @@ -76,12 +73,13 @@ const resolve = async (opts: IFixOptionsNormalized): Promise<TFixContext> => {
allJsModules,
allModules,
_localModules,
localModules
localModules,
options
}
}

const patch = async (ctx: TFixContext, options: IFixOptionsNormalized) => {
const {cwd, unlink, sourceMap} = options
const {cwd, unlink, sourceMap, tsExt, jsExt} = options
const {
outDir,
isSource,
Expand Down
14 changes: 8 additions & 6 deletions src/main/ts/fixes/fix-module-ref.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {dirname, resolve} from 'node:path'
import {TFixer} from '../interface'
import {unixify} from '../util'
import { dirname, resolve } from 'node:path'
import { patchRefs } from 'depseek'
import { TFixer } from '../interface'
import { unixify } from '../util'
import { DEFAULT_FIX_OPTIONS } from '../options'

export const fixModuleReferences: TFixer = (ctx) => {
const { contents, filename, filenames, options: {cwd}, ignore } = ctx
const { contents, filename, filenames, options: {cwd, jsExt}, ignore } = ctx
const _contents = patchRefs(contents, (value) => {
const v = value.endsWith('/') ? value.slice(0, -1) : value
return (v.includes('/') || v === '.' || v === '..') && !ignore.includes(v)
? resolveDependency(filename, v, filenames, cwd)
? resolveDependency(filename, v, filenames, cwd, jsExt)
: value
})

Expand All @@ -20,13 +21,14 @@ export const resolveDependency = (
nested: string,
files: string[],
cwd: string,
jsExt: string[] = DEFAULT_FIX_OPTIONS.jsExt,
): string => {
const dir = dirname(parent)
const nmdir = resolve(cwd, 'node_modules')
const bases = /^\..+\.[^./\\]+$/.test(nested)
? [nested, nested.replace(/\.[^./\\]+$/, '')]
: [nested]
const variants = ['.js', '.cjs', '.mjs'].reduce<string[]>((m, e) => {
const variants = jsExt.reduce<string[]>((m, e) => {
bases.forEach((v) => m.push(`${v}${e}`, `${v}/index${e}`))
return m
}, [])
Expand Down
17 changes: 13 additions & 4 deletions src/main/ts/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ export type IFixOptionsNormalized = {
cwd: string
debug: IFunction
out?: string
src?: string | string[]
target?: string | string[]
src : string[]
target: string[]
tsconfig: string | string[]
dirnameVar: boolean
filenameVar: boolean
fillBlank?: boolean
forceDefaultExport?: boolean
sourceMap?: boolean
ext: boolean | string
tsExt: string[]
jsExt: string[]
unlink?: boolean
}

Expand All @@ -21,7 +23,13 @@ export type TSConfig = {
compilerOptions?: Record<string, any>
}

export type IFixOptions = Partial<Omit<IFixOptionsNormalized, 'debug'>> & {debug?: boolean | IFunction}
export type IFixOptions = Partial<Omit<IFixOptionsNormalized, 'debug'>>& {
debug?: boolean | IFunction
src?: string | string[]
target?:string | string[]
tsExt?: string | string[]
jsExt?: string | string[]
}

export type TFixContext = {
outDir: string
Expand All @@ -31,17 +39,18 @@ export type TFixContext = {
allModules: string[]
_localModules: string[]
localModules: string[]
options: IFixOptionsNormalized
}

export type TResourceContext = {
options: IFixOptionsNormalized
contents: string
filename: string
filenames: string[]
originName: string
nextName: string
isSource: boolean
ignore: string[]
options: IFixOptionsNormalized
}

export type TFixer = (ctx: TResourceContext) => TResourceContext
13 changes: 12 additions & 1 deletion src/main/ts/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
fixModuleReferences as _fixModuleReferences,
fixSourceMapRef as _fixSourceMapRef,
} from './fixes'
import {DEFAULT_FIX_OPTIONS} from "./options";

export const fixModuleReferences = (
contents: string,
Expand All @@ -16,7 +17,17 @@ export const fixModuleReferences = (
cwd: string,
ignore: string[],
): string =>
_fixModuleReferences({contents, filename, filenames, options: {cwd}, ignore} as TResourceContext).contents
_fixModuleReferences({
contents,
filename,
filenames,
options: {
cwd,
tsExt: DEFAULT_FIX_OPTIONS.tsExt,
jsExt: DEFAULT_FIX_OPTIONS.jsExt,
},
ignore
} as TResourceContext).contents

export const fixDirnameVar = (contents: string, isSource?: boolean): string =>
_fixDirnameVar({contents, isSource} as TResourceContext).contents
Expand Down
26 changes: 19 additions & 7 deletions src/main/ts/options.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import {IFixOptions, IFixOptionsNormalized} from "./interface";
import {omitUndefinedKeys} from './util'
import { IFixOptions, IFixOptionsNormalized } from './interface'
import { asArray, omitUndefinedKeys } from './util'

export const JS_EXT = ['.js', '.jsx', '.mjs', '.mjsx', '.cjs', '.cjsx']
export const TS_EXT = ['.ts', '.tsx', '.mts', '.mtsx', '.cts', '.ctsx']

export const DEFAULT_FIX_OPTIONS: IFixOptionsNormalized = {
cwd: process.cwd(),
tsconfig: './tsconfig.json',
tsconfig: ['./tsconfig.json'],
src: [],
target: [],
filenameVar: true,
dirnameVar: true,
ext: true,
tsExt: TS_EXT,
jsExt: JS_EXT,
unlink: true,
debug: () => {}, // eslint-disable-line
}

export const normalizeOptions = (
opts?: IFixOptions,
opts: IFixOptions = {},
): IFixOptionsNormalized => ({
...DEFAULT_FIX_OPTIONS,
...omitUndefinedKeys(opts || {}),
debug: typeof opts?.debug === 'function'
...omitUndefinedKeys(opts),
tsconfig: opts.tsconfig ? asArray(opts.tsconfig) : DEFAULT_FIX_OPTIONS.tsconfig,
src: asArray(opts.src),
target: asArray(opts.target),
jsExt: typeof opts.jsExt === 'string' ? opts.jsExt.split(',') : opts.jsExt || DEFAULT_FIX_OPTIONS.jsExt,
tsExt: typeof opts.tsExt === 'string' ? opts.tsExt.split(',') : opts.tsExt || DEFAULT_FIX_OPTIONS.tsExt,
debug: typeof opts.debug === 'function'
? opts.debug
: opts?.debug === true
: opts.debug === true
? console.log
: DEFAULT_FIX_OPTIONS.debug,
})
2 changes: 2 additions & 0 deletions src/main/ts/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ export const resolveTsConfig = (file: string): TSConfig => {

export const omitUndefinedKeys = <T extends Record<string, any>>(obj: T): T =>
Object.fromEntries(Object.entries(obj).filter(([, value]) => value !== undefined)) as T

export const extToGlob = (ext: string[]): string => `**/*.{${ext.map(e => e.slice(1)).join(',')}}`
22 changes: 19 additions & 3 deletions src/test/ts/fix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ describe('normalizeOptions()', () => {
filenameVar: true,
ext: true,
unlink: true,
src: [],
target: [],
jsExt: DEFAULT_FIX_OPTIONS.jsExt,
tsExt: DEFAULT_FIX_OPTIONS.tsExt,
})
})
})
Expand Down Expand Up @@ -168,7 +172,11 @@ describe('patches', () => {
filenameVar: false,
dirnameVar: false,
tsconfig: './tsconfig.json', // eslint-disable-line
debug: () => {}, // eslint-disable-line
debug(){}, // eslint-disable-line
jsExt: DEFAULT_FIX_OPTIONS.jsExt,
tsExt: DEFAULT_FIX_OPTIONS.tsExt,
src: [],
target: [],
}),
).toEqual(content)
})
Expand All @@ -184,7 +192,11 @@ describe('patches', () => {
filenameVar: false,
dirnameVar: false,
tsconfig: './tsconfig.json',
debug: () => {}, // eslint-disable-line
debug() {}, // eslint-disable-line
jsExt: DEFAULT_FIX_OPTIONS.jsExt,
tsExt: DEFAULT_FIX_OPTIONS.tsExt,
src: [],
target: [],
}),
).toMatchSnapshot()
})
Expand All @@ -209,7 +221,11 @@ describe('patches', () => {
filenameVar: false,
dirnameVar: false,
tsconfig: './tsconfig.json', // eslint-disable-line
debug: () => {}, // eslint-disable-line
debug() {}, // eslint-disable-line @typescript-eslint/no-empty-function,
jsExt: DEFAULT_FIX_OPTIONS.jsExt,
tsExt: DEFAULT_FIX_OPTIONS.tsExt,
src: [],
target: [],
}),
).toMatchSnapshot()
})
Expand Down

0 comments on commit 3d2630e

Please sign in to comment.