@liuli-util/cli 3.17.1 → 3.19.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.
- package/CHANGELOG.md +4 -0
- package/README.md +30 -42
- package/README.zh-CN.md +130 -0
- package/dist/bin.js +114 -94
- package/dist/bin.js.map +3 -3
- package/dist/commands/deploy/DeployService.d.ts +25 -7
- package/dist/commands/deploy/DeployService.d.ts.map +1 -1
- package/dist/commands/deploy/util/validate.d.ts +8 -0
- package/dist/commands/deploy/util/validate.d.ts.map +1 -0
- package/dist/commands/esbuild/ESBuildProgram.d.ts +5 -2
- package/dist/commands/esbuild/ESBuildProgram.d.ts.map +1 -1
- package/dist/commands/esbuild/index.d.ts.map +1 -1
- package/dist/commands/esbuild/util/esbuildPlugins.d.ts +1 -0
- package/dist/commands/esbuild/util/esbuildPlugins.d.ts.map +1 -1
- package/dist/commands/sync/when.d.ts.map +1 -1
- package/dist/index.esm.js +4 -2
- package/dist/index.esm.js.map +2 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +2 -2
- package/package.json +16 -15
- package/src/commands/deploy/DeployService.ts +83 -45
- package/src/commands/deploy/__tests__/.temp/test.lock +0 -0
- package/src/commands/deploy/__tests__/DeployService.test.ts +52 -20
- package/src/commands/deploy/__tests__/conf.test.ts +0 -1
- package/src/commands/deploy/__tests__/simpleGit.test.ts +24 -1
- package/src/commands/deploy/__tests__/util/deployGhPageWorker.ts +3 -2
- package/src/commands/deploy/util/validate.ts +18 -0
- package/src/commands/esbuild/ESBuildProgram.ts +25 -5
- package/src/commands/esbuild/__tests__/.temp/package.json +1 -0
- package/src/commands/esbuild/__tests__/.temp/src/index.ts +1 -0
- package/src/commands/esbuild/__tests__/ESBuildProgram.test.ts +50 -13
- package/src/commands/esbuild/index.ts +26 -13
- package/src/commands/esbuild/util/esbuildPlugins.ts +37 -1
- package/src/commands/generate/__tests__/.temp/README.md +1 -0
- package/src/commands/generate/__tests__/.temp/package.json +3 -0
- package/src/commands/generate/__tests__/.temp/test-cli/package.json +8 -18
- package/src/commands/generate/__tests__/.temp/test-cli/src/bin.ts +1 -1
- package/src/commands/generate/__tests__/.temp/test-cli/tsconfig.json +28 -28
- package/src/commands/sync/SyncProgram.ts +1 -1
- package/src/commands/sync/__tests__/.temp/package.json +16 -0
- package/src/commands/sync/__tests__/SyncProgram.test.ts +1 -1
- package/src/commands/sync/__tests__/when.test.ts +3 -7
- package/src/commands/sync/when.ts +8 -23
- package/templates/cli/package.json +5 -9
- package/templates/cli/src/bin.ts +1 -1
- package/templates/cli/tsconfig.json +28 -28
- package/templates/lib/package.json +4 -11
- package/templates/lib/tsconfig.json +28 -28
- package/tsconfig.json +34 -34
- package/dist/commands/deploy/util/FileLock.d.ts +0 -14
- package/dist/commands/deploy/util/FileLock.d.ts.map +0 -1
- package/src/commands/deploy/__tests__/FileLock.test.ts +0 -27
- package/src/commands/deploy/util/FileLock.ts +0 -31
- package/src/commands/esbuild/__tests__/.temp/getDeps/package.json +0 -1
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as path from 'path'
|
2
2
|
import { mkdirp, remove, writeFile } from 'fs-extra'
|
3
|
-
import { GhPagesDeployService, SftpDeployOptions, SftpDeployService } from '../DeployService'
|
4
|
-
import {
|
3
|
+
import { GhPagesDeployOptions, GhPagesDeployService, SftpDeployOptions, SftpDeployService } from '../DeployService'
|
4
|
+
import { nodeCacheDir } from '../../../utils/nodeCacheDir'
|
5
5
|
|
6
6
|
const tempPath = path.resolve(__dirname, '.temp')
|
7
7
|
beforeAll(async () => {
|
@@ -25,14 +25,15 @@ beforeAll(async () => {
|
|
25
25
|
)
|
26
26
|
})
|
27
27
|
|
28
|
-
describe('测试 SftpDeployService', () => {
|
28
|
+
describe.skip('测试 SftpDeployService', () => {
|
29
29
|
const options: SftpDeployOptions = {
|
30
|
+
debug: false,
|
30
31
|
cwd: tempPath,
|
31
|
-
|
32
|
-
|
32
|
+
dist: 'dist',
|
33
|
+
dest: process.env.dest!,
|
33
34
|
sshConfig: {
|
34
|
-
host:
|
35
|
-
username:
|
35
|
+
host: process.env.host,
|
36
|
+
username: process.env.username,
|
36
37
|
},
|
37
38
|
}
|
38
39
|
it('基本示例', async () => {
|
@@ -54,22 +55,53 @@ describe('测试 SftpDeployService', () => {
|
|
54
55
|
})
|
55
56
|
})
|
56
57
|
|
57
|
-
describe('测试 GhPagesDeployService', () => {
|
58
|
-
const
|
58
|
+
describe.skip('测试 GhPagesDeployService', () => {
|
59
|
+
const options: GhPagesDeployOptions = {
|
60
|
+
debug: false,
|
59
61
|
cwd: tempPath,
|
60
|
-
|
61
|
-
|
62
|
+
dist: 'dist',
|
63
|
+
dest: '/',
|
64
|
+
repo: 'https://github.com/rxliuli/test-git.git',
|
65
|
+
remote: 'origin',
|
66
|
+
branch: 'gh-pages',
|
67
|
+
}
|
68
|
+
const ghPagesDeployService = new GhPagesDeployService(options)
|
69
|
+
const distPath = path.resolve(tempPath, 'dist')
|
70
|
+
const mock = jest.fn().mockImplementation((title) => console.log(title))
|
71
|
+
beforeEach(async () => {
|
72
|
+
await writeFile(
|
73
|
+
path.resolve(distPath, 'index.html'),
|
74
|
+
`<!DOCTYPE html>
|
75
|
+
<html lang="en">
|
76
|
+
<head>
|
77
|
+
<meta charset="UTF-8" />
|
78
|
+
<title>测试部署</title>
|
79
|
+
</head>
|
80
|
+
<body>
|
81
|
+
<h1>测试部署</h1>
|
82
|
+
<p>${Date.now()}</p>
|
83
|
+
</body>
|
84
|
+
</html>
|
85
|
+
`,
|
86
|
+
)
|
87
|
+
mock.mockClear()
|
62
88
|
})
|
63
89
|
it('基本示例', async () => {
|
64
|
-
await ghPagesDeployService.deploy().on('process',
|
90
|
+
await ghPagesDeployService.deploy().on('process', mock)
|
91
|
+
console.log(mock.mock.calls)
|
92
|
+
expect(mock.mock.calls.some((item: string[]) => item.includes('完成推送'))).toBeTruthy()
|
65
93
|
}, 10_000)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
await
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
94
|
+
it('测试没有任何修改', async () => {
|
95
|
+
await writeFile(path.resolve(distPath, 'index.html'), 'test')
|
96
|
+
await ghPagesDeployService.deploy().on('process', mock)
|
97
|
+
await ghPagesDeployService.deploy().on('process', mock)
|
98
|
+
expect(mock.mock.calls.some((item: string[]) => item.includes('没有任何提交,跳过提交'))).toBeTruthy()
|
99
|
+
expect(mock.mock.calls.some((item: string[]) => item.includes('没有更新,跳过推送'))).toBeTruthy()
|
100
|
+
}, 20_000)
|
101
|
+
it('测试首次拉取代码', async () => {
|
102
|
+
const dir = path.resolve(nodeCacheDir('liuli-cli'), 'gh-pages', options.repo!.replace(new RegExp('[/:]', 'g'), '_'))
|
103
|
+
await remove(dir)
|
104
|
+
await ghPagesDeployService.deploy().on('process', mock)
|
105
|
+
expect(mock.mock.calls.some((item: string[]) => item.includes('克隆项目'))).toBeTruthy()
|
74
106
|
}, 10_000)
|
75
107
|
})
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import simpleGit, { SimpleGit } from 'simple-git'
|
2
2
|
import * as path from 'path'
|
3
3
|
import { mkdirp, remove } from 'fs-extra'
|
4
|
+
import * as os from 'os'
|
4
5
|
|
5
|
-
describe('测试 simple-git', () => {
|
6
|
+
describe.skip('测试 simple-git', () => {
|
6
7
|
async function getOriginRemote() {
|
7
8
|
const git = simpleGit()
|
8
9
|
const remotes = await git.getRemotes(true)
|
@@ -32,3 +33,25 @@ describe('测试 simple-git', () => {
|
|
32
33
|
console.log('status: ', status.files)
|
33
34
|
})
|
34
35
|
})
|
36
|
+
|
37
|
+
describe.skip('测试真实场景', () => {
|
38
|
+
const gitPath = path.resolve(
|
39
|
+
os.homedir(),
|
40
|
+
'./AppData/Local/liuli-cli/Cache/gh-pages/https___github.com_rxliuli_webos.git',
|
41
|
+
)
|
42
|
+
let git: SimpleGit
|
43
|
+
beforeAll(() => {
|
44
|
+
git = simpleGit(gitPath)
|
45
|
+
})
|
46
|
+
it('测试获取提交状态', async () => {
|
47
|
+
const res = await git.status()
|
48
|
+
console.log(res)
|
49
|
+
})
|
50
|
+
it('测试获取更新', async () => {
|
51
|
+
const res = await git.pull()
|
52
|
+
console.log(res)
|
53
|
+
}, 100_000)
|
54
|
+
it('测试 git add -A', async () => {
|
55
|
+
await git.add('-A')
|
56
|
+
})
|
57
|
+
})
|
@@ -5,8 +5,9 @@ async function deployGhPages() {
|
|
5
5
|
const tempPath = path.resolve(__dirname, '../.temp/')
|
6
6
|
const ghPagesDeployService = new GhPagesDeployService({
|
7
7
|
cwd: tempPath,
|
8
|
-
|
9
|
-
|
8
|
+
dist: 'dist',
|
9
|
+
dest: 'examples/test-app',
|
10
|
+
debug: false,
|
10
11
|
})
|
11
12
|
const now = Date.now()
|
12
13
|
await ghPagesDeployService.deploy().on('process', (title) => console.log(`[${now}] ${title}`))
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import Ajv, { JSONSchemaType } from 'ajv'
|
2
|
+
import localize from 'ajv-i18n/localize'
|
3
|
+
import formatsPlugin from 'ajv-formats'
|
4
|
+
|
5
|
+
/**
|
6
|
+
* 使用 ajv 校验数据
|
7
|
+
* @param schema json 模式配置
|
8
|
+
* @param data 校验的数据
|
9
|
+
*/
|
10
|
+
export function validate<T>(schema: JSONSchemaType<T>, data: T): [isValid: boolean, errorText: string] {
|
11
|
+
const ajv = new Ajv({ allErrors: true, messages: false })
|
12
|
+
formatsPlugin(ajv)
|
13
|
+
const res = ajv.validate(schema, data)
|
14
|
+
if (!res) {
|
15
|
+
localize.zh(ajv.errors)
|
16
|
+
}
|
17
|
+
return [res, ajv.errorsText()]
|
18
|
+
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { build, BuildOptions, Platform, Plugin } from 'esbuild'
|
2
|
-
import { pathExists, readFile, readJson } from 'fs-extra'
|
2
|
+
import { pathExists, readFile, readJson, remove } from 'fs-extra'
|
3
3
|
import * as path from 'path'
|
4
4
|
import { PackageJson } from 'type-fest'
|
5
5
|
import { Project } from 'ts-morph'
|
6
6
|
import { promise } from 'glob-promise'
|
7
7
|
import { IOptions } from 'glob'
|
8
|
-
import { nativeNodeModules, nodeExternals } from './util/esbuildPlugins'
|
8
|
+
import { nativeNodeModules, nodeExternals, userJS } from './util/esbuildPlugins'
|
9
9
|
import { watch } from 'chokidar'
|
10
10
|
import Spinnies from 'spinnies'
|
11
11
|
import { debounce } from './util/debounce'
|
@@ -22,7 +22,7 @@ interface Task {
|
|
22
22
|
task(): Promise<any>
|
23
23
|
}
|
24
24
|
|
25
|
-
export type TaskTypeEnum = 'esm' | 'cjs' | 'iife' | 'cli' | 'dts'
|
25
|
+
export type TaskTypeEnum = 'esm' | 'cjs' | 'iife' | 'cli' | 'dts' | 'userjs'
|
26
26
|
|
27
27
|
export class ESBuildProgram {
|
28
28
|
constructor(private readonly options: ESBuildProgramOptions) {}
|
@@ -52,7 +52,7 @@ export class ESBuildProgram {
|
|
52
52
|
const tsconfigPath = path.resolve(base, 'tsconfig.json')
|
53
53
|
if (await pathExists(tsconfigPath)) {
|
54
54
|
const tsconfigJson = parse(await readFile(tsconfigPath, 'utf-8'))
|
55
|
-
if ((tsconfigJson
|
55
|
+
if ((tsconfigJson?.compilerOptions?.lib as string[])?.some((lib) => lib.toLowerCase() === 'dom')) {
|
56
56
|
return 'browser'
|
57
57
|
}
|
58
58
|
}
|
@@ -97,6 +97,22 @@ export class ESBuildProgram {
|
|
97
97
|
emitOnlyDtsFiles: true,
|
98
98
|
})
|
99
99
|
}
|
100
|
+
/**
|
101
|
+
* 获取构建 cjs 的选项
|
102
|
+
*/
|
103
|
+
getBuildUserJSOption(): BuildOptions {
|
104
|
+
return {
|
105
|
+
entryPoints: [path.resolve(this.options.base, './src/index.ts')],
|
106
|
+
outfile: path.resolve(this.options.base, './dist/index.user.js'),
|
107
|
+
format: 'iife',
|
108
|
+
bundle: true,
|
109
|
+
external: [...ESBuildProgram.globalExternal],
|
110
|
+
platform: 'browser',
|
111
|
+
plugins: [userJS()],
|
112
|
+
incremental: this.options.isWatch,
|
113
|
+
absWorkingDir: this.options.base,
|
114
|
+
}
|
115
|
+
}
|
100
116
|
|
101
117
|
/**
|
102
118
|
* 获取构建 cjs 的选项
|
@@ -144,7 +160,6 @@ export class ESBuildProgram {
|
|
144
160
|
* 获取构建 iife 的选项
|
145
161
|
* @param deps
|
146
162
|
* @param platform
|
147
|
-
* @param plugins
|
148
163
|
*/
|
149
164
|
getBuildIifeOption({ platform, globalName }: { platform: Platform; globalName: string }): BuildOptions {
|
150
165
|
return {
|
@@ -253,6 +268,10 @@ export class ESBuildProgram {
|
|
253
268
|
title: '生成类型定义',
|
254
269
|
task: () => this.genDTS(),
|
255
270
|
},
|
271
|
+
userjs: {
|
272
|
+
title: '打包 userjs',
|
273
|
+
task: () => this.build(this.getBuildUserJSOption()),
|
274
|
+
},
|
256
275
|
}
|
257
276
|
}
|
258
277
|
|
@@ -277,6 +296,7 @@ export class ESBuildProgram {
|
|
277
296
|
}
|
278
297
|
|
279
298
|
if (!this.options.isWatch) {
|
299
|
+
await remove(path.resolve(this.options.base, 'dist'))
|
280
300
|
await run()
|
281
301
|
return
|
282
302
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"name":"test","version":"1.0.0","userjs":{"name":"test","version":"0.1.0","description":"测试脚本","author":"rxliuli","match":["https://twitter.com/*"],"grant":["unsafeWindow"],"license":"MIT"}}
|
@@ -0,0 +1 @@
|
|
1
|
+
console.log(unsafeWindow)
|
@@ -1,17 +1,18 @@
|
|
1
1
|
import { ESBuildProgram } from '../ESBuildProgram'
|
2
2
|
import * as path from 'path'
|
3
|
-
import { mkdirp, pathExists, remove, writeJson } from 'fs-extra'
|
3
|
+
import { mkdirp, pathExists, remove, writeFile, writeJson } from 'fs-extra'
|
4
4
|
import { PackageJson } from 'type-fest'
|
5
5
|
import { build, Platform } from 'esbuild'
|
6
6
|
import { nativeNodeModules, nodeExternals } from '../util/esbuildPlugins'
|
7
|
+
import { findParent } from '../../../utils'
|
7
8
|
|
8
9
|
describe('测试 ESBuildProgram', () => {
|
10
|
+
const base: string = path.resolve(__dirname, '.temp')
|
11
|
+
beforeEach(async () => {
|
12
|
+
await remove(base)
|
13
|
+
await mkdirp(base)
|
14
|
+
})
|
9
15
|
describe('测试 getPlatform', () => {
|
10
|
-
const base: string = path.resolve(__dirname, '.temp/getPlatform')
|
11
|
-
beforeEach(async () => {
|
12
|
-
await remove(base)
|
13
|
-
await mkdirp(base)
|
14
|
-
})
|
15
16
|
it('测试 node 类型', async () => {
|
16
17
|
await writeJson(path.resolve(base, 'package.json'), {
|
17
18
|
devDependencies: {
|
@@ -34,11 +35,6 @@ describe('测试 ESBuildProgram', () => {
|
|
34
35
|
})
|
35
36
|
})
|
36
37
|
describe('测试 getDeps', () => {
|
37
|
-
const base: string = path.resolve(__dirname, '.temp/getDeps')
|
38
|
-
beforeEach(async () => {
|
39
|
-
await remove(base)
|
40
|
-
await mkdirp(base)
|
41
|
-
})
|
42
38
|
it('基本示例', async () => {
|
43
39
|
await writeJson(path.resolve(base, 'package.json'), {
|
44
40
|
devDependencies: {
|
@@ -72,7 +68,7 @@ describe('测试 ESBuildProgram', () => {
|
|
72
68
|
it('测试 genDTS', async () => {
|
73
69
|
await program.genDTS()
|
74
70
|
expect(await pathExists(path.resolve(base, 'dist/index.d.ts'))).toBeTruthy()
|
75
|
-
})
|
71
|
+
}, 10_000)
|
76
72
|
it('测试 getBuildCjsOption', async () => {
|
77
73
|
await build(
|
78
74
|
program.getBuildCjsOption({
|
@@ -112,7 +108,7 @@ describe('测试 ESBuildProgram', () => {
|
|
112
108
|
)
|
113
109
|
expect(await pathExists(path.resolve(base, 'dist/bin.js'))).toBeTruthy()
|
114
110
|
})
|
115
|
-
it('测试 metafile', async () => {
|
111
|
+
it.skip('测试 metafile', async () => {
|
116
112
|
program.isWatch = true
|
117
113
|
await program.build(
|
118
114
|
program.getBuildCliOption({
|
@@ -123,6 +119,33 @@ describe('测试 ESBuildProgram', () => {
|
|
123
119
|
expect(await pathExists(path.resolve(base, 'dist/bin.js'))).toBeTruthy()
|
124
120
|
})
|
125
121
|
})
|
122
|
+
describe('测试构建 userjs', () => {
|
123
|
+
const program = new ESBuildProgram({
|
124
|
+
base,
|
125
|
+
isWatch: false,
|
126
|
+
})
|
127
|
+
beforeEach(async () => {
|
128
|
+
await mkdirp(path.resolve(base, 'src'))
|
129
|
+
await writeJson(path.resolve(base, 'package.json'), {
|
130
|
+
name: 'test',
|
131
|
+
version: '1.0.0',
|
132
|
+
userjs: {
|
133
|
+
name: 'test',
|
134
|
+
version: '0.1.0',
|
135
|
+
description: '测试脚本',
|
136
|
+
author: 'rxliuli',
|
137
|
+
match: ['https://twitter.com/*'],
|
138
|
+
grant: ['unsafeWindow'],
|
139
|
+
license: 'MIT',
|
140
|
+
},
|
141
|
+
} as PackageJson)
|
142
|
+
await writeFile(path.resolve(base, 'src/index.ts'), `console.log(unsafeWindow)`)
|
143
|
+
})
|
144
|
+
it('基本示例', async () => {
|
145
|
+
await build(program.getBuildUserJSOption())
|
146
|
+
expect(await pathExists(path.resolve(base, 'dist/index.user.js'))).toBeTruthy()
|
147
|
+
})
|
148
|
+
})
|
126
149
|
})
|
127
150
|
it('测试 esbuild', async () => {
|
128
151
|
await build({
|
@@ -140,3 +163,17 @@ it('测试 esbuild', async () => {
|
|
140
163
|
treeShaking: true,
|
141
164
|
})
|
142
165
|
})
|
166
|
+
describe('测试 cli 本身的构建', () => {
|
167
|
+
let selfPath: string
|
168
|
+
beforeAll(async () => {
|
169
|
+
selfPath = (await findParent(__dirname, async (dir) => pathExists(path.join(dir, 'package.json'))))!
|
170
|
+
})
|
171
|
+
it('基本示例', async () => {
|
172
|
+
const program = new ESBuildProgram({
|
173
|
+
base: selfPath,
|
174
|
+
isWatch: false,
|
175
|
+
})
|
176
|
+
const { cli, cjs, esm } = await program.getTasks()
|
177
|
+
await program.execTasks([cli, cjs, esm])
|
178
|
+
})
|
179
|
+
})
|
@@ -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(
|
34
|
-
res
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
@@ -6,39 +6,29 @@
|
|
6
6
|
"types": "dist/index.d.ts",
|
7
7
|
"license": "MIT",
|
8
8
|
"scripts": {
|
9
|
-
"build": "
|
9
|
+
"build": "liuli-cli build cli",
|
10
10
|
"dev": "liuli-cli build cli -w",
|
11
|
-
"start": "esno src/bin.ts"
|
12
|
-
"docs:server": "live-server docs",
|
13
|
-
"docs:dev": "typedoc --watch",
|
14
|
-
"docs:build": "rimraf docs && typedoc",
|
15
|
-
"docs:deploy": "yarn docs:build && gh-pages -d docs/ -e / -a"
|
11
|
+
"start": "esno src/bin.ts"
|
16
12
|
},
|
17
13
|
"bin": {
|
18
14
|
"cli-name": "./bin.js"
|
19
15
|
},
|
20
|
-
"jest": {
|
21
|
-
"preset": "ts-jest"
|
22
|
-
},
|
23
16
|
"dependencies": {
|
24
17
|
"commander": "^8.2.0",
|
25
|
-
"
|
26
|
-
"
|
18
|
+
"enquirer": "^2.3.6",
|
19
|
+
"fs-extra": "^10.0.0"
|
27
20
|
},
|
28
21
|
"devDependencies": {
|
29
|
-
"@liuli-util/cli": "^3.
|
22
|
+
"@liuli-util/cli": "^3.18.0",
|
30
23
|
"@types/fs-extra": "^9.0.13",
|
31
|
-
"@types/inquirer": "^8.1.2",
|
32
24
|
"@types/jest": "^27.0.2",
|
33
25
|
"@types/lodash": "^4.14.173",
|
34
26
|
"@types/node": "^16.9.6",
|
35
27
|
"esno": "^0.9.1",
|
36
|
-
"
|
37
|
-
"jest": "^27.2.1",
|
28
|
+
"jest": "^27.4.7",
|
38
29
|
"rimraf": "^3.0.2",
|
39
|
-
"ts-jest": "^27.
|
30
|
+
"ts-jest": "^27.1.3",
|
40
31
|
"type-fest": "^2.3.4",
|
41
|
-
"
|
42
|
-
"typescript": "^4.4.3"
|
32
|
+
"typescript": "^4.5.5"
|
43
33
|
}
|
44
34
|
}
|
@@ -1,28 +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
|
+
{
|
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
|
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
|
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
|
3
|
-
import
|
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,
|
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 () => {
|