@liuli-util/cli 3.10.1 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -3
  3. package/dist/PathUtil.d.ts +6 -6
  4. package/dist/bin.d.ts +1 -1
  5. package/dist/bin.js +102 -86
  6. package/dist/bin.js.map +3 -3
  7. package/dist/commands/esbuild/ESBuildProgram.d.ts +70 -10
  8. package/dist/commands/esbuild/ESBuildProgram.d.ts.map +1 -1
  9. package/dist/commands/esbuild/index.d.ts +2 -2
  10. package/dist/commands/esbuild/index.d.ts.map +1 -1
  11. package/dist/commands/esbuild/util/debounce.d.ts +15 -0
  12. package/dist/commands/esbuild/util/debounce.d.ts.map +1 -0
  13. package/dist/commands/esbuild/util/esbuildPlugins.d.ts +16 -0
  14. package/dist/commands/esbuild/util/esbuildPlugins.d.ts.map +1 -0
  15. package/dist/commands/generate/GenerateProgram.d.ts +17 -17
  16. package/dist/commands/generate/GenerateProgram.d.ts.map +1 -1
  17. package/dist/commands/generate/index.d.ts +2 -2
  18. package/dist/commands/sync/SyncProgram.d.ts +14 -15
  19. package/dist/commands/sync/SyncProgram.d.ts.map +1 -1
  20. package/dist/commands/sync/index.d.ts +2 -2
  21. package/dist/commands/sync/when.d.ts +20 -20
  22. package/dist/index.d.ts +3 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.esm.js +5 -0
  25. package/dist/index.esm.js.map +3 -3
  26. package/dist/index.js +5 -5
  27. package/dist/index.js.map +3 -3
  28. package/dist/utils/AsyncArray.d.ts +20 -20
  29. package/dist/utils/appendScript.d.ts +6 -6
  30. package/dist/utils/arrayToMap.d.ts +2 -2
  31. package/dist/utils/findParent.d.ts +7 -7
  32. package/dist/utils/index.d.ts +4 -4
  33. package/package.json +19 -7
  34. package/src/@types/global.d.ts +8 -0
  35. package/src/bin.ts +2 -2
  36. package/src/commands/esbuild/ESBuildProgram.ts +263 -63
  37. package/src/commands/esbuild/__tests__/ESBuildProgram.test.ts +125 -0
  38. package/src/commands/esbuild/__tests__/spinnies.test.ts +11 -0
  39. package/src/commands/esbuild/index.ts +14 -6
  40. package/src/commands/esbuild/util/debounce.ts +29 -0
  41. package/src/commands/esbuild/util/esbuildPlugins.ts +82 -0
  42. package/src/commands/generate/GenerateProgram.ts +7 -5
  43. package/src/commands/sync/SyncProgram.ts +6 -12
  44. package/src/commands/sync/__tests__/SyncProgram.test.ts +2 -2
  45. package/src/index.ts +3 -1
  46. package/src/utils/__tests__/appendScript.test.ts +1 -1
  47. package/templates/cli/package.json +1 -1
  48. package/templates/lib/package.json +1 -1
  49. package/dist/commands/generate/__tests__/GenerateProgram.test.d.ts +0 -2
  50. package/dist/commands/generate/__tests__/GenerateProgram.test.d.ts.map +0 -1
  51. package/dist/commands/sync/__tests__/SyncProgram.test.d.ts +0 -2
  52. package/dist/commands/sync/__tests__/SyncProgram.test.d.ts.map +0 -1
  53. package/dist/commands/sync/__tests__/when.test.d.ts +0 -2
  54. package/dist/commands/sync/__tests__/when.test.d.ts.map +0 -1
  55. package/dist/tsconfig.tsbuildinfo +0 -1
  56. package/dist/utils/__tests__/appendScript.test.d.ts +0 -2
  57. package/dist/utils/__tests__/appendScript.test.d.ts.map +0 -1
  58. package/dist/utils/__tests__/arrayToMap.test.d.ts +0 -2
  59. package/dist/utils/__tests__/arrayToMap.test.d.ts.map +0 -1
  60. package/dist/utils/__tests__/findParent.test.d.ts +0 -2
  61. package/dist/utils/__tests__/findParent.test.d.ts.map +0 -1
  62. package/dist/utils/execPromise.d.ts +0 -4
  63. package/dist/utils/execPromise.d.ts.map +0 -1
  64. package/src/utils/execPromise.ts +0 -16
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export {}\r\n"],
5
- "mappings": ";;;;AAAA;",
3
+ "sources": ["../src/index.ts", "../src/commands/esbuild/ESBuildProgram.ts", "../src/commands/esbuild/util/esbuildPlugins.ts", "../src/commands/esbuild/util/debounce.ts", "../src/commands/generate/GenerateProgram.ts", "../src/commands/sync/SyncProgram.ts", "../src/commands/sync/when.ts", "../src/utils/arrayToMap.ts", "../src/utils/appendScript.ts", "../src/utils/findParent.ts", "../src/utils/AsyncArray.ts", "../src/PathUtil.ts"],
4
+ "sourcesContent": ["export * from './commands/esbuild/ESBuildProgram'\r\nexport * from './commands/generate/GenerateProgram'\r\nexport * from './commands/sync/SyncProgram'\r\n", "import { build, BuildOptions, Platform, Plugin } from 'esbuild'\r\nimport { pathExists, readJson } from 'fs-extra'\r\nimport * as path from 'path'\r\nimport { PackageJson } from 'type-fest'\r\nimport { Project } from 'ts-morph'\r\nimport { promise } from 'glob-promise'\r\nimport { IOptions } from 'glob'\r\nimport { nativeNodeModules, nodeExternals } from './util/esbuildPlugins'\r\nimport { watch } from 'chokidar'\r\nimport Spinnies from 'spinnies'\r\nimport { debounce } from './util/debounce'\r\n\r\ninterface ESBuildProgramOptions {\r\n base: string\r\n isWatch: boolean\r\n}\r\n\r\ninterface Task {\r\n title: string\r\n task(): Promise<any>\r\n}\r\n\r\nexport class ESBuildProgram {\r\n constructor(private readonly options: ESBuildProgramOptions) {}\r\n\r\n static readonly globalExternal = ['esbuild', 'pnpapi', 'ts-morph']\r\n\r\n /**\r\n * \u83B7\u53D6\u6240\u6709\u4F9D\u8D56\r\n */\r\n static async getDeps(base: string): Promise<string[]> {\r\n const json = (await readJson(\r\n path.resolve(base, 'package.json'),\r\n )) as PackageJson\r\n return Object.keys({\r\n ...json.dependencies,\r\n ...json.devDependencies,\r\n ...json.peerDependencies,\r\n })\r\n }\r\n\r\n /**\r\n * \u83B7\u53D6\u6240\u5728\u6A21\u5757\u7684\u7C7B\u578B\r\n */\r\n static async getPlatform(base: string): Promise<Platform> {\r\n const tsconfigPath = path.resolve(base, 'tsconfig.json')\r\n if (await pathExists(tsconfigPath)) {\r\n const tsconfigJson = await readJson(tsconfigPath)\r\n if (\r\n (tsconfigJson.compilerOptions.lib as string[]).some(\r\n (lib) => lib.toLowerCase() === 'dom',\r\n )\r\n ) {\r\n return 'browser'\r\n }\r\n }\r\n const pkgPath = path.resolve(base, 'package.json')\r\n if (await pathExists(pkgPath)) {\r\n const pkgJson = (await readJson(pkgPath)) as PackageJson\r\n if (Object.keys(pkgJson.devDependencies ?? {}).includes('@types/node')) {\r\n return 'node'\r\n }\r\n }\r\n return 'neutral'\r\n }\r\n static getWatchOptions(base: string): {\r\n pattern: string\r\n options: IOptions\r\n } {\r\n const pattern = 'src/**/*.ts'\r\n const options: Pick<IOptions, 'cwd' | 'ignore'> = {\r\n cwd: base,\r\n ignore: '**/__tests__/**/*',\r\n }\r\n return { pattern, options }\r\n }\r\n /**\r\n * \u751F\u6210\u7C7B\u578B\u5B9A\u4E49\r\n */\r\n async genDTS(): Promise<void> {\r\n const base = this.options.base\r\n const { pattern, options } = ESBuildProgram.getWatchOptions(\r\n this.options.base,\r\n )\r\n const project = new Project({\r\n tsConfigFilePath: path.resolve(base, 'tsconfig.json'),\r\n skipAddingFilesFromTsConfig: true,\r\n compilerOptions: {\r\n emitDeclarationOnly: true,\r\n noEmit: false,\r\n incremental: this.options.isWatch,\r\n },\r\n })\r\n const fileList = (await promise(pattern, options)).map((filePath) =>\r\n path.resolve(base, filePath),\r\n )\r\n project.addSourceFilesAtPaths(fileList)\r\n await project.emit({\r\n emitOnlyDtsFiles: true,\r\n })\r\n }\r\n\r\n /**\r\n * \u83B7\u53D6\u6784\u5EFA cjs \u7684\u9009\u9879\r\n * @param deps\r\n * @param platform\r\n * @param plugins\r\n */\r\n getBuildCjsOption({\r\n deps,\r\n platform,\r\n }: {\r\n deps: string[]\r\n platform: Platform\r\n }): BuildOptions {\r\n return {\r\n outfile: './dist/index.js',\r\n format: 'cjs',\r\n sourcemap: true,\r\n entryPoints: ['./src/index.ts'],\r\n bundle: true,\r\n external: [...ESBuildProgram.globalExternal, ...deps],\r\n platform: platform,\r\n minify: !this.options.isWatch,\r\n incremental: this.options.isWatch,\r\n }\r\n }\r\n\r\n /**\r\n * \u83B7\u53D6\u6784\u5EFA esm \u7684\u9009\u9879\r\n * @param deps\r\n * @param platform\r\n * @param plugins\r\n */\r\n getBuildESMOption({\r\n deps,\r\n platform,\r\n }: {\r\n deps: string[]\r\n platform: Platform\r\n }): BuildOptions {\r\n return {\r\n outfile: './dist/index.esm.js',\r\n format: 'esm',\r\n sourcemap: true,\r\n entryPoints: ['./src/index.ts'],\r\n bundle: true,\r\n external: [...ESBuildProgram.globalExternal, ...deps],\r\n platform: platform,\r\n minify: !this.options.isWatch,\r\n incremental: this.options.isWatch,\r\n }\r\n }\r\n\r\n /**\r\n * \u83B7\u53D6\u6784\u5EFA cli \u7684\u9009\u9879\r\n * @param deps\r\n * @param platform\r\n * @param plugins\r\n */\r\n getBuildCliOption({\r\n deps,\r\n platform,\r\n }: {\r\n deps: string[]\r\n platform: Platform\r\n }): BuildOptions {\r\n const plugins = ESBuildProgram.getPlugins(platform)\r\n return {\r\n entryPoints: ['./src/bin.ts'],\r\n outfile: './dist/bin.js',\r\n format: 'cjs',\r\n sourcemap: true,\r\n platform: platform,\r\n bundle: true,\r\n banner: {\r\n js: '#!/usr/bin/env node',\r\n },\r\n external: [\r\n ...ESBuildProgram.globalExternal,\r\n ...(this.options.isWatch ? deps : []),\r\n ],\r\n plugins,\r\n minify: !this.options.isWatch,\r\n incremental: this.options.isWatch,\r\n }\r\n }\r\n\r\n static getPlugins(platform: string): Plugin[] {\r\n const plugins: Plugin[] = []\r\n if (platform === 'node') {\r\n plugins.push(nodeExternals(), nativeNodeModules())\r\n }\r\n return plugins\r\n }\r\n\r\n async buildLib(): Promise<void> {\r\n await this.build(this.getBuildLibTask.bind(this))\r\n }\r\n\r\n async buildCli(): Promise<void> {\r\n await this.build(this.getBuildCliTask.bind(this))\r\n }\r\n\r\n getBuildLibTask(deps: string[], platform: Platform): Task[] {\r\n return [\r\n {\r\n title: '\u6784\u5EFA esm',\r\n task: () =>\r\n build(\r\n this.getBuildESMOption({\r\n deps: deps,\r\n platform: platform,\r\n }),\r\n ),\r\n },\r\n {\r\n title: '\u6784\u5EFA cjs',\r\n task: () =>\r\n build(\r\n this.getBuildCjsOption({\r\n deps: deps,\r\n platform: platform,\r\n }),\r\n ),\r\n },\r\n {\r\n title: '\u751F\u6210\u7C7B\u578B\u5B9A\u4E49',\r\n task: () => this.genDTS(),\r\n },\r\n ]\r\n }\r\n getBuildCliTask(deps: string[], platform: Platform): Task[] {\r\n return [\r\n {\r\n title: '\u6784\u5EFA cli',\r\n task: () =>\r\n build(\r\n this.getBuildCliOption({\r\n deps: deps,\r\n platform: platform,\r\n }),\r\n ),\r\n },\r\n ...this.getBuildLibTask(deps, platform),\r\n ]\r\n }\r\n\r\n static async execTask(spinnies: Spinnies, task: Task): Promise<void> {\r\n const start = Date.now()\r\n spinnies.add(task.title, { text: task.title })\r\n try {\r\n await task.task()\r\n spinnies.succeed(task.title, {\r\n text: `${task.title}: ${Date.now() - start}ms`,\r\n })\r\n } catch (e) {\r\n spinnies.fail(task.title, { text: task.title })\r\n }\r\n }\r\n async build(\r\n genTasks: (deps: string[], platform: Platform) => Task[],\r\n ): Promise<void> {\r\n const run = async () => {\r\n const start = Date.now()\r\n const deps = await ESBuildProgram.getDeps(this.options.base)\r\n const platform = await ESBuildProgram.getPlatform(this.options.base)\r\n const tasks = genTasks(deps, platform)\r\n const spinnies = new Spinnies()\r\n await Promise.all(\r\n tasks.map(async (task) => ESBuildProgram.execTask(spinnies, task)),\r\n )\r\n console.log(`\u6784\u5EFA\u5B8C\u6210: ${Date.now() - start}ms`)\r\n }\r\n\r\n if (!this.options.isWatch) {\r\n await run()\r\n return\r\n }\r\n\r\n const { pattern, options } = ESBuildProgram.getWatchOptions(\r\n this.options.base,\r\n )\r\n await new Promise((resolve, reject) => {\r\n watch(pattern, options).on('error', reject).on('all', debounce(run, 10))\r\n })\r\n }\r\n}\r\n", "import { Plugin } from 'esbuild'\r\n\r\n/**\r\n * \u5904\u7406 nodejs \u539F\u751F\u6A21\u5757\r\n * @link https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487\r\n */\r\nexport function nativeNodeModules(): Plugin {\r\n return {\r\n name: 'native-node-modules',\r\n setup(build) {\r\n // If a \".node\" file is imported within a module in the \"file\" namespace, resolve\r\n // it to an absolute path and put it into the \"node-file\" virtual namespace.\r\n build.onResolve({ filter: /\\.node$/, namespace: 'file' }, (args) => ({\r\n path: require.resolve(args.path, { paths: [args.resolveDir] }),\r\n namespace: 'node-file',\r\n }))\r\n\r\n // Files in the \"node-file\" virtual namespace call \"require()\" on the\r\n // path from esbuild of the \".node\" file in the output directory.\r\n build.onLoad({ filter: /.*/, namespace: 'node-file' }, (args) => ({\r\n contents: `\r\n import path from ${JSON.stringify(args.path)}\r\n try { module.exports = require(path) }\r\n catch {}\r\n `,\r\n }))\r\n\r\n // If a \".node\" file is imported within a module in the \"node-file\" namespace, put\r\n // it in the \"file\" namespace where esbuild's default loading behavior will handle\r\n // it. It is already an absolute path since we resolved it to one above.\r\n build.onResolve(\r\n { filter: /\\.node$/, namespace: 'node-file' },\r\n (args) => ({\r\n path: args.path,\r\n namespace: 'file',\r\n }),\r\n )\r\n\r\n // Tell esbuild's default loading behavior to use the \"file\" loader for\r\n // these \".node\" files.\r\n const opts = build.initialOptions\r\n opts.loader = opts.loader || {}\r\n opts.loader['.node'] = 'file'\r\n },\r\n }\r\n}\r\n\r\n/**\r\n * \u6392\u9664\u548C\u66FF\u6362 node \u5185\u7F6E\u6A21\u5757\r\n */\r\nexport function nodeExternals(): Plugin {\r\n return {\r\n name: 'esbuild-plugin-node-externals',\r\n setup(build) {\r\n build.onResolve({ filter: /(^node:)/ }, (args) => ({\r\n path: args.path.slice(5),\r\n external: true,\r\n }))\r\n },\r\n }\r\n}\r\n\r\n/**\r\n * \u81EA\u52A8\u6392\u9664\u6240\u6709\u4F9D\u8D56\u9879\r\n * golang \u4E0D\u652F\u6301 js \u7684\u4E00\u4E9B\u8BED\u6CD5\uFF0C\u53C2\u8003 https://github.com/evanw/esbuild/issues/1634\r\n */\r\nexport function autoExternal(): Plugin {\r\n return {\r\n name: 'esbuild-plugin-auto-external',\r\n setup(build) {\r\n build.onResolve({ filter: /.*/ }, (args) => {\r\n if (/^\\.{1,2}\\//.test(args.path)) {\r\n return\r\n }\r\n return {\r\n path: args.path,\r\n external: true,\r\n }\r\n })\r\n },\r\n }\r\n}\r\n", "/**\r\n * \u51FD\u6570\u53BB\u6296\r\n * \u53BB\u6296 (debounce) \u53BB\u6296\u5C31\u662F\u5BF9\u4E8E\u4E00\u5B9A\u65F6\u95F4\u6BB5\u7684\u8FDE\u7EED\u7684\u51FD\u6570\u8C03\u7528\uFF0C\u53EA\u8BA9\u5176\u6267\u884C\u4E00\u6B21\r\n * \u6CE8: \u5305\u88C5\u540E\u7684\u51FD\u6570\u5982\u679C\u4E24\u6B21\u64CD\u4F5C\u95F4\u9694\u5C0F\u4E8E delay \u5219\u4E0D\u4F1A\u88AB\u6267\u884C, \u5982\u679C\u4E00\u76F4\u5728\u64CD\u4F5C\u5C31\u4F1A\u4E00\u76F4\u4E0D\u6267\u884C, \u76F4\u5230\u64CD\u4F5C\u505C\u6B62\u7684\u65F6\u95F4\u5927\u4E8E delay \u6700\u5C0F\u95F4\u9694\u65F6\u95F4\u624D\u4F1A\u6267\u884C\u4E00\u6B21, \u4E0D\u7BA1\u4EFB\u4F55\u65F6\u95F4\u8C03\u7528\u90FD\u9700\u8981\u505C\u6B62\u64CD\u4F5C\u7B49\u5F85\u6700\u5C0F\u5EF6\u8FDF\u65F6\u95F4\r\n * \u5E94\u7528\u573A\u666F\u4E3B\u8981\u5728\u90A3\u4E9B\u8FDE\u7EED\u7684\u64CD\u4F5C, \u4F8B\u5982\u9875\u9762\u6EDA\u52A8\u76D1\u542C, \u5305\u88C5\u540E\u7684\u51FD\u6570\u53EA\u4F1A\u6267\u884C\u6700\u540E\u4E00\u6B21\r\n * \u6CE8: \u8BE5\u51FD\u6570\u7B2C\u4E00\u6B21\u8C03\u7528\u4E00\u5B9A\u4E0D\u4F1A\u6267\u884C\uFF0C\u7B2C\u4E00\u6B21\u4E00\u5B9A\u62FF\u4E0D\u5230\u7F13\u5B58\u503C\uFF0C\u540E\u9762\u7684\u8FDE\u7EED\u8C03\u7528\u90FD\u4F1A\u62FF\u5230\u4E0A\u4E00\u6B21\u7684\u7F13\u5B58\u503C\u3002\u5982\u679C\u9700\u8981\u5728\u7B2C\u4E00\u6B21\u8C03\u7528\u83B7\u53D6\u5230\u7684\u7F13\u5B58\u503C\uFF0C\u5219\u9700\u8981\u4F20\u5165\u7B2C\u4E09\u4E2A\u53C2\u6570 {@param init}\uFF0C\u9ED8\u8BA4\u4E3A {@code undefined} \u7684\u53EF\u9009\u53C2\u6570\r\n * \u6CE8: \u8FD4\u56DE\u51FD\u6570\u7ED3\u679C\u7684\u9AD8\u9636\u51FD\u6570\u9700\u8981\u4F7F\u7528 {@see Proxy} \u5B9E\u73B0\uFF0C\u4EE5\u907F\u514D\u539F\u51FD\u6570\u539F\u578B\u94FE\u4E0A\u7684\u4FE1\u606F\u4E22\u5931\r\n *\r\n * @param fn \u771F\u6B63\u9700\u8981\u6267\u884C\u7684\u64CD\u4F5C\r\n * @param delay \u6700\u5C0F\u5EF6\u8FDF\u65F6\u95F4\uFF0C\u5355\u4F4D\u4E3A ms\r\n * @param init \u521D\u59CB\u7684\u7F13\u5B58\u503C\uFF0C\u4E0D\u586B\u9ED8\u8BA4\u4E3A {@see undefined}\r\n * @return \u5305\u88C5\u540E\u6709\u53BB\u6296\u529F\u80FD\u7684\u51FD\u6570\u3002\u8BE5\u51FD\u6570\u662F\u5F02\u6B65\u7684\uFF0C\u4E0E\u9700\u8981\u5305\u88C5\u7684\u51FD\u6570 {@param fn} \u662F\u5426\u5F02\u6B65\u6CA1\u6709\u592A\u5927\u5173\u8054\r\n */\r\nexport function debounce<\r\n T extends (...args: any[]) => any,\r\n R extends (...args: Parameters<T>) => Promise<ReturnType<T>>,\r\n>(fn: T, delay: number, init: any = null): R {\r\n let flag: number\r\n let result = init\r\n return async function (...args) {\r\n return new Promise((resolve) => {\r\n if (flag) {\r\n clearTimeout(flag as any)\r\n }\r\n flag = setTimeout(() => resolve((result = fn(...args))), delay) as any\r\n setTimeout(() => resolve(result), delay)\r\n })\r\n } as R\r\n}\r\n", "import path from 'path'\r\nimport {\r\n copy,\r\n pathExists,\r\n readdir,\r\n readFile,\r\n readJSON,\r\n remove,\r\n writeFile,\r\n writeJSON,\r\n} from 'fs-extra'\r\nimport { prompt } from 'enquirer'\r\nimport { SyncProgram } from '../sync/SyncProgram'\r\nimport { PathUtil } from '../../PathUtil'\r\n\r\nexport enum TemplateTypeEnum {\r\n Cli = 'cli',\r\n Lib = 'lib',\r\n}\r\n\r\nexport interface GenerateConfig {\r\n template: TemplateTypeEnum\r\n dest: string\r\n initSync?: boolean\r\n}\r\n\r\nexport class GenerateProgram {\r\n /**\r\n * \u751F\u6210\u9879\u76EE\r\n */\r\n async generate(config: GenerateConfig): Promise<void> {\r\n if (!config.dest) {\r\n const { dest } = await prompt<{ dest: string }>({\r\n name: 'dest',\r\n type: 'input',\r\n message: '\u8BF7\u8F93\u5165\u9879\u76EE\u540D',\r\n validate(input: string): boolean {\r\n return input.trim() !== ''\r\n },\r\n })\r\n config.dest = path.resolve(dest)\r\n }\r\n if (!config.template) {\r\n const { template } = await prompt<{ template: TemplateTypeEnum }>({\r\n name: 'template',\r\n type: 'list',\r\n message: '\u8BF7\u9009\u62E9\u6A21\u677F',\r\n choices: [\r\n TemplateTypeEnum.Lib,\r\n TemplateTypeEnum.Cli,\r\n ] as TemplateTypeEnum[],\r\n })\r\n config.template = template\r\n }\r\n\r\n /*\r\n \u514B\u9686\u9879\u76EE\r\n \u4FEE\u6539\u4E00\u4E9B\u5185\u5BB9\r\n \u5171\u901A\u4FEE\u6539\r\n - \u4FEE\u6539 package.json\uFF0C\u5220\u9664 private\uFF0C\u4FEE\u6539\u540D\u5B57\r\n \u6A21\u677F\u7279\u5B9A\u4FEE\u6539\r\n */\r\n const srcFile = path.resolve(\r\n PathUtil.RootPath,\r\n `templates/${config.template}`,\r\n )\r\n const destFile = path.resolve(config.dest)\r\n if (\r\n (await pathExists(destFile)) &&\r\n (await readdir(destFile)).some((file) => pathExists(file))\r\n ) {\r\n const { override } = await prompt<{\r\n override: boolean\r\n }>({\r\n name: 'override',\r\n type: 'confirm',\r\n initial: true,\r\n message: '\u76EE\u6807\u4F4D\u7F6E\u4E0D\u662F\u4E00\u4E2A\u7A7A\u76EE\u5F55\uFF0C\u786E\u8BA4\u8981\u8986\u76D6\u4E48\uFF1F',\r\n })\r\n if (!override) {\r\n return\r\n }\r\n }\r\n await remove(destFile)\r\n await copy(srcFile, destFile)\r\n await GenerateProgram.updatePackageJSON(destFile)\r\n await GenerateProgram.updateReadme(destFile)\r\n if (config.initSync) {\r\n const syncProgram = new SyncProgram(path.resolve(config.dest))\r\n await syncProgram.init()\r\n await syncProgram.sync()\r\n }\r\n }\r\n\r\n static async updatePackageJSON(destFile: string): Promise<void> {\r\n const pkgPath = path.resolve(destFile, 'package.json')\r\n await writeJSON(\r\n pkgPath,\r\n {\r\n ...(await readJSON(pkgPath)),\r\n name: path.basename(destFile),\r\n },\r\n {\r\n spaces: 2,\r\n },\r\n )\r\n }\r\n\r\n static async updateReadme(destFile: string): Promise<void> {\r\n const readmePath = path.resolve(destFile, 'README.md')\r\n let readmeFile = await readFile(readmePath, 'utf-8')\r\n readmeFile = readmeFile.replace('template', path.basename(destFile))\r\n await writeFile(readmePath, readmeFile)\r\n }\r\n}\r\n", "import { readFile, readJson, writeFile, writeJson } from 'fs-extra'\r\nimport path from 'path'\r\nimport { merge } from 'lodash-es'\r\nimport { PackageJson } from 'type-fest'\r\nimport prettier from '@liuli-util/prettier-standard-config/package.json'\r\nimport eslintTs from '@liuli-util/eslint-config-ts/package.json'\r\nimport eslintReactTs from '@liuli-util/eslint-config-react-ts/package.json'\r\nimport commitlint from '@liuli-util/commitlint-standard-config/package.json'\r\nimport { prompt } from 'enquirer'\r\nimport { isIncludeDep, isNpmPackage, isYarnRoot, isYarnSubModule } from './when'\r\nimport { appendScript, arrayToMap, AsyncArray } from '../../utils'\r\nimport { PathUtil } from '../../PathUtil'\r\n\r\nexport async function mergeJson(base: string, json: object): Promise<void> {\r\n const pkgJsonFilePath = path.resolve(base, './package.json')\r\n await writeJson(\r\n pkgJsonFilePath,\r\n merge(await readJson(pkgJsonFilePath), json),\r\n {\r\n spaces: 2,\r\n },\r\n )\r\n}\r\n\r\nexport type SyncConfigType =\r\n | 'prettier'\r\n | 'commitlint'\r\n | 'simplehooks'\r\n | 'workspaces'\r\n | 'gitignore'\r\n | 'eslint-ts'\r\n | 'eslint-vue-ts'\r\n | 'eslint-react-ts'\r\n | 'jest'\r\n\r\nexport interface SyncConfig {\r\n type: SyncConfigType\r\n handler(): Promise<void>\r\n when?(): Promise<boolean>\r\n}\r\n\r\nexport class SyncProgram {\r\n constructor(private readonly base: string) {}\r\n private syncConfigs: SyncConfig[] = [\r\n {\r\n type: 'workspaces',\r\n handler: async () => {\r\n const pkgPath = path.resolve(this.base, './package.json')\r\n const lernaPath = path.resolve(this.base, 'lerna.json')\r\n const pkgJson = (await readJson(pkgPath)) as { workspaces: string[] }\r\n const lernaJson = await readJson(lernaPath)\r\n lernaJson.packages = pkgJson.workspaces\r\n await writeJson(lernaPath, lernaJson, {\r\n spaces: 2,\r\n })\r\n },\r\n when: isYarnRoot,\r\n },\r\n {\r\n type: 'prettier',\r\n handler: async () => {\r\n await mergeJson(this.base, {\r\n prettier: '@liuli-util/prettier-standard-config',\r\n devDependencies: {\r\n prettier: '^2.3.2',\r\n '@liuli-util/prettier-standard-config': `^${prettier.version}`,\r\n },\r\n } as PackageJson)\r\n },\r\n async when(): Promise<boolean> {\r\n return (\r\n (await isNpmPackage()) &&\r\n ((await isYarnRoot()) || !(await isYarnSubModule()))\r\n )\r\n },\r\n },\r\n {\r\n type: 'commitlint',\r\n handler: async () => {\r\n await mergeJson(this.base, {\r\n 'simple-git-hooks': {\r\n 'commit-msg': 'yarn commitlint --edit $1',\r\n },\r\n commitlint: {\r\n extends: ['@liuli-util/commitlint-standard-config'],\r\n },\r\n devDependencies: {\r\n '@commitlint/cli': '^12.1.4',\r\n '@liuli-util/commitlint-standard-config': `^${commitlint.version}`,\r\n },\r\n } as PackageJson)\r\n },\r\n async when(): Promise<boolean> {\r\n return (\r\n (await isNpmPackage()) &&\r\n ((await isYarnRoot()) || !(await isYarnSubModule()))\r\n )\r\n },\r\n },\r\n {\r\n type: 'gitignore',\r\n handler: async () => {\r\n const gitignorePath = path.resolve(this.base, '.gitignore')\r\n await writeFile(\r\n gitignorePath,\r\n await readFile(\r\n path.resolve(PathUtil.RootPath, '_gitignore'),\r\n 'utf-8',\r\n ),\r\n )\r\n },\r\n },\r\n {\r\n type: 'eslint-ts',\r\n handler: async () => {\r\n await mergeJson(this.base, {\r\n eslintConfig: {\r\n extends: ['@liuli-util/eslint-config-ts'],\r\n },\r\n devDependencies: {\r\n '@liuli-util/eslint-config-ts': `^${eslintTs.version}`,\r\n },\r\n } as PackageJson)\r\n },\r\n async when(): Promise<boolean> {\r\n return (\r\n (await isNpmPackage()) &&\r\n !(await isIncludeDep(['vue'])) &&\r\n !(await isIncludeDep(['react']))\r\n )\r\n },\r\n },\r\n {\r\n type: 'eslint-react-ts',\r\n handler: async () => {\r\n await mergeJson(this.base, {\r\n eslintConfig: {\r\n extends: ['@liuli-util/eslint-config-react-ts'],\r\n },\r\n devDependencies: {\r\n '@liuli-util/eslint-config-react-ts': `^${eslintReactTs.version}`,\r\n },\r\n } as PackageJson)\r\n },\r\n async when(): Promise<boolean> {\r\n return (await isNpmPackage()) && (await isIncludeDep(['react']))\r\n },\r\n },\r\n {\r\n type: 'jest',\r\n handler: async () => {\r\n await mergeJson(this.base, {\r\n jest: {\r\n preset: 'ts-jest',\r\n testMatch: ['<rootDir>/src/**/__tests__/*.test.ts'],\r\n },\r\n })\r\n },\r\n },\r\n //\u5FC5\u987B\u653E\u5230\u6700\u540E\u4E00\u4E2A\uFF0C\u540E\u7EED\u6839\u636E\u68C0\u6D4B\u7ED3\u679C\u6DFB\u52A0 hooks\r\n {\r\n type: 'simplehooks',\r\n handler: async () => {\r\n const json = await readJson(path.resolve(this.base, './package.json'))\r\n const lintStaged: string[] = []\r\n if (json.prettier) {\r\n lintStaged.push('prettier --write')\r\n }\r\n if (json.eslintConfig) {\r\n lintStaged.push('eslint --fix')\r\n }\r\n let config = {\r\n scripts: {\r\n postinstall: appendScript(\r\n json?.scripts?.postinstall,\r\n 'npx simple-git-hooks',\r\n ),\r\n },\r\n 'simple-git-hooks': {\r\n 'pre-commit': 'yarn lint-staged',\r\n },\r\n 'lint-staged': {\r\n '*.{ts,tsx,js,jsx,css,vue}': [...lintStaged, 'git add'],\r\n },\r\n devDependencies: {\r\n 'simple-git-hooks': '^2.5.1',\r\n 'lint-staged': '^11.1.1',\r\n },\r\n }\r\n if (json.commitlint) {\r\n config = merge(config, {\r\n 'simple-git-hooks': {\r\n 'commit-msg': 'yarn commitlint --edit $1',\r\n },\r\n })\r\n }\r\n await mergeJson(this.base, config as PackageJson)\r\n },\r\n async when(): Promise<boolean> {\r\n return (\r\n (await isNpmPackage()) &&\r\n ((await isYarnRoot()) || !(await isYarnSubModule()))\r\n )\r\n },\r\n },\r\n ]\r\n\r\n async sync(): Promise<void> {\r\n const { sync } = (await readJson(\r\n path.resolve(this.base, 'package.json'),\r\n )) as {\r\n sync?: SyncConfigType[]\r\n }\r\n if (!sync) {\r\n return\r\n }\r\n const syncConfigs = this.syncConfigs.filter((config) =>\r\n sync.includes(config.type),\r\n )\r\n for (const syncConfig of syncConfigs) {\r\n await syncConfig.handler()\r\n }\r\n }\r\n\r\n async init(): Promise<void> {\r\n const configMap = arrayToMap(\r\n await AsyncArray.filter(this.syncConfigs, async (config) => {\r\n if (!config.when) {\r\n return true\r\n }\r\n return await config.when()\r\n }),\r\n (item) => item.type,\r\n )\r\n const res = await prompt<{\r\n sync: string[]\r\n }>({\r\n type: 'multiselect',\r\n message: '\u8BF7\u9009\u62E9\u9700\u8981\u540C\u6B65\u7684\u914D\u7F6E\u9879',\r\n name: 'sync',\r\n choices: [...configMap.keys()],\r\n })\r\n await mergeJson(this.base, {\r\n sync: res.sync,\r\n })\r\n }\r\n}\r\n", "import { pathExists, readJson } from 'fs-extra'\r\nimport path from 'path'\r\nimport { PackageJson } from 'type-fest'\r\nimport { findParent } from '../../utils'\r\n\r\n/**\r\n * \u5224\u65AD\u662F\u5426\u5305\u542B package.json\r\n * @param cwd\r\n */\r\nexport async function isNpmPackage(\r\n cwd: string = process.cwd(),\r\n): Promise<boolean> {\r\n return await pathExists(path.resolve(cwd, './package.json'))\r\n}\r\n\r\n/**\r\n * \u5224\u65AD\u662F yarn2 monorepo \u9879\u76EE\r\n * @param cwd\r\n */\r\nexport async function isYarnRoot(\r\n cwd: string = process.cwd(),\r\n): Promise<boolean> {\r\n if (!(await isNpmPackage(cwd))) {\r\n return false\r\n }\r\n const json = (await readJson(\r\n path.resolve(cwd, './package.json'),\r\n )) as PackageJson\r\n return !!json.workspaces\r\n}\r\n\r\n/**\r\n * \u5224\u65AD\u662F yarn2 monorepo \u7684\u5B50\u6A21\u5757\r\n */\r\nexport async function isYarnSubModule(\r\n cwd: string = process.cwd(),\r\n): Promise<boolean> {\r\n if (!(await isNpmPackage(cwd))) {\r\n return false\r\n }\r\n //\u5982\u679C\u662F yarn monorepo \u6839\u6A21\u5757\u5219\u76F4\u63A5\u8FD4\u56DE true\r\n if (await isYarnRoot(cwd)) {\r\n return false\r\n }\r\n return (await findParent(path.dirname(cwd), isYarnRoot)) !== null\r\n}\r\n\r\n/**\r\n * \u662F\u5426\u5305\u542B\u6307\u5B9A\u4F9D\u8D56\r\n * @param deps\r\n * @param cwd\r\n */\r\nexport async function isIncludeDep(\r\n deps: string[],\r\n cwd: string = process.cwd(),\r\n): Promise<boolean> {\r\n if (!(await isNpmPackage(cwd))) {\r\n return false\r\n }\r\n const json = (await readJson(\r\n path.resolve(cwd, './package.json'),\r\n )) as PackageJson\r\n const set = new Set(\r\n Object.keys({ ...json.dependencies, ...json.devDependencies }),\r\n )\r\n return deps.every((dep) => set.has(dep))\r\n}\r\n", "export function arrayToMap<T, K>(\r\n arr: T[],\r\n kFn: (item: T, index: number, arr: T[]) => K,\r\n): Map<K, T>\r\nexport function arrayToMap<T, K, V>(\r\n arr: T[],\r\n kFn: (item: T, index: number, arr: T[]) => K,\r\n vFn: (item: T, index: number, arr: T[]) => V,\r\n): Map<K, V>\r\n/**\r\n * \u5C06\u6570\u7EC4\u6620\u5C04\u4E3A Map\r\n * @param arr \u6570\u7EC4\r\n * @param kFn \u4EA7\u751F Map \u5143\u7D20\u552F\u4E00\u6807\u8BC6\u7684\u51FD\u6570\r\n * @param vFn \u4EA7\u751F Map \u503C\u7684\u51FD\u6570\uFF0C\u9ED8\u8BA4\u4E3A\u8FD4\u56DE\u6570\u7EC4\u7684\u5143\u7D20\r\n * @returns \u6620\u5C04\u4EA7\u751F\u7684 map \u96C6\u5408\r\n */\r\nexport function arrayToMap<T, K, V>(\r\n arr: T[],\r\n kFn: (item: T, index: number, arr: T[]) => K,\r\n vFn: (item: T, index: number, arr: T[]) => V = (v) => v as any,\r\n): Map<K, V> {\r\n return arr.reduce(\r\n (res, item, index, arr) =>\r\n res.set(kFn(item, index, arr), vFn(item, index, arr)),\r\n new Map<K, V>(),\r\n )\r\n}\r\n", "/**\r\n * \u5728\u4E4B\u524D\u7684\u811A\u672C\u4E2D\u8FFD\u52A0\u65B0\u7684\u811A\u672C\r\n * @param oldScript\r\n * @param newScript\r\n */\r\nexport function appendScript(\r\n oldScript: string | undefined,\r\n newScript: string,\r\n): string {\r\n if (!oldScript) {\r\n return newScript\r\n }\r\n if (oldScript.includes(newScript)) {\r\n return oldScript\r\n }\r\n return oldScript + ' && ' + newScript\r\n}\r\n", "import path from 'path'\r\n\r\n/**\r\n * \u5411\u4E0A\u67E5\u627E\u76EE\u5F55\r\n * @param cwd\r\n * @param predicate\r\n */\r\nexport function findParent(\r\n cwd: string,\r\n predicate: (dir: string) => boolean,\r\n): string | null\r\nexport function findParent(\r\n cwd: string,\r\n predicate: (dir: string) => Promise<boolean>,\r\n): Promise<string | null>\r\nexport function findParent<\r\n T extends (dir: string) => boolean | Promise<boolean>,\r\n R extends string | null,\r\n>(\r\n cwd: string,\r\n predicate: T,\r\n): ReturnType<T> extends Promise<any> ? Promise<R> : R {\r\n const res = predicate(cwd)\r\n function f(res: boolean): string | null {\r\n if (res) {\r\n return cwd\r\n }\r\n const parent = path.dirname(cwd)\r\n if (parent === cwd) {\r\n return null\r\n }\r\n return findParent(parent, predicate as any)\r\n }\r\n\r\n return res instanceof Promise ? res.then(f) : (f(res) as any)\r\n}\r\n", "import { IterableElement } from 'type-fest'\r\n\r\nenum ActionTypeEnum {\r\n Filter = 'filter',\r\n Map = 'map',\r\n ForEach = 'forEach',\r\n Reduce = 'reduce',\r\n FlatMap = 'flatMap',\r\n}\r\n\r\nclass Action {\r\n public static Type = ActionTypeEnum\r\n\r\n constructor(\r\n public readonly type: ActionTypeEnum,\r\n public readonly args: any[],\r\n ) {\r\n this.type = type\r\n this.args = args\r\n }\r\n}\r\n\r\n/**\r\n * \u5F02\u6B65\u6570\u7EC4\uFF0C\u652F\u6301\u9759\u6001\u65B9\u6CD5\u548C\u94FE\u5F0F\u8C03\u7528\r\n */\r\nexport class AsyncArray<T> implements PromiseLike<T[]> {\r\n static reduce<T extends any[], R>(\r\n arr: T,\r\n fn: (res: R, item: IterableElement<T>, index: number) => Promise<R>,\r\n res: R,\r\n ): Promise<R> {\r\n return arr.reduce(\r\n (res: Promise<R>, item: IterableElement<T>, index: number) =>\r\n res.then((r) => fn(r, item, index)),\r\n Promise.resolve(res),\r\n )\r\n }\r\n\r\n static map<T, R>(\r\n arr: T[],\r\n fn: (item: T, index: number) => Promise<R>,\r\n ): Promise<R[]> {\r\n return Promise.all(arr.map((item, index) => fn(item, index)))\r\n }\r\n\r\n static async filter<T>(\r\n arr: T[],\r\n fn: (item: T, index: number) => Promise<boolean>,\r\n ): Promise<T[]> {\r\n const res: T[] = []\r\n await AsyncArray.map(arr, async (item, index) => {\r\n if (await fn(item, index)) {\r\n res.push(item)\r\n }\r\n })\r\n return res\r\n }\r\n\r\n static async flatMap<T, R>(\r\n arr: T[],\r\n fn: (item: T, index: number) => Promise<R[]>,\r\n ): Promise<R[]> {\r\n return (\r\n await Promise.all(arr.map((item, index) => fn(item, index)))\r\n ).flatMap((r) => r)\r\n }\r\n\r\n static async forEach<T extends any[]>(\r\n arr: T,\r\n fn: (item: IterableElement<T>, index: number) => Promise<void>,\r\n ): Promise<void> {\r\n await AsyncArray.map(arr, fn)\r\n }\r\n\r\n private tasks: Action[] = []\r\n\r\n constructor(private readonly arr: T[]) {}\r\n\r\n map<R>(fn: (item: T, index: number) => Promise<R>): AsyncArray<R> {\r\n this.tasks.push(new Action(ActionTypeEnum.Map, [fn]))\r\n return this as any\r\n }\r\n\r\n flatMap<R>(fn: (item: T, index: number) => Promise<R[]>): AsyncArray<R> {\r\n this.tasks.push(new Action(ActionTypeEnum.FlatMap, [fn]))\r\n return this as any\r\n }\r\n\r\n filter(fn: (item: T, index: number) => Promise<boolean>): this {\r\n this.tasks.push(new Action(ActionTypeEnum.Filter, [fn]))\r\n return this\r\n }\r\n\r\n async forEach<R>(fn: (item: T, index: number) => Promise<R>): Promise<void> {\r\n this.tasks.push(new Action(ActionTypeEnum.Map, [fn]))\r\n await this\r\n }\r\n\r\n then<TResult1 = T[], TResult2 = never>(\r\n resolve?:\r\n | ((value: T[]) => PromiseLike<TResult1> | TResult1)\r\n | undefined\r\n | null,\r\n reject?:\r\n | ((reason: any) => PromiseLike<TResult2> | TResult2)\r\n | undefined\r\n | null,\r\n ): PromiseLike<TResult1 | TResult2> {\r\n const res = this.value()\r\n res\r\n .then((r) => {\r\n resolve && resolve(res as any)\r\n return r\r\n })\r\n .catch((e) => {\r\n reject && reject(e as any)\r\n throw e\r\n })\r\n return res as any\r\n }\r\n\r\n private async value(): Promise<any> {\r\n let res = this.arr\r\n for (const task of this.tasks) {\r\n switch (task.type) {\r\n case ActionTypeEnum.Filter:\r\n res = await AsyncArray.filter(res, task.args[0])\r\n break\r\n case ActionTypeEnum.Map:\r\n res = await AsyncArray.map(res, task.args[0])\r\n break\r\n case ActionTypeEnum.FlatMap:\r\n res = await AsyncArray.flatMap(res, task.args[0])\r\n break\r\n case ActionTypeEnum.ForEach:\r\n await AsyncArray.forEach(res, task.args[0])\r\n return\r\n case ActionTypeEnum.Reduce:\r\n return await AsyncArray.reduce(res, task.args[0], task.args[1])\r\n }\r\n }\r\n return res\r\n }\r\n}\r\n", "import path from 'path'\r\n\r\nexport class PathUtil {\r\n /**\r\n * \u4ECE\u8FD9\u4E2A\u9879\u76EE\u7684\u6839\u76EE\u5F55\u8BFB\u53D6\uFF0C\u5F00\u53D1\u73AF\u5883\u662F src/../\uFF0C\u8FD0\u884C\u65F6\u5219\u662F dist/../\r\n */\r\n static readonly RootPath = path.resolve(__dirname, '..')\r\n}\r\n"],
5
+ "mappings": "8uBAAA,kHCAA,MAAsD,sBACtD,EAAqC,uBACrC,EAAsB,mBAEtB,EAAwB,uBACxB,EAAwB,2BCCjB,YAAqC,CAC1C,MAAO,CACL,KAAM,sBACN,MAAM,EAAO,CAGX,EAAM,UAAU,CAAE,OAAQ,UAAW,UAAW,QAAU,AAAC,GAAU,EACnE,KAAM,QAAQ,QAAQ,EAAK,KAAM,CAAE,MAAO,CAAC,EAAK,cAChD,UAAW,eAKb,EAAM,OAAO,CAAE,OAAQ,KAAM,UAAW,aAAe,AAAC,GAAU,EAChE,SAAU;AAAA,2BACS,KAAK,UAAU,EAAK;AAAA;AAAA;AAAA,WASzC,EAAM,UACJ,CAAE,OAAQ,UAAW,UAAW,aAChC,AAAC,GAAU,EACT,KAAM,EAAK,KACX,UAAW,UAMf,GAAM,GAAO,EAAM,eACnB,EAAK,OAAS,EAAK,QAAU,GAC7B,EAAK,OAAO,SAAW,SAQtB,YAAiC,CACtC,MAAO,CACL,KAAM,gCACN,MAAM,EAAO,CACX,EAAM,UAAU,CAAE,OAAQ,YAAc,AAAC,GAAU,EACjD,KAAM,EAAK,KAAK,MAAM,GACtB,SAAU,QDhDlB,MAAsB,uBACtB,EAAqB,uBEId,WAGL,EAAO,EAAe,EAAY,KAAS,CAC3C,GAAI,GACA,EAAS,EACb,MAAO,mBAAmB,EAAM,CAC9B,MAAO,IAAI,SAAQ,AAAC,GAAY,CAC9B,AAAI,GACF,aAAa,GAEf,EAAO,WAAW,IAAM,EAAS,EAAS,EAAG,GAAG,IAAS,GACzD,WAAW,IAAM,EAAQ,GAAS,MFHjC,WAAqB,CAC1B,YAA6B,EAAgC,CAAhC,2BAOhB,SAAQ,EAAiC,CACpD,GAAM,GAAQ,KAAM,eAClB,AAAK,UAAQ,EAAM,iBAErB,MAAO,QAAO,KAAK,IACd,EAAK,gBACL,EAAK,mBACL,EAAK,+BAOC,aAAY,EAAiC,CACxD,GAAM,GAAe,AAAK,UAAQ,EAAM,iBACxC,GAAI,KAAM,iBAAW,IAGhB,AAFkB,MAAM,eAAS,IAEpB,gBAAgB,IAAiB,KAC7C,AAAC,GAAQ,EAAI,gBAAkB,OAGjC,MAAO,UAGX,GAAM,GAAU,AAAK,UAAQ,EAAM,gBACnC,GAAI,KAAM,iBAAW,GAAU,CAC7B,GAAM,GAAW,KAAM,eAAS,GAChC,GAAI,OAAO,KAAK,EAAQ,iBAAmB,IAAI,SAAS,eACtD,MAAO,OAGX,MAAO,gBAEF,iBAAgB,EAGrB,CAMA,MAAO,CAAE,QALO,cAKE,QAJgC,CAChD,IAAK,EACL,OAAQ,2BAON,SAAwB,CAC5B,GAAM,GAAO,KAAK,QAAQ,KACpB,CAAE,UAAS,WAAY,EAAe,gBAC1C,KAAK,QAAQ,MAET,EAAU,GAAI,WAAQ,CAC1B,iBAAkB,AAAK,UAAQ,EAAM,iBACrC,4BAA6B,GAC7B,gBAAiB,CACf,oBAAqB,GACrB,OAAQ,GACR,YAAa,KAAK,QAAQ,WAGxB,EAAY,MAAM,cAAQ,EAAS,IAAU,IAAI,AAAC,GACtD,AAAK,UAAQ,EAAM,IAErB,EAAQ,sBAAsB,GAC9B,KAAM,GAAQ,KAAK,CACjB,iBAAkB,KAUtB,kBAAkB,CAChB,OACA,YAIe,CACf,MAAO,CACL,QAAS,kBACT,OAAQ,MACR,UAAW,GACX,YAAa,CAAC,kBACd,OAAQ,GACR,SAAU,CAAC,GAAG,EAAe,eAAgB,GAAG,GAChD,SAAU,EACV,OAAQ,CAAC,KAAK,QAAQ,QACtB,YAAa,KAAK,QAAQ,SAU9B,kBAAkB,CAChB,OACA,YAIe,CACf,MAAO,CACL,QAAS,sBACT,OAAQ,MACR,UAAW,GACX,YAAa,CAAC,kBACd,OAAQ,GACR,SAAU,CAAC,GAAG,EAAe,eAAgB,GAAG,GAChD,SAAU,EACV,OAAQ,CAAC,KAAK,QAAQ,QACtB,YAAa,KAAK,QAAQ,SAU9B,kBAAkB,CAChB,OACA,YAIe,CACf,GAAM,GAAU,EAAe,WAAW,GAC1C,MAAO,CACL,YAAa,CAAC,gBACd,QAAS,gBACT,OAAQ,MACR,UAAW,GACX,SAAU,EACV,OAAQ,GACR,OAAQ,CACN,GAAI,uBAEN,SAAU,CACR,GAAG,EAAe,eAClB,GAAI,KAAK,QAAQ,QAAU,EAAO,IAEpC,UACA,OAAQ,CAAC,KAAK,QAAQ,QACtB,YAAa,KAAK,QAAQ,eAIvB,YAAW,EAA4B,CAC5C,GAAM,GAAoB,GAC1B,MAAI,KAAa,QACf,EAAQ,KAAK,IAAiB,KAEzB,OAGH,WAA0B,CAC9B,KAAM,MAAK,MAAM,KAAK,gBAAgB,KAAK,YAGvC,WAA0B,CAC9B,KAAM,MAAK,MAAM,KAAK,gBAAgB,KAAK,OAG7C,gBAAgB,EAAgB,EAA4B,CAC1D,MAAO,CACL,CACE,MAAO,mBACP,KAAM,IACJ,YACE,KAAK,kBAAkB,CACrB,KAAM,EACN,SAAU,MAIlB,CACE,MAAO,mBACP,KAAM,IACJ,YACE,KAAK,kBAAkB,CACrB,KAAM,EACN,SAAU,MAIlB,CACE,MAAO,uCACP,KAAM,IAAM,KAAK,WAIvB,gBAAgB,EAAgB,EAA4B,CAC1D,MAAO,CACL,CACE,MAAO,mBACP,KAAM,IACJ,YACE,KAAK,kBAAkB,CACrB,KAAM,EACN,SAAU,MAIlB,GAAG,KAAK,gBAAgB,EAAM,gBAIrB,UAAS,EAAoB,EAA2B,CACnE,GAAM,GAAQ,KAAK,MACnB,EAAS,IAAI,EAAK,MAAO,CAAE,KAAM,EAAK,QACtC,GAAI,CACF,KAAM,GAAK,OACX,EAAS,QAAQ,EAAK,MAAO,CAC3B,KAAM,GAAG,EAAK,UAAU,KAAK,MAAQ,cAEhC,EAAP,CACA,EAAS,KAAK,EAAK,MAAO,CAAE,KAAM,EAAK,cAGrC,OACJ,EACe,CACf,GAAM,GAAM,SAAY,CACtB,GAAM,GAAQ,KAAK,MACb,EAAO,KAAM,GAAe,QAAQ,KAAK,QAAQ,MACjD,EAAW,KAAM,GAAe,YAAY,KAAK,QAAQ,MACzD,GAAQ,EAAS,EAAM,GACvB,GAAW,GAAI,WACrB,KAAM,SAAQ,IACZ,GAAM,IAAI,KAAO,KAAS,EAAe,SAAS,GAAU,MAE9D,QAAQ,IAAI,6BAAS,KAAK,MAAQ,QAGpC,GAAI,CAAC,KAAK,QAAQ,QAAS,CACzB,KAAM,KACN,OAGF,GAAM,CAAE,UAAS,WAAY,EAAe,gBAC1C,KAAK,QAAQ,MAEf,KAAM,IAAI,SAAQ,CAAC,EAAS,IAAW,CACrC,YAAM,EAAS,GAAS,GAAG,QAAS,GAAQ,GAAG,MAAO,EAAS,EAAK,SAtQnE,IAGW,EAHX,EAGW,iBAAiB,CAAC,UAAW,SAAU,aGzBzD,MAAiB,mBACjB,EASO,uBACP,EAAuB,uBCXvB,MAAyD,uBACzD,EAAiB,mBACjB,EAAsB,wBAEtB,EAAqB,gEACrB,EAAqB,wDACrB,EAA0B,8DAC1B,EAAuB,kEACvB,EAAuB,uBCRvB,MAAqC,uBACrC,EAAiB,mBCeV,WACL,EACA,EACA,EAA+C,AAAC,GAAM,EAC3C,CACX,MAAO,GAAI,OACT,CAAC,EAAK,EAAM,EAAO,IACjB,EAAI,IAAI,EAAI,EAAM,EAAO,GAAM,EAAI,EAAM,EAAO,IAClD,GAAI,MCnBD,WACL,EACA,EACQ,CACR,MAAK,GAGD,EAAU,SAAS,GACd,EAEF,EAAY,OAAS,EALnB,ECVX,MAAiB,mBAeV,WAIL,EACA,EACqD,CACrD,GAAM,GAAM,EAAU,GACtB,WAAW,EAA6B,CACtC,GAAI,EACF,MAAO,GAET,GAAM,GAAS,UAAK,QAAQ,GAC5B,MAAI,KAAW,EACN,KAEF,EAAW,EAAQ,GAG5B,MAAO,aAAe,SAAU,EAAI,KAAK,GAAM,EAAE,GChCnD,GAAK,GAAL,UAAK,EAAL,CACE,SAAS,SACT,MAAM,MACN,UAAU,UACV,SAAS,SACT,UAAU,YALP,WAQL,WAAa,CAGX,YACkB,EACA,EAChB,CAFgB,YACA,YAEhB,KAAK,KAAO,EACZ,KAAK,KAAO,IAPA,EADhB,EACgB,OAAO,GAchB,WAAgD,CAmDrD,YAA6B,EAAU,CAAV,iBAlDtB,QACL,EACA,EACA,EACY,CACZ,MAAO,GAAI,OACT,CAAC,EAAiB,EAA0B,IAC1C,EAAI,KAAK,AAAC,GAAM,EAAG,EAAG,EAAM,IAC9B,QAAQ,QAAQ,UAIb,KACL,EACA,EACc,CACd,MAAO,SAAQ,IAAI,EAAI,IAAI,CAAC,EAAM,IAAU,EAAG,EAAM,iBAG1C,QACX,EACA,EACc,CACd,GAAM,GAAW,GACjB,YAAM,GAAW,IAAI,EAAK,MAAO,EAAM,IAAU,CAC/C,AAAI,KAAM,GAAG,EAAM,IACjB,EAAI,KAAK,KAGN,cAGI,SACX,EACA,EACc,CACd,MACE,MAAM,SAAQ,IAAI,EAAI,IAAI,CAAC,EAAM,IAAU,EAAG,EAAM,MACpD,QAAQ,AAAC,GAAM,eAGN,SACX,EACA,EACe,CACf,KAAM,GAAW,IAAI,EAAK,GAGpB,MAAkB,GAI1B,IAAO,EAA2D,CAChE,YAAK,MAAM,KAAK,GAAI,GAAO,EAAe,IAAK,CAAC,KACzC,KAGT,QAAW,EAA6D,CACtE,YAAK,MAAM,KAAK,GAAI,GAAO,EAAe,QAAS,CAAC,KAC7C,KAGT,OAAO,EAAwD,CAC7D,YAAK,MAAM,KAAK,GAAI,GAAO,EAAe,OAAQ,CAAC,KAC5C,UAGH,SAAW,EAA2D,CAC1E,KAAK,MAAM,KAAK,GAAI,GAAO,EAAe,IAAK,CAAC,KAChD,KAAM,MAGR,KACE,EAIA,EAIkC,CAClC,GAAM,GAAM,KAAK,QACjB,SACG,KAAK,AAAC,GACL,IAAW,EAAQ,GACZ,IAER,MAAM,AAAC,GAAM,CACZ,SAAU,EAAO,GACX,IAEH,OAGK,QAAsB,CAClC,GAAI,GAAM,KAAK,IACf,OAAW,KAAQ,MAAK,MACtB,OAAQ,EAAK,UACN,GAAe,OAClB,EAAM,KAAM,GAAW,OAAO,EAAK,EAAK,KAAK,IAC7C,UACG,GAAe,IAClB,EAAM,KAAM,GAAW,IAAI,EAAK,EAAK,KAAK,IAC1C,UACG,GAAe,QAClB,EAAM,KAAM,GAAW,QAAQ,EAAK,EAAK,KAAK,IAC9C,UACG,GAAe,QAClB,KAAM,GAAW,QAAQ,EAAK,EAAK,KAAK,IACxC,WACG,GAAe,OAClB,MAAO,MAAM,GAAW,OAAO,EAAK,EAAK,KAAK,GAAI,EAAK,KAAK,IAGlE,MAAO,KJpIX,iBACE,EAAc,QAAQ,MACJ,CAClB,MAAO,MAAM,iBAAW,UAAK,QAAQ,EAAK,mBAO5C,iBACE,EAAc,QAAQ,MACJ,CAClB,MAAM,MAAM,GAAa,GAMlB,CAAC,CAAC,AAHK,MAAM,eAClB,UAAK,QAAQ,EAAK,oBAEN,WALL,GAWX,iBACE,EAAc,QAAQ,MACJ,CAKlB,MAJI,CAAE,KAAM,GAAa,IAIrB,KAAM,GAAW,GACZ,GAED,KAAM,GAAW,UAAK,QAAQ,GAAM,KAAiB,KAQ/D,iBACE,EACA,EAAc,QAAQ,MACJ,CAClB,GAAI,CAAE,KAAM,GAAa,GACvB,MAAO,GAET,GAAM,GAAQ,KAAM,eAClB,UAAK,QAAQ,EAAK,mBAEd,EAAM,GAAI,KACd,OAAO,KAAK,IAAK,EAAK,gBAAiB,EAAK,mBAE9C,MAAO,GAAK,MAAM,AAAC,GAAQ,EAAI,IAAI,IKjErC,MAAiB,mBAEV,OAAe,GAIJ,EAJX,EAIW,WAAW,UAAK,QAAQ,UAAW,ONOrD,iBAAgC,EAAc,EAA6B,CACzE,GAAM,GAAkB,UAAK,QAAQ,EAAM,kBAC3C,KAAM,gBACJ,EACA,YAAM,KAAM,eAAS,GAAkB,GACvC,CACE,OAAQ,IAsBP,WAAkB,CACvB,YAA6B,EAAc,CAAd,YACrB,YAA4B,CAClC,CACE,KAAM,aACN,QAAS,SAAY,CACnB,GAAM,GAAU,UAAK,QAAQ,KAAK,KAAM,kBAClC,EAAY,UAAK,QAAQ,KAAK,KAAM,cACpC,EAAW,KAAM,eAAS,GAC1B,EAAY,KAAM,eAAS,GACjC,EAAU,SAAW,EAAQ,WAC7B,KAAM,gBAAU,EAAW,EAAW,CACpC,OAAQ,KAGZ,KAAM,GAER,CACE,KAAM,WACN,QAAS,SAAY,CACnB,KAAM,GAAU,KAAK,KAAM,CACzB,SAAU,uCACV,gBAAiB,CACf,SAAU,SACV,uCAAwC,IAAI,UAAS,mBAIrD,OAAyB,CAC7B,MACG,MAAM,MACL,MAAM,MAAiB,CAAE,KAAM,QAIvC,CACE,KAAM,aACN,QAAS,SAAY,CACnB,KAAM,GAAU,KAAK,KAAM,CACzB,mBAAoB,CAClB,aAAc,6BAEhB,WAAY,CACV,QAAS,CAAC,2CAEZ,gBAAiB,CACf,kBAAmB,UACnB,yCAA0C,IAAI,UAAW,mBAIzD,OAAyB,CAC7B,MACG,MAAM,MACL,MAAM,MAAiB,CAAE,KAAM,QAIvC,CACE,KAAM,YACN,QAAS,SAAY,CACnB,GAAM,GAAgB,UAAK,QAAQ,KAAK,KAAM,cAC9C,KAAM,gBACJ,EACA,KAAM,eACJ,UAAK,QAAQ,EAAS,SAAU,cAChC,YAKR,CACE,KAAM,YACN,QAAS,SAAY,CACnB,KAAM,GAAU,KAAK,KAAM,CACzB,aAAc,CACZ,QAAS,CAAC,iCAEZ,gBAAiB,CACf,+BAAgC,IAAI,UAAS,mBAI7C,OAAyB,CAC7B,MACG,MAAM,MACP,CAAE,KAAM,GAAa,CAAC,SACtB,CAAE,KAAM,GAAa,CAAC,YAI5B,CACE,KAAM,kBACN,QAAS,SAAY,CACnB,KAAM,GAAU,KAAK,KAAM,CACzB,aAAc,CACZ,QAAS,CAAC,uCAEZ,gBAAiB,CACf,qCAAsC,IAAI,UAAc,mBAIxD,OAAyB,CAC7B,MAAQ,MAAM,MAAoB,KAAM,GAAa,CAAC,YAG1D,CACE,KAAM,OACN,QAAS,SAAY,CACnB,KAAM,GAAU,KAAK,KAAM,CACzB,KAAM,CACJ,OAAQ,UACR,UAAW,CAAC,6CAMpB,CACE,KAAM,cACN,QAAS,SAAY,CACnB,GAAM,GAAO,KAAM,eAAS,UAAK,QAAQ,KAAK,KAAM,mBAC9C,EAAuB,GAC7B,AAAI,EAAK,UACP,EAAW,KAAK,oBAEd,EAAK,cACP,EAAW,KAAK,gBAElB,GAAI,GAAS,CACX,QAAS,CACP,YAAa,EACX,GAAM,SAAS,YACf,yBAGJ,mBAAoB,CAClB,aAAc,oBAEhB,cAAe,CACb,4BAA6B,CAAC,GAAG,EAAY,YAE/C,gBAAiB,CACf,mBAAoB,SACpB,cAAe,YAGnB,AAAI,EAAK,YACP,GAAS,YAAM,EAAQ,CACrB,mBAAoB,CAClB,aAAc,gCAIpB,KAAM,GAAU,KAAK,KAAM,SAEvB,OAAyB,CAC7B,MACG,MAAM,MACL,MAAM,MAAiB,CAAE,KAAM,cAMnC,OAAsB,CAC1B,GAAM,CAAE,QAAU,KAAM,eACtB,UAAK,QAAQ,KAAK,KAAM,iBAI1B,GAAI,CAAC,EACH,OAEF,GAAM,GAAc,KAAK,YAAY,OAAO,AAAC,GAC3C,EAAK,SAAS,EAAO,OAEvB,OAAW,KAAc,GACvB,KAAM,GAAW,eAIf,OAAsB,CAC1B,GAAM,GAAY,EAChB,KAAM,GAAW,OAAO,KAAK,YAAa,KAAO,IAC1C,EAAO,KAGL,KAAM,GAAO,OAFX,IAIX,AAAC,GAAS,EAAK,MAEX,EAAM,KAAM,aAEf,CACD,KAAM,cACN,QAAS,qEACT,KAAM,OACN,QAAS,CAAC,GAAG,EAAU,UAEzB,KAAM,GAAU,KAAK,KAAM,CACzB,KAAM,EAAI,SDpOT,GAAK,GAAL,UAAK,EAAL,CACL,MAAM,MACN,MAAM,QAFI,WAWL,WAAsB,MAIrB,UAAS,EAAuC,CACpD,GAAI,CAAC,EAAO,KAAM,CAChB,GAAM,CAAE,QAAS,KAAM,aAAyB,CAC9C,KAAM,OACN,KAAM,QACN,QAAS,uCACT,SAAS,EAAwB,CAC/B,MAAO,GAAM,SAAW,MAG5B,EAAO,KAAO,UAAK,QAAQ,GAE7B,GAAI,CAAC,EAAO,SAAU,CACpB,GAAM,CAAE,YAAa,KAAM,aAAuC,CAChE,KAAM,WACN,KAAM,OACN,QAAS,iCACT,QAAS,CACP,EAAiB,IACjB,EAAiB,OAGrB,EAAO,SAAW,EAUpB,GAAM,GAAU,UAAK,QACnB,EAAS,SACT,aAAa,EAAO,YAEhB,EAAW,UAAK,QAAQ,EAAO,MACrC,GACG,KAAM,iBAAW,IACjB,MAAM,cAAQ,IAAW,KAAK,AAAC,GAAS,iBAAW,IACpD,CACA,GAAM,CAAE,YAAa,KAAM,aAExB,CACD,KAAM,WACN,KAAM,UACN,QAAS,GACT,QAAS,uHAEX,GAAI,CAAC,EACH,OAOJ,GAJA,KAAM,aAAO,GACb,KAAM,WAAK,EAAS,GACpB,KAAM,GAAgB,kBAAkB,GACxC,KAAM,GAAgB,aAAa,GAC/B,EAAO,SAAU,CACnB,GAAM,GAAc,GAAI,GAAY,UAAK,QAAQ,EAAO,OACxD,KAAM,GAAY,OAClB,KAAM,GAAY,oBAIT,mBAAkB,EAAiC,CAC9D,GAAM,GAAU,UAAK,QAAQ,EAAU,gBACvC,KAAM,gBACJ,EACA,IACM,KAAM,eAAS,GACnB,KAAM,UAAK,SAAS,IAEtB,CACE,OAAQ,gBAKD,cAAa,EAAiC,CACzD,GAAM,GAAa,UAAK,QAAQ,EAAU,aACtC,EAAa,KAAM,eAAS,EAAY,SAC5C,EAAa,EAAW,QAAQ,WAAY,UAAK,SAAS,IAC1D,KAAM,gBAAU,EAAY",
6
6
  "names": []
7
7
  }
@@ -1,21 +1,21 @@
1
- import { IterableElement } from 'type-fest';
2
- /**
3
- * 异步数组,支持静态方法和链式调用
4
- */
5
- export declare class AsyncArray<T> implements PromiseLike<T[]> {
6
- private readonly arr;
7
- static reduce<T extends any[], R>(arr: T, fn: (res: R, item: IterableElement<T>, index: number) => Promise<R>, res: R): Promise<R>;
8
- static map<T, R>(arr: T[], fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
9
- static filter<T>(arr: T[], fn: (item: T, index: number) => Promise<boolean>): Promise<T[]>;
10
- static flatMap<T, R>(arr: T[], fn: (item: T, index: number) => Promise<R[]>): Promise<R[]>;
11
- static forEach<T extends any[]>(arr: T, fn: (item: IterableElement<T>, index: number) => Promise<void>): Promise<void>;
12
- private tasks;
13
- constructor(arr: T[]);
14
- map<R>(fn: (item: T, index: number) => Promise<R>): AsyncArray<R>;
15
- flatMap<R>(fn: (item: T, index: number) => Promise<R[]>): AsyncArray<R>;
16
- filter(fn: (item: T, index: number) => Promise<boolean>): this;
17
- forEach<R>(fn: (item: T, index: number) => Promise<R>): Promise<void>;
18
- then<TResult1 = T[], TResult2 = never>(resolve?: ((value: T[]) => PromiseLike<TResult1> | TResult1) | undefined | null, reject?: ((reason: any) => PromiseLike<TResult2> | TResult2) | undefined | null): PromiseLike<TResult1 | TResult2>;
19
- private value;
20
- }
1
+ import { IterableElement } from 'type-fest';
2
+ /**
3
+ * 异步数组,支持静态方法和链式调用
4
+ */
5
+ export declare class AsyncArray<T> implements PromiseLike<T[]> {
6
+ private readonly arr;
7
+ static reduce<T extends any[], R>(arr: T, fn: (res: R, item: IterableElement<T>, index: number) => Promise<R>, res: R): Promise<R>;
8
+ static map<T, R>(arr: T[], fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
9
+ static filter<T>(arr: T[], fn: (item: T, index: number) => Promise<boolean>): Promise<T[]>;
10
+ static flatMap<T, R>(arr: T[], fn: (item: T, index: number) => Promise<R[]>): Promise<R[]>;
11
+ static forEach<T extends any[]>(arr: T, fn: (item: IterableElement<T>, index: number) => Promise<void>): Promise<void>;
12
+ private tasks;
13
+ constructor(arr: T[]);
14
+ map<R>(fn: (item: T, index: number) => Promise<R>): AsyncArray<R>;
15
+ flatMap<R>(fn: (item: T, index: number) => Promise<R[]>): AsyncArray<R>;
16
+ filter(fn: (item: T, index: number) => Promise<boolean>): this;
17
+ forEach<R>(fn: (item: T, index: number) => Promise<R>): Promise<void>;
18
+ then<TResult1 = T[], TResult2 = never>(resolve?: ((value: T[]) => PromiseLike<TResult1> | TResult1) | undefined | null, reject?: ((reason: any) => PromiseLike<TResult2> | TResult2) | undefined | null): PromiseLike<TResult1 | TResult2>;
19
+ private value;
20
+ }
21
21
  //# sourceMappingURL=AsyncArray.d.ts.map
@@ -1,7 +1,7 @@
1
- /**
2
- * 在之前的脚本中追加新的脚本
3
- * @param oldScript
4
- * @param newScript
5
- */
6
- export declare function appendScript(oldScript: string | undefined, newScript: string): string;
1
+ /**
2
+ * 在之前的脚本中追加新的脚本
3
+ * @param oldScript
4
+ * @param newScript
5
+ */
6
+ export declare function appendScript(oldScript: string | undefined, newScript: string): string;
7
7
  //# sourceMappingURL=appendScript.d.ts.map
@@ -1,3 +1,3 @@
1
- export declare function arrayToMap<T, K>(arr: T[], kFn: (item: T, index: number, arr: T[]) => K): Map<K, T>;
2
- export declare function arrayToMap<T, K, V>(arr: T[], kFn: (item: T, index: number, arr: T[]) => K, vFn: (item: T, index: number, arr: T[]) => V): Map<K, V>;
1
+ export declare function arrayToMap<T, K>(arr: T[], kFn: (item: T, index: number, arr: T[]) => K): Map<K, T>;
2
+ export declare function arrayToMap<T, K, V>(arr: T[], kFn: (item: T, index: number, arr: T[]) => K, vFn: (item: T, index: number, arr: T[]) => V): Map<K, V>;
3
3
  //# sourceMappingURL=arrayToMap.d.ts.map
@@ -1,8 +1,8 @@
1
- /**
2
- * 向上查找目录
3
- * @param cwd
4
- * @param predicate
5
- */
6
- export declare function findParent(cwd: string, predicate: (dir: string) => boolean): string | null;
7
- export declare function findParent(cwd: string, predicate: (dir: string) => Promise<boolean>): Promise<string | null>;
1
+ /**
2
+ * 向上查找目录
3
+ * @param cwd
4
+ * @param predicate
5
+ */
6
+ export declare function findParent(cwd: string, predicate: (dir: string) => boolean): string | null;
7
+ export declare function findParent(cwd: string, predicate: (dir: string) => Promise<boolean>): Promise<string | null>;
8
8
  //# sourceMappingURL=findParent.d.ts.map
@@ -1,5 +1,5 @@
1
- export * from './arrayToMap';
2
- export * from './appendScript';
3
- export * from './findParent';
4
- export * from './AsyncArray';
1
+ export * from './arrayToMap';
2
+ export * from './appendScript';
3
+ export * from './findParent';
4
+ export * from './AsyncArray';
5
5
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liuli-util/cli",
3
- "version": "3.10.1",
3
+ "version": "3.11.0",
4
4
  "description": "一个针对于库和 CLI 应用程序打包的零配置 CLI",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -19,28 +19,40 @@
19
19
  "liuli-cli": "dist/bin.js"
20
20
  },
21
21
  "jest": {
22
- "preset": "ts-jest"
22
+ "preset": "ts-jest",
23
+ "moduleNameMapper": {
24
+ "lodash-es": "lodash"
25
+ }
23
26
  },
24
27
  "publishConfig": {
25
28
  "access": "public",
26
29
  "registry": "https://registry.npmjs.org/"
27
30
  },
28
31
  "dependencies": {
29
- "chalk": "^4.1.2",
32
+ "@liuli-util/commitlint-standard-config": "^0.1.6",
33
+ "@liuli-util/eslint-config-react-ts": "^0.1.0",
34
+ "@liuli-util/eslint-config-ts": "^0.2.0",
35
+ "@liuli-util/prettier-standard-config": "^0.1.0",
36
+ "chokidar": "^3.5.2",
30
37
  "commander": "^8.2.0",
38
+ "enquirer": "^2.3.6",
31
39
  "esbuild": "^0.13.2",
32
40
  "fs-extra": "^10.0.0",
33
- "inquirer": "^8.1.5",
34
- "lodash": "^4.17.21"
41
+ "glob": "^7.2.0",
42
+ "glob-promise": "^4.2.0",
43
+ "lodash-es": "^4.17.21",
44
+ "spinnies": "^0.5.1",
45
+ "ts-morph": "^12.0.0"
35
46
  },
36
47
  "devDependencies": {
37
48
  "@types/fs-extra": "^9.0.13",
38
- "@types/inquirer": "^8.1.2",
49
+ "@types/glob": "^7",
39
50
  "@types/jest": "^27.0.2",
40
- "@types/lodash": "^4.14.173",
51
+ "@types/lodash-es": "^4.17.5",
41
52
  "@types/node": "^16.9.6",
42
53
  "esno": "^0.9.1",
43
54
  "jest": "^27.2.1",
55
+ "lodash": "^4.17.21",
44
56
  "rimraf": "^3.0.2",
45
57
  "ts-jest": "^27.0.5",
46
58
  "type-fest": "^2.3.4",
@@ -0,0 +1,8 @@
1
+ declare module 'spinnies' {
2
+ type Spinnie = (id: string, args: { text: string }) => void
3
+ export default class Spinnies {
4
+ add: Spinnie
5
+ succeed: Spinnie
6
+ fail: Spinnie
7
+ }
8
+ }
package/src/bin.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Command } from 'commander'
2
- import { buildCommand } from './commands/esbuild'
2
+ import { esbuildCommand } from './commands/esbuild'
3
3
  import { generateCommand } from './commands/generate'
4
4
  import { syncCommand } from './commands/sync'
5
5
 
6
6
  const main = new Command()
7
7
  main
8
- .addCommand(buildCommand)
8
+ .addCommand(esbuildCommand)
9
9
  .addCommand(generateCommand)
10
10
  .addCommand(syncCommand)
11
11
  .parse()
@@ -1,22 +1,36 @@
1
- import { build, BuildOptions } from 'esbuild'
2
- import { execPromise } from '../../utils/execPromise'
3
- import { readJson } from 'fs-extra'
4
- import path from 'path'
1
+ import { build, BuildOptions, Platform, Plugin } from 'esbuild'
2
+ import { pathExists, readJson } from 'fs-extra'
3
+ import * as path from 'path'
5
4
  import { PackageJson } from 'type-fest'
5
+ import { Project } from 'ts-morph'
6
+ import { promise } from 'glob-promise'
7
+ import { IOptions } from 'glob'
8
+ import { nativeNodeModules, nodeExternals } from './util/esbuildPlugins'
9
+ import { watch } from 'chokidar'
10
+ import Spinnies from 'spinnies'
11
+ import { debounce } from './util/debounce'
12
+
13
+ interface ESBuildProgramOptions {
14
+ base: string
15
+ isWatch: boolean
16
+ }
17
+
18
+ interface Task {
19
+ title: string
20
+ task(): Promise<any>
21
+ }
6
22
 
7
23
  export class ESBuildProgram {
8
- constructor(private readonly base: string) {}
9
- async build(options: BuildOptions[]): Promise<void> {
10
- await Promise.all([
11
- ...options.map(async (option) => {
12
- await build(option)
13
- }),
14
- ] as Promise<void>[])
15
- }
24
+ constructor(private readonly options: ESBuildProgramOptions) {}
16
25
 
17
- async getDeps(): Promise<string[]> {
26
+ static readonly globalExternal = ['esbuild', 'pnpapi', 'ts-morph']
27
+
28
+ /**
29
+ * 获取所有依赖
30
+ */
31
+ static async getDeps(base: string): Promise<string[]> {
18
32
  const json = (await readJson(
19
- path.resolve(this.base, 'package.json'),
33
+ path.resolve(base, 'package.json'),
20
34
  )) as PackageJson
21
35
  return Object.keys({
22
36
  ...json.dependencies,
@@ -25,64 +39,250 @@ export class ESBuildProgram {
25
39
  })
26
40
  }
27
41
 
28
- async genDTS(isWatch: boolean): Promise<void> {
29
- await execPromise(
30
- `tsc --emitDeclarationOnly --outDir dist --incremental --declaration --declarationMap --noEmit false ${
31
- isWatch ? '--watch' : ''
32
- }`,
33
- {
34
- cwd: path.resolve(this.base),
42
+ /**
43
+ * 获取所在模块的类型
44
+ */
45
+ static async getPlatform(base: string): Promise<Platform> {
46
+ const tsconfigPath = path.resolve(base, 'tsconfig.json')
47
+ if (await pathExists(tsconfigPath)) {
48
+ const tsconfigJson = await readJson(tsconfigPath)
49
+ if (
50
+ (tsconfigJson.compilerOptions.lib as string[]).some(
51
+ (lib) => lib.toLowerCase() === 'dom',
52
+ )
53
+ ) {
54
+ return 'browser'
55
+ }
56
+ }
57
+ const pkgPath = path.resolve(base, 'package.json')
58
+ if (await pathExists(pkgPath)) {
59
+ const pkgJson = (await readJson(pkgPath)) as PackageJson
60
+ if (Object.keys(pkgJson.devDependencies ?? {}).includes('@types/node')) {
61
+ return 'node'
62
+ }
63
+ }
64
+ return 'neutral'
65
+ }
66
+ static getWatchOptions(base: string): {
67
+ pattern: string
68
+ options: IOptions
69
+ } {
70
+ const pattern = 'src/**/*.ts'
71
+ const options: Pick<IOptions, 'cwd' | 'ignore'> = {
72
+ cwd: base,
73
+ ignore: '**/__tests__/**/*',
74
+ }
75
+ return { pattern, options }
76
+ }
77
+ /**
78
+ * 生成类型定义
79
+ */
80
+ async genDTS(): Promise<void> {
81
+ const base = this.options.base
82
+ const { pattern, options } = ESBuildProgram.getWatchOptions(
83
+ this.options.base,
84
+ )
85
+ const project = new Project({
86
+ tsConfigFilePath: path.resolve(base, 'tsconfig.json'),
87
+ skipAddingFilesFromTsConfig: true,
88
+ compilerOptions: {
89
+ emitDeclarationOnly: true,
90
+ noEmit: false,
91
+ incremental: this.options.isWatch,
35
92
  },
93
+ })
94
+ const fileList = (await promise(pattern, options)).map((filePath) =>
95
+ path.resolve(base, filePath),
36
96
  )
97
+ project.addSourceFilesAtPaths(fileList)
98
+ await project.emit({
99
+ emitOnlyDtsFiles: true,
100
+ })
101
+ }
102
+
103
+ /**
104
+ * 获取构建 cjs 的选项
105
+ * @param deps
106
+ * @param platform
107
+ * @param plugins
108
+ */
109
+ getBuildCjsOption({
110
+ deps,
111
+ platform,
112
+ }: {
113
+ deps: string[]
114
+ platform: Platform
115
+ }): BuildOptions {
116
+ return {
117
+ outfile: './dist/index.js',
118
+ format: 'cjs',
119
+ sourcemap: true,
120
+ entryPoints: ['./src/index.ts'],
121
+ bundle: true,
122
+ external: [...ESBuildProgram.globalExternal, ...deps],
123
+ platform: platform,
124
+ minify: !this.options.isWatch,
125
+ incremental: this.options.isWatch,
126
+ }
127
+ }
128
+
129
+ /**
130
+ * 获取构建 esm 的选项
131
+ * @param deps
132
+ * @param platform
133
+ * @param plugins
134
+ */
135
+ getBuildESMOption({
136
+ deps,
137
+ platform,
138
+ }: {
139
+ deps: string[]
140
+ platform: Platform
141
+ }): BuildOptions {
142
+ return {
143
+ outfile: './dist/index.esm.js',
144
+ format: 'esm',
145
+ sourcemap: true,
146
+ entryPoints: ['./src/index.ts'],
147
+ bundle: true,
148
+ external: [...ESBuildProgram.globalExternal, ...deps],
149
+ platform: platform,
150
+ minify: !this.options.isWatch,
151
+ incremental: this.options.isWatch,
152
+ }
153
+ }
154
+
155
+ /**
156
+ * 获取构建 cli 的选项
157
+ * @param deps
158
+ * @param platform
159
+ * @param plugins
160
+ */
161
+ getBuildCliOption({
162
+ deps,
163
+ platform,
164
+ }: {
165
+ deps: string[]
166
+ platform: Platform
167
+ }): BuildOptions {
168
+ const plugins = ESBuildProgram.getPlugins(platform)
169
+ return {
170
+ entryPoints: ['./src/bin.ts'],
171
+ outfile: './dist/bin.js',
172
+ format: 'cjs',
173
+ sourcemap: true,
174
+ platform: platform,
175
+ bundle: true,
176
+ banner: {
177
+ js: '#!/usr/bin/env node',
178
+ },
179
+ external: [
180
+ ...ESBuildProgram.globalExternal,
181
+ ...(this.options.isWatch ? deps : []),
182
+ ],
183
+ plugins,
184
+ minify: !this.options.isWatch,
185
+ incremental: this.options.isWatch,
186
+ }
37
187
  }
38
- async buildPkg(isWatch: boolean): Promise<void> {
39
- const outputOptions: BuildOptions[] = [
188
+
189
+ static getPlugins(platform: string): Plugin[] {
190
+ const plugins: Plugin[] = []
191
+ if (platform === 'node') {
192
+ plugins.push(nodeExternals(), nativeNodeModules())
193
+ }
194
+ return plugins
195
+ }
196
+
197
+ async buildLib(): Promise<void> {
198
+ await this.build(this.getBuildLibTask.bind(this))
199
+ }
200
+
201
+ async buildCli(): Promise<void> {
202
+ await this.build(this.getBuildCliTask.bind(this))
203
+ }
204
+
205
+ getBuildLibTask(deps: string[], platform: Platform): Task[] {
206
+ return [
40
207
  {
41
- outfile: './dist/index.js',
42
- format: 'cjs',
43
- sourcemap: true,
208
+ title: '构建 esm',
209
+ task: () =>
210
+ build(
211
+ this.getBuildESMOption({
212
+ deps: deps,
213
+ platform: platform,
214
+ }),
215
+ ),
44
216
  },
45
217
  {
46
- outfile: './dist/index.esm.js',
47
- format: 'esm',
48
- sourcemap: true,
218
+ title: '构建 cjs',
219
+ task: () =>
220
+ build(
221
+ this.getBuildCjsOption({
222
+ deps: deps,
223
+ platform: platform,
224
+ }),
225
+ ),
226
+ },
227
+ {
228
+ title: '生成类型定义',
229
+ task: () => this.genDTS(),
49
230
  },
50
231
  ]
51
- const deps = await this.getDeps()
52
- const rollupOptions = outputOptions.map(
53
- (output) =>
54
- ({
55
- ...output,
56
- entryPoints: ['./src/index.ts'],
57
- watch: isWatch,
58
- bundle: true,
59
- external: deps,
60
- platform: 'node',
61
- } as BuildOptions),
62
- )
63
- await Promise.all([this.genDTS(isWatch), this.build(rollupOptions)])
232
+ }
233
+ getBuildCliTask(deps: string[], platform: Platform): Task[] {
234
+ return [
235
+ {
236
+ title: '构建 cli',
237
+ task: () =>
238
+ build(
239
+ this.getBuildCliOption({
240
+ deps: deps,
241
+ platform: platform,
242
+ }),
243
+ ),
244
+ },
245
+ ...this.getBuildLibTask(deps, platform),
246
+ ]
64
247
  }
65
248
 
66
- async buildCli(isWatch: boolean): Promise<void> {
67
- const deps = await this.getDeps()
68
- await Promise.all([
69
- this.build([
70
- {
71
- entryPoints: ['./src/bin.ts'],
72
- outfile: './dist/bin.js',
73
- format: 'cjs',
74
- sourcemap: true,
75
- platform: 'node',
76
- watch: isWatch,
77
- bundle: true,
78
- minify: !isWatch,
79
- banner: {
80
- js: '#!/usr/bin/env node',
81
- },
82
- external: ['esbuild', ...(isWatch ? deps : [])],
83
- } as BuildOptions,
84
- ]),
85
- this.buildPkg(isWatch),
86
- ])
249
+ static async execTask(spinnies: Spinnies, task: Task): Promise<void> {
250
+ const start = Date.now()
251
+ spinnies.add(task.title, { text: task.title })
252
+ try {
253
+ await task.task()
254
+ spinnies.succeed(task.title, {
255
+ text: `${task.title}: ${Date.now() - start}ms`,
256
+ })
257
+ } catch (e) {
258
+ spinnies.fail(task.title, { text: task.title })
259
+ }
260
+ }
261
+ async build(
262
+ genTasks: (deps: string[], platform: Platform) => Task[],
263
+ ): Promise<void> {
264
+ const run = async () => {
265
+ const start = Date.now()
266
+ const deps = await ESBuildProgram.getDeps(this.options.base)
267
+ const platform = await ESBuildProgram.getPlatform(this.options.base)
268
+ const tasks = genTasks(deps, platform)
269
+ const spinnies = new Spinnies()
270
+ await Promise.all(
271
+ tasks.map(async (task) => ESBuildProgram.execTask(spinnies, task)),
272
+ )
273
+ console.log(`构建完成: ${Date.now() - start}ms`)
274
+ }
275
+
276
+ if (!this.options.isWatch) {
277
+ await run()
278
+ return
279
+ }
280
+
281
+ const { pattern, options } = ESBuildProgram.getWatchOptions(
282
+ this.options.base,
283
+ )
284
+ await new Promise((resolve, reject) => {
285
+ watch(pattern, options).on('error', reject).on('all', debounce(run, 10))
286
+ })
87
287
  }
88
288
  }