@zappinginc/zm2 6.0.14
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/.claude/settings.local.json +8 -0
- package/.gitattributes +4 -0
- package/.mocharc.js +14 -0
- package/CHANGELOG.md +2416 -0
- package/CLAUDE.md +84 -0
- package/CONTRIBUTING.md +124 -0
- package/GNU-AGPL-3.0.txt +665 -0
- package/LICENSE +1 -0
- package/README.md +248 -0
- package/bin/zm2 +3 -0
- package/bin/zm2-dev +3 -0
- package/bin/zm2-docker +3 -0
- package/bin/zm2-runtime +3 -0
- package/bin/zm2-windows +3 -0
- package/bin/zm2.ps1 +3 -0
- package/bun.lock +421 -0
- package/constants.js +114 -0
- package/index.js +13 -0
- package/lib/API/Configuration.js +212 -0
- package/lib/API/Containerizer.js +335 -0
- package/lib/API/Dashboard.js +459 -0
- package/lib/API/Deploy.js +117 -0
- package/lib/API/Extra.js +775 -0
- package/lib/API/ExtraMgmt/Docker.js +30 -0
- package/lib/API/Log.js +315 -0
- package/lib/API/LogManagement.js +371 -0
- package/lib/API/Modules/LOCAL.js +122 -0
- package/lib/API/Modules/Modularizer.js +148 -0
- package/lib/API/Modules/NPM.js +445 -0
- package/lib/API/Modules/TAR.js +362 -0
- package/lib/API/Modules/flagExt.js +46 -0
- package/lib/API/Modules/index.js +120 -0
- package/lib/API/Monit.js +247 -0
- package/lib/API/Serve.js +343 -0
- package/lib/API/Startup.js +629 -0
- package/lib/API/UX/helpers.js +213 -0
- package/lib/API/UX/index.js +9 -0
- package/lib/API/UX/pm2-describe.js +193 -0
- package/lib/API/UX/pm2-ls-minimal.js +31 -0
- package/lib/API/UX/pm2-ls.js +483 -0
- package/lib/API/Version.js +382 -0
- package/lib/API/interpreter.json +12 -0
- package/lib/API/pm2-plus/PM2IO.js +372 -0
- package/lib/API/pm2-plus/auth-strategies/CliAuth.js +288 -0
- package/lib/API/pm2-plus/auth-strategies/WebAuth.js +187 -0
- package/lib/API/pm2-plus/helpers.js +97 -0
- package/lib/API/pm2-plus/link.js +126 -0
- package/lib/API/pm2-plus/pres/motd +16 -0
- package/lib/API/pm2-plus/pres/motd.update +26 -0
- package/lib/API/pm2-plus/pres/welcome +28 -0
- package/lib/API/pm2-plus/process-selector.js +52 -0
- package/lib/API/schema.json +379 -0
- package/lib/API.js +1931 -0
- package/lib/Client.js +776 -0
- package/lib/Common.js +911 -0
- package/lib/Configuration.js +304 -0
- package/lib/Daemon.js +456 -0
- package/lib/Event.js +37 -0
- package/lib/God/ActionMethods.js +909 -0
- package/lib/God/ClusterMode.js +97 -0
- package/lib/God/ForkMode.js +297 -0
- package/lib/God/Methods.js +265 -0
- package/lib/God/Reload.js +240 -0
- package/lib/God.js +632 -0
- package/lib/HttpInterface.js +76 -0
- package/lib/ProcessContainer.js +305 -0
- package/lib/ProcessContainerBun.js +360 -0
- package/lib/ProcessContainerFork.js +42 -0
- package/lib/ProcessContainerForkBun.js +33 -0
- package/lib/ProcessUtils.js +55 -0
- package/lib/TreeKill.js +118 -0
- package/lib/Utility.js +430 -0
- package/lib/VersionCheck.js +46 -0
- package/lib/Watcher.js +117 -0
- package/lib/Worker.js +169 -0
- package/lib/binaries/CLI.js +1041 -0
- package/lib/binaries/DevCLI.js +183 -0
- package/lib/binaries/Runtime.js +101 -0
- package/lib/binaries/Runtime4Docker.js +192 -0
- package/lib/completion.js +229 -0
- package/lib/completion.sh +40 -0
- package/lib/motd +36 -0
- package/lib/templates/Dockerfiles/Dockerfile-java.tpl +7 -0
- package/lib/templates/Dockerfiles/Dockerfile-nodejs.tpl +8 -0
- package/lib/templates/Dockerfiles/Dockerfile-ruby.tpl +7 -0
- package/lib/templates/ecosystem-es.tpl +24 -0
- package/lib/templates/ecosystem-simple-es.tpl +8 -0
- package/lib/templates/ecosystem-simple.tpl +6 -0
- package/lib/templates/ecosystem.tpl +22 -0
- package/lib/templates/init-scripts/launchd.tpl +35 -0
- package/lib/templates/init-scripts/openrc.tpl +52 -0
- package/lib/templates/init-scripts/pm2-init-amazon.sh +86 -0
- package/lib/templates/init-scripts/rcd-openbsd.tpl +41 -0
- package/lib/templates/init-scripts/rcd.tpl +44 -0
- package/lib/templates/init-scripts/smf.tpl +43 -0
- package/lib/templates/init-scripts/systemd-online.tpl +22 -0
- package/lib/templates/init-scripts/systemd.tpl +22 -0
- package/lib/templates/init-scripts/upstart.tpl +103 -0
- package/lib/templates/logrotate.d/pm2 +10 -0
- package/lib/templates/sample-apps/http-server/README.md +14 -0
- package/lib/templates/sample-apps/http-server/api.js +9 -0
- package/lib/templates/sample-apps/http-server/ecosystem.config.js +14 -0
- package/lib/templates/sample-apps/http-server/package.json +11 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/README.md +45 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/custom-metrics.js +66 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/ecosystem.config.js +12 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/package.json +11 -0
- package/lib/templates/sample-apps/python-app/README.md +4 -0
- package/lib/templates/sample-apps/python-app/echo.py +7 -0
- package/lib/templates/sample-apps/python-app/ecosystem.config.js +12 -0
- package/lib/templates/sample-apps/python-app/package.json +11 -0
- package/lib/tools/Config.js +248 -0
- package/lib/tools/IsAbsolute.js +20 -0
- package/lib/tools/copydirSync.js +101 -0
- package/lib/tools/deleteFolderRecursive.js +19 -0
- package/lib/tools/find-package-json.js +74 -0
- package/lib/tools/fmt.js +72 -0
- package/lib/tools/isbinaryfile.js +94 -0
- package/lib/tools/json5.js +752 -0
- package/lib/tools/open.js +63 -0
- package/lib/tools/passwd.js +58 -0
- package/lib/tools/promise.min.js +1 -0
- package/lib/tools/sexec.js +55 -0
- package/lib/tools/treeify.js +113 -0
- package/lib/tools/which.js +120 -0
- package/lib/tools/xdg-open +861 -0
- package/package.json +219 -0
- package/paths.js +93 -0
- package/pm2 +11 -0
- package/preinstall.js +24 -0
- package/run.sh +9 -0
- package/types/index.d.ts +722 -0
- package/types/tsconfig.json +14 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "simple-http-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Simple HTTP server that can be used in cluster mode",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC"
|
|
11
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
# pm2 custom metrics boilerplate
|
|
3
|
+
|
|
4
|
+
In this boilerplate you will discover a working example of custom metrics feature.
|
|
5
|
+
|
|
6
|
+
Metrics covered are:
|
|
7
|
+
- io.metric
|
|
8
|
+
- io.counter
|
|
9
|
+
- io.meter
|
|
10
|
+
- io.histogram
|
|
11
|
+
|
|
12
|
+
## What is Custom Metrics?
|
|
13
|
+
|
|
14
|
+
Custom metrics is a powerfull way to get more visibility from a running application. It will allow you to monitor in realtime the current value of variables, know the number of actions being processed, measure latency and much more.
|
|
15
|
+
|
|
16
|
+
Once you have plugged in some custom metrics you will be able to monitor their value in realtime with
|
|
17
|
+
|
|
18
|
+
`pm2 monit`
|
|
19
|
+
|
|
20
|
+
Or
|
|
21
|
+
|
|
22
|
+
`pm2 describe`
|
|
23
|
+
|
|
24
|
+
Or on the PM2+ Web interface
|
|
25
|
+
|
|
26
|
+
`pm2 open`
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
const io = require('@pm2/io')
|
|
32
|
+
|
|
33
|
+
const currentReq = io.counter({
|
|
34
|
+
name: 'CM: Current Processing',
|
|
35
|
+
type: 'counter'
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
setInterval(() => {
|
|
39
|
+
currentReq.inc()
|
|
40
|
+
}, 1000)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Documentation
|
|
44
|
+
|
|
45
|
+
https://doc.pm2.io/en/plus/guide/custom-metrics/
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
const io = require('@pm2/io')
|
|
3
|
+
|
|
4
|
+
// Straight Metric
|
|
5
|
+
var user_count = 10
|
|
6
|
+
|
|
7
|
+
const users = io.metric({
|
|
8
|
+
name: 'CM: Realtime user',
|
|
9
|
+
value: () => {
|
|
10
|
+
return user_count
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
// or users.set(user_count)
|
|
15
|
+
|
|
16
|
+
// Counter (.inc() .dec())
|
|
17
|
+
const currentReq = io.counter({
|
|
18
|
+
name: 'CM: Current Processing',
|
|
19
|
+
type: 'counter'
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
setInterval(() => {
|
|
23
|
+
currentReq.inc()
|
|
24
|
+
}, 1000)
|
|
25
|
+
|
|
26
|
+
// Meter
|
|
27
|
+
const reqsec = io.meter({
|
|
28
|
+
name: 'CM: req/sec'
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
setInterval(() => {
|
|
32
|
+
reqsec.mark()
|
|
33
|
+
}, 100)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// Histogram
|
|
37
|
+
const latency = io.histogram({
|
|
38
|
+
name: 'CM: latency'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
var latencyValue = 0;
|
|
42
|
+
|
|
43
|
+
setInterval(() => {
|
|
44
|
+
latencyValue = Math.round(Math.random() * 100);
|
|
45
|
+
latency.update(latencyValue);
|
|
46
|
+
}, 100)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
////////////////////
|
|
50
|
+
// Custom Actions //
|
|
51
|
+
////////////////////
|
|
52
|
+
|
|
53
|
+
io.action('add user', (done) => {
|
|
54
|
+
user_count++
|
|
55
|
+
done({success:true})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
io.action('remove user', (done) => {
|
|
59
|
+
user_count++
|
|
60
|
+
done({success:true})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
io.action('with params', (arg, done) => {
|
|
64
|
+
console.log(arg)
|
|
65
|
+
done({success:arg})
|
|
66
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pm2-plus-custom-metrics",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Example that shows how to use pm2+ custom metrics",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC"
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "python-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Example on how to manage a Python application with PM2",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC"
|
|
11
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-2022 the PM2 project authors. All rights reserved.
|
|
3
|
+
* Use of this source code is governed by a license that
|
|
4
|
+
* can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
var util = require('util');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validator of configured file / commander options.
|
|
10
|
+
*/
|
|
11
|
+
var Config = module.exports = {
|
|
12
|
+
_errMsgs: {
|
|
13
|
+
'require': '"%s" is required',
|
|
14
|
+
'type' : 'Expect "%s" to be a typeof %s, but now is %s',
|
|
15
|
+
'regex' : 'Verify "%s" with regex failed, %s',
|
|
16
|
+
'max' : 'The maximum of "%s" is %s, but now is %s',
|
|
17
|
+
'min' : 'The minimum of "%s" is %s, but now is %s'
|
|
18
|
+
},
|
|
19
|
+
/**
|
|
20
|
+
* Schema definition.
|
|
21
|
+
* @returns {exports|*}
|
|
22
|
+
*/
|
|
23
|
+
get schema(){
|
|
24
|
+
// Cache.
|
|
25
|
+
if (this._schema) {
|
|
26
|
+
return this._schema;
|
|
27
|
+
}
|
|
28
|
+
// Render aliases.
|
|
29
|
+
this._schema = require('../API/schema');
|
|
30
|
+
for (var k in this._schema) {
|
|
31
|
+
if (k.indexOf('\\') > 0) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
var aliases = [
|
|
35
|
+
k.split('_').map(function(n, i){
|
|
36
|
+
if (i != 0 && n && n.length > 1) {
|
|
37
|
+
return n[0].toUpperCase() + n.slice(1);
|
|
38
|
+
}
|
|
39
|
+
return n;
|
|
40
|
+
}).join('')
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
if (this._schema[k].alias && Array.isArray(this._schema[k].alias)) {
|
|
44
|
+
// If multiple aliases, merge
|
|
45
|
+
this._schema[k].alias.forEach(function(alias) {
|
|
46
|
+
aliases.splice(0, 0, alias);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else if (this._schema[k].alias)
|
|
50
|
+
aliases.splice(0, 0, this._schema[k].alias);
|
|
51
|
+
|
|
52
|
+
this._schema[k].alias = aliases;
|
|
53
|
+
}
|
|
54
|
+
return this._schema;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Filter / Alias options
|
|
60
|
+
*/
|
|
61
|
+
Config.filterOptions = function(cmd) {
|
|
62
|
+
var conf = {};
|
|
63
|
+
var schema = this.schema;
|
|
64
|
+
|
|
65
|
+
for (var key in schema) {
|
|
66
|
+
var aliases = schema[key].alias;
|
|
67
|
+
aliases && aliases.forEach(function(alias){
|
|
68
|
+
if (typeof(cmd[alias]) !== 'undefined') {
|
|
69
|
+
conf[key] || (conf[key] = cmd[alias]);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return conf;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Verify JSON configurations.
|
|
79
|
+
* @param {Object} json
|
|
80
|
+
* @returns {{errors: Array, config: {}}}
|
|
81
|
+
*/
|
|
82
|
+
Config.validateJSON = function(json){
|
|
83
|
+
// clone config
|
|
84
|
+
var conf = Object.assign({}, json),
|
|
85
|
+
res = {};
|
|
86
|
+
this._errors = [];
|
|
87
|
+
|
|
88
|
+
var regexKeys = {}, defines = this.schema;
|
|
89
|
+
|
|
90
|
+
for (var sk in defines) {
|
|
91
|
+
// Pick up RegExp keys.
|
|
92
|
+
if (sk.indexOf('\\') >= 0) {
|
|
93
|
+
regexKeys[sk] = false;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var aliases = defines[sk].alias;
|
|
98
|
+
|
|
99
|
+
aliases && aliases.forEach(function(alias){
|
|
100
|
+
conf[sk] || (conf[sk] = json[alias]);
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
var val = conf[sk];
|
|
104
|
+
delete conf[sk];
|
|
105
|
+
|
|
106
|
+
// Validate key-value pairs.
|
|
107
|
+
if (val === undefined ||
|
|
108
|
+
val === null ||
|
|
109
|
+
((val = this._valid(sk, val)) === null)) {
|
|
110
|
+
|
|
111
|
+
// If value is not defined
|
|
112
|
+
// Set default value (via schema.json)
|
|
113
|
+
if (typeof(defines[sk].default) !== 'undefined')
|
|
114
|
+
res[sk] = defines[sk].default;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
//console.log(sk, val, val === null, val === undefined);
|
|
118
|
+
res[sk] = val;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Validate RegExp values.
|
|
122
|
+
var hasRegexKey = false;
|
|
123
|
+
for (var k in regexKeys) {
|
|
124
|
+
hasRegexKey = true;
|
|
125
|
+
regexKeys[k] = new RegExp(k);
|
|
126
|
+
}
|
|
127
|
+
if (hasRegexKey) {
|
|
128
|
+
for (var k in conf) {
|
|
129
|
+
for (var rk in regexKeys) {
|
|
130
|
+
if (regexKeys[rk].test(k))
|
|
131
|
+
if (this._valid(k, conf[k], defines[rk])) {
|
|
132
|
+
res[k] = conf[k];
|
|
133
|
+
delete conf[k];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {errors: this._errors, config: res};
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Validate key-value pairs by specific schema
|
|
144
|
+
* @param {String} key
|
|
145
|
+
* @param {Mixed} value
|
|
146
|
+
* @param {Object} sch
|
|
147
|
+
* @returns {*}
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
150
|
+
Config._valid = function(key, value, sch){
|
|
151
|
+
var sch = sch || this.schema[key],
|
|
152
|
+
scht = typeof sch.type == 'string' ? [sch.type] : sch.type;
|
|
153
|
+
|
|
154
|
+
// Required value.
|
|
155
|
+
var undef = typeof value == 'undefined';
|
|
156
|
+
if(this._error(sch.require && undef, 'require', key)){
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// If undefined, make a break.
|
|
161
|
+
if (undef) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Wrap schema types.
|
|
166
|
+
scht = scht.map(function(t){
|
|
167
|
+
return '[object ' + t[0].toUpperCase() + t.slice(1) + ']'
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Typeof value.
|
|
171
|
+
var type = Object.prototype.toString.call(value), nt = '[object Number]';
|
|
172
|
+
|
|
173
|
+
// Auto parse Number
|
|
174
|
+
if (type != '[object Boolean]' && scht.indexOf(nt) >= 0 && !isNaN(value)) {
|
|
175
|
+
value = parseFloat(value);
|
|
176
|
+
type = nt;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Verify types.
|
|
180
|
+
if (this._error(!~scht.indexOf(type), 'type', key, scht.join(' / '), type)) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Verify RegExp if exists.
|
|
185
|
+
if (this._error(type == '[object String]' && sch.regex && !(new RegExp(sch.regex)).test(value),
|
|
186
|
+
'regex', key, sch.desc || ('should match ' + sch.regex))) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Verify maximum / minimum of Number value.
|
|
191
|
+
if (type == '[object Number]') {
|
|
192
|
+
if (this._error(typeof sch.max != 'undefined' && value > sch.max, 'max', key, sch.max, value)) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
if (this._error(typeof sch.min != 'undefined' && value < sch.min, 'min', key, sch.min, value)) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// If first type is Array, but current is String, try to split them.
|
|
201
|
+
if(scht.length > 1 && type != scht[0] && type == '[object String]'){
|
|
202
|
+
if(scht[0] == '[object Array]') {
|
|
203
|
+
value = value.split(/([\w\-]+\="[^"]*")|([\w\-]+\='[^']*')|"([^"]*)"|'([^']*)'|\s/)
|
|
204
|
+
// unfortunately, js does not support lookahead RegExp (/(?<!\\)\s+/) now (until next ver).
|
|
205
|
+
//value = value.split(/((?<![\w\-])([\w\-]+\="[^"]*")|(?<![\w\-])([\w\-]+\='[^']*')|"([^"]*)"|'([^']*)'|\s )/)
|
|
206
|
+
.filter(function(v){
|
|
207
|
+
return v && v.trim();
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Custom types: sbyte && stime.
|
|
213
|
+
if(sch.ext_type && type == '[object String]' && value.length >= 2) {
|
|
214
|
+
var seed = {
|
|
215
|
+
'sbyte': {
|
|
216
|
+
'G': 1024 * 1024 * 1024,
|
|
217
|
+
'M': 1024 * 1024,
|
|
218
|
+
'K': 1024
|
|
219
|
+
},
|
|
220
|
+
'stime': {
|
|
221
|
+
'h': 60 * 60 * 1000,
|
|
222
|
+
'm': 60 * 1000,
|
|
223
|
+
's': 1000
|
|
224
|
+
}
|
|
225
|
+
}[sch.ext_type];
|
|
226
|
+
|
|
227
|
+
if(seed){
|
|
228
|
+
value = parseFloat(value.slice(0, -1)) * (seed[value.slice(-1)]);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return value;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Wrap errors.
|
|
236
|
+
* @param {Boolean} possible A value indicates whether it is an error or not.
|
|
237
|
+
* @param {String} type
|
|
238
|
+
* @returns {*}
|
|
239
|
+
* @private
|
|
240
|
+
*/
|
|
241
|
+
Config._error = function(possible, type){
|
|
242
|
+
if (possible) {
|
|
243
|
+
var args = Array.prototype.slice.call(arguments);
|
|
244
|
+
args.splice(0, 2, this._errMsgs[type]);
|
|
245
|
+
this._errors && this._errors.push(util.format.apply(null, args));
|
|
246
|
+
}
|
|
247
|
+
return possible;
|
|
248
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function posix(path) {
|
|
4
|
+
return path.charAt(0) === '/';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function win32(path) {
|
|
8
|
+
// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
|
|
9
|
+
var splitDeviceRe = /^([a-zA-Z]:|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)?([\\/])?([\s\S]*?)$/;
|
|
10
|
+
var result = splitDeviceRe.exec(path);
|
|
11
|
+
var device = result[1] || '';
|
|
12
|
+
var isUnc = Boolean(device && device.charAt(1) !== ':');
|
|
13
|
+
|
|
14
|
+
// UNC paths are always absolute
|
|
15
|
+
return Boolean(result[2] || isUnc);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = process.platform === 'win32' ? win32 : posix;
|
|
19
|
+
module.exports.posix = posix;
|
|
20
|
+
module.exports.win32 = win32;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
var fs = require('fs');
|
|
2
|
+
var path = require('path');
|
|
3
|
+
/*
|
|
4
|
+
options: {
|
|
5
|
+
utimes: false, // Boolean | Object, keep utimes if true
|
|
6
|
+
mode: false, // Boolean | Number, keep file mode if true
|
|
7
|
+
cover: true, // Boolean, cover if file exists
|
|
8
|
+
filter: true, // Boolean | Function, file filter
|
|
9
|
+
}
|
|
10
|
+
*/
|
|
11
|
+
function copydirSync(from, to, options) {
|
|
12
|
+
if (typeof options === 'function') {
|
|
13
|
+
options = {
|
|
14
|
+
filter: options
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if(typeof options === 'undefined') options = {};
|
|
18
|
+
if(typeof options.cover === 'undefined') {
|
|
19
|
+
options.cover = true;
|
|
20
|
+
}
|
|
21
|
+
options.filter = typeof options.filter === 'function' ? options.filter : function(state, filepath, filename) {
|
|
22
|
+
return options.filter;
|
|
23
|
+
};
|
|
24
|
+
var stats = fs.lstatSync(from);
|
|
25
|
+
var statsname = stats.isDirectory() ? 'directory' :
|
|
26
|
+
stats.isFile() ? 'file' :
|
|
27
|
+
stats.isSymbolicLink() ? 'symbolicLink' :
|
|
28
|
+
'';
|
|
29
|
+
var valid = options.filter(statsname, from, path.dirname(from), path.basename(from));
|
|
30
|
+
|
|
31
|
+
if (statsname === 'directory' || statsname === 'symbolicLink') {
|
|
32
|
+
// Directory or SymbolicLink
|
|
33
|
+
if(valid) {
|
|
34
|
+
try {
|
|
35
|
+
fs.statSync(to);
|
|
36
|
+
} catch(err) {
|
|
37
|
+
if(err.code === 'ENOENT') {
|
|
38
|
+
fs.mkdirSync(to, { recursive: true });
|
|
39
|
+
options.debug && console.log('>> ' + to);
|
|
40
|
+
} else {
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
rewriteSync(to, options, stats);
|
|
45
|
+
if (statsname != 'symbolicLink')
|
|
46
|
+
listDirectorySync(from, to, options);
|
|
47
|
+
}
|
|
48
|
+
} else if(stats.isFile()) {
|
|
49
|
+
// File
|
|
50
|
+
if(valid) {
|
|
51
|
+
if(options.cover) {
|
|
52
|
+
writeFileSync(from, to, options, stats);
|
|
53
|
+
} else {
|
|
54
|
+
try {
|
|
55
|
+
fs.statSync(to);
|
|
56
|
+
} catch(err) {
|
|
57
|
+
if(err.code === 'ENOENT') {
|
|
58
|
+
writeFileSync(from, to, options, stats);
|
|
59
|
+
} else {
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error('stats invalid: '+ from);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
function listDirectorySync(from, to, options) {
|
|
71
|
+
var files = fs.readdirSync(from);
|
|
72
|
+
copyFromArraySync(files, from, to, options);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function copyFromArraySync(files, from, to, options) {
|
|
76
|
+
if(files.length === 0) return true;
|
|
77
|
+
var f = files.shift();
|
|
78
|
+
copydirSync(path.join(from, f), path.join(to, f), options);
|
|
79
|
+
copyFromArraySync(files, from, to, options);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function writeFileSync(from, to, options, stats) {
|
|
83
|
+
fs.writeFileSync(to, fs.readFileSync(from, 'binary'), 'binary');
|
|
84
|
+
options.debug && console.log('>> ' + to);
|
|
85
|
+
rewriteSync(to, options, stats);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function rewriteSync(f, options, stats, callback) {
|
|
89
|
+
if(options.cover) {
|
|
90
|
+
var mode = options.mode === true ? stats.mode : options.mode;
|
|
91
|
+
var utimes = options.utimes === true ? {
|
|
92
|
+
atime: stats.atime,
|
|
93
|
+
mtime: stats.mtime
|
|
94
|
+
} : options.utimes;
|
|
95
|
+
mode && fs.chmodSync(f, mode);
|
|
96
|
+
utimes && fs.utimesSync(f, utimes.atime, utimes.mtime);
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = copydirSync;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const Path = require('path');
|
|
4
|
+
|
|
5
|
+
const deleteFolderRecursive = function(path) {
|
|
6
|
+
if (fs.existsSync(path)) {
|
|
7
|
+
fs.readdirSync(path).forEach((file, index) => {
|
|
8
|
+
const curPath = Path.join(path, file);
|
|
9
|
+
if (fs.lstatSync(curPath).isDirectory()) { // recurse
|
|
10
|
+
deleteFolderRecursive(curPath);
|
|
11
|
+
} else { // delete file
|
|
12
|
+
fs.unlinkSync(curPath);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
fs.rmdirSync(path);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports = deleteFolderRecursive
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path')
|
|
4
|
+
, fs = require('fs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Attempt to somewhat safely parse the JSON.
|
|
8
|
+
*
|
|
9
|
+
* @param {String} data JSON blob that needs to be parsed.
|
|
10
|
+
* @returns {Object|false} Parsed JSON or false.
|
|
11
|
+
* @api private
|
|
12
|
+
*/
|
|
13
|
+
function parse(data) {
|
|
14
|
+
data = data.toString('utf-8');
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Remove a possible UTF-8 BOM (byte order marker) as this can lead to parse
|
|
18
|
+
// values when passed in to the JSON.parse.
|
|
19
|
+
//
|
|
20
|
+
if (data.charCodeAt(0) === 0xFEFF) data = data.slice(1);
|
|
21
|
+
|
|
22
|
+
try { return JSON.parse(data); }
|
|
23
|
+
catch (e) { return false; }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Find package.json files.
|
|
28
|
+
*
|
|
29
|
+
* @param {String|Object} root The root directory we should start searching in.
|
|
30
|
+
* @returns {Object} Iterator interface.
|
|
31
|
+
* @api public
|
|
32
|
+
*/
|
|
33
|
+
module.exports = function find(root) {
|
|
34
|
+
root = root || process.cwd();
|
|
35
|
+
if (typeof root !== "string") {
|
|
36
|
+
if (typeof root === "object" && typeof root.filename === 'string') {
|
|
37
|
+
root = root.filename;
|
|
38
|
+
} else {
|
|
39
|
+
throw new Error("Must pass a filename string or a module object to finder");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
/**
|
|
44
|
+
* Return the parsed package.json that we find in a parent folder.
|
|
45
|
+
*
|
|
46
|
+
* @returns {Object} Value, filename and indication if the iteration is done.
|
|
47
|
+
* @api public
|
|
48
|
+
*/
|
|
49
|
+
next: function next() {
|
|
50
|
+
if (root.match(/^(\w:\\|\/)$/)) return {
|
|
51
|
+
value: undefined,
|
|
52
|
+
filename: undefined,
|
|
53
|
+
done: true
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
var file = path.join(root, 'package.json')
|
|
57
|
+
, data;
|
|
58
|
+
|
|
59
|
+
root = path.resolve(root, '..');
|
|
60
|
+
|
|
61
|
+
if (fs.existsSync(file) && (data = parse(fs.readFileSync(file)))) {
|
|
62
|
+
data.__path = file;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
value: data,
|
|
66
|
+
filename: file,
|
|
67
|
+
done: false
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return next();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
};
|