@liuli-util/cli 3.18.0 → 3.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/README.zh-CN.md +53 -9
  2. package/dist/bin.js +113 -93
  3. package/dist/bin.js.map +3 -3
  4. package/dist/commands/deploy/DeployService.d.ts.map +1 -1
  5. package/dist/commands/esbuild/ESBuildProgram.d.ts +5 -2
  6. package/dist/commands/esbuild/ESBuildProgram.d.ts.map +1 -1
  7. package/dist/commands/esbuild/index.d.ts.map +1 -1
  8. package/dist/commands/esbuild/util/esbuildPlugins.d.ts +1 -0
  9. package/dist/commands/esbuild/util/esbuildPlugins.d.ts.map +1 -1
  10. package/dist/commands/sync/when.d.ts.map +1 -1
  11. package/dist/index.esm.js +4 -2
  12. package/dist/index.esm.js.map +2 -2
  13. package/dist/index.js +4 -2
  14. package/dist/index.js.map +2 -2
  15. package/package.json +14 -14
  16. package/src/commands/deploy/DeployService.ts +0 -2
  17. package/src/commands/deploy/__tests__/.temp/test.lock +0 -0
  18. package/src/commands/deploy/__tests__/DeployService.test.ts +2 -3
  19. package/src/commands/deploy/__tests__/conf.test.ts +0 -1
  20. package/src/commands/deploy/__tests__/simpleGit.test.ts +6 -3
  21. package/src/commands/deploy/__tests__/util/deployGhPageWorker.ts +3 -2
  22. package/src/commands/esbuild/ESBuildProgram.ts +25 -5
  23. package/src/commands/esbuild/__tests__/.temp/package.json +1 -0
  24. package/src/commands/esbuild/__tests__/.temp/src/index.ts +1 -0
  25. package/src/commands/esbuild/__tests__/ESBuildProgram.test.ts +50 -13
  26. package/src/commands/esbuild/index.ts +26 -13
  27. package/src/commands/esbuild/util/esbuildPlugins.ts +37 -1
  28. package/src/commands/generate/__tests__/.temp/README.md +1 -0
  29. package/src/commands/generate/__tests__/.temp/package.json +3 -0
  30. package/src/commands/generate/__tests__/.temp/test-cli/CHANGELOG.md +1 -0
  31. package/src/commands/generate/__tests__/.temp/test-cli/README.md +1 -0
  32. package/src/commands/generate/__tests__/.temp/test-cli/bin.js +3 -0
  33. package/src/commands/generate/__tests__/.temp/test-cli/package.json +34 -0
  34. package/src/commands/generate/__tests__/.temp/test-cli/src/bin.ts +13 -0
  35. package/src/commands/generate/__tests__/.temp/test-cli/src/index.ts +1 -0
  36. package/src/commands/generate/__tests__/.temp/test-cli/tsconfig.json +28 -0
  37. package/src/commands/sync/SyncProgram.ts +1 -1
  38. package/src/commands/sync/__tests__/SyncProgram.test.ts +1 -1
  39. package/src/commands/sync/__tests__/when.test.ts +3 -7
  40. package/src/commands/sync/when.ts +8 -23
  41. package/templates/cli/package.json +4 -4
  42. package/templates/lib/package.json +2 -2
  43. package/dist/commands/deploy/util/FileLock.d.ts +0 -14
  44. package/dist/commands/deploy/util/FileLock.d.ts.map +0 -1
  45. package/src/commands/deploy/__tests__/FileLock.test.ts +0 -27
  46. package/src/commands/deploy/util/FileLock.ts +0 -31
@@ -30,17 +30,30 @@ export const esbuildCommand = new Command('build')
30
30
  }),
31
31
  )
32
32
  .addCommand(
33
- (['iife', 'cli', 'esm', 'cjs', 'dts'] as TaskTypeEnum[]).reduce((res, type) => {
34
- res.addCommand(
35
- new Command(type)
36
- .description(`单独构建 ${type}`)
37
- .option('-w --watch', '监视模式')
38
- .action(async (options: CliBuildOptions) => {
39
- program.isWatch = !!options.watch
40
- const tasks = await program.getTasks()
41
- await program.execTasks([tasks[type]])
42
- }),
43
- )
44
- return res
45
- }, new Command('single').description('单独构建某种类型的 bundle')),
33
+ (['iife', 'cli', 'esm', 'cjs', 'dts'] as TaskTypeEnum[]).reduce(
34
+ (res, type) => {
35
+ res.addCommand(
36
+ new Command(type)
37
+ .description(`单独构建 ${type}`)
38
+ .option('-w --watch', '监视模式')
39
+ .action(async (options: CliBuildOptions) => {
40
+ program.isWatch = !!options.watch
41
+ const tasks = await program.getTasks()
42
+ await program.execTasks([tasks[type]])
43
+ }),
44
+ )
45
+ return res
46
+ },
47
+ new Command('single')
48
+ .description('单独构建某种类型的 bundle')
49
+ .option('-t, --target <target...>', '构建目标,是一个数组,可以使用 , 分割')
50
+ .option('-w, --watch', '监视模式')
51
+ .action(async (options: { target: TaskTypeEnum[]; watch?: boolean }) => {
52
+ program.isWatch = !!options.watch
53
+ const tasks = await program.getTasks()
54
+ await program.execTasks(
55
+ options.target.flatMap((s) => s.split(',') as TaskTypeEnum[]).map((type) => tasks[type]),
56
+ )
57
+ }),
58
+ ),
46
59
  )
@@ -1,5 +1,6 @@
1
1
  import { Plugin } from 'esbuild'
2
- import { writeJson } from 'fs-extra'
2
+ import { readJson, writeJson } from 'fs-extra'
3
+ import path from 'path'
3
4
 
4
5
  /**
5
6
  * 处理 nodejs 原生模块
@@ -93,3 +94,38 @@ export function metafile(metafilePath: string): Plugin {
93
94
  },
94
95
  }
95
96
  }
97
+
98
+ function generateBanner(meta: object) {
99
+ return (
100
+ [
101
+ '// ==UserScript==',
102
+ ...Object.entries(meta)
103
+ .map(([key, value]) => {
104
+ if (Array.isArray(value)) {
105
+ return value.map((item) => `// @${key} ${item}`)
106
+ }
107
+ return `// @${key} ${value}`
108
+ })
109
+ .flat(),
110
+ '// ==/UserScript==',
111
+ ].join('\n') + '\n'
112
+ )
113
+ }
114
+
115
+ export function userJS(): Plugin {
116
+ return {
117
+ name: 'esbuild-plugin-userjs',
118
+ async setup(build) {
119
+ const json = (await readJson(path.resolve(build.initialOptions.absWorkingDir!, 'package.json'))) as {
120
+ userjs: object
121
+ }
122
+ if (!json.userjs) {
123
+ throw new Error('userjs is not supported')
124
+ }
125
+ if (!build.initialOptions.banner) {
126
+ build.initialOptions.banner = {}
127
+ }
128
+ build.initialOptions.banner!['js'] = generateBanner(json.userjs)
129
+ },
130
+ }
131
+ }
@@ -0,0 +1 @@
1
+ # @liuli-util/.temp
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": ".temp"
3
+ }
@@ -0,0 +1 @@
1
+ # @liuli-util/cli-test-cli
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ // eslint-disable-next-line no-undef
3
+ require('./dist/bin.js')
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "test-cli",
3
+ "version": "0.1.0",
4
+ "main": "dist/index.js",
5
+ "module": "dist/index.esm.js",
6
+ "types": "dist/index.d.ts",
7
+ "license": "MIT",
8
+ "scripts": {
9
+ "build": "liuli-cli build cli",
10
+ "dev": "liuli-cli build cli -w",
11
+ "start": "esno src/bin.ts"
12
+ },
13
+ "bin": {
14
+ "cli-name": "./bin.js"
15
+ },
16
+ "dependencies": {
17
+ "commander": "^8.2.0",
18
+ "enquirer": "^2.3.6",
19
+ "fs-extra": "^10.0.0"
20
+ },
21
+ "devDependencies": {
22
+ "@liuli-util/cli": "^3.18.0",
23
+ "@types/fs-extra": "^9.0.13",
24
+ "@types/jest": "^27.0.2",
25
+ "@types/lodash": "^4.14.173",
26
+ "@types/node": "^16.9.6",
27
+ "esno": "^0.9.1",
28
+ "jest": "^27.4.7",
29
+ "rimraf": "^3.0.2",
30
+ "ts-jest": "^27.1.3",
31
+ "type-fest": "^2.3.4",
32
+ "typescript": "^4.5.5"
33
+ }
34
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from 'commander'
2
+ import { prompt } from 'enquirer'
3
+
4
+ new Command()
5
+ .action(async () => {
6
+ const { name } = await prompt<{ name: string }>({
7
+ type: 'input',
8
+ name: 'name',
9
+ message: '请输入名字',
10
+ })
11
+ console.log(`hello ${name}`)
12
+ })
13
+ .parse()
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "lib": [
5
+ "ESNext"
6
+ ],
7
+ "outDir": "./dist",
8
+ "skipLibCheck": true,
9
+ "esModuleInterop": true,
10
+ "strict": true,
11
+ "module": "ESNext",
12
+ "moduleResolution": "node",
13
+ "sourceMap": true,
14
+ "declaration": true,
15
+ "declarationMap": true
16
+ },
17
+ "include": [
18
+ "src"
19
+ ],
20
+ "typedocOptions": {
21
+ "entryPoints": [
22
+ "src/index.ts"
23
+ ],
24
+ "out": "docs",
25
+ "readme": "README.md",
26
+ "gitRemote": "origin"
27
+ }
28
+ }
@@ -1,6 +1,6 @@
1
1
  import { readFile, readJson, writeFile, writeJson } from 'fs-extra'
2
2
  import path from 'path'
3
- import { merge } from 'lodash-es'
3
+ import { merge } from 'lodash'
4
4
  import { PackageJson } from 'type-fest'
5
5
  import prettier from '@liuli-util/prettier-standard-config/package.json'
6
6
  import eslintTs from '@liuli-util/eslint-config-ts/package.json'
@@ -1,7 +1,7 @@
1
1
  import { mkdir, readJson, remove, writeJson } from 'fs-extra'
2
2
  import path from 'path'
3
3
  import { SyncConfigType, SyncProgram } from '../SyncProgram'
4
- import { merge } from 'lodash-es'
4
+ import { merge } from 'lodash'
5
5
  import { PackageJson } from 'type-fest'
6
6
 
7
7
  describe('测试 SyncProgram', () => {
@@ -1,17 +1,13 @@
1
1
  import { isIncludeDep, isNpmPackage, isYarnRoot, isYarnSubModule } from '../when'
2
- import { pathExists, readJson } from 'fs-extra'
3
- import { PackageJson } from 'type-fest'
4
- import path from 'path'
2
+ import { pathExists } from 'fs-extra'
3
+ import * as path from 'path'
5
4
  import { findParent } from '../../../utils'
6
5
 
7
6
  describe('测试 when', () => {
8
7
  let rootPath: string
9
8
  let subModulePath: string
10
9
  beforeAll(async () => {
11
- rootPath = (await findParent(__dirname, async (dir) => {
12
- const jsonPath = path.resolve(dir, 'package.json')
13
- return (await pathExists(jsonPath)) && !!((await readJson(jsonPath)) as PackageJson).workspaces
14
- }))!
10
+ rootPath = (await findParent(__dirname, (dir) => pathExists(path.resolve(dir, 'pnpm-workspace.yaml'))))!
15
11
  subModulePath = (await findParent(__dirname, async (dir) => pathExists(path.join(dir, 'package.json'))))!
16
12
  })
17
13
  it('测试 isNpmPackage', async () => {
@@ -1,5 +1,5 @@
1
1
  import { pathExists, readJson } from 'fs-extra'
2
- import path from 'path'
2
+ import * as path from 'path'
3
3
  import { PackageJson } from 'type-fest'
4
4
  import { findParent } from '../../utils'
5
5
 
@@ -7,9 +7,7 @@ import { findParent } from '../../utils'
7
7
  * 判断是否包含 package.json
8
8
  * @param cwd
9
9
  */
10
- export async function isNpmPackage(
11
- cwd: string = process.cwd(),
12
- ): Promise<boolean> {
10
+ export async function isNpmPackage(cwd: string = process.cwd()): Promise<boolean> {
13
11
  return await pathExists(path.resolve(cwd, './package.json'))
14
12
  }
15
13
 
@@ -17,24 +15,18 @@ export async function isNpmPackage(
17
15
  * 判断是 yarn2 monorepo 项目
18
16
  * @param cwd
19
17
  */
20
- export async function isYarnRoot(
21
- cwd: string = process.cwd(),
22
- ): Promise<boolean> {
18
+ export async function isYarnRoot(cwd: string = process.cwd()): Promise<boolean> {
23
19
  if (!(await isNpmPackage(cwd))) {
24
20
  return false
25
21
  }
26
- const json = (await readJson(
27
- path.resolve(cwd, './package.json'),
28
- )) as PackageJson
22
+ const json = (await readJson(path.resolve(cwd, './package.json'))) as PackageJson
29
23
  return !!json.workspaces
30
24
  }
31
25
 
32
26
  /**
33
27
  * 判断是 yarn2 monorepo 的子模块
34
28
  */
35
- export async function isYarnSubModule(
36
- cwd: string = process.cwd(),
37
- ): Promise<boolean> {
29
+ export async function isYarnSubModule(cwd: string = process.cwd()): Promise<boolean> {
38
30
  if (!(await isNpmPackage(cwd))) {
39
31
  return false
40
32
  }
@@ -50,18 +42,11 @@ export async function isYarnSubModule(
50
42
  * @param deps
51
43
  * @param cwd
52
44
  */
53
- export async function isIncludeDep(
54
- deps: string[],
55
- cwd: string = process.cwd(),
56
- ): Promise<boolean> {
45
+ export async function isIncludeDep(deps: string[], cwd: string = process.cwd()): Promise<boolean> {
57
46
  if (!(await isNpmPackage(cwd))) {
58
47
  return false
59
48
  }
60
- const json = (await readJson(
61
- path.resolve(cwd, './package.json'),
62
- )) as PackageJson
63
- const set = new Set(
64
- Object.keys({ ...json.dependencies, ...json.devDependencies }),
65
- )
49
+ const json = (await readJson(path.resolve(cwd, './package.json'))) as PackageJson
50
+ const set = new Set(Object.keys({ ...json.dependencies, ...json.devDependencies }))
66
51
  return deps.every((dep) => set.has(dep))
67
52
  }
@@ -6,7 +6,7 @@
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "MIT",
8
8
  "scripts": {
9
- "build": "rimraf dist && liuli-cli build cli",
9
+ "build": "liuli-cli build cli",
10
10
  "dev": "liuli-cli build cli -w",
11
11
  "start": "esno src/bin.ts"
12
12
  },
@@ -25,10 +25,10 @@
25
25
  "@types/lodash": "^4.14.173",
26
26
  "@types/node": "^16.9.6",
27
27
  "esno": "^0.9.1",
28
- "jest": "^27.2.1",
28
+ "jest": "^27.4.7",
29
29
  "rimraf": "^3.0.2",
30
- "ts-jest": "^27.0.5",
30
+ "ts-jest": "^27.1.3",
31
31
  "type-fest": "^2.3.4",
32
- "typescript": "^4.4.3"
32
+ "typescript": "^4.5.5"
33
33
  }
34
34
  }
@@ -7,13 +7,13 @@
7
7
  "types": "dist/index.d.ts",
8
8
  "license": "MIT",
9
9
  "scripts": {
10
- "build": "rimraf dist && liuli-cli build lib",
10
+ "build": "liuli-cli build lib",
11
11
  "dev": "liuli-cli build lib -w"
12
12
  },
13
13
  "devDependencies": {
14
14
  "@liuli-util/cli": "^3.18.0",
15
15
  "rimraf": "^3.0.2",
16
16
  "type-fest": "^2.3.4",
17
- "typescript": "^4.4.3"
17
+ "typescript": "^4.5.5"
18
18
  }
19
19
  }
@@ -1,14 +0,0 @@
1
- export declare class FileLock {
2
- private readonly lockFilePath;
3
- constructor(lockFilePath: string);
4
- private lockId?;
5
- /**
6
- * 加锁
7
- */
8
- lock(): Promise<boolean>;
9
- /**
10
- * 解锁
11
- */
12
- unlock(): Promise<void>;
13
- }
14
- //# sourceMappingURL=FileLock.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileLock.d.ts","sourceRoot":"","sources":["../../../../src/commands/deploy/util/FileLock.ts"],"names":[],"mappings":"AAGA,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,MAAM;IAEjD,OAAO,CAAC,MAAM,CAAC,CAAQ;IAEvB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9B;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAO9B"}
@@ -1,27 +0,0 @@
1
- import * as path from 'path'
2
- import { FileLock } from '../util/FileLock'
3
- import { AsyncArray } from '../../../utils'
4
- import { wait } from '../util/wait'
5
-
6
- describe('测试文件锁', () => {
7
- const tempPath = path.resolve(__dirname, '.temp/test.lock')
8
- it('基本示例', async () => {
9
- const fileLock = new FileLock(tempPath)
10
- expect(await fileLock.lock()).toBeTruthy()
11
- expect(await fileLock.lock()).toBeFalsy()
12
- await fileLock.unlock()
13
- expect(await fileLock.lock()).toBeTruthy()
14
- await fileLock.unlock()
15
- })
16
- it('测试并发调用', async () => {
17
- const start = Date.now()
18
- await AsyncArray.forEach(Array(10).fill(0), async () => {
19
- const fileLock = new FileLock(tempPath)
20
- await wait(() => fileLock.lock())
21
- await wait(100)
22
- await fileLock.unlock()
23
- })
24
- const time = Date.now() - start
25
- expect(time).toBeLessThan(3000)
26
- })
27
- })
@@ -1,31 +0,0 @@
1
- import { close, open, remove } from 'fs-extra'
2
- import path from 'path'
3
-
4
- export class FileLock {
5
- constructor(private readonly lockFilePath: string) {}
6
-
7
- private lockId?: number
8
-
9
- /**
10
- * 加锁
11
- */
12
- async lock(): Promise<boolean> {
13
- try {
14
- this.lockId = await open(path.resolve(this.lockFilePath), 'wx')
15
- return true
16
- } catch (e) {
17
- return false
18
- }
19
- }
20
-
21
- /**
22
- * 解锁
23
- */
24
- async unlock(): Promise<void> {
25
- if (!this.lockId) {
26
- throw new Error('未加锁')
27
- }
28
- await remove(path.resolve(this.lockFilePath))
29
- close(this.lockId)
30
- }
31
- }