@liuli-util/cli 3.17.1 → 3.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 () => {
|