@struggler/cli 1.0.2 → 1.0.5
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/.strugglerignore +6 -0
- package/Makefile +81 -0
- package/README.md +124 -0
- package/command/addVersion.js +11 -5
- package/command/deploy.js +75 -0
- package/command/index.js +4 -2
- package/command/init.js +20 -20
- package/command/refresh.js +111 -0
- package/command/upload.js +108 -169
- package/index.js +84 -23
- package/lib/config.js +22 -4
- package/lib/date.js +14 -0
- package/lib/deploy.js +132 -0
- package/lib/files.js +30 -4
- package/lib/i18n.js +189 -0
- package/lib/ignore.js +69 -0
- package/lib/output.js +37 -0
- package/lib/prefix.js +2 -16
- package/package.json +28 -27
- package/test/config.test.js +41 -0
- package/test/init.test.js +52 -0
- package/test/test.sh +2 -2
- package/test/upload.test.js +113 -0
package/.strugglerignore
ADDED
package/Makefile
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
SHELL := /bin/zsh
|
|
2
|
+
|
|
3
|
+
NODE ?= node
|
|
4
|
+
PNPM ?= pnpm
|
|
5
|
+
CLI_ENTRY ?= ./index.js
|
|
6
|
+
CONFIG ?= ./command/qiniu.json
|
|
7
|
+
DIR ?= ./dist
|
|
8
|
+
DRY_RUN ?=
|
|
9
|
+
CONCURRENCY ?= 5
|
|
10
|
+
EXCLUDE ?=
|
|
11
|
+
MANIFEST ?=
|
|
12
|
+
JSON ?=
|
|
13
|
+
SKIP_INIT ?=
|
|
14
|
+
SKIP_REFRESH ?=
|
|
15
|
+
|
|
16
|
+
.PHONY: help install reinstall link unlink init upload refresh deploy add-version example-upload test
|
|
17
|
+
|
|
18
|
+
help:
|
|
19
|
+
@echo "Available targets:"
|
|
20
|
+
@echo " make install Install dependencies"
|
|
21
|
+
@echo " make reinstall Reinstall dependencies from scratch"
|
|
22
|
+
@echo " make link Link the CLI globally for local usage"
|
|
23
|
+
@echo " make unlink Remove the global link"
|
|
24
|
+
@echo " make init Generate/update upload config metadata"
|
|
25
|
+
@echo " make upload Upload files from DIR using CONFIG"
|
|
26
|
+
@echo " make refresh Refresh CDN for files from DIR using CONFIG"
|
|
27
|
+
@echo " make deploy Run init, upload, and refresh in one go"
|
|
28
|
+
@echo " make add-version Run the package version bump script"
|
|
29
|
+
@echo " make example-upload Upload the sample test/dist3 directory"
|
|
30
|
+
@echo " make test Run the automated test suite"
|
|
31
|
+
@echo ""
|
|
32
|
+
@echo "Variables:"
|
|
33
|
+
@echo " CONFIG=$(CONFIG)"
|
|
34
|
+
@echo " DIR=$(DIR)"
|
|
35
|
+
@echo " CLI_ENTRY=$(CLI_ENTRY)"
|
|
36
|
+
@echo " CONCURRENCY=$(CONCURRENCY)"
|
|
37
|
+
@echo " DRY_RUN=$(DRY_RUN)"
|
|
38
|
+
@echo " EXCLUDE=$(EXCLUDE)"
|
|
39
|
+
@echo " MANIFEST=$(MANIFEST)"
|
|
40
|
+
@echo " JSON=$(JSON)"
|
|
41
|
+
@echo ""
|
|
42
|
+
@echo "Example:"
|
|
43
|
+
@echo " make upload DIR=./test/dist3 CONFIG=./test/command/qiniu.json DRY_RUN=--dry-run EXCLUDE=.DS_Store"
|
|
44
|
+
|
|
45
|
+
install:
|
|
46
|
+
$(PNPM) install
|
|
47
|
+
|
|
48
|
+
reinstall:
|
|
49
|
+
rm -rf node_modules
|
|
50
|
+
$(PNPM) install
|
|
51
|
+
|
|
52
|
+
link:
|
|
53
|
+
@if ! $(PNPM) bin --global >/dev/null 2>&1; then \
|
|
54
|
+
echo "pnpm global bin not configured, running 'pnpm setup' first..."; \
|
|
55
|
+
$(PNPM) setup; \
|
|
56
|
+
fi
|
|
57
|
+
@$(PNPM) link --global
|
|
58
|
+
|
|
59
|
+
unlink:
|
|
60
|
+
@$(PNPM) unlink --global @struggler/cli
|
|
61
|
+
|
|
62
|
+
init:
|
|
63
|
+
$(NODE) $(CLI_ENTRY) --config $(CONFIG) --dir $(DIR) $(DRY_RUN) $(JSON) init
|
|
64
|
+
|
|
65
|
+
upload:
|
|
66
|
+
$(NODE) $(CLI_ENTRY) --config $(CONFIG) --dir $(DIR) --concurrency $(CONCURRENCY) $(DRY_RUN) $(if $(EXCLUDE),--exclude $(EXCLUDE),) $(if $(MANIFEST),--manifest $(MANIFEST),) $(JSON) upload
|
|
67
|
+
|
|
68
|
+
refresh:
|
|
69
|
+
$(NODE) $(CLI_ENTRY) --config $(CONFIG) --dir $(DIR) $(DRY_RUN) $(if $(EXCLUDE),--exclude $(EXCLUDE),) $(if $(MANIFEST),--manifest $(MANIFEST),) $(JSON) refresh
|
|
70
|
+
|
|
71
|
+
deploy:
|
|
72
|
+
$(NODE) $(CLI_ENTRY) --config $(CONFIG) --dir $(DIR) --concurrency $(CONCURRENCY) $(DRY_RUN) $(if $(EXCLUDE),--exclude $(EXCLUDE),) $(if $(MANIFEST),--manifest $(MANIFEST),) $(JSON) $(SKIP_INIT) $(SKIP_REFRESH) deploy
|
|
73
|
+
|
|
74
|
+
add-version:
|
|
75
|
+
$(PNPM) add-version
|
|
76
|
+
|
|
77
|
+
example-upload:
|
|
78
|
+
$(NODE) $(CLI_ENTRY) --config ./test/command/qiniu.json --dir ./test/dist3 --concurrency $(CONCURRENCY) $(DRY_RUN) $(if $(EXCLUDE),--exclude $(EXCLUDE),) $(if $(MANIFEST),--manifest $(MANIFEST),) $(JSON) upload
|
|
79
|
+
|
|
80
|
+
test:
|
|
81
|
+
$(PNPM) test
|
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# struggler-cli
|
|
2
|
+
|
|
3
|
+
`struggler-cli` is a small deployment CLI for front-end build assets on Qiniu Cloud. It can generate versioned paths, upload build output, refresh CDN URLs, and now supports `dry-run`, concurrent uploads, ignore rules, manifest export, JSON output, and a one-shot `deploy` command.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For local command usage:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm link --global
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Config Files
|
|
18
|
+
|
|
19
|
+
The CLI expects two files in the same directory:
|
|
20
|
+
|
|
21
|
+
- `qiniu.json`: Qiniu credentials and bucket metadata
|
|
22
|
+
- `config.json`: generated deploy prefix metadata used by upload/refresh
|
|
23
|
+
|
|
24
|
+
Example `qiniu.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"path": "your-project",
|
|
29
|
+
"accessKey": "",
|
|
30
|
+
"secretKey": "",
|
|
31
|
+
"Bucket": "",
|
|
32
|
+
"zone": "Zone_z1",
|
|
33
|
+
"domain": "https://cdn.example.com/"
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Optional ignore file:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
.strugglerignore
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
.DS_Store
|
|
47
|
+
*.map
|
|
48
|
+
legacy/**
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
Initialize versioned config:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist init
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Preview upload work without changing files or calling Qiniu:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist --dry-run upload
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Upload with concurrency:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist --concurrency 8 upload
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Upload with ignore patterns and a manifest:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist --exclude ".DS_Store,*.map" --manifest ./artifacts/upload-manifest.json upload
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Refresh CDN for generated URLs:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist refresh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Run the full flow:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist --concurrency 8 deploy
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Skip parts of deploy:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist --skip-refresh deploy
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Machine-readable output:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
node ./index.js --config ./command/qiniu.json --dir ./dist --json --dry-run deploy
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Version bump script:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pnpm add-version
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Makefile Shortcuts
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
make init
|
|
111
|
+
make upload
|
|
112
|
+
make refresh
|
|
113
|
+
make deploy
|
|
114
|
+
make upload DIR=./test/dist3 CONFIG=./test/command/qiniu.json DRY_RUN=--dry-run
|
|
115
|
+
make deploy MANIFEST=./artifacts/deploy.json JSON=--json SKIP_REFRESH=--skip-refresh
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Test
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pnpm test
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The automated tests cover config path resolution, init dry-run behavior, upload ignore handling, manifest generation, and deploy JSON summaries.
|
package/command/addVersion.js
CHANGED
|
@@ -14,16 +14,22 @@ function getPackageJson() {
|
|
|
14
14
|
function main(){
|
|
15
15
|
let packageData = getPackageJson();//获取package的json
|
|
16
16
|
let arr = packageData.version.split('.');//切割后的版本号数组
|
|
17
|
+
if (arr.length !== 3 || arr.some((item) => Number.isNaN(parseInt(item, 10)))) {
|
|
18
|
+
throw new Error(`Invalid semver version: ${packageData.version}`)
|
|
19
|
+
}
|
|
17
20
|
arr[2] = parseInt(arr[2]) + 1;
|
|
18
21
|
packageData.version = arr.join('.');//转换为以"."分割的字符串
|
|
19
|
-
|
|
20
|
-
fs.writeFile(
|
|
22
|
+
fs.writeFileSync(
|
|
21
23
|
packagePath,
|
|
22
24
|
JSON.stringify(packageData, null, "\t"
|
|
23
|
-
)
|
|
24
|
-
(err) => { }
|
|
25
|
+
)
|
|
25
26
|
)
|
|
27
|
+
console.log(`Version updated to ${packageData.version}`)
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
|
|
29
|
-
module.exports = main
|
|
31
|
+
module.exports = main
|
|
32
|
+
|
|
33
|
+
if (require.main === module) {
|
|
34
|
+
main()
|
|
35
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const init = require('./init');
|
|
2
|
+
const upload = require('./upload');
|
|
3
|
+
const refresh = require('./refresh');
|
|
4
|
+
const { collectDeployFiles, createSummary, finalizeOutput } = require('../lib/deploy');
|
|
5
|
+
const { getDir } = require('../lib/config');
|
|
6
|
+
const { createIgnoreMatcher } = require('../lib/ignore');
|
|
7
|
+
const { printMessage } = require('../lib/output');
|
|
8
|
+
|
|
9
|
+
async function main(options) {
|
|
10
|
+
const startedAt = Date.now();
|
|
11
|
+
const dir = getDir(options);
|
|
12
|
+
const ignoreMatcher = createIgnoreMatcher(dir, options);
|
|
13
|
+
const files = await collectDeployFiles(dir, options);
|
|
14
|
+
const manifestExtra = {
|
|
15
|
+
command: 'deploy',
|
|
16
|
+
skippedSteps: {
|
|
17
|
+
init: Boolean(options.skipInit),
|
|
18
|
+
refresh: Boolean(options.skipRefresh),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
let initConfig = null;
|
|
23
|
+
if (!options.skipInit) {
|
|
24
|
+
initConfig = await init(options);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const prefix = initConfig ? initConfig.publicPath : undefined;
|
|
28
|
+
const uploadSummary = await upload(options, {
|
|
29
|
+
files,
|
|
30
|
+
prefix,
|
|
31
|
+
excludePatterns: ignoreMatcher.patterns,
|
|
32
|
+
suppressOutput: true,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
let refreshSummary = createSummary('refresh', Boolean(options.dryRun), [], startedAt, {
|
|
36
|
+
skipped: Boolean(options.skipRefresh),
|
|
37
|
+
prefix: uploadSummary.prefix,
|
|
38
|
+
excludedPatterns: ignoreMatcher.patterns,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (!options.skipRefresh) {
|
|
42
|
+
const refreshFiles = uploadSummary.succeeded.map((item) => item.localFile);
|
|
43
|
+
refreshSummary = await refresh(options, {
|
|
44
|
+
files: refreshFiles,
|
|
45
|
+
prefix: uploadSummary.prefix,
|
|
46
|
+
excludePatterns: ignoreMatcher.patterns,
|
|
47
|
+
suppressOutput: true,
|
|
48
|
+
});
|
|
49
|
+
} else {
|
|
50
|
+
printMessage(options, '[deploy] refresh step skipped');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const deploySummary = finalizeOutput(createSummary('deploy', Boolean(options.dryRun), [
|
|
54
|
+
{
|
|
55
|
+
ok: uploadSummary.failedCount === 0,
|
|
56
|
+
step: 'upload',
|
|
57
|
+
detail: uploadSummary,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
ok: options.skipRefresh || refreshSummary.failedCount === 0,
|
|
61
|
+
step: 'refresh',
|
|
62
|
+
detail: refreshSummary,
|
|
63
|
+
},
|
|
64
|
+
], startedAt, {
|
|
65
|
+
upload: uploadSummary,
|
|
66
|
+
refresh: refreshSummary,
|
|
67
|
+
prefix: uploadSummary.prefix,
|
|
68
|
+
excludedPatterns: ignoreMatcher.patterns,
|
|
69
|
+
}), options, manifestExtra);
|
|
70
|
+
|
|
71
|
+
printMessage(options, `[deploy] upload=${uploadSummary.succeededCount}/${uploadSummary.total} refresh=${refreshSummary.succeededCount}/${refreshSummary.total}`);
|
|
72
|
+
return deploySummary;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = main
|
package/command/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
var init = require('./init');
|
|
2
2
|
var upload = require('./upload');
|
|
3
|
-
var
|
|
3
|
+
var refresh = require('./refresh');
|
|
4
|
+
var deploy = require('./deploy');
|
|
4
5
|
|
|
5
6
|
exports.init = init;
|
|
6
7
|
exports.upload = upload;
|
|
7
|
-
exports.
|
|
8
|
+
exports.refresh = refresh;
|
|
9
|
+
exports.deploy = deploy;
|
package/command/init.js
CHANGED
|
@@ -2,22 +2,17 @@ let { getConfig, getQiniuConfig } = require('../lib/config')
|
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
let { getJsonData, setJsonData, setSyncJsonData, directoryExists } = require('../lib/files')
|
|
4
4
|
let path = require('path')
|
|
5
|
+
const { formatDate } = require('../lib/date');
|
|
6
|
+
const { printMessage } = require('../lib/output');
|
|
5
7
|
|
|
6
|
-
function
|
|
7
|
-
date = date || new Date()
|
|
8
|
-
const year = date.getFullYear()
|
|
9
|
-
const month = date.getMonth() + 1
|
|
10
|
-
const day = date.getDate()
|
|
11
|
-
const hours = date.getHours()
|
|
12
|
-
const minutes = date.getMinutes()
|
|
13
|
-
|
|
14
|
-
return `${year}${month < 10 ? `0${month}` : month}${day < 10 ? `0${day}` : day}${hours < 10 ? `0${hours}` : hours}${minutes < 10 ? `0${minutes}` : minutes}`
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function init(qiniuConfigPath, configPath){
|
|
8
|
+
function init(qiniuConfigPath, options){
|
|
18
9
|
if (!directoryExists(qiniuConfigPath)){
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
printMessage(options, chalk.red("七牛配置不存在 正在生成模版 请稍后在下面的文件里填写必要的信息!"))
|
|
11
|
+
printMessage(options, chalk.blue(qiniuConfigPath))
|
|
12
|
+
if (options.dryRun) {
|
|
13
|
+
printMessage(options, `[dry-run] init would create template ${qiniuConfigPath}`)
|
|
14
|
+
return
|
|
15
|
+
}
|
|
21
16
|
setSyncJsonData(qiniuConfigPath, getJsonData(path.resolve(__dirname, '../def/qiniu.json')))
|
|
22
17
|
}
|
|
23
18
|
|
|
@@ -26,16 +21,21 @@ function init(qiniuConfigPath, configPath){
|
|
|
26
21
|
function main(options){
|
|
27
22
|
let configPath = getConfig(options)
|
|
28
23
|
let qiniuConfigPath = getQiniuConfig(options)
|
|
29
|
-
init(qiniuConfigPath,
|
|
24
|
+
init(qiniuConfigPath, options)
|
|
30
25
|
const qiniuConfig = getJsonData(qiniuConfigPath)
|
|
31
26
|
let domain = qiniuConfig.domain
|
|
32
|
-
|
|
27
|
+
const versionPrefix = formatDate()
|
|
33
28
|
let config = getJsonData(configPath)
|
|
34
|
-
config.publicPath = qiniuConfig.path
|
|
35
|
-
config.base = domain
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
config.publicPath = `${qiniuConfig.path || ''}/${versionPrefix}/`
|
|
30
|
+
config.base = `${domain || ''}${qiniuConfig.path || ''}/${versionPrefix}/`
|
|
31
|
+
if (options.dryRun) {
|
|
32
|
+
printMessage(options, `[dry-run] init would write ${configPath}`)
|
|
33
|
+
printMessage(options, JSON.stringify(config, null, 2))
|
|
34
|
+
return config
|
|
35
|
+
}
|
|
36
|
+
printMessage(options, JSON.stringify(config, null, 2))
|
|
38
37
|
setJsonData(configPath, config)
|
|
38
|
+
return config
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
module.exports = main
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
var qiniu = require("qiniu");
|
|
2
|
+
|
|
3
|
+
var qiniuPrefix = require("../lib/prefix")
|
|
4
|
+
|
|
5
|
+
let { getQiniuConfig, getDir } = require('../lib/config')
|
|
6
|
+
let { getJsonData } = require('../lib/files')
|
|
7
|
+
const { createIgnoreMatcher } = require('../lib/ignore');
|
|
8
|
+
const {
|
|
9
|
+
collectDeployFiles,
|
|
10
|
+
createSummary,
|
|
11
|
+
ensureRequiredConfig,
|
|
12
|
+
finalizeOutput,
|
|
13
|
+
logPlan,
|
|
14
|
+
toRemoteKey,
|
|
15
|
+
} = require('../lib/deploy');
|
|
16
|
+
const { printMessage } = require('../lib/output');
|
|
17
|
+
|
|
18
|
+
async function main(options, runtime = {}) {
|
|
19
|
+
const qiniuConfig = getJsonData(getQiniuConfig(options))
|
|
20
|
+
const prefix = runtime.prefix || qiniuPrefix.prefix(options);
|
|
21
|
+
let dir = getDir(options)
|
|
22
|
+
const startedAt = Date.now();
|
|
23
|
+
const ignoreMatcher = createIgnoreMatcher(dir, options);
|
|
24
|
+
const excludedPatterns = runtime.excludePatterns || ignoreMatcher.patterns;
|
|
25
|
+
const files = runtime.files || await collectDeployFiles(dir, options);
|
|
26
|
+
const plans = files.map((localFile) => {
|
|
27
|
+
const key = toRemoteKey(prefix, dir, localFile);
|
|
28
|
+
return {
|
|
29
|
+
localFile,
|
|
30
|
+
key,
|
|
31
|
+
target: `${qiniuConfig.domain || ''}${key}`,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (options.dryRun) {
|
|
36
|
+
if (!runtime.suppressOutput) {
|
|
37
|
+
logPlan('refresh', plans, options);
|
|
38
|
+
}
|
|
39
|
+
const summary = createSummary('refresh', true, plans.map((plan) => ({
|
|
40
|
+
ok: true,
|
|
41
|
+
localFile: plan.localFile,
|
|
42
|
+
key: plan.key,
|
|
43
|
+
target: plan.target,
|
|
44
|
+
})), startedAt, {
|
|
45
|
+
prefix,
|
|
46
|
+
excludedPatterns,
|
|
47
|
+
});
|
|
48
|
+
return runtime.suppressOutput ? summary : finalizeOutput(summary, options, runtime.manifestExtra);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ensureRequiredConfig(
|
|
52
|
+
{ ...qiniuConfig, 'publicPath(config.json)': prefix },
|
|
53
|
+
['accessKey', 'secretKey', 'domain', 'publicPath(config.json)']
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
var accessKey = qiniuConfig.accessKey
|
|
57
|
+
var secretKey = qiniuConfig.secretKey;
|
|
58
|
+
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
|
|
59
|
+
var cdnManager = new qiniu.cdn.CdnManager(mac);
|
|
60
|
+
|
|
61
|
+
function refresh(plan) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
cdnManager.refreshUrls([plan.target], function (respErr, respBody, respInfo) {
|
|
64
|
+
if (respErr || respInfo.statusCode !== 200) {
|
|
65
|
+
const errorMessage = respErr || (respBody && respBody.error) || `statusCode=${respInfo && respInfo.statusCode}`;
|
|
66
|
+
reject(new Error(errorMessage));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
resolve(respBody);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const results = [];
|
|
76
|
+
for (const plan of plans) {
|
|
77
|
+
try {
|
|
78
|
+
await refresh(plan);
|
|
79
|
+
if (!runtime.suppressOutput) {
|
|
80
|
+
printMessage(options, `[refreshed] ${plan.target}`);
|
|
81
|
+
}
|
|
82
|
+
results.push({
|
|
83
|
+
ok: true,
|
|
84
|
+
localFile: plan.localFile,
|
|
85
|
+
key: plan.key,
|
|
86
|
+
target: plan.target,
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
results.push({
|
|
90
|
+
ok: false,
|
|
91
|
+
localFile: plan.localFile,
|
|
92
|
+
key: plan.key,
|
|
93
|
+
target: plan.target,
|
|
94
|
+
error: error.message,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const summary = createSummary('refresh', false, results, startedAt, {
|
|
100
|
+
prefix,
|
|
101
|
+
excludedPatterns,
|
|
102
|
+
});
|
|
103
|
+
const finalSummary = runtime.suppressOutput ? summary : finalizeOutput(summary, options, runtime.manifestExtra);
|
|
104
|
+
if (finalSummary.failedCount > 0) {
|
|
105
|
+
throw new Error(`Refresh finished with ${summary.failedCount} failures`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return finalSummary;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = main
|