Skip to content

Commit

Permalink
feat: add RegExp extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jul 20, 2021
1 parent 762a4e6 commit 51e1d22
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 59 deletions.
1 change: 1 addition & 0 deletions src/IndexGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const indexFilePaths = [
join(__dirname, './__fixtures__/types/index.ts'),
join(__dirname, './__fixtures__/scripts/index.html'),
join(__dirname, './__fixtures__/cross_negative/index.txt'),
join(__dirname, './__fixtures__/re/index.js'),
]

test('ok', async () => {
Expand Down
188 changes: 129 additions & 59 deletions src/IndexGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import * as changeCase from 'change-case'
import globby, { GlobbyOptions } from 'globby'
import { castArray, noop } from 'vtils'
import { CodeGenerator, Marker, ParsedPath, Pattern } from './types'
import { castArray, isRegExp, noop } from 'vtils'
import {
CodeGenerator,
CodeGeneratorRe,
Marker,
ParsedPath,
Pattern,
} from './types'
import { dirname, join, parse, relative } from 'path'
import { statSync } from 'fs'
import { readFile, statSync } from 'fs-extra'

export interface IndexGeneratorOptions {
filePath: string
Expand All @@ -21,65 +27,95 @@ export class IndexGenerator {
const markers = IndexGenerator.findMarkers(fileContent, onWarning)
if (markers.length) {
for (const marker of markers) {
const paths = await globby(marker.patterns, {
dot: true,
onlyFiles: false,
// TODO: fix https://github.com/sindresorhus/globby/issues/133
gitignore: false,
...(marker.globbyOptions || {}),
cwd: fileDir,
absolute: true,
})
paths.sort(
new Intl.Collator(['en', 'co'], {
sensitivity: 'base',
numeric: true,
}).compare,
)
const codes = paths
.filter(path => path !== filePath)
.map((path, index, paths) => {
const pp = parse(path)
const parsedPath: ParsedPath = {
path: IndexGenerator.getRelativePath(
fileDir,
join(pp.dir, pp.name),
),
name: pp.name,
ext: pp.ext,
}
const code = marker.codeGenerator(parsedPath, changeCase, {
if (!marker.isRe) {
const paths = await globby(marker.patterns, {
dot: true,
onlyFiles: false,
// TODO: fix https://github.com/sindresorhus/globby/issues/133
gitignore: false,
...(marker.globbyOptions || {}),
cwd: fileDir,
absolute: true,
})
paths.sort(
new Intl.Collator(['en', 'co'], {
sensitivity: 'base',
numeric: true,
}).compare,
)
const codes = paths
.filter(path => path !== filePath)
.map((path, index, paths) => {
const pp = parse(path)
const parsedPath: ParsedPath = {
path: IndexGenerator.getRelativePath(
fileDir,
join(pp.dir, pp.name),
),
name: pp.name,
ext: pp.ext,
}
const code = marker.codeGenerator(parsedPath, changeCase, {
get total() {
return paths.length
},
get index() {
return index
},
get first() {
return index === 0
},
get last() {
return index === paths.length - 1
},
get isFirst() {
return index === 0
},
get isLast() {
return index === paths.length - 1
},
get isDir() {
return statSync(path).isDirectory()
},
get isFile() {
return statSync(path).isFile()
},
})
return marker.indent + code
})
await onGenerate({
marker: marker,
code: `${marker.start === 0 ? '' : '\n'}${codes.join('\n')}\n`,
})
} else {
const sourceContent = await readFile(
join(fileDir, marker.fileRe),
'utf-8',
)
const region = sourceContent.match(marker.regionRe)?.[0] || ''
const matches = [...(region.matchAll(marker.matchRe) || [])]
const codes = matches.map((match, index, { length }) => {
const code = marker.codeGeneratorRe(match, changeCase, {
get total() {
return paths.length
return length
},
get index() {
return index
},
get first() {
return index === 0
},
get last() {
return index === paths.length - 1
},
get isFirst() {
return index === 0
},
get isLast() {
return index === paths.length - 1
},
get isDir() {
return statSync(path).isDirectory()
},
get isFile() {
return statSync(path).isFile()
return index === length - 1
},
})
return marker.indent + code
})
await onGenerate({
marker: marker,
code: `${marker.start === 0 ? '' : '\n'}${codes.join('\n')}\n`,
})
await onGenerate({
marker: marker,
code: `${marker.start === 0 ? '' : '\n'}${codes.join('\n')}\n`,
})
}
}
} else {
onWarning('No @index maker found.')
Expand Down Expand Up @@ -108,18 +144,47 @@ export class IndexGenerator {
let patterns: Pattern[] = []
let codeGenerator: CodeGenerator = noop
let globbyOptions: GlobbyOptions = {}
let isRe = false
let fileRe = ''
let codeGeneratorRe: CodeGeneratorRe = noop
let regionRe = /1/
let matchRe = /1/
// eslint-disable-next-line no-inner-declarations
function setParams(
localPatterns: Pattern | Pattern[],
localCodeGenerator: CodeGenerator,
localGlobbyOptions: GlobbyOptions,
) {
if (localPatterns == null) {
throw new TypeError('Invalid patterns')
function setParams(...args: any[]) {
if (isRegExp(args[1])) {
// eslint-disable-next-line prefer-const
let [_file, _regionRe, _matchRe, _codeGeneratorRe]: [
Pattern,
RegExp,
RegExp,
CodeGeneratorRe,
] = args as any
if (_codeGeneratorRe == null) {
_codeGeneratorRe = _matchRe as any
_matchRe = _regionRe as any
_regionRe = /^.+$/s as any
}
if (typeof _file !== 'string') {
throw new TypeError('Invalid file')
}
isRe = true
fileRe = _file
regionRe = _regionRe
matchRe = _matchRe
codeGeneratorRe = _codeGeneratorRe
} else {
const [_patterns, _codeGenerator, _globbyOptions]: [
Pattern | Pattern[],
CodeGenerator,
GlobbyOptions,
] = args as any
if (_patterns == null) {
throw new TypeError('Invalid patterns')
}
patterns = castArray(_patterns)
codeGenerator = _codeGenerator
globbyOptions = _globbyOptions
}
patterns = castArray(localPatterns)
codeGenerator = localCodeGenerator
globbyOptions = localGlobbyOptions
}
try {
eval(`${setParams.name}(${startMatch[2]})`)
Expand All @@ -130,6 +195,11 @@ export class IndexGenerator {
patterns: patterns,
codeGenerator: codeGenerator,
globbyOptions: globbyOptions,
isRe: isRe,
fileRe: fileRe,
regionRe: regionRe,
matchRe: matchRe,
codeGeneratorRe: codeGeneratorRe,
})
} catch (e) {
onInvalid?.(
Expand Down
11 changes: 11 additions & 0 deletions src/__fixtures__/re/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @index('../../../node_modules/fs-extra/lib/index.js', /\.\.\.require\('(.+?)'\)/g, (m, _) => `${_.camel(m[1])}`)

// @endindex

// @index('../../../node_modules/fs-extra/package.json', /(?<="dependencies": \{).+?(?=\})/s, /"(.+?)": "(.+?)"/g, (m, _, e) => `${e.index}. ${m[1]} ==> ${m[2]}`)

// @endindex

// @index('../../../node_modules/fs-extra/lib/index.js', /\.\.\.require\('(.+?)'\)/g, (m, _) => `${_.camel(m[1])}`)

// @endindex
44 changes: 44 additions & 0 deletions src/__snapshots__/IndexGenerator.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports[`ok: generated content of /cross/index.txt 1`] = `
../cross_negative/index.txt
../invalid/empty
../invalid/error
../re/index.js
../scripts/index.html
../scripts/jssdk.js
../scripts/polyfill.js
Expand Down Expand Up @@ -58,6 +59,7 @@ exports[`ok: generated content of /cross/index.txt 1`] = `
./
../cross_negative
../invalid
../re
../scripts
../scss
../sort
Expand All @@ -80,6 +82,7 @@ exports[`ok: generated content of /cross_negative/index.txt 1`] = `
../cross
./
../invalid
../re
../scripts
../sort
../types
Expand All @@ -94,6 +97,45 @@ exports[`ok: generated content of /invalid/error 1`] = `
"
`;

exports[`ok: generated content of /re/index.js 1`] = `
"// @index('../../../node_modules/fs-extra/lib/index.js', /\\\\.\\\\.\\\\.require\\\\('(.+?)'\\\\)/g, (m, _) => \`\${_.camel(m[1])}\`)
fs
copySync
copy
empty
ensure
json
mkdirs
moveSync
move
output
pathExists
remove
// @endindex
// @index('../../../node_modules/fs-extra/package.json', /(?<=\\"dependencies\\": \\\\{).+?(?=\\\\})/s, /\\"(.+?)\\": \\"(.+?)\\"/g, (m, _, e) => \`\${e.index}. \${m[1]} ==> \${m[2]}\`)
0. at-least-node ==> ^1.0.0
1. graceful-fs ==> ^4.2.0
2. jsonfile ==> ^6.0.1
3. universalify ==> ^2.0.0
// @endindex
// @index('../../../node_modules/fs-extra/lib/index.js', /\\\\.\\\\.\\\\.require\\\\('(.+?)'\\\\)/g, (m, _) => \`\${_.camel(m[1])}\`)
fs
copySync
copy
empty
ensure
json
mkdirs
moveSync
move
output
pathExists
remove
// @endindex"
`;
exports[`ok: generated content of /scripts/index.html 1`] = `
"<html>
<head>
Expand Down Expand Up @@ -182,6 +224,8 @@ Array [
]
`;
exports[`ok: messages of /re/index.js 1`] = `Array []`;
exports[`ok: messages of /scripts/index.html 1`] = `Array []`;
exports[`ok: messages of /scss/index.scss 1`] = `Array []`;
Expand Down
22 changes: 22 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ export interface ExtraInfo {
isFile: boolean
}

export interface ExtraInfoRe {
/** total number of matches */
total: number
/** index of current match */
index: number
/** if current item is the first */
isFirst: boolean
/** if current item is the last */
isLast: boolean
}

export type Pattern = string

export type CodeGenerator = (
Expand All @@ -45,11 +56,22 @@ export type CodeGenerator = (
extraInfo: ExtraInfo,
) => string

export type CodeGeneratorRe = (
matches: string[],
changeCase: ChangeCase,
extraInfo: ExtraInfoRe,
) => string

export interface Marker {
indent: string
start: number
end: number
patterns: Pattern[]
codeGenerator: CodeGenerator
globbyOptions: GlobbyOptions
isRe: boolean
fileRe: string
codeGeneratorRe: CodeGeneratorRe
regionRe: RegExp
matchRe: RegExp
}

0 comments on commit 51e1d22

Please sign in to comment.