@sveltejs/kit 1.0.0-next.43 → 1.0.0-next.430
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/README.md +12 -9
- package/package.json +95 -63
- package/src/cli.js +112 -0
- package/src/core/adapt/builder.js +207 -0
- package/src/core/adapt/index.js +19 -0
- package/src/core/config/index.js +86 -0
- package/src/core/config/options.js +488 -0
- package/src/core/config/types.d.ts +1 -0
- package/src/core/constants.js +5 -0
- package/src/core/env.js +97 -0
- package/src/core/generate_manifest/index.js +99 -0
- package/src/core/prerender/crawl.js +194 -0
- package/src/core/prerender/prerender.js +378 -0
- package/src/core/prerender/queue.js +80 -0
- package/src/core/sync/create_manifest_data/index.js +506 -0
- package/src/core/sync/create_manifest_data/types.d.ts +40 -0
- package/src/core/sync/sync.js +59 -0
- package/src/core/sync/utils.js +44 -0
- package/src/core/sync/write_ambient.js +27 -0
- package/src/core/sync/write_client_manifest.js +82 -0
- package/src/core/sync/write_matchers.js +25 -0
- package/src/core/sync/write_root.js +91 -0
- package/src/core/sync/write_tsconfig.js +195 -0
- package/src/core/sync/write_types.js +775 -0
- package/src/core/utils.js +70 -0
- package/src/hooks.js +26 -0
- package/src/index/index.js +45 -0
- package/src/index/private.js +33 -0
- package/src/node/index.js +145 -0
- package/src/node/polyfills.js +40 -0
- package/src/runtime/app/env.js +11 -0
- package/src/runtime/app/navigation.js +22 -0
- package/src/runtime/app/paths.js +1 -0
- package/src/runtime/app/stores.js +102 -0
- package/src/runtime/client/ambient.d.ts +17 -0
- package/src/runtime/client/client.js +1289 -0
- package/src/runtime/client/fetcher.js +60 -0
- package/src/runtime/client/parse.js +36 -0
- package/src/runtime/client/singletons.js +21 -0
- package/src/runtime/client/start.js +46 -0
- package/src/runtime/client/types.d.ts +105 -0
- package/src/runtime/client/utils.js +113 -0
- package/src/runtime/components/error.svelte +16 -0
- package/{assets → src/runtime}/components/layout.svelte +0 -0
- package/src/runtime/env/dynamic/private.js +1 -0
- package/src/runtime/env/dynamic/public.js +1 -0
- package/src/runtime/env-private.js +7 -0
- package/src/runtime/env-public.js +7 -0
- package/src/runtime/env.js +6 -0
- package/src/runtime/hash.js +16 -0
- package/src/runtime/paths.js +11 -0
- package/src/runtime/server/endpoint.js +58 -0
- package/src/runtime/server/index.js +448 -0
- package/src/runtime/server/page/cookie.js +25 -0
- package/src/runtime/server/page/crypto.js +239 -0
- package/src/runtime/server/page/csp.js +249 -0
- package/src/runtime/server/page/fetch.js +266 -0
- package/src/runtime/server/page/index.js +416 -0
- package/src/runtime/server/page/load_data.js +135 -0
- package/src/runtime/server/page/render.js +362 -0
- package/src/runtime/server/page/respond_with_error.js +94 -0
- package/src/runtime/server/page/types.d.ts +44 -0
- package/src/runtime/server/utils.js +116 -0
- package/src/utils/error.js +22 -0
- package/src/utils/escape.js +104 -0
- package/src/utils/filesystem.js +108 -0
- package/src/utils/http.js +55 -0
- package/src/utils/misc.js +1 -0
- package/src/utils/routing.js +108 -0
- package/src/utils/url.js +97 -0
- package/src/vite/build/build_server.js +337 -0
- package/src/vite/build/build_service_worker.js +90 -0
- package/src/vite/build/utils.js +160 -0
- package/src/vite/dev/index.js +551 -0
- package/src/vite/index.js +574 -0
- package/src/vite/preview/index.js +186 -0
- package/src/vite/types.d.ts +3 -0
- package/src/vite/utils.js +345 -0
- package/svelte-kit.js +1 -1
- package/types/ambient.d.ts +357 -0
- package/types/index.d.ts +343 -0
- package/types/internal.d.ts +308 -0
- package/types/private.d.ts +209 -0
- package/CHANGELOG.md +0 -431
- package/assets/components/error.svelte +0 -13
- package/assets/runtime/app/env.js +0 -5
- package/assets/runtime/app/navigation.js +0 -41
- package/assets/runtime/app/paths.js +0 -1
- package/assets/runtime/app/stores.js +0 -93
- package/assets/runtime/chunks/utils.js +0 -19
- package/assets/runtime/internal/singletons.js +0 -23
- package/assets/runtime/internal/start.js +0 -770
- package/assets/runtime/paths.js +0 -12
- package/dist/.DS_Store +0 -0
- package/dist/chunks/index.js +0 -3521
- package/dist/chunks/index2.js +0 -587
- package/dist/chunks/index3.js +0 -246
- package/dist/chunks/index4.js +0 -538
- package/dist/chunks/index5.js +0 -761
- package/dist/chunks/index6.js +0 -322
- package/dist/chunks/standard.js +0 -99
- package/dist/chunks/utils.js +0 -83
- package/dist/cli.js +0 -546
- package/dist/ssr.js +0 -2581
package/dist/chunks/index.js
DELETED
|
@@ -1,3521 +0,0 @@
|
|
|
1
|
-
import http from 'http';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { parse, URLSearchParams } from 'url';
|
|
5
|
-
import require$$0, { EventEmitter } from 'events';
|
|
6
|
-
import CheapWatch from 'cheap-watch';
|
|
7
|
-
import util from 'util';
|
|
8
|
-
import os from 'os';
|
|
9
|
-
import https from 'https';
|
|
10
|
-
import require$$1 from 'child_process';
|
|
11
|
-
import require$$0$1 from 'domain';
|
|
12
|
-
import 'querystring';
|
|
13
|
-
import vm from 'vm';
|
|
14
|
-
import vite from 'vite';
|
|
15
|
-
import { c as create_manifest_data, a as create_app } from './index2.js';
|
|
16
|
-
import { r as rimraf, c as copy_assets } from './utils.js';
|
|
17
|
-
import { ssr } from '../ssr.js';
|
|
18
|
-
import { g as get_body } from './index3.js';
|
|
19
|
-
import svelte from '@svitejs/vite-plugin-svelte';
|
|
20
|
-
import './standard.js';
|
|
21
|
-
import '../cli.js';
|
|
22
|
-
import 'sade';
|
|
23
|
-
import 'crypto';
|
|
24
|
-
import 'zlib';
|
|
25
|
-
import 'stream';
|
|
26
|
-
|
|
27
|
-
function createCommonjsModule(fn) {
|
|
28
|
-
var module = { exports: {} };
|
|
29
|
-
return fn(module, module.exports), module.exports;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/*
|
|
33
|
-
The MIT License (MIT)
|
|
34
|
-
|
|
35
|
-
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
36
|
-
|
|
37
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
38
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
39
|
-
in the Software without restriction, including without limitation the rights
|
|
40
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
41
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
42
|
-
furnished to do so, subject to the following conditions:
|
|
43
|
-
|
|
44
|
-
The above copyright notice and this permission notice shall be included in
|
|
45
|
-
all copies or substantial portions of the Software.
|
|
46
|
-
|
|
47
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
48
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
49
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
50
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
51
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
52
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
53
|
-
THE SOFTWARE.
|
|
54
|
-
|
|
55
|
-
*/
|
|
56
|
-
|
|
57
|
-
var styles_1 = createCommonjsModule(function (module) {
|
|
58
|
-
var styles = {};
|
|
59
|
-
module['exports'] = styles;
|
|
60
|
-
|
|
61
|
-
var codes = {
|
|
62
|
-
reset: [0, 0],
|
|
63
|
-
|
|
64
|
-
bold: [1, 22],
|
|
65
|
-
dim: [2, 22],
|
|
66
|
-
italic: [3, 23],
|
|
67
|
-
underline: [4, 24],
|
|
68
|
-
inverse: [7, 27],
|
|
69
|
-
hidden: [8, 28],
|
|
70
|
-
strikethrough: [9, 29],
|
|
71
|
-
|
|
72
|
-
black: [30, 39],
|
|
73
|
-
red: [31, 39],
|
|
74
|
-
green: [32, 39],
|
|
75
|
-
yellow: [33, 39],
|
|
76
|
-
blue: [34, 39],
|
|
77
|
-
magenta: [35, 39],
|
|
78
|
-
cyan: [36, 39],
|
|
79
|
-
white: [37, 39],
|
|
80
|
-
gray: [90, 39],
|
|
81
|
-
grey: [90, 39],
|
|
82
|
-
|
|
83
|
-
brightRed: [91, 39],
|
|
84
|
-
brightGreen: [92, 39],
|
|
85
|
-
brightYellow: [93, 39],
|
|
86
|
-
brightBlue: [94, 39],
|
|
87
|
-
brightMagenta: [95, 39],
|
|
88
|
-
brightCyan: [96, 39],
|
|
89
|
-
brightWhite: [97, 39],
|
|
90
|
-
|
|
91
|
-
bgBlack: [40, 49],
|
|
92
|
-
bgRed: [41, 49],
|
|
93
|
-
bgGreen: [42, 49],
|
|
94
|
-
bgYellow: [43, 49],
|
|
95
|
-
bgBlue: [44, 49],
|
|
96
|
-
bgMagenta: [45, 49],
|
|
97
|
-
bgCyan: [46, 49],
|
|
98
|
-
bgWhite: [47, 49],
|
|
99
|
-
bgGray: [100, 49],
|
|
100
|
-
bgGrey: [100, 49],
|
|
101
|
-
|
|
102
|
-
bgBrightRed: [101, 49],
|
|
103
|
-
bgBrightGreen: [102, 49],
|
|
104
|
-
bgBrightYellow: [103, 49],
|
|
105
|
-
bgBrightBlue: [104, 49],
|
|
106
|
-
bgBrightMagenta: [105, 49],
|
|
107
|
-
bgBrightCyan: [106, 49],
|
|
108
|
-
bgBrightWhite: [107, 49],
|
|
109
|
-
|
|
110
|
-
// legacy styles for colors pre v1.0.0
|
|
111
|
-
blackBG: [40, 49],
|
|
112
|
-
redBG: [41, 49],
|
|
113
|
-
greenBG: [42, 49],
|
|
114
|
-
yellowBG: [43, 49],
|
|
115
|
-
blueBG: [44, 49],
|
|
116
|
-
magentaBG: [45, 49],
|
|
117
|
-
cyanBG: [46, 49],
|
|
118
|
-
whiteBG: [47, 49],
|
|
119
|
-
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
Object.keys(codes).forEach(function(key) {
|
|
123
|
-
var val = codes[key];
|
|
124
|
-
var style = styles[key] = [];
|
|
125
|
-
style.open = '\u001b[' + val[0] + 'm';
|
|
126
|
-
style.close = '\u001b[' + val[1] + 'm';
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
/*
|
|
131
|
-
MIT License
|
|
132
|
-
|
|
133
|
-
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
134
|
-
|
|
135
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
136
|
-
this software and associated documentation files (the "Software"), to deal in
|
|
137
|
-
the Software without restriction, including without limitation the rights to
|
|
138
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
139
|
-
of the Software, and to permit persons to whom the Software is furnished to do
|
|
140
|
-
so, subject to the following conditions:
|
|
141
|
-
|
|
142
|
-
The above copyright notice and this permission notice shall be included in all
|
|
143
|
-
copies or substantial portions of the Software.
|
|
144
|
-
|
|
145
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
146
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
147
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
148
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
149
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
150
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
151
|
-
SOFTWARE.
|
|
152
|
-
*/
|
|
153
|
-
|
|
154
|
-
var hasFlag = function(flag, argv) {
|
|
155
|
-
argv = argv || process.argv;
|
|
156
|
-
|
|
157
|
-
var terminatorPos = argv.indexOf('--');
|
|
158
|
-
var prefix = /^-{1,2}/.test(flag) ? '' : '--';
|
|
159
|
-
var pos = argv.indexOf(prefix + flag);
|
|
160
|
-
|
|
161
|
-
return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
/*
|
|
165
|
-
The MIT License (MIT)
|
|
166
|
-
|
|
167
|
-
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
168
|
-
|
|
169
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
170
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
171
|
-
in the Software without restriction, including without limitation the rights
|
|
172
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
173
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
174
|
-
furnished to do so, subject to the following conditions:
|
|
175
|
-
|
|
176
|
-
The above copyright notice and this permission notice shall be included in
|
|
177
|
-
all copies or substantial portions of the Software.
|
|
178
|
-
|
|
179
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
180
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
181
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
182
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
183
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
184
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
185
|
-
THE SOFTWARE.
|
|
186
|
-
|
|
187
|
-
*/
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
var env = process.env;
|
|
193
|
-
|
|
194
|
-
var forceColor = void 0;
|
|
195
|
-
if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false')) {
|
|
196
|
-
forceColor = false;
|
|
197
|
-
} else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true')
|
|
198
|
-
|| hasFlag('color=always')) {
|
|
199
|
-
forceColor = true;
|
|
200
|
-
}
|
|
201
|
-
if ('FORCE_COLOR' in env) {
|
|
202
|
-
forceColor = env.FORCE_COLOR.length === 0
|
|
203
|
-
|| parseInt(env.FORCE_COLOR, 10) !== 0;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function translateLevel(level) {
|
|
207
|
-
if (level === 0) {
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
level: level,
|
|
213
|
-
hasBasic: true,
|
|
214
|
-
has256: level >= 2,
|
|
215
|
-
has16m: level >= 3,
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function supportsColor(stream) {
|
|
220
|
-
if (forceColor === false) {
|
|
221
|
-
return 0;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (hasFlag('color=16m') || hasFlag('color=full')
|
|
225
|
-
|| hasFlag('color=truecolor')) {
|
|
226
|
-
return 3;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (hasFlag('color=256')) {
|
|
230
|
-
return 2;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (stream && !stream.isTTY && forceColor !== true) {
|
|
234
|
-
return 0;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
var min = forceColor ? 1 : 0;
|
|
238
|
-
|
|
239
|
-
if (process.platform === 'win32') {
|
|
240
|
-
// Node.js 7.5.0 is the first version of Node.js to include a patch to
|
|
241
|
-
// libuv that enables 256 color output on Windows. Anything earlier and it
|
|
242
|
-
// won't work. However, here we target Node.js 8 at minimum as it is an LTS
|
|
243
|
-
// release, and Node.js 7 is not. Windows 10 build 10586 is the first
|
|
244
|
-
// Windows release that supports 256 colors. Windows 10 build 14931 is the
|
|
245
|
-
// first release that supports 16m/TrueColor.
|
|
246
|
-
var osRelease = os.release().split('.');
|
|
247
|
-
if (Number(process.versions.node.split('.')[0]) >= 8
|
|
248
|
-
&& Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
249
|
-
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return 1;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if ('CI' in env) {
|
|
256
|
-
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(function(sign) {
|
|
257
|
-
return sign in env;
|
|
258
|
-
}) || env.CI_NAME === 'codeship') {
|
|
259
|
-
return 1;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return min;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if ('TEAMCITY_VERSION' in env) {
|
|
266
|
-
return (/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if ('TERM_PROGRAM' in env) {
|
|
271
|
-
var version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
272
|
-
|
|
273
|
-
switch (env.TERM_PROGRAM) {
|
|
274
|
-
case 'iTerm.app':
|
|
275
|
-
return version >= 3 ? 3 : 2;
|
|
276
|
-
case 'Hyper':
|
|
277
|
-
return 3;
|
|
278
|
-
case 'Apple_Terminal':
|
|
279
|
-
return 2;
|
|
280
|
-
// No default
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (/-256(color)?$/i.test(env.TERM)) {
|
|
285
|
-
return 2;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
289
|
-
return 1;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if ('COLORTERM' in env) {
|
|
293
|
-
return 1;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (env.TERM === 'dumb') {
|
|
297
|
-
return min;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return min;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function getSupportLevel(stream) {
|
|
304
|
-
var level = supportsColor(stream);
|
|
305
|
-
return translateLevel(level);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
var supportsColors = {
|
|
309
|
-
supportsColor: getSupportLevel,
|
|
310
|
-
stdout: getSupportLevel(process.stdout),
|
|
311
|
-
stderr: getSupportLevel(process.stderr),
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
var trap = createCommonjsModule(function (module) {
|
|
315
|
-
module['exports'] = function runTheTrap(text, options) {
|
|
316
|
-
var result = '';
|
|
317
|
-
text = text || 'Run the trap, drop the bass';
|
|
318
|
-
text = text.split('');
|
|
319
|
-
var trap = {
|
|
320
|
-
a: ['\u0040', '\u0104', '\u023a', '\u0245', '\u0394', '\u039b', '\u0414'],
|
|
321
|
-
b: ['\u00df', '\u0181', '\u0243', '\u026e', '\u03b2', '\u0e3f'],
|
|
322
|
-
c: ['\u00a9', '\u023b', '\u03fe'],
|
|
323
|
-
d: ['\u00d0', '\u018a', '\u0500', '\u0501', '\u0502', '\u0503'],
|
|
324
|
-
e: ['\u00cb', '\u0115', '\u018e', '\u0258', '\u03a3', '\u03be', '\u04bc',
|
|
325
|
-
'\u0a6c'],
|
|
326
|
-
f: ['\u04fa'],
|
|
327
|
-
g: ['\u0262'],
|
|
328
|
-
h: ['\u0126', '\u0195', '\u04a2', '\u04ba', '\u04c7', '\u050a'],
|
|
329
|
-
i: ['\u0f0f'],
|
|
330
|
-
j: ['\u0134'],
|
|
331
|
-
k: ['\u0138', '\u04a0', '\u04c3', '\u051e'],
|
|
332
|
-
l: ['\u0139'],
|
|
333
|
-
m: ['\u028d', '\u04cd', '\u04ce', '\u0520', '\u0521', '\u0d69'],
|
|
334
|
-
n: ['\u00d1', '\u014b', '\u019d', '\u0376', '\u03a0', '\u048a'],
|
|
335
|
-
o: ['\u00d8', '\u00f5', '\u00f8', '\u01fe', '\u0298', '\u047a', '\u05dd',
|
|
336
|
-
'\u06dd', '\u0e4f'],
|
|
337
|
-
p: ['\u01f7', '\u048e'],
|
|
338
|
-
q: ['\u09cd'],
|
|
339
|
-
r: ['\u00ae', '\u01a6', '\u0210', '\u024c', '\u0280', '\u042f'],
|
|
340
|
-
s: ['\u00a7', '\u03de', '\u03df', '\u03e8'],
|
|
341
|
-
t: ['\u0141', '\u0166', '\u0373'],
|
|
342
|
-
u: ['\u01b1', '\u054d'],
|
|
343
|
-
v: ['\u05d8'],
|
|
344
|
-
w: ['\u0428', '\u0460', '\u047c', '\u0d70'],
|
|
345
|
-
x: ['\u04b2', '\u04fe', '\u04fc', '\u04fd'],
|
|
346
|
-
y: ['\u00a5', '\u04b0', '\u04cb'],
|
|
347
|
-
z: ['\u01b5', '\u0240'],
|
|
348
|
-
};
|
|
349
|
-
text.forEach(function(c) {
|
|
350
|
-
c = c.toLowerCase();
|
|
351
|
-
var chars = trap[c] || [' '];
|
|
352
|
-
var rand = Math.floor(Math.random() * chars.length);
|
|
353
|
-
if (typeof trap[c] !== 'undefined') {
|
|
354
|
-
result += trap[c][rand];
|
|
355
|
-
} else {
|
|
356
|
-
result += c;
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
return result;
|
|
360
|
-
};
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
var zalgo = createCommonjsModule(function (module) {
|
|
364
|
-
// please no
|
|
365
|
-
module['exports'] = function zalgo(text, options) {
|
|
366
|
-
text = text || ' he is here ';
|
|
367
|
-
var soul = {
|
|
368
|
-
'up': [
|
|
369
|
-
'̍', '̎', '̄', '̅',
|
|
370
|
-
'̿', '̑', '̆', '̐',
|
|
371
|
-
'͒', '͗', '͑', '̇',
|
|
372
|
-
'̈', '̊', '͂', '̓',
|
|
373
|
-
'̈', '͊', '͋', '͌',
|
|
374
|
-
'̃', '̂', '̌', '͐',
|
|
375
|
-
'̀', '́', '̋', '̏',
|
|
376
|
-
'̒', '̓', '̔', '̽',
|
|
377
|
-
'̉', 'ͣ', 'ͤ', 'ͥ',
|
|
378
|
-
'ͦ', 'ͧ', 'ͨ', 'ͩ',
|
|
379
|
-
'ͪ', 'ͫ', 'ͬ', 'ͭ',
|
|
380
|
-
'ͮ', 'ͯ', '̾', '͛',
|
|
381
|
-
'͆', '̚',
|
|
382
|
-
],
|
|
383
|
-
'down': [
|
|
384
|
-
'̖', '̗', '̘', '̙',
|
|
385
|
-
'̜', '̝', '̞', '̟',
|
|
386
|
-
'̠', '̤', '̥', '̦',
|
|
387
|
-
'̩', '̪', '̫', '̬',
|
|
388
|
-
'̭', '̮', '̯', '̰',
|
|
389
|
-
'̱', '̲', '̳', '̹',
|
|
390
|
-
'̺', '̻', '̼', 'ͅ',
|
|
391
|
-
'͇', '͈', '͉', '͍',
|
|
392
|
-
'͎', '͓', '͔', '͕',
|
|
393
|
-
'͖', '͙', '͚', '̣',
|
|
394
|
-
],
|
|
395
|
-
'mid': [
|
|
396
|
-
'̕', '̛', '̀', '́',
|
|
397
|
-
'͘', '̡', '̢', '̧',
|
|
398
|
-
'̨', '̴', '̵', '̶',
|
|
399
|
-
'͜', '͝', '͞',
|
|
400
|
-
'͟', '͠', '͢', '̸',
|
|
401
|
-
'̷', '͡', ' ҉',
|
|
402
|
-
],
|
|
403
|
-
};
|
|
404
|
-
var all = [].concat(soul.up, soul.down, soul.mid);
|
|
405
|
-
|
|
406
|
-
function randomNumber(range) {
|
|
407
|
-
var r = Math.floor(Math.random() * range);
|
|
408
|
-
return r;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function isChar(character) {
|
|
412
|
-
var bool = false;
|
|
413
|
-
all.filter(function(i) {
|
|
414
|
-
bool = (i === character);
|
|
415
|
-
});
|
|
416
|
-
return bool;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
function heComes(text, options) {
|
|
421
|
-
var result = '';
|
|
422
|
-
var counts;
|
|
423
|
-
var l;
|
|
424
|
-
options = options || {};
|
|
425
|
-
options['up'] =
|
|
426
|
-
typeof options['up'] !== 'undefined' ? options['up'] : true;
|
|
427
|
-
options['mid'] =
|
|
428
|
-
typeof options['mid'] !== 'undefined' ? options['mid'] : true;
|
|
429
|
-
options['down'] =
|
|
430
|
-
typeof options['down'] !== 'undefined' ? options['down'] : true;
|
|
431
|
-
options['size'] =
|
|
432
|
-
typeof options['size'] !== 'undefined' ? options['size'] : 'maxi';
|
|
433
|
-
text = text.split('');
|
|
434
|
-
for (l in text) {
|
|
435
|
-
if (isChar(l)) {
|
|
436
|
-
continue;
|
|
437
|
-
}
|
|
438
|
-
result = result + text[l];
|
|
439
|
-
counts = {'up': 0, 'down': 0, 'mid': 0};
|
|
440
|
-
switch (options.size) {
|
|
441
|
-
case 'mini':
|
|
442
|
-
counts.up = randomNumber(8);
|
|
443
|
-
counts.mid = randomNumber(2);
|
|
444
|
-
counts.down = randomNumber(8);
|
|
445
|
-
break;
|
|
446
|
-
case 'maxi':
|
|
447
|
-
counts.up = randomNumber(16) + 3;
|
|
448
|
-
counts.mid = randomNumber(4) + 1;
|
|
449
|
-
counts.down = randomNumber(64) + 3;
|
|
450
|
-
break;
|
|
451
|
-
default:
|
|
452
|
-
counts.up = randomNumber(8) + 1;
|
|
453
|
-
counts.mid = randomNumber(6) / 2;
|
|
454
|
-
counts.down = randomNumber(8) + 1;
|
|
455
|
-
break;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
var arr = ['up', 'mid', 'down'];
|
|
459
|
-
for (var d in arr) {
|
|
460
|
-
var index = arr[d];
|
|
461
|
-
for (var i = 0; i <= counts[index]; i++) {
|
|
462
|
-
if (options[index]) {
|
|
463
|
-
result = result + soul[index][randomNumber(soul[index].length)];
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
return result;
|
|
469
|
-
}
|
|
470
|
-
// don't summon him
|
|
471
|
-
return heComes(text, options);
|
|
472
|
-
};
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
var america = createCommonjsModule(function (module) {
|
|
476
|
-
module['exports'] = function(colors) {
|
|
477
|
-
return function(letter, i, exploded) {
|
|
478
|
-
if (letter === ' ') return letter;
|
|
479
|
-
switch (i%3) {
|
|
480
|
-
case 0: return colors.red(letter);
|
|
481
|
-
case 1: return colors.white(letter);
|
|
482
|
-
case 2: return colors.blue(letter);
|
|
483
|
-
}
|
|
484
|
-
};
|
|
485
|
-
};
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
var zebra = createCommonjsModule(function (module) {
|
|
489
|
-
module['exports'] = function(colors) {
|
|
490
|
-
return function(letter, i, exploded) {
|
|
491
|
-
return i % 2 === 0 ? letter : colors.inverse(letter);
|
|
492
|
-
};
|
|
493
|
-
};
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
var rainbow = createCommonjsModule(function (module) {
|
|
497
|
-
module['exports'] = function(colors) {
|
|
498
|
-
// RoY G BiV
|
|
499
|
-
var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta'];
|
|
500
|
-
return function(letter, i, exploded) {
|
|
501
|
-
if (letter === ' ') {
|
|
502
|
-
return letter;
|
|
503
|
-
} else {
|
|
504
|
-
return colors[rainbowColors[i++ % rainbowColors.length]](letter);
|
|
505
|
-
}
|
|
506
|
-
};
|
|
507
|
-
};
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
var random = createCommonjsModule(function (module) {
|
|
511
|
-
module['exports'] = function(colors) {
|
|
512
|
-
var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green',
|
|
513
|
-
'blue', 'white', 'cyan', 'magenta', 'brightYellow', 'brightRed',
|
|
514
|
-
'brightGreen', 'brightBlue', 'brightWhite', 'brightCyan', 'brightMagenta'];
|
|
515
|
-
return function(letter, i, exploded) {
|
|
516
|
-
return letter === ' ' ? letter :
|
|
517
|
-
colors[
|
|
518
|
-
available[Math.round(Math.random() * (available.length - 2))]
|
|
519
|
-
](letter);
|
|
520
|
-
};
|
|
521
|
-
};
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
/*
|
|
525
|
-
|
|
526
|
-
The MIT License (MIT)
|
|
527
|
-
|
|
528
|
-
Original Library
|
|
529
|
-
- Copyright (c) Marak Squires
|
|
530
|
-
|
|
531
|
-
Additional functionality
|
|
532
|
-
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
533
|
-
|
|
534
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
535
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
536
|
-
in the Software without restriction, including without limitation the rights
|
|
537
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
538
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
539
|
-
furnished to do so, subject to the following conditions:
|
|
540
|
-
|
|
541
|
-
The above copyright notice and this permission notice shall be included in
|
|
542
|
-
all copies or substantial portions of the Software.
|
|
543
|
-
|
|
544
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
545
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
546
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
547
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
548
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
549
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
550
|
-
THE SOFTWARE.
|
|
551
|
-
|
|
552
|
-
*/
|
|
553
|
-
|
|
554
|
-
var colors_1 = createCommonjsModule(function (module) {
|
|
555
|
-
var colors = {};
|
|
556
|
-
module['exports'] = colors;
|
|
557
|
-
|
|
558
|
-
colors.themes = {};
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
var ansiStyles = colors.styles = styles_1;
|
|
562
|
-
var defineProps = Object.defineProperties;
|
|
563
|
-
var newLineRegex = new RegExp(/[\r\n]+/g);
|
|
564
|
-
|
|
565
|
-
colors.supportsColor = supportsColors.supportsColor;
|
|
566
|
-
|
|
567
|
-
if (typeof colors.enabled === 'undefined') {
|
|
568
|
-
colors.enabled = colors.supportsColor() !== false;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
colors.enable = function() {
|
|
572
|
-
colors.enabled = true;
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
colors.disable = function() {
|
|
576
|
-
colors.enabled = false;
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
colors.stripColors = colors.strip = function(str) {
|
|
580
|
-
return ('' + str).replace(/\x1B\[\d+m/g, '');
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
// eslint-disable-next-line no-unused-vars
|
|
584
|
-
colors.stylize = function stylize(str, style) {
|
|
585
|
-
if (!colors.enabled) {
|
|
586
|
-
return str+'';
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
var styleMap = ansiStyles[style];
|
|
590
|
-
|
|
591
|
-
// Stylize should work for non-ANSI styles, too
|
|
592
|
-
if(!styleMap && style in colors){
|
|
593
|
-
// Style maps like trap operate as functions on strings;
|
|
594
|
-
// they don't have properties like open or close.
|
|
595
|
-
return colors[style](str);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return styleMap.open + str + styleMap.close;
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
|
|
602
|
-
var escapeStringRegexp = function(str) {
|
|
603
|
-
if (typeof str !== 'string') {
|
|
604
|
-
throw new TypeError('Expected a string');
|
|
605
|
-
}
|
|
606
|
-
return str.replace(matchOperatorsRe, '\\$&');
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
function build(_styles) {
|
|
610
|
-
var builder = function builder() {
|
|
611
|
-
return applyStyle.apply(builder, arguments);
|
|
612
|
-
};
|
|
613
|
-
builder._styles = _styles;
|
|
614
|
-
// __proto__ is used because we must return a function, but there is
|
|
615
|
-
// no way to create a function with a different prototype.
|
|
616
|
-
builder.__proto__ = proto;
|
|
617
|
-
return builder;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
var styles = (function() {
|
|
621
|
-
var ret = {};
|
|
622
|
-
ansiStyles.grey = ansiStyles.gray;
|
|
623
|
-
Object.keys(ansiStyles).forEach(function(key) {
|
|
624
|
-
ansiStyles[key].closeRe =
|
|
625
|
-
new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
|
|
626
|
-
ret[key] = {
|
|
627
|
-
get: function() {
|
|
628
|
-
return build(this._styles.concat(key));
|
|
629
|
-
},
|
|
630
|
-
};
|
|
631
|
-
});
|
|
632
|
-
return ret;
|
|
633
|
-
})();
|
|
634
|
-
|
|
635
|
-
var proto = defineProps(function colors() {}, styles);
|
|
636
|
-
|
|
637
|
-
function applyStyle() {
|
|
638
|
-
var args = Array.prototype.slice.call(arguments);
|
|
639
|
-
|
|
640
|
-
var str = args.map(function(arg) {
|
|
641
|
-
// Use weak equality check so we can colorize null/undefined in safe mode
|
|
642
|
-
if (arg != null && arg.constructor === String) {
|
|
643
|
-
return arg;
|
|
644
|
-
} else {
|
|
645
|
-
return util.inspect(arg);
|
|
646
|
-
}
|
|
647
|
-
}).join(' ');
|
|
648
|
-
|
|
649
|
-
if (!colors.enabled || !str) {
|
|
650
|
-
return str;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
var newLinesPresent = str.indexOf('\n') != -1;
|
|
654
|
-
|
|
655
|
-
var nestedStyles = this._styles;
|
|
656
|
-
|
|
657
|
-
var i = nestedStyles.length;
|
|
658
|
-
while (i--) {
|
|
659
|
-
var code = ansiStyles[nestedStyles[i]];
|
|
660
|
-
str = code.open + str.replace(code.closeRe, code.open) + code.close;
|
|
661
|
-
if (newLinesPresent) {
|
|
662
|
-
str = str.replace(newLineRegex, function(match) {
|
|
663
|
-
return code.close + match + code.open;
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
return str;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
colors.setTheme = function(theme) {
|
|
672
|
-
if (typeof theme === 'string') {
|
|
673
|
-
console.log('colors.setTheme now only accepts an object, not a string. ' +
|
|
674
|
-
'If you are trying to set a theme from a file, it is now your (the ' +
|
|
675
|
-
'caller\'s) responsibility to require the file. The old syntax ' +
|
|
676
|
-
'looked like colors.setTheme(__dirname + ' +
|
|
677
|
-
'\'/../themes/generic-logging.js\'); The new syntax looks like '+
|
|
678
|
-
'colors.setTheme(require(__dirname + ' +
|
|
679
|
-
'\'/../themes/generic-logging.js\'));');
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
for (var style in theme) {
|
|
683
|
-
(function(style) {
|
|
684
|
-
colors[style] = function(str) {
|
|
685
|
-
if (typeof theme[style] === 'object') {
|
|
686
|
-
var out = str;
|
|
687
|
-
for (var i in theme[style]) {
|
|
688
|
-
out = colors[theme[style][i]](out);
|
|
689
|
-
}
|
|
690
|
-
return out;
|
|
691
|
-
}
|
|
692
|
-
return colors[theme[style]](str);
|
|
693
|
-
};
|
|
694
|
-
})(style);
|
|
695
|
-
}
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
function init() {
|
|
699
|
-
var ret = {};
|
|
700
|
-
Object.keys(styles).forEach(function(name) {
|
|
701
|
-
ret[name] = {
|
|
702
|
-
get: function() {
|
|
703
|
-
return build([name]);
|
|
704
|
-
},
|
|
705
|
-
};
|
|
706
|
-
});
|
|
707
|
-
return ret;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
var sequencer = function sequencer(map, str) {
|
|
711
|
-
var exploded = str.split('');
|
|
712
|
-
exploded = exploded.map(map);
|
|
713
|
-
return exploded.join('');
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
// custom formatter methods
|
|
717
|
-
colors.trap = trap;
|
|
718
|
-
colors.zalgo = zalgo;
|
|
719
|
-
|
|
720
|
-
// maps
|
|
721
|
-
colors.maps = {};
|
|
722
|
-
colors.maps.america = america(colors);
|
|
723
|
-
colors.maps.zebra = zebra(colors);
|
|
724
|
-
colors.maps.rainbow = rainbow(colors);
|
|
725
|
-
colors.maps.random = random(colors);
|
|
726
|
-
|
|
727
|
-
for (var map in colors.maps) {
|
|
728
|
-
(function(map) {
|
|
729
|
-
colors[map] = function(str) {
|
|
730
|
-
return sequencer(colors.maps[map], str);
|
|
731
|
-
};
|
|
732
|
-
})(map);
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
defineProps(colors, init());
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
var safe = createCommonjsModule(function (module) {
|
|
739
|
-
//
|
|
740
|
-
// Remark: Requiring this file will use the "safe" colors API,
|
|
741
|
-
// which will not touch String.prototype.
|
|
742
|
-
//
|
|
743
|
-
// var colors = require('colors/safe');
|
|
744
|
-
// colors.red("foo")
|
|
745
|
-
//
|
|
746
|
-
//
|
|
747
|
-
|
|
748
|
-
module['exports'] = colors_1;
|
|
749
|
-
});
|
|
750
|
-
|
|
751
|
-
/**
|
|
752
|
-
* Module dependencies.
|
|
753
|
-
*/
|
|
754
|
-
|
|
755
|
-
var commander = createCommonjsModule(function (module, exports) {
|
|
756
|
-
var EventEmitter = require$$0.EventEmitter;
|
|
757
|
-
var spawn = require$$1.spawn;
|
|
758
|
-
|
|
759
|
-
var dirname = path.dirname;
|
|
760
|
-
var basename = path.basename;
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* Inherit `Command` from `EventEmitter.prototype`.
|
|
765
|
-
*/
|
|
766
|
-
|
|
767
|
-
util.inherits(Command, EventEmitter);
|
|
768
|
-
|
|
769
|
-
/**
|
|
770
|
-
* Expose the root command.
|
|
771
|
-
*/
|
|
772
|
-
|
|
773
|
-
exports = module.exports = new Command();
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
* Expose `Command`.
|
|
777
|
-
*/
|
|
778
|
-
|
|
779
|
-
exports.Command = Command;
|
|
780
|
-
|
|
781
|
-
/**
|
|
782
|
-
* Expose `Option`.
|
|
783
|
-
*/
|
|
784
|
-
|
|
785
|
-
exports.Option = Option;
|
|
786
|
-
|
|
787
|
-
/**
|
|
788
|
-
* Initialize a new `Option` with the given `flags` and `description`.
|
|
789
|
-
*
|
|
790
|
-
* @param {String} flags
|
|
791
|
-
* @param {String} description
|
|
792
|
-
* @api public
|
|
793
|
-
*/
|
|
794
|
-
|
|
795
|
-
function Option(flags, description) {
|
|
796
|
-
this.flags = flags;
|
|
797
|
-
this.required = ~flags.indexOf('<');
|
|
798
|
-
this.optional = ~flags.indexOf('[');
|
|
799
|
-
this.bool = !~flags.indexOf('-no-');
|
|
800
|
-
flags = flags.split(/[ ,|]+/);
|
|
801
|
-
if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();
|
|
802
|
-
this.long = flags.shift();
|
|
803
|
-
this.description = description || '';
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Return option name.
|
|
808
|
-
*
|
|
809
|
-
* @return {String}
|
|
810
|
-
* @api private
|
|
811
|
-
*/
|
|
812
|
-
|
|
813
|
-
Option.prototype.name = function() {
|
|
814
|
-
return this.long
|
|
815
|
-
.replace('--', '')
|
|
816
|
-
.replace('no-', '');
|
|
817
|
-
};
|
|
818
|
-
|
|
819
|
-
/**
|
|
820
|
-
* Return option name, in a camelcase format that can be used
|
|
821
|
-
* as a object attribute key.
|
|
822
|
-
*
|
|
823
|
-
* @return {String}
|
|
824
|
-
* @api private
|
|
825
|
-
*/
|
|
826
|
-
|
|
827
|
-
Option.prototype.attributeName = function() {
|
|
828
|
-
return camelcase(this.name());
|
|
829
|
-
};
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* Check if `arg` matches the short or long flag.
|
|
833
|
-
*
|
|
834
|
-
* @param {String} arg
|
|
835
|
-
* @return {Boolean}
|
|
836
|
-
* @api private
|
|
837
|
-
*/
|
|
838
|
-
|
|
839
|
-
Option.prototype.is = function(arg) {
|
|
840
|
-
return this.short === arg || this.long === arg;
|
|
841
|
-
};
|
|
842
|
-
|
|
843
|
-
/**
|
|
844
|
-
* Initialize a new `Command`.
|
|
845
|
-
*
|
|
846
|
-
* @param {String} name
|
|
847
|
-
* @api public
|
|
848
|
-
*/
|
|
849
|
-
|
|
850
|
-
function Command(name) {
|
|
851
|
-
this.commands = [];
|
|
852
|
-
this.options = [];
|
|
853
|
-
this._execs = {};
|
|
854
|
-
this._allowUnknownOption = false;
|
|
855
|
-
this._args = [];
|
|
856
|
-
this._name = name || '';
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
/**
|
|
860
|
-
* Add command `name`.
|
|
861
|
-
*
|
|
862
|
-
* The `.action()` callback is invoked when the
|
|
863
|
-
* command `name` is specified via __ARGV__,
|
|
864
|
-
* and the remaining arguments are applied to the
|
|
865
|
-
* function for access.
|
|
866
|
-
*
|
|
867
|
-
* When the `name` is "*" an un-matched command
|
|
868
|
-
* will be passed as the first arg, followed by
|
|
869
|
-
* the rest of __ARGV__ remaining.
|
|
870
|
-
*
|
|
871
|
-
* Examples:
|
|
872
|
-
*
|
|
873
|
-
* program
|
|
874
|
-
* .version('0.0.1')
|
|
875
|
-
* .option('-C, --chdir <path>', 'change the working directory')
|
|
876
|
-
* .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
|
|
877
|
-
* .option('-T, --no-tests', 'ignore test hook')
|
|
878
|
-
*
|
|
879
|
-
* program
|
|
880
|
-
* .command('setup')
|
|
881
|
-
* .description('run remote setup commands')
|
|
882
|
-
* .action(function() {
|
|
883
|
-
* console.log('setup');
|
|
884
|
-
* });
|
|
885
|
-
*
|
|
886
|
-
* program
|
|
887
|
-
* .command('exec <cmd>')
|
|
888
|
-
* .description('run the given remote command')
|
|
889
|
-
* .action(function(cmd) {
|
|
890
|
-
* console.log('exec "%s"', cmd);
|
|
891
|
-
* });
|
|
892
|
-
*
|
|
893
|
-
* program
|
|
894
|
-
* .command('teardown <dir> [otherDirs...]')
|
|
895
|
-
* .description('run teardown commands')
|
|
896
|
-
* .action(function(dir, otherDirs) {
|
|
897
|
-
* console.log('dir "%s"', dir);
|
|
898
|
-
* if (otherDirs) {
|
|
899
|
-
* otherDirs.forEach(function (oDir) {
|
|
900
|
-
* console.log('dir "%s"', oDir);
|
|
901
|
-
* });
|
|
902
|
-
* }
|
|
903
|
-
* });
|
|
904
|
-
*
|
|
905
|
-
* program
|
|
906
|
-
* .command('*')
|
|
907
|
-
* .description('deploy the given env')
|
|
908
|
-
* .action(function(env) {
|
|
909
|
-
* console.log('deploying "%s"', env);
|
|
910
|
-
* });
|
|
911
|
-
*
|
|
912
|
-
* program.parse(process.argv);
|
|
913
|
-
*
|
|
914
|
-
* @param {String} name
|
|
915
|
-
* @param {String} [desc] for git-style sub-commands
|
|
916
|
-
* @return {Command} the new command
|
|
917
|
-
* @api public
|
|
918
|
-
*/
|
|
919
|
-
|
|
920
|
-
Command.prototype.command = function(name, desc, opts) {
|
|
921
|
-
if (typeof desc === 'object' && desc !== null) {
|
|
922
|
-
opts = desc;
|
|
923
|
-
desc = null;
|
|
924
|
-
}
|
|
925
|
-
opts = opts || {};
|
|
926
|
-
var args = name.split(/ +/);
|
|
927
|
-
var cmd = new Command(args.shift());
|
|
928
|
-
|
|
929
|
-
if (desc) {
|
|
930
|
-
cmd.description(desc);
|
|
931
|
-
this.executables = true;
|
|
932
|
-
this._execs[cmd._name] = true;
|
|
933
|
-
if (opts.isDefault) this.defaultExecutable = cmd._name;
|
|
934
|
-
}
|
|
935
|
-
cmd._noHelp = !!opts.noHelp;
|
|
936
|
-
this.commands.push(cmd);
|
|
937
|
-
cmd.parseExpectedArgs(args);
|
|
938
|
-
cmd.parent = this;
|
|
939
|
-
|
|
940
|
-
if (desc) return this;
|
|
941
|
-
return cmd;
|
|
942
|
-
};
|
|
943
|
-
|
|
944
|
-
/**
|
|
945
|
-
* Define argument syntax for the top-level command.
|
|
946
|
-
*
|
|
947
|
-
* @api public
|
|
948
|
-
*/
|
|
949
|
-
|
|
950
|
-
Command.prototype.arguments = function(desc) {
|
|
951
|
-
return this.parseExpectedArgs(desc.split(/ +/));
|
|
952
|
-
};
|
|
953
|
-
|
|
954
|
-
/**
|
|
955
|
-
* Add an implicit `help [cmd]` subcommand
|
|
956
|
-
* which invokes `--help` for the given command.
|
|
957
|
-
*
|
|
958
|
-
* @api private
|
|
959
|
-
*/
|
|
960
|
-
|
|
961
|
-
Command.prototype.addImplicitHelpCommand = function() {
|
|
962
|
-
this.command('help [cmd]', 'display help for [cmd]');
|
|
963
|
-
};
|
|
964
|
-
|
|
965
|
-
/**
|
|
966
|
-
* Parse expected `args`.
|
|
967
|
-
*
|
|
968
|
-
* For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
|
|
969
|
-
*
|
|
970
|
-
* @param {Array} args
|
|
971
|
-
* @return {Command} for chaining
|
|
972
|
-
* @api public
|
|
973
|
-
*/
|
|
974
|
-
|
|
975
|
-
Command.prototype.parseExpectedArgs = function(args) {
|
|
976
|
-
if (!args.length) return;
|
|
977
|
-
var self = this;
|
|
978
|
-
args.forEach(function(arg) {
|
|
979
|
-
var argDetails = {
|
|
980
|
-
required: false,
|
|
981
|
-
name: '',
|
|
982
|
-
variadic: false
|
|
983
|
-
};
|
|
984
|
-
|
|
985
|
-
switch (arg[0]) {
|
|
986
|
-
case '<':
|
|
987
|
-
argDetails.required = true;
|
|
988
|
-
argDetails.name = arg.slice(1, -1);
|
|
989
|
-
break;
|
|
990
|
-
case '[':
|
|
991
|
-
argDetails.name = arg.slice(1, -1);
|
|
992
|
-
break;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
|
|
996
|
-
argDetails.variadic = true;
|
|
997
|
-
argDetails.name = argDetails.name.slice(0, -3);
|
|
998
|
-
}
|
|
999
|
-
if (argDetails.name) {
|
|
1000
|
-
self._args.push(argDetails);
|
|
1001
|
-
}
|
|
1002
|
-
});
|
|
1003
|
-
return this;
|
|
1004
|
-
};
|
|
1005
|
-
|
|
1006
|
-
/**
|
|
1007
|
-
* Register callback `fn` for the command.
|
|
1008
|
-
*
|
|
1009
|
-
* Examples:
|
|
1010
|
-
*
|
|
1011
|
-
* program
|
|
1012
|
-
* .command('help')
|
|
1013
|
-
* .description('display verbose help')
|
|
1014
|
-
* .action(function() {
|
|
1015
|
-
* // output help here
|
|
1016
|
-
* });
|
|
1017
|
-
*
|
|
1018
|
-
* @param {Function} fn
|
|
1019
|
-
* @return {Command} for chaining
|
|
1020
|
-
* @api public
|
|
1021
|
-
*/
|
|
1022
|
-
|
|
1023
|
-
Command.prototype.action = function(fn) {
|
|
1024
|
-
var self = this;
|
|
1025
|
-
var listener = function(args, unknown) {
|
|
1026
|
-
// Parse any so-far unknown options
|
|
1027
|
-
args = args || [];
|
|
1028
|
-
unknown = unknown || [];
|
|
1029
|
-
|
|
1030
|
-
var parsed = self.parseOptions(unknown);
|
|
1031
|
-
|
|
1032
|
-
// Output help if necessary
|
|
1033
|
-
outputHelpIfNecessary(self, parsed.unknown);
|
|
1034
|
-
|
|
1035
|
-
// If there are still any unknown options, then we simply
|
|
1036
|
-
// die, unless someone asked for help, in which case we give it
|
|
1037
|
-
// to them, and then we die.
|
|
1038
|
-
if (parsed.unknown.length > 0) {
|
|
1039
|
-
self.unknownOption(parsed.unknown[0]);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
// Leftover arguments need to be pushed back. Fixes issue #56
|
|
1043
|
-
if (parsed.args.length) args = parsed.args.concat(args);
|
|
1044
|
-
|
|
1045
|
-
self._args.forEach(function(arg, i) {
|
|
1046
|
-
if (arg.required && args[i] == null) {
|
|
1047
|
-
self.missingArgument(arg.name);
|
|
1048
|
-
} else if (arg.variadic) {
|
|
1049
|
-
if (i !== self._args.length - 1) {
|
|
1050
|
-
self.variadicArgNotLast(arg.name);
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
args[i] = args.splice(i);
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
|
|
1057
|
-
// Always append ourselves to the end of the arguments,
|
|
1058
|
-
// to make sure we match the number of arguments the user
|
|
1059
|
-
// expects
|
|
1060
|
-
if (self._args.length) {
|
|
1061
|
-
args[self._args.length] = self;
|
|
1062
|
-
} else {
|
|
1063
|
-
args.push(self);
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
fn.apply(self, args);
|
|
1067
|
-
};
|
|
1068
|
-
var parent = this.parent || this;
|
|
1069
|
-
var name = parent === this ? '*' : this._name;
|
|
1070
|
-
parent.on('command:' + name, listener);
|
|
1071
|
-
if (this._alias) parent.on('command:' + this._alias, listener);
|
|
1072
|
-
return this;
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
|
-
/**
|
|
1076
|
-
* Define option with `flags`, `description` and optional
|
|
1077
|
-
* coercion `fn`.
|
|
1078
|
-
*
|
|
1079
|
-
* The `flags` string should contain both the short and long flags,
|
|
1080
|
-
* separated by comma, a pipe or space. The following are all valid
|
|
1081
|
-
* all will output this way when `--help` is used.
|
|
1082
|
-
*
|
|
1083
|
-
* "-p, --pepper"
|
|
1084
|
-
* "-p|--pepper"
|
|
1085
|
-
* "-p --pepper"
|
|
1086
|
-
*
|
|
1087
|
-
* Examples:
|
|
1088
|
-
*
|
|
1089
|
-
* // simple boolean defaulting to false
|
|
1090
|
-
* program.option('-p, --pepper', 'add pepper');
|
|
1091
|
-
*
|
|
1092
|
-
* --pepper
|
|
1093
|
-
* program.pepper
|
|
1094
|
-
* // => Boolean
|
|
1095
|
-
*
|
|
1096
|
-
* // simple boolean defaulting to true
|
|
1097
|
-
* program.option('-C, --no-cheese', 'remove cheese');
|
|
1098
|
-
*
|
|
1099
|
-
* program.cheese
|
|
1100
|
-
* // => true
|
|
1101
|
-
*
|
|
1102
|
-
* --no-cheese
|
|
1103
|
-
* program.cheese
|
|
1104
|
-
* // => false
|
|
1105
|
-
*
|
|
1106
|
-
* // required argument
|
|
1107
|
-
* program.option('-C, --chdir <path>', 'change the working directory');
|
|
1108
|
-
*
|
|
1109
|
-
* --chdir /tmp
|
|
1110
|
-
* program.chdir
|
|
1111
|
-
* // => "/tmp"
|
|
1112
|
-
*
|
|
1113
|
-
* // optional argument
|
|
1114
|
-
* program.option('-c, --cheese [type]', 'add cheese [marble]');
|
|
1115
|
-
*
|
|
1116
|
-
* @param {String} flags
|
|
1117
|
-
* @param {String} description
|
|
1118
|
-
* @param {Function|*} [fn] or default
|
|
1119
|
-
* @param {*} [defaultValue]
|
|
1120
|
-
* @return {Command} for chaining
|
|
1121
|
-
* @api public
|
|
1122
|
-
*/
|
|
1123
|
-
|
|
1124
|
-
Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
1125
|
-
var self = this,
|
|
1126
|
-
option = new Option(flags, description),
|
|
1127
|
-
oname = option.name(),
|
|
1128
|
-
name = option.attributeName();
|
|
1129
|
-
|
|
1130
|
-
// default as 3rd arg
|
|
1131
|
-
if (typeof fn !== 'function') {
|
|
1132
|
-
if (fn instanceof RegExp) {
|
|
1133
|
-
var regex = fn;
|
|
1134
|
-
fn = function(val, def) {
|
|
1135
|
-
var m = regex.exec(val);
|
|
1136
|
-
return m ? m[0] : def;
|
|
1137
|
-
};
|
|
1138
|
-
} else {
|
|
1139
|
-
defaultValue = fn;
|
|
1140
|
-
fn = null;
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
// preassign default value only for --no-*, [optional], or <required>
|
|
1145
|
-
if (!option.bool || option.optional || option.required) {
|
|
1146
|
-
// when --no-* we make sure default is true
|
|
1147
|
-
if (!option.bool) defaultValue = true;
|
|
1148
|
-
// preassign only if we have a default
|
|
1149
|
-
if (defaultValue !== undefined) {
|
|
1150
|
-
self[name] = defaultValue;
|
|
1151
|
-
option.defaultValue = defaultValue;
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
// register the option
|
|
1156
|
-
this.options.push(option);
|
|
1157
|
-
|
|
1158
|
-
// when it's passed assign the value
|
|
1159
|
-
// and conditionally invoke the callback
|
|
1160
|
-
this.on('option:' + oname, function(val) {
|
|
1161
|
-
// coercion
|
|
1162
|
-
if (val !== null && fn) {
|
|
1163
|
-
val = fn(val, self[name] === undefined ? defaultValue : self[name]);
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
// unassigned or bool
|
|
1167
|
-
if (typeof self[name] === 'boolean' || typeof self[name] === 'undefined') {
|
|
1168
|
-
// if no value, bool true, and we have a default, then use it!
|
|
1169
|
-
if (val == null) {
|
|
1170
|
-
self[name] = option.bool
|
|
1171
|
-
? defaultValue || true
|
|
1172
|
-
: false;
|
|
1173
|
-
} else {
|
|
1174
|
-
self[name] = val;
|
|
1175
|
-
}
|
|
1176
|
-
} else if (val !== null) {
|
|
1177
|
-
// reassign
|
|
1178
|
-
self[name] = val;
|
|
1179
|
-
}
|
|
1180
|
-
});
|
|
1181
|
-
|
|
1182
|
-
return this;
|
|
1183
|
-
};
|
|
1184
|
-
|
|
1185
|
-
/**
|
|
1186
|
-
* Allow unknown options on the command line.
|
|
1187
|
-
*
|
|
1188
|
-
* @param {Boolean} arg if `true` or omitted, no error will be thrown
|
|
1189
|
-
* for unknown options.
|
|
1190
|
-
* @api public
|
|
1191
|
-
*/
|
|
1192
|
-
Command.prototype.allowUnknownOption = function(arg) {
|
|
1193
|
-
this._allowUnknownOption = arguments.length === 0 || arg;
|
|
1194
|
-
return this;
|
|
1195
|
-
};
|
|
1196
|
-
|
|
1197
|
-
/**
|
|
1198
|
-
* Parse `argv`, settings options and invoking commands when defined.
|
|
1199
|
-
*
|
|
1200
|
-
* @param {Array} argv
|
|
1201
|
-
* @return {Command} for chaining
|
|
1202
|
-
* @api public
|
|
1203
|
-
*/
|
|
1204
|
-
|
|
1205
|
-
Command.prototype.parse = function(argv) {
|
|
1206
|
-
// implicit help
|
|
1207
|
-
if (this.executables) this.addImplicitHelpCommand();
|
|
1208
|
-
|
|
1209
|
-
// store raw args
|
|
1210
|
-
this.rawArgs = argv;
|
|
1211
|
-
|
|
1212
|
-
// guess name
|
|
1213
|
-
this._name = this._name || basename(argv[1], '.js');
|
|
1214
|
-
|
|
1215
|
-
// github-style sub-commands with no sub-command
|
|
1216
|
-
if (this.executables && argv.length < 3 && !this.defaultExecutable) {
|
|
1217
|
-
// this user needs help
|
|
1218
|
-
argv.push('--help');
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
// process argv
|
|
1222
|
-
var parsed = this.parseOptions(this.normalize(argv.slice(2)));
|
|
1223
|
-
var args = this.args = parsed.args;
|
|
1224
|
-
|
|
1225
|
-
var result = this.parseArgs(this.args, parsed.unknown);
|
|
1226
|
-
|
|
1227
|
-
// executable sub-commands
|
|
1228
|
-
var name = result.args[0];
|
|
1229
|
-
|
|
1230
|
-
var aliasCommand = null;
|
|
1231
|
-
// check alias of sub commands
|
|
1232
|
-
if (name) {
|
|
1233
|
-
aliasCommand = this.commands.filter(function(command) {
|
|
1234
|
-
return command.alias() === name;
|
|
1235
|
-
})[0];
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
if (this._execs[name] && typeof this._execs[name] !== 'function') {
|
|
1239
|
-
return this.executeSubCommand(argv, args, parsed.unknown);
|
|
1240
|
-
} else if (aliasCommand) {
|
|
1241
|
-
// is alias of a subCommand
|
|
1242
|
-
args[0] = aliasCommand._name;
|
|
1243
|
-
return this.executeSubCommand(argv, args, parsed.unknown);
|
|
1244
|
-
} else if (this.defaultExecutable) {
|
|
1245
|
-
// use the default subcommand
|
|
1246
|
-
args.unshift(this.defaultExecutable);
|
|
1247
|
-
return this.executeSubCommand(argv, args, parsed.unknown);
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
return result;
|
|
1251
|
-
};
|
|
1252
|
-
|
|
1253
|
-
/**
|
|
1254
|
-
* Execute a sub-command executable.
|
|
1255
|
-
*
|
|
1256
|
-
* @param {Array} argv
|
|
1257
|
-
* @param {Array} args
|
|
1258
|
-
* @param {Array} unknown
|
|
1259
|
-
* @api private
|
|
1260
|
-
*/
|
|
1261
|
-
|
|
1262
|
-
Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
1263
|
-
args = args.concat(unknown);
|
|
1264
|
-
|
|
1265
|
-
if (!args.length) this.help();
|
|
1266
|
-
if (args[0] === 'help' && args.length === 1) this.help();
|
|
1267
|
-
|
|
1268
|
-
// <cmd> --help
|
|
1269
|
-
if (args[0] === 'help') {
|
|
1270
|
-
args[0] = args[1];
|
|
1271
|
-
args[1] = '--help';
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
// executable
|
|
1275
|
-
var f = argv[1];
|
|
1276
|
-
// name of the subcommand, link `pm-install`
|
|
1277
|
-
var bin = basename(f, '.js') + '-' + args[0];
|
|
1278
|
-
|
|
1279
|
-
// In case of globally installed, get the base dir where executable
|
|
1280
|
-
// subcommand file should be located at
|
|
1281
|
-
var baseDir,
|
|
1282
|
-
link = fs.lstatSync(f).isSymbolicLink() ? fs.readlinkSync(f) : f;
|
|
1283
|
-
|
|
1284
|
-
// when symbolink is relative path
|
|
1285
|
-
if (link !== f && link.charAt(0) !== '/') {
|
|
1286
|
-
link = path.join(dirname(f), link);
|
|
1287
|
-
}
|
|
1288
|
-
baseDir = dirname(link);
|
|
1289
|
-
|
|
1290
|
-
// prefer local `./<bin>` to bin in the $PATH
|
|
1291
|
-
var localBin = path.join(baseDir, bin);
|
|
1292
|
-
|
|
1293
|
-
// whether bin file is a js script with explicit `.js` extension
|
|
1294
|
-
var isExplicitJS = false;
|
|
1295
|
-
if (exists(localBin + '.js')) {
|
|
1296
|
-
bin = localBin + '.js';
|
|
1297
|
-
isExplicitJS = true;
|
|
1298
|
-
} else if (exists(localBin)) {
|
|
1299
|
-
bin = localBin;
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
args = args.slice(1);
|
|
1303
|
-
|
|
1304
|
-
var proc;
|
|
1305
|
-
if (process.platform !== 'win32') {
|
|
1306
|
-
if (isExplicitJS) {
|
|
1307
|
-
args.unshift(bin);
|
|
1308
|
-
// add executable arguments to spawn
|
|
1309
|
-
args = (process.execArgv || []).concat(args);
|
|
1310
|
-
|
|
1311
|
-
proc = spawn(process.argv[0], args, { stdio: 'inherit', customFds: [0, 1, 2] });
|
|
1312
|
-
} else {
|
|
1313
|
-
proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] });
|
|
1314
|
-
}
|
|
1315
|
-
} else {
|
|
1316
|
-
args.unshift(bin);
|
|
1317
|
-
proc = spawn(process.execPath, args, { stdio: 'inherit' });
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
var signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];
|
|
1321
|
-
signals.forEach(function(signal) {
|
|
1322
|
-
process.on(signal, function() {
|
|
1323
|
-
if (proc.killed === false && proc.exitCode === null) {
|
|
1324
|
-
proc.kill(signal);
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
});
|
|
1328
|
-
proc.on('close', process.exit.bind(process));
|
|
1329
|
-
proc.on('error', function(err) {
|
|
1330
|
-
if (err.code === 'ENOENT') {
|
|
1331
|
-
console.error('\n %s(1) does not exist, try --help\n', bin);
|
|
1332
|
-
} else if (err.code === 'EACCES') {
|
|
1333
|
-
console.error('\n %s(1) not executable. try chmod or run with root\n', bin);
|
|
1334
|
-
}
|
|
1335
|
-
process.exit(1);
|
|
1336
|
-
});
|
|
1337
|
-
|
|
1338
|
-
// Store the reference to the child process
|
|
1339
|
-
this.runningCommand = proc;
|
|
1340
|
-
};
|
|
1341
|
-
|
|
1342
|
-
/**
|
|
1343
|
-
* Normalize `args`, splitting joined short flags. For example
|
|
1344
|
-
* the arg "-abc" is equivalent to "-a -b -c".
|
|
1345
|
-
* This also normalizes equal sign and splits "--abc=def" into "--abc def".
|
|
1346
|
-
*
|
|
1347
|
-
* @param {Array} args
|
|
1348
|
-
* @return {Array}
|
|
1349
|
-
* @api private
|
|
1350
|
-
*/
|
|
1351
|
-
|
|
1352
|
-
Command.prototype.normalize = function(args) {
|
|
1353
|
-
var ret = [],
|
|
1354
|
-
arg,
|
|
1355
|
-
lastOpt,
|
|
1356
|
-
index;
|
|
1357
|
-
|
|
1358
|
-
for (var i = 0, len = args.length; i < len; ++i) {
|
|
1359
|
-
arg = args[i];
|
|
1360
|
-
if (i > 0) {
|
|
1361
|
-
lastOpt = this.optionFor(args[i - 1]);
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
if (arg === '--') {
|
|
1365
|
-
// Honor option terminator
|
|
1366
|
-
ret = ret.concat(args.slice(i));
|
|
1367
|
-
break;
|
|
1368
|
-
} else if (lastOpt && lastOpt.required) {
|
|
1369
|
-
ret.push(arg);
|
|
1370
|
-
} else if (arg.length > 1 && arg[0] === '-' && arg[1] !== '-') {
|
|
1371
|
-
arg.slice(1).split('').forEach(function(c) {
|
|
1372
|
-
ret.push('-' + c);
|
|
1373
|
-
});
|
|
1374
|
-
} else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) {
|
|
1375
|
-
ret.push(arg.slice(0, index), arg.slice(index + 1));
|
|
1376
|
-
} else {
|
|
1377
|
-
ret.push(arg);
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
return ret;
|
|
1382
|
-
};
|
|
1383
|
-
|
|
1384
|
-
/**
|
|
1385
|
-
* Parse command `args`.
|
|
1386
|
-
*
|
|
1387
|
-
* When listener(s) are available those
|
|
1388
|
-
* callbacks are invoked, otherwise the "*"
|
|
1389
|
-
* event is emitted and those actions are invoked.
|
|
1390
|
-
*
|
|
1391
|
-
* @param {Array} args
|
|
1392
|
-
* @return {Command} for chaining
|
|
1393
|
-
* @api private
|
|
1394
|
-
*/
|
|
1395
|
-
|
|
1396
|
-
Command.prototype.parseArgs = function(args, unknown) {
|
|
1397
|
-
var name;
|
|
1398
|
-
|
|
1399
|
-
if (args.length) {
|
|
1400
|
-
name = args[0];
|
|
1401
|
-
if (this.listeners('command:' + name).length) {
|
|
1402
|
-
this.emit('command:' + args.shift(), args, unknown);
|
|
1403
|
-
} else {
|
|
1404
|
-
this.emit('command:*', args);
|
|
1405
|
-
}
|
|
1406
|
-
} else {
|
|
1407
|
-
outputHelpIfNecessary(this, unknown);
|
|
1408
|
-
|
|
1409
|
-
// If there were no args and we have unknown options,
|
|
1410
|
-
// then they are extraneous and we need to error.
|
|
1411
|
-
if (unknown.length > 0) {
|
|
1412
|
-
this.unknownOption(unknown[0]);
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
return this;
|
|
1417
|
-
};
|
|
1418
|
-
|
|
1419
|
-
/**
|
|
1420
|
-
* Return an option matching `arg` if any.
|
|
1421
|
-
*
|
|
1422
|
-
* @param {String} arg
|
|
1423
|
-
* @return {Option}
|
|
1424
|
-
* @api private
|
|
1425
|
-
*/
|
|
1426
|
-
|
|
1427
|
-
Command.prototype.optionFor = function(arg) {
|
|
1428
|
-
for (var i = 0, len = this.options.length; i < len; ++i) {
|
|
1429
|
-
if (this.options[i].is(arg)) {
|
|
1430
|
-
return this.options[i];
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
};
|
|
1434
|
-
|
|
1435
|
-
/**
|
|
1436
|
-
* Parse options from `argv` returning `argv`
|
|
1437
|
-
* void of these options.
|
|
1438
|
-
*
|
|
1439
|
-
* @param {Array} argv
|
|
1440
|
-
* @return {Array}
|
|
1441
|
-
* @api public
|
|
1442
|
-
*/
|
|
1443
|
-
|
|
1444
|
-
Command.prototype.parseOptions = function(argv) {
|
|
1445
|
-
var args = [],
|
|
1446
|
-
len = argv.length,
|
|
1447
|
-
literal,
|
|
1448
|
-
option,
|
|
1449
|
-
arg;
|
|
1450
|
-
|
|
1451
|
-
var unknownOptions = [];
|
|
1452
|
-
|
|
1453
|
-
// parse options
|
|
1454
|
-
for (var i = 0; i < len; ++i) {
|
|
1455
|
-
arg = argv[i];
|
|
1456
|
-
|
|
1457
|
-
// literal args after --
|
|
1458
|
-
if (literal) {
|
|
1459
|
-
args.push(arg);
|
|
1460
|
-
continue;
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
if (arg === '--') {
|
|
1464
|
-
literal = true;
|
|
1465
|
-
continue;
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
// find matching Option
|
|
1469
|
-
option = this.optionFor(arg);
|
|
1470
|
-
|
|
1471
|
-
// option is defined
|
|
1472
|
-
if (option) {
|
|
1473
|
-
// requires arg
|
|
1474
|
-
if (option.required) {
|
|
1475
|
-
arg = argv[++i];
|
|
1476
|
-
if (arg == null) return this.optionMissingArgument(option);
|
|
1477
|
-
this.emit('option:' + option.name(), arg);
|
|
1478
|
-
// optional arg
|
|
1479
|
-
} else if (option.optional) {
|
|
1480
|
-
arg = argv[i + 1];
|
|
1481
|
-
if (arg == null || (arg[0] === '-' && arg !== '-')) {
|
|
1482
|
-
arg = null;
|
|
1483
|
-
} else {
|
|
1484
|
-
++i;
|
|
1485
|
-
}
|
|
1486
|
-
this.emit('option:' + option.name(), arg);
|
|
1487
|
-
// bool
|
|
1488
|
-
} else {
|
|
1489
|
-
this.emit('option:' + option.name());
|
|
1490
|
-
}
|
|
1491
|
-
continue;
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
// looks like an option
|
|
1495
|
-
if (arg.length > 1 && arg[0] === '-') {
|
|
1496
|
-
unknownOptions.push(arg);
|
|
1497
|
-
|
|
1498
|
-
// If the next argument looks like it might be
|
|
1499
|
-
// an argument for this option, we pass it on.
|
|
1500
|
-
// If it isn't, then it'll simply be ignored
|
|
1501
|
-
if ((i + 1) < argv.length && argv[i + 1][0] !== '-') {
|
|
1502
|
-
unknownOptions.push(argv[++i]);
|
|
1503
|
-
}
|
|
1504
|
-
continue;
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
// arg
|
|
1508
|
-
args.push(arg);
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
|
-
return { args: args, unknown: unknownOptions };
|
|
1512
|
-
};
|
|
1513
|
-
|
|
1514
|
-
/**
|
|
1515
|
-
* Return an object containing options as key-value pairs
|
|
1516
|
-
*
|
|
1517
|
-
* @return {Object}
|
|
1518
|
-
* @api public
|
|
1519
|
-
*/
|
|
1520
|
-
Command.prototype.opts = function() {
|
|
1521
|
-
var result = {},
|
|
1522
|
-
len = this.options.length;
|
|
1523
|
-
|
|
1524
|
-
for (var i = 0; i < len; i++) {
|
|
1525
|
-
var key = this.options[i].attributeName();
|
|
1526
|
-
result[key] = key === this._versionOptionName ? this._version : this[key];
|
|
1527
|
-
}
|
|
1528
|
-
return result;
|
|
1529
|
-
};
|
|
1530
|
-
|
|
1531
|
-
/**
|
|
1532
|
-
* Argument `name` is missing.
|
|
1533
|
-
*
|
|
1534
|
-
* @param {String} name
|
|
1535
|
-
* @api private
|
|
1536
|
-
*/
|
|
1537
|
-
|
|
1538
|
-
Command.prototype.missingArgument = function(name) {
|
|
1539
|
-
console.error();
|
|
1540
|
-
console.error(" error: missing required argument `%s'", name);
|
|
1541
|
-
console.error();
|
|
1542
|
-
process.exit(1);
|
|
1543
|
-
};
|
|
1544
|
-
|
|
1545
|
-
/**
|
|
1546
|
-
* `Option` is missing an argument, but received `flag` or nothing.
|
|
1547
|
-
*
|
|
1548
|
-
* @param {String} option
|
|
1549
|
-
* @param {String} flag
|
|
1550
|
-
* @api private
|
|
1551
|
-
*/
|
|
1552
|
-
|
|
1553
|
-
Command.prototype.optionMissingArgument = function(option, flag) {
|
|
1554
|
-
console.error();
|
|
1555
|
-
if (flag) {
|
|
1556
|
-
console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag);
|
|
1557
|
-
} else {
|
|
1558
|
-
console.error(" error: option `%s' argument missing", option.flags);
|
|
1559
|
-
}
|
|
1560
|
-
console.error();
|
|
1561
|
-
process.exit(1);
|
|
1562
|
-
};
|
|
1563
|
-
|
|
1564
|
-
/**
|
|
1565
|
-
* Unknown option `flag`.
|
|
1566
|
-
*
|
|
1567
|
-
* @param {String} flag
|
|
1568
|
-
* @api private
|
|
1569
|
-
*/
|
|
1570
|
-
|
|
1571
|
-
Command.prototype.unknownOption = function(flag) {
|
|
1572
|
-
if (this._allowUnknownOption) return;
|
|
1573
|
-
console.error();
|
|
1574
|
-
console.error(" error: unknown option `%s'", flag);
|
|
1575
|
-
console.error();
|
|
1576
|
-
process.exit(1);
|
|
1577
|
-
};
|
|
1578
|
-
|
|
1579
|
-
/**
|
|
1580
|
-
* Variadic argument with `name` is not the last argument as required.
|
|
1581
|
-
*
|
|
1582
|
-
* @param {String} name
|
|
1583
|
-
* @api private
|
|
1584
|
-
*/
|
|
1585
|
-
|
|
1586
|
-
Command.prototype.variadicArgNotLast = function(name) {
|
|
1587
|
-
console.error();
|
|
1588
|
-
console.error(" error: variadic arguments must be last `%s'", name);
|
|
1589
|
-
console.error();
|
|
1590
|
-
process.exit(1);
|
|
1591
|
-
};
|
|
1592
|
-
|
|
1593
|
-
/**
|
|
1594
|
-
* Set the program version to `str`.
|
|
1595
|
-
*
|
|
1596
|
-
* This method auto-registers the "-V, --version" flag
|
|
1597
|
-
* which will print the version number when passed.
|
|
1598
|
-
*
|
|
1599
|
-
* @param {String} str
|
|
1600
|
-
* @param {String} [flags]
|
|
1601
|
-
* @return {Command} for chaining
|
|
1602
|
-
* @api public
|
|
1603
|
-
*/
|
|
1604
|
-
|
|
1605
|
-
Command.prototype.version = function(str, flags) {
|
|
1606
|
-
if (arguments.length === 0) return this._version;
|
|
1607
|
-
this._version = str;
|
|
1608
|
-
flags = flags || '-V, --version';
|
|
1609
|
-
var versionOption = new Option(flags, 'output the version number');
|
|
1610
|
-
this._versionOptionName = versionOption.long.substr(2) || 'version';
|
|
1611
|
-
this.options.push(versionOption);
|
|
1612
|
-
this.on('option:' + this._versionOptionName, function() {
|
|
1613
|
-
process.stdout.write(str + '\n');
|
|
1614
|
-
process.exit(0);
|
|
1615
|
-
});
|
|
1616
|
-
return this;
|
|
1617
|
-
};
|
|
1618
|
-
|
|
1619
|
-
/**
|
|
1620
|
-
* Set the description to `str`.
|
|
1621
|
-
*
|
|
1622
|
-
* @param {String} str
|
|
1623
|
-
* @param {Object} argsDescription
|
|
1624
|
-
* @return {String|Command}
|
|
1625
|
-
* @api public
|
|
1626
|
-
*/
|
|
1627
|
-
|
|
1628
|
-
Command.prototype.description = function(str, argsDescription) {
|
|
1629
|
-
if (arguments.length === 0) return this._description;
|
|
1630
|
-
this._description = str;
|
|
1631
|
-
this._argsDescription = argsDescription;
|
|
1632
|
-
return this;
|
|
1633
|
-
};
|
|
1634
|
-
|
|
1635
|
-
/**
|
|
1636
|
-
* Set an alias for the command
|
|
1637
|
-
*
|
|
1638
|
-
* @param {String} alias
|
|
1639
|
-
* @return {String|Command}
|
|
1640
|
-
* @api public
|
|
1641
|
-
*/
|
|
1642
|
-
|
|
1643
|
-
Command.prototype.alias = function(alias) {
|
|
1644
|
-
var command = this;
|
|
1645
|
-
if (this.commands.length !== 0) {
|
|
1646
|
-
command = this.commands[this.commands.length - 1];
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
if (arguments.length === 0) return command._alias;
|
|
1650
|
-
|
|
1651
|
-
if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');
|
|
1652
|
-
|
|
1653
|
-
command._alias = alias;
|
|
1654
|
-
return this;
|
|
1655
|
-
};
|
|
1656
|
-
|
|
1657
|
-
/**
|
|
1658
|
-
* Set / get the command usage `str`.
|
|
1659
|
-
*
|
|
1660
|
-
* @param {String} str
|
|
1661
|
-
* @return {String|Command}
|
|
1662
|
-
* @api public
|
|
1663
|
-
*/
|
|
1664
|
-
|
|
1665
|
-
Command.prototype.usage = function(str) {
|
|
1666
|
-
var args = this._args.map(function(arg) {
|
|
1667
|
-
return humanReadableArgName(arg);
|
|
1668
|
-
});
|
|
1669
|
-
|
|
1670
|
-
var usage = '[options]' +
|
|
1671
|
-
(this.commands.length ? ' [command]' : '') +
|
|
1672
|
-
(this._args.length ? ' ' + args.join(' ') : '');
|
|
1673
|
-
|
|
1674
|
-
if (arguments.length === 0) return this._usage || usage;
|
|
1675
|
-
this._usage = str;
|
|
1676
|
-
|
|
1677
|
-
return this;
|
|
1678
|
-
};
|
|
1679
|
-
|
|
1680
|
-
/**
|
|
1681
|
-
* Get or set the name of the command
|
|
1682
|
-
*
|
|
1683
|
-
* @param {String} str
|
|
1684
|
-
* @return {String|Command}
|
|
1685
|
-
* @api public
|
|
1686
|
-
*/
|
|
1687
|
-
|
|
1688
|
-
Command.prototype.name = function(str) {
|
|
1689
|
-
if (arguments.length === 0) return this._name;
|
|
1690
|
-
this._name = str;
|
|
1691
|
-
return this;
|
|
1692
|
-
};
|
|
1693
|
-
|
|
1694
|
-
/**
|
|
1695
|
-
* Return prepared commands.
|
|
1696
|
-
*
|
|
1697
|
-
* @return {Array}
|
|
1698
|
-
* @api private
|
|
1699
|
-
*/
|
|
1700
|
-
|
|
1701
|
-
Command.prototype.prepareCommands = function() {
|
|
1702
|
-
return this.commands.filter(function(cmd) {
|
|
1703
|
-
return !cmd._noHelp;
|
|
1704
|
-
}).map(function(cmd) {
|
|
1705
|
-
var args = cmd._args.map(function(arg) {
|
|
1706
|
-
return humanReadableArgName(arg);
|
|
1707
|
-
}).join(' ');
|
|
1708
|
-
|
|
1709
|
-
return [
|
|
1710
|
-
cmd._name +
|
|
1711
|
-
(cmd._alias ? '|' + cmd._alias : '') +
|
|
1712
|
-
(cmd.options.length ? ' [options]' : '') +
|
|
1713
|
-
(args ? ' ' + args : ''),
|
|
1714
|
-
cmd._description
|
|
1715
|
-
];
|
|
1716
|
-
});
|
|
1717
|
-
};
|
|
1718
|
-
|
|
1719
|
-
/**
|
|
1720
|
-
* Return the largest command length.
|
|
1721
|
-
*
|
|
1722
|
-
* @return {Number}
|
|
1723
|
-
* @api private
|
|
1724
|
-
*/
|
|
1725
|
-
|
|
1726
|
-
Command.prototype.largestCommandLength = function() {
|
|
1727
|
-
var commands = this.prepareCommands();
|
|
1728
|
-
return commands.reduce(function(max, command) {
|
|
1729
|
-
return Math.max(max, command[0].length);
|
|
1730
|
-
}, 0);
|
|
1731
|
-
};
|
|
1732
|
-
|
|
1733
|
-
/**
|
|
1734
|
-
* Return the largest option length.
|
|
1735
|
-
*
|
|
1736
|
-
* @return {Number}
|
|
1737
|
-
* @api private
|
|
1738
|
-
*/
|
|
1739
|
-
|
|
1740
|
-
Command.prototype.largestOptionLength = function() {
|
|
1741
|
-
var options = [].slice.call(this.options);
|
|
1742
|
-
options.push({
|
|
1743
|
-
flags: '-h, --help'
|
|
1744
|
-
});
|
|
1745
|
-
return options.reduce(function(max, option) {
|
|
1746
|
-
return Math.max(max, option.flags.length);
|
|
1747
|
-
}, 0);
|
|
1748
|
-
};
|
|
1749
|
-
|
|
1750
|
-
/**
|
|
1751
|
-
* Return the largest arg length.
|
|
1752
|
-
*
|
|
1753
|
-
* @return {Number}
|
|
1754
|
-
* @api private
|
|
1755
|
-
*/
|
|
1756
|
-
|
|
1757
|
-
Command.prototype.largestArgLength = function() {
|
|
1758
|
-
return this._args.reduce(function(max, arg) {
|
|
1759
|
-
return Math.max(max, arg.name.length);
|
|
1760
|
-
}, 0);
|
|
1761
|
-
};
|
|
1762
|
-
|
|
1763
|
-
/**
|
|
1764
|
-
* Return the pad width.
|
|
1765
|
-
*
|
|
1766
|
-
* @return {Number}
|
|
1767
|
-
* @api private
|
|
1768
|
-
*/
|
|
1769
|
-
|
|
1770
|
-
Command.prototype.padWidth = function() {
|
|
1771
|
-
var width = this.largestOptionLength();
|
|
1772
|
-
if (this._argsDescription && this._args.length) {
|
|
1773
|
-
if (this.largestArgLength() > width) {
|
|
1774
|
-
width = this.largestArgLength();
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
if (this.commands && this.commands.length) {
|
|
1779
|
-
if (this.largestCommandLength() > width) {
|
|
1780
|
-
width = this.largestCommandLength();
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
|
-
return width;
|
|
1785
|
-
};
|
|
1786
|
-
|
|
1787
|
-
/**
|
|
1788
|
-
* Return help for options.
|
|
1789
|
-
*
|
|
1790
|
-
* @return {String}
|
|
1791
|
-
* @api private
|
|
1792
|
-
*/
|
|
1793
|
-
|
|
1794
|
-
Command.prototype.optionHelp = function() {
|
|
1795
|
-
var width = this.padWidth();
|
|
1796
|
-
|
|
1797
|
-
// Append the help information
|
|
1798
|
-
return this.options.map(function(option) {
|
|
1799
|
-
return pad(option.flags, width) + ' ' + option.description +
|
|
1800
|
-
((option.bool && option.defaultValue !== undefined) ? ' (default: ' + option.defaultValue + ')' : '');
|
|
1801
|
-
}).concat([pad('-h, --help', width) + ' ' + 'output usage information'])
|
|
1802
|
-
.join('\n');
|
|
1803
|
-
};
|
|
1804
|
-
|
|
1805
|
-
/**
|
|
1806
|
-
* Return command help documentation.
|
|
1807
|
-
*
|
|
1808
|
-
* @return {String}
|
|
1809
|
-
* @api private
|
|
1810
|
-
*/
|
|
1811
|
-
|
|
1812
|
-
Command.prototype.commandHelp = function() {
|
|
1813
|
-
if (!this.commands.length) return '';
|
|
1814
|
-
|
|
1815
|
-
var commands = this.prepareCommands();
|
|
1816
|
-
var width = this.padWidth();
|
|
1817
|
-
|
|
1818
|
-
return [
|
|
1819
|
-
' Commands:',
|
|
1820
|
-
'',
|
|
1821
|
-
commands.map(function(cmd) {
|
|
1822
|
-
var desc = cmd[1] ? ' ' + cmd[1] : '';
|
|
1823
|
-
return (desc ? pad(cmd[0], width) : cmd[0]) + desc;
|
|
1824
|
-
}).join('\n').replace(/^/gm, ' '),
|
|
1825
|
-
''
|
|
1826
|
-
].join('\n');
|
|
1827
|
-
};
|
|
1828
|
-
|
|
1829
|
-
/**
|
|
1830
|
-
* Return program help documentation.
|
|
1831
|
-
*
|
|
1832
|
-
* @return {String}
|
|
1833
|
-
* @api private
|
|
1834
|
-
*/
|
|
1835
|
-
|
|
1836
|
-
Command.prototype.helpInformation = function() {
|
|
1837
|
-
var desc = [];
|
|
1838
|
-
if (this._description) {
|
|
1839
|
-
desc = [
|
|
1840
|
-
' ' + this._description,
|
|
1841
|
-
''
|
|
1842
|
-
];
|
|
1843
|
-
|
|
1844
|
-
var argsDescription = this._argsDescription;
|
|
1845
|
-
if (argsDescription && this._args.length) {
|
|
1846
|
-
var width = this.padWidth();
|
|
1847
|
-
desc.push(' Arguments:');
|
|
1848
|
-
desc.push('');
|
|
1849
|
-
this._args.forEach(function(arg) {
|
|
1850
|
-
desc.push(' ' + pad(arg.name, width) + ' ' + argsDescription[arg.name]);
|
|
1851
|
-
});
|
|
1852
|
-
desc.push('');
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
1855
|
-
|
|
1856
|
-
var cmdName = this._name;
|
|
1857
|
-
if (this._alias) {
|
|
1858
|
-
cmdName = cmdName + '|' + this._alias;
|
|
1859
|
-
}
|
|
1860
|
-
var usage = [
|
|
1861
|
-
'',
|
|
1862
|
-
' Usage: ' + cmdName + ' ' + this.usage(),
|
|
1863
|
-
''
|
|
1864
|
-
];
|
|
1865
|
-
|
|
1866
|
-
var cmds = [];
|
|
1867
|
-
var commandHelp = this.commandHelp();
|
|
1868
|
-
if (commandHelp) cmds = [commandHelp];
|
|
1869
|
-
|
|
1870
|
-
var options = [
|
|
1871
|
-
' Options:',
|
|
1872
|
-
'',
|
|
1873
|
-
'' + this.optionHelp().replace(/^/gm, ' '),
|
|
1874
|
-
''
|
|
1875
|
-
];
|
|
1876
|
-
|
|
1877
|
-
return usage
|
|
1878
|
-
.concat(desc)
|
|
1879
|
-
.concat(options)
|
|
1880
|
-
.concat(cmds)
|
|
1881
|
-
.join('\n');
|
|
1882
|
-
};
|
|
1883
|
-
|
|
1884
|
-
/**
|
|
1885
|
-
* Output help information for this command
|
|
1886
|
-
*
|
|
1887
|
-
* @api public
|
|
1888
|
-
*/
|
|
1889
|
-
|
|
1890
|
-
Command.prototype.outputHelp = function(cb) {
|
|
1891
|
-
if (!cb) {
|
|
1892
|
-
cb = function(passthru) {
|
|
1893
|
-
return passthru;
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
process.stdout.write(cb(this.helpInformation()));
|
|
1897
|
-
this.emit('--help');
|
|
1898
|
-
};
|
|
1899
|
-
|
|
1900
|
-
/**
|
|
1901
|
-
* Output help information and exit.
|
|
1902
|
-
*
|
|
1903
|
-
* @api public
|
|
1904
|
-
*/
|
|
1905
|
-
|
|
1906
|
-
Command.prototype.help = function(cb) {
|
|
1907
|
-
this.outputHelp(cb);
|
|
1908
|
-
process.exit();
|
|
1909
|
-
};
|
|
1910
|
-
|
|
1911
|
-
/**
|
|
1912
|
-
* Camel-case the given `flag`
|
|
1913
|
-
*
|
|
1914
|
-
* @param {String} flag
|
|
1915
|
-
* @return {String}
|
|
1916
|
-
* @api private
|
|
1917
|
-
*/
|
|
1918
|
-
|
|
1919
|
-
function camelcase(flag) {
|
|
1920
|
-
return flag.split('-').reduce(function(str, word) {
|
|
1921
|
-
return str + word[0].toUpperCase() + word.slice(1);
|
|
1922
|
-
});
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
/**
|
|
1926
|
-
* Pad `str` to `width`.
|
|
1927
|
-
*
|
|
1928
|
-
* @param {String} str
|
|
1929
|
-
* @param {Number} width
|
|
1930
|
-
* @return {String}
|
|
1931
|
-
* @api private
|
|
1932
|
-
*/
|
|
1933
|
-
|
|
1934
|
-
function pad(str, width) {
|
|
1935
|
-
var len = Math.max(0, width - str.length);
|
|
1936
|
-
return str + Array(len + 1).join(' ');
|
|
1937
|
-
}
|
|
1938
|
-
|
|
1939
|
-
/**
|
|
1940
|
-
* Output help information if necessary
|
|
1941
|
-
*
|
|
1942
|
-
* @param {Command} command to output help for
|
|
1943
|
-
* @param {Array} array of options to search for -h or --help
|
|
1944
|
-
* @api private
|
|
1945
|
-
*/
|
|
1946
|
-
|
|
1947
|
-
function outputHelpIfNecessary(cmd, options) {
|
|
1948
|
-
options = options || [];
|
|
1949
|
-
for (var i = 0; i < options.length; i++) {
|
|
1950
|
-
if (options[i] === '--help' || options[i] === '-h') {
|
|
1951
|
-
cmd.outputHelp();
|
|
1952
|
-
process.exit(0);
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1956
|
-
|
|
1957
|
-
/**
|
|
1958
|
-
* Takes an argument an returns its human readable equivalent for help usage.
|
|
1959
|
-
*
|
|
1960
|
-
* @param {Object} arg
|
|
1961
|
-
* @return {String}
|
|
1962
|
-
* @api private
|
|
1963
|
-
*/
|
|
1964
|
-
|
|
1965
|
-
function humanReadableArgName(arg) {
|
|
1966
|
-
var nameOutput = arg.name + (arg.variadic === true ? '...' : '');
|
|
1967
|
-
|
|
1968
|
-
return arg.required
|
|
1969
|
-
? '<' + nameOutput + '>'
|
|
1970
|
-
: '[' + nameOutput + ']';
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
// for versions before node v0.8 when there weren't `fs.existsSync`
|
|
1974
|
-
function exists(file) {
|
|
1975
|
-
try {
|
|
1976
|
-
if (fs.statSync(file).isFile()) {
|
|
1977
|
-
return true;
|
|
1978
|
-
}
|
|
1979
|
-
} catch (e) {
|
|
1980
|
-
return false;
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1983
|
-
});
|
|
1984
|
-
|
|
1985
|
-
var domain; // The domain module is executed on demand
|
|
1986
|
-
var hasSetImmediate = typeof setImmediate === "function";
|
|
1987
|
-
|
|
1988
|
-
// Use the fastest means possible to execute a task in its own turn, with
|
|
1989
|
-
// priority over other events including network IO events in Node.js.
|
|
1990
|
-
//
|
|
1991
|
-
// An exception thrown by a task will permanently interrupt the processing of
|
|
1992
|
-
// subsequent tasks. The higher level `asap` function ensures that if an
|
|
1993
|
-
// exception is thrown by a task, that the task queue will continue flushing as
|
|
1994
|
-
// soon as possible, but if you use `rawAsap` directly, you are responsible to
|
|
1995
|
-
// either ensure that no exceptions are thrown from your task, or to manually
|
|
1996
|
-
// call `rawAsap.requestFlush` if an exception is thrown.
|
|
1997
|
-
var raw = rawAsap;
|
|
1998
|
-
function rawAsap(task) {
|
|
1999
|
-
if (!queue.length) {
|
|
2000
|
-
requestFlush();
|
|
2001
|
-
flushing = true;
|
|
2002
|
-
}
|
|
2003
|
-
// Avoids a function call
|
|
2004
|
-
queue[queue.length] = task;
|
|
2005
|
-
}
|
|
2006
|
-
|
|
2007
|
-
var queue = [];
|
|
2008
|
-
// Once a flush has been requested, no further calls to `requestFlush` are
|
|
2009
|
-
// necessary until the next `flush` completes.
|
|
2010
|
-
var flushing = false;
|
|
2011
|
-
// The position of the next task to execute in the task queue. This is
|
|
2012
|
-
// preserved between calls to `flush` so that it can be resumed if
|
|
2013
|
-
// a task throws an exception.
|
|
2014
|
-
var index = 0;
|
|
2015
|
-
// If a task schedules additional tasks recursively, the task queue can grow
|
|
2016
|
-
// unbounded. To prevent memory excaustion, the task queue will periodically
|
|
2017
|
-
// truncate already-completed tasks.
|
|
2018
|
-
var capacity = 1024;
|
|
2019
|
-
|
|
2020
|
-
// The flush function processes all tasks that have been scheduled with
|
|
2021
|
-
// `rawAsap` unless and until one of those tasks throws an exception.
|
|
2022
|
-
// If a task throws an exception, `flush` ensures that its state will remain
|
|
2023
|
-
// consistent and will resume where it left off when called again.
|
|
2024
|
-
// However, `flush` does not make any arrangements to be called again if an
|
|
2025
|
-
// exception is thrown.
|
|
2026
|
-
function flush() {
|
|
2027
|
-
while (index < queue.length) {
|
|
2028
|
-
var currentIndex = index;
|
|
2029
|
-
// Advance the index before calling the task. This ensures that we will
|
|
2030
|
-
// begin flushing on the next task the task throws an error.
|
|
2031
|
-
index = index + 1;
|
|
2032
|
-
queue[currentIndex].call();
|
|
2033
|
-
// Prevent leaking memory for long chains of recursive calls to `asap`.
|
|
2034
|
-
// If we call `asap` within tasks scheduled by `asap`, the queue will
|
|
2035
|
-
// grow, but to avoid an O(n) walk for every task we execute, we don't
|
|
2036
|
-
// shift tasks off the queue after they have been executed.
|
|
2037
|
-
// Instead, we periodically shift 1024 tasks off the queue.
|
|
2038
|
-
if (index > capacity) {
|
|
2039
|
-
// Manually shift all values starting at the index back to the
|
|
2040
|
-
// beginning of the queue.
|
|
2041
|
-
for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
|
|
2042
|
-
queue[scan] = queue[scan + index];
|
|
2043
|
-
}
|
|
2044
|
-
queue.length -= index;
|
|
2045
|
-
index = 0;
|
|
2046
|
-
}
|
|
2047
|
-
}
|
|
2048
|
-
queue.length = 0;
|
|
2049
|
-
index = 0;
|
|
2050
|
-
flushing = false;
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2053
|
-
rawAsap.requestFlush = requestFlush;
|
|
2054
|
-
function requestFlush() {
|
|
2055
|
-
// Ensure flushing is not bound to any domain.
|
|
2056
|
-
// It is not sufficient to exit the domain, because domains exist on a stack.
|
|
2057
|
-
// To execute code outside of any domain, the following dance is necessary.
|
|
2058
|
-
var parentDomain = process.domain;
|
|
2059
|
-
if (parentDomain) {
|
|
2060
|
-
if (!domain) {
|
|
2061
|
-
// Lazy execute the domain module.
|
|
2062
|
-
// Only employed if the user elects to use domains.
|
|
2063
|
-
domain = require$$0$1;
|
|
2064
|
-
}
|
|
2065
|
-
domain.active = process.domain = null;
|
|
2066
|
-
}
|
|
2067
|
-
|
|
2068
|
-
// `setImmediate` is slower that `process.nextTick`, but `process.nextTick`
|
|
2069
|
-
// cannot handle recursion.
|
|
2070
|
-
// `requestFlush` will only be called recursively from `asap.js`, to resume
|
|
2071
|
-
// flushing after an error is thrown into a domain.
|
|
2072
|
-
// Conveniently, `setImmediate` was introduced in the same version
|
|
2073
|
-
// `process.nextTick` started throwing recursion errors.
|
|
2074
|
-
if (flushing && hasSetImmediate) {
|
|
2075
|
-
setImmediate(flush);
|
|
2076
|
-
} else {
|
|
2077
|
-
process.nextTick(flush);
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
if (parentDomain) {
|
|
2081
|
-
domain.active = process.domain = parentDomain;
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
function noop() {}
|
|
2086
|
-
|
|
2087
|
-
// States:
|
|
2088
|
-
//
|
|
2089
|
-
// 0 - pending
|
|
2090
|
-
// 1 - fulfilled with _value
|
|
2091
|
-
// 2 - rejected with _value
|
|
2092
|
-
// 3 - adopted the state of another promise, _value
|
|
2093
|
-
//
|
|
2094
|
-
// once the state is no longer pending (0) it is immutable
|
|
2095
|
-
|
|
2096
|
-
// All `_` prefixed properties will be reduced to `_{random number}`
|
|
2097
|
-
// at build time to obfuscate them and discourage their use.
|
|
2098
|
-
// We don't use symbols or Object.defineProperty to fully hide them
|
|
2099
|
-
// because the performance isn't good enough.
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
// to avoid using try/catch inside critical functions, we
|
|
2103
|
-
// extract them to here.
|
|
2104
|
-
var LAST_ERROR = null;
|
|
2105
|
-
var IS_ERROR = {};
|
|
2106
|
-
function getThen(obj) {
|
|
2107
|
-
try {
|
|
2108
|
-
return obj.then;
|
|
2109
|
-
} catch (ex) {
|
|
2110
|
-
LAST_ERROR = ex;
|
|
2111
|
-
return IS_ERROR;
|
|
2112
|
-
}
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
function tryCallOne(fn, a) {
|
|
2116
|
-
try {
|
|
2117
|
-
return fn(a);
|
|
2118
|
-
} catch (ex) {
|
|
2119
|
-
LAST_ERROR = ex;
|
|
2120
|
-
return IS_ERROR;
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
function tryCallTwo(fn, a, b) {
|
|
2124
|
-
try {
|
|
2125
|
-
fn(a, b);
|
|
2126
|
-
} catch (ex) {
|
|
2127
|
-
LAST_ERROR = ex;
|
|
2128
|
-
return IS_ERROR;
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
|
-
var core = Promise$1;
|
|
2133
|
-
|
|
2134
|
-
function Promise$1(fn) {
|
|
2135
|
-
if (typeof this !== 'object') {
|
|
2136
|
-
throw new TypeError('Promises must be constructed via new');
|
|
2137
|
-
}
|
|
2138
|
-
if (typeof fn !== 'function') {
|
|
2139
|
-
throw new TypeError('Promise constructor\'s argument is not a function');
|
|
2140
|
-
}
|
|
2141
|
-
this._75 = 0;
|
|
2142
|
-
this._83 = 0;
|
|
2143
|
-
this._18 = null;
|
|
2144
|
-
this._38 = null;
|
|
2145
|
-
if (fn === noop) return;
|
|
2146
|
-
doResolve(fn, this);
|
|
2147
|
-
}
|
|
2148
|
-
Promise$1._47 = null;
|
|
2149
|
-
Promise$1._71 = null;
|
|
2150
|
-
Promise$1._44 = noop;
|
|
2151
|
-
|
|
2152
|
-
Promise$1.prototype.then = function(onFulfilled, onRejected) {
|
|
2153
|
-
if (this.constructor !== Promise$1) {
|
|
2154
|
-
return safeThen(this, onFulfilled, onRejected);
|
|
2155
|
-
}
|
|
2156
|
-
var res = new Promise$1(noop);
|
|
2157
|
-
handle(this, new Handler(onFulfilled, onRejected, res));
|
|
2158
|
-
return res;
|
|
2159
|
-
};
|
|
2160
|
-
|
|
2161
|
-
function safeThen(self, onFulfilled, onRejected) {
|
|
2162
|
-
return new self.constructor(function (resolve, reject) {
|
|
2163
|
-
var res = new Promise$1(noop);
|
|
2164
|
-
res.then(resolve, reject);
|
|
2165
|
-
handle(self, new Handler(onFulfilled, onRejected, res));
|
|
2166
|
-
});
|
|
2167
|
-
}
|
|
2168
|
-
function handle(self, deferred) {
|
|
2169
|
-
while (self._83 === 3) {
|
|
2170
|
-
self = self._18;
|
|
2171
|
-
}
|
|
2172
|
-
if (Promise$1._47) {
|
|
2173
|
-
Promise$1._47(self);
|
|
2174
|
-
}
|
|
2175
|
-
if (self._83 === 0) {
|
|
2176
|
-
if (self._75 === 0) {
|
|
2177
|
-
self._75 = 1;
|
|
2178
|
-
self._38 = deferred;
|
|
2179
|
-
return;
|
|
2180
|
-
}
|
|
2181
|
-
if (self._75 === 1) {
|
|
2182
|
-
self._75 = 2;
|
|
2183
|
-
self._38 = [self._38, deferred];
|
|
2184
|
-
return;
|
|
2185
|
-
}
|
|
2186
|
-
self._38.push(deferred);
|
|
2187
|
-
return;
|
|
2188
|
-
}
|
|
2189
|
-
handleResolved(self, deferred);
|
|
2190
|
-
}
|
|
2191
|
-
|
|
2192
|
-
function handleResolved(self, deferred) {
|
|
2193
|
-
raw(function() {
|
|
2194
|
-
var cb = self._83 === 1 ? deferred.onFulfilled : deferred.onRejected;
|
|
2195
|
-
if (cb === null) {
|
|
2196
|
-
if (self._83 === 1) {
|
|
2197
|
-
resolve(deferred.promise, self._18);
|
|
2198
|
-
} else {
|
|
2199
|
-
reject(deferred.promise, self._18);
|
|
2200
|
-
}
|
|
2201
|
-
return;
|
|
2202
|
-
}
|
|
2203
|
-
var ret = tryCallOne(cb, self._18);
|
|
2204
|
-
if (ret === IS_ERROR) {
|
|
2205
|
-
reject(deferred.promise, LAST_ERROR);
|
|
2206
|
-
} else {
|
|
2207
|
-
resolve(deferred.promise, ret);
|
|
2208
|
-
}
|
|
2209
|
-
});
|
|
2210
|
-
}
|
|
2211
|
-
function resolve(self, newValue) {
|
|
2212
|
-
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
|
|
2213
|
-
if (newValue === self) {
|
|
2214
|
-
return reject(
|
|
2215
|
-
self,
|
|
2216
|
-
new TypeError('A promise cannot be resolved with itself.')
|
|
2217
|
-
);
|
|
2218
|
-
}
|
|
2219
|
-
if (
|
|
2220
|
-
newValue &&
|
|
2221
|
-
(typeof newValue === 'object' || typeof newValue === 'function')
|
|
2222
|
-
) {
|
|
2223
|
-
var then = getThen(newValue);
|
|
2224
|
-
if (then === IS_ERROR) {
|
|
2225
|
-
return reject(self, LAST_ERROR);
|
|
2226
|
-
}
|
|
2227
|
-
if (
|
|
2228
|
-
then === self.then &&
|
|
2229
|
-
newValue instanceof Promise$1
|
|
2230
|
-
) {
|
|
2231
|
-
self._83 = 3;
|
|
2232
|
-
self._18 = newValue;
|
|
2233
|
-
finale(self);
|
|
2234
|
-
return;
|
|
2235
|
-
} else if (typeof then === 'function') {
|
|
2236
|
-
doResolve(then.bind(newValue), self);
|
|
2237
|
-
return;
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
self._83 = 1;
|
|
2241
|
-
self._18 = newValue;
|
|
2242
|
-
finale(self);
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
function reject(self, newValue) {
|
|
2246
|
-
self._83 = 2;
|
|
2247
|
-
self._18 = newValue;
|
|
2248
|
-
if (Promise$1._71) {
|
|
2249
|
-
Promise$1._71(self, newValue);
|
|
2250
|
-
}
|
|
2251
|
-
finale(self);
|
|
2252
|
-
}
|
|
2253
|
-
function finale(self) {
|
|
2254
|
-
if (self._75 === 1) {
|
|
2255
|
-
handle(self, self._38);
|
|
2256
|
-
self._38 = null;
|
|
2257
|
-
}
|
|
2258
|
-
if (self._75 === 2) {
|
|
2259
|
-
for (var i = 0; i < self._38.length; i++) {
|
|
2260
|
-
handle(self, self._38[i]);
|
|
2261
|
-
}
|
|
2262
|
-
self._38 = null;
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
|
|
2266
|
-
function Handler(onFulfilled, onRejected, promise){
|
|
2267
|
-
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
|
|
2268
|
-
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
|
|
2269
|
-
this.promise = promise;
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2272
|
-
/**
|
|
2273
|
-
* Take a potentially misbehaving resolver function and make sure
|
|
2274
|
-
* onFulfilled and onRejected are only called once.
|
|
2275
|
-
*
|
|
2276
|
-
* Makes no guarantees about asynchrony.
|
|
2277
|
-
*/
|
|
2278
|
-
function doResolve(fn, promise) {
|
|
2279
|
-
var done = false;
|
|
2280
|
-
var res = tryCallTwo(fn, function (value) {
|
|
2281
|
-
if (done) return;
|
|
2282
|
-
done = true;
|
|
2283
|
-
resolve(promise, value);
|
|
2284
|
-
}, function (reason) {
|
|
2285
|
-
if (done) return;
|
|
2286
|
-
done = true;
|
|
2287
|
-
reject(promise, reason);
|
|
2288
|
-
});
|
|
2289
|
-
if (!done && res === IS_ERROR) {
|
|
2290
|
-
done = true;
|
|
2291
|
-
reject(promise, LAST_ERROR);
|
|
2292
|
-
}
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
core.prototype.done = function (onFulfilled, onRejected) {
|
|
2296
|
-
var self = arguments.length ? this.then.apply(this, arguments) : this;
|
|
2297
|
-
self.then(null, function (err) {
|
|
2298
|
-
setTimeout(function () {
|
|
2299
|
-
throw err;
|
|
2300
|
-
}, 0);
|
|
2301
|
-
});
|
|
2302
|
-
};
|
|
2303
|
-
|
|
2304
|
-
core.prototype['finally'] = function (f) {
|
|
2305
|
-
return this.then(function (value) {
|
|
2306
|
-
return core.resolve(f()).then(function () {
|
|
2307
|
-
return value;
|
|
2308
|
-
});
|
|
2309
|
-
}, function (err) {
|
|
2310
|
-
return core.resolve(f()).then(function () {
|
|
2311
|
-
throw err;
|
|
2312
|
-
});
|
|
2313
|
-
});
|
|
2314
|
-
};
|
|
2315
|
-
|
|
2316
|
-
/* Static Functions */
|
|
2317
|
-
|
|
2318
|
-
var TRUE = valuePromise(true);
|
|
2319
|
-
var FALSE = valuePromise(false);
|
|
2320
|
-
var NULL = valuePromise(null);
|
|
2321
|
-
var UNDEFINED = valuePromise(undefined);
|
|
2322
|
-
var ZERO = valuePromise(0);
|
|
2323
|
-
var EMPTYSTRING = valuePromise('');
|
|
2324
|
-
|
|
2325
|
-
function valuePromise(value) {
|
|
2326
|
-
var p = new core(core._44);
|
|
2327
|
-
p._83 = 1;
|
|
2328
|
-
p._18 = value;
|
|
2329
|
-
return p;
|
|
2330
|
-
}
|
|
2331
|
-
core.resolve = function (value) {
|
|
2332
|
-
if (value instanceof core) return value;
|
|
2333
|
-
|
|
2334
|
-
if (value === null) return NULL;
|
|
2335
|
-
if (value === undefined) return UNDEFINED;
|
|
2336
|
-
if (value === true) return TRUE;
|
|
2337
|
-
if (value === false) return FALSE;
|
|
2338
|
-
if (value === 0) return ZERO;
|
|
2339
|
-
if (value === '') return EMPTYSTRING;
|
|
2340
|
-
|
|
2341
|
-
if (typeof value === 'object' || typeof value === 'function') {
|
|
2342
|
-
try {
|
|
2343
|
-
var then = value.then;
|
|
2344
|
-
if (typeof then === 'function') {
|
|
2345
|
-
return new core(then.bind(value));
|
|
2346
|
-
}
|
|
2347
|
-
} catch (ex) {
|
|
2348
|
-
return new core(function (resolve, reject) {
|
|
2349
|
-
reject(ex);
|
|
2350
|
-
});
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
return valuePromise(value);
|
|
2354
|
-
};
|
|
2355
|
-
|
|
2356
|
-
core.all = function (arr) {
|
|
2357
|
-
var args = Array.prototype.slice.call(arr);
|
|
2358
|
-
|
|
2359
|
-
return new core(function (resolve, reject) {
|
|
2360
|
-
if (args.length === 0) return resolve([]);
|
|
2361
|
-
var remaining = args.length;
|
|
2362
|
-
function res(i, val) {
|
|
2363
|
-
if (val && (typeof val === 'object' || typeof val === 'function')) {
|
|
2364
|
-
if (val instanceof core && val.then === core.prototype.then) {
|
|
2365
|
-
while (val._83 === 3) {
|
|
2366
|
-
val = val._18;
|
|
2367
|
-
}
|
|
2368
|
-
if (val._83 === 1) return res(i, val._18);
|
|
2369
|
-
if (val._83 === 2) reject(val._18);
|
|
2370
|
-
val.then(function (val) {
|
|
2371
|
-
res(i, val);
|
|
2372
|
-
}, reject);
|
|
2373
|
-
return;
|
|
2374
|
-
} else {
|
|
2375
|
-
var then = val.then;
|
|
2376
|
-
if (typeof then === 'function') {
|
|
2377
|
-
var p = new core(then.bind(val));
|
|
2378
|
-
p.then(function (val) {
|
|
2379
|
-
res(i, val);
|
|
2380
|
-
}, reject);
|
|
2381
|
-
return;
|
|
2382
|
-
}
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
args[i] = val;
|
|
2386
|
-
if (--remaining === 0) {
|
|
2387
|
-
resolve(args);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
for (var i = 0; i < args.length; i++) {
|
|
2391
|
-
res(i, args[i]);
|
|
2392
|
-
}
|
|
2393
|
-
});
|
|
2394
|
-
};
|
|
2395
|
-
|
|
2396
|
-
core.reject = function (value) {
|
|
2397
|
-
return new core(function (resolve, reject) {
|
|
2398
|
-
reject(value);
|
|
2399
|
-
});
|
|
2400
|
-
};
|
|
2401
|
-
|
|
2402
|
-
core.race = function (values) {
|
|
2403
|
-
return new core(function (resolve, reject) {
|
|
2404
|
-
values.forEach(function(value){
|
|
2405
|
-
core.resolve(value).then(resolve, reject);
|
|
2406
|
-
});
|
|
2407
|
-
});
|
|
2408
|
-
};
|
|
2409
|
-
|
|
2410
|
-
/* Prototype Methods */
|
|
2411
|
-
|
|
2412
|
-
core.prototype['catch'] = function (onRejected) {
|
|
2413
|
-
return this.then(null, onRejected);
|
|
2414
|
-
};
|
|
2415
|
-
|
|
2416
|
-
var freeTasks = [];
|
|
2417
|
-
|
|
2418
|
-
/**
|
|
2419
|
-
* Calls a task as soon as possible after returning, in its own event, with
|
|
2420
|
-
* priority over IO events. An exception thrown in a task can be handled by
|
|
2421
|
-
* `process.on("uncaughtException") or `domain.on("error")`, but will otherwise
|
|
2422
|
-
* crash the process. If the error is handled, all subsequent tasks will
|
|
2423
|
-
* resume.
|
|
2424
|
-
*
|
|
2425
|
-
* @param {{call}} task A callable object, typically a function that takes no
|
|
2426
|
-
* arguments.
|
|
2427
|
-
*/
|
|
2428
|
-
var asap_1 = asap;
|
|
2429
|
-
function asap(task) {
|
|
2430
|
-
var rawTask;
|
|
2431
|
-
if (freeTasks.length) {
|
|
2432
|
-
rawTask = freeTasks.pop();
|
|
2433
|
-
} else {
|
|
2434
|
-
rawTask = new RawTask();
|
|
2435
|
-
}
|
|
2436
|
-
rawTask.task = task;
|
|
2437
|
-
rawTask.domain = process.domain;
|
|
2438
|
-
raw(rawTask);
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
function RawTask() {
|
|
2442
|
-
this.task = null;
|
|
2443
|
-
this.domain = null;
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
RawTask.prototype.call = function () {
|
|
2447
|
-
if (this.domain) {
|
|
2448
|
-
this.domain.enter();
|
|
2449
|
-
}
|
|
2450
|
-
var threw = true;
|
|
2451
|
-
try {
|
|
2452
|
-
this.task.call();
|
|
2453
|
-
threw = false;
|
|
2454
|
-
// If the task throws an exception (presumably) Node.js restores the
|
|
2455
|
-
// domain stack for the next event.
|
|
2456
|
-
if (this.domain) {
|
|
2457
|
-
this.domain.exit();
|
|
2458
|
-
}
|
|
2459
|
-
} finally {
|
|
2460
|
-
// We use try/finally and a threw flag to avoid messing up stack traces
|
|
2461
|
-
// when we catch and release errors.
|
|
2462
|
-
if (threw) {
|
|
2463
|
-
// In Node.js, uncaught exceptions are considered fatal errors.
|
|
2464
|
-
// Re-throw them to interrupt flushing!
|
|
2465
|
-
// Ensure that flushing continues if an uncaught exception is
|
|
2466
|
-
// suppressed listening process.on("uncaughtException") or
|
|
2467
|
-
// domain.on("error").
|
|
2468
|
-
raw.requestFlush();
|
|
2469
|
-
}
|
|
2470
|
-
// If the task threw an error, we do not want to exit the domain here.
|
|
2471
|
-
// Exiting the domain would prevent the domain from catching the error.
|
|
2472
|
-
this.task = null;
|
|
2473
|
-
this.domain = null;
|
|
2474
|
-
freeTasks.push(this);
|
|
2475
|
-
}
|
|
2476
|
-
};
|
|
2477
|
-
|
|
2478
|
-
/* Static Functions */
|
|
2479
|
-
|
|
2480
|
-
core.denodeify = function (fn, argumentCount) {
|
|
2481
|
-
if (
|
|
2482
|
-
typeof argumentCount === 'number' && argumentCount !== Infinity
|
|
2483
|
-
) {
|
|
2484
|
-
return denodeifyWithCount(fn, argumentCount);
|
|
2485
|
-
} else {
|
|
2486
|
-
return denodeifyWithoutCount(fn);
|
|
2487
|
-
}
|
|
2488
|
-
};
|
|
2489
|
-
|
|
2490
|
-
var callbackFn = (
|
|
2491
|
-
'function (err, res) {' +
|
|
2492
|
-
'if (err) { rj(err); } else { rs(res); }' +
|
|
2493
|
-
'}'
|
|
2494
|
-
);
|
|
2495
|
-
function denodeifyWithCount(fn, argumentCount) {
|
|
2496
|
-
var args = [];
|
|
2497
|
-
for (var i = 0; i < argumentCount; i++) {
|
|
2498
|
-
args.push('a' + i);
|
|
2499
|
-
}
|
|
2500
|
-
var body = [
|
|
2501
|
-
'return function (' + args.join(',') + ') {',
|
|
2502
|
-
'var self = this;',
|
|
2503
|
-
'return new Promise(function (rs, rj) {',
|
|
2504
|
-
'var res = fn.call(',
|
|
2505
|
-
['self'].concat(args).concat([callbackFn]).join(','),
|
|
2506
|
-
');',
|
|
2507
|
-
'if (res &&',
|
|
2508
|
-
'(typeof res === "object" || typeof res === "function") &&',
|
|
2509
|
-
'typeof res.then === "function"',
|
|
2510
|
-
') {rs(res);}',
|
|
2511
|
-
'});',
|
|
2512
|
-
'};'
|
|
2513
|
-
].join('');
|
|
2514
|
-
return Function(['Promise', 'fn'], body)(core, fn);
|
|
2515
|
-
}
|
|
2516
|
-
function denodeifyWithoutCount(fn) {
|
|
2517
|
-
var fnLength = Math.max(fn.length - 1, 3);
|
|
2518
|
-
var args = [];
|
|
2519
|
-
for (var i = 0; i < fnLength; i++) {
|
|
2520
|
-
args.push('a' + i);
|
|
2521
|
-
}
|
|
2522
|
-
var body = [
|
|
2523
|
-
'return function (' + args.join(',') + ') {',
|
|
2524
|
-
'var self = this;',
|
|
2525
|
-
'var args;',
|
|
2526
|
-
'var argLength = arguments.length;',
|
|
2527
|
-
'if (arguments.length > ' + fnLength + ') {',
|
|
2528
|
-
'args = new Array(arguments.length + 1);',
|
|
2529
|
-
'for (var i = 0; i < arguments.length; i++) {',
|
|
2530
|
-
'args[i] = arguments[i];',
|
|
2531
|
-
'}',
|
|
2532
|
-
'}',
|
|
2533
|
-
'return new Promise(function (rs, rj) {',
|
|
2534
|
-
'var cb = ' + callbackFn + ';',
|
|
2535
|
-
'var res;',
|
|
2536
|
-
'switch (argLength) {',
|
|
2537
|
-
args.concat(['extra']).map(function (_, index) {
|
|
2538
|
-
return (
|
|
2539
|
-
'case ' + (index) + ':' +
|
|
2540
|
-
'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' +
|
|
2541
|
-
'break;'
|
|
2542
|
-
);
|
|
2543
|
-
}).join(''),
|
|
2544
|
-
'default:',
|
|
2545
|
-
'args[argLength] = cb;',
|
|
2546
|
-
'res = fn.apply(self, args);',
|
|
2547
|
-
'}',
|
|
2548
|
-
|
|
2549
|
-
'if (res &&',
|
|
2550
|
-
'(typeof res === "object" || typeof res === "function") &&',
|
|
2551
|
-
'typeof res.then === "function"',
|
|
2552
|
-
') {rs(res);}',
|
|
2553
|
-
'});',
|
|
2554
|
-
'};'
|
|
2555
|
-
].join('');
|
|
2556
|
-
|
|
2557
|
-
return Function(
|
|
2558
|
-
['Promise', 'fn'],
|
|
2559
|
-
body
|
|
2560
|
-
)(core, fn);
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
|
-
core.nodeify = function (fn) {
|
|
2564
|
-
return function () {
|
|
2565
|
-
var args = Array.prototype.slice.call(arguments);
|
|
2566
|
-
var callback =
|
|
2567
|
-
typeof args[args.length - 1] === 'function' ? args.pop() : null;
|
|
2568
|
-
var ctx = this;
|
|
2569
|
-
try {
|
|
2570
|
-
return fn.apply(this, arguments).nodeify(callback, ctx);
|
|
2571
|
-
} catch (ex) {
|
|
2572
|
-
if (callback === null || typeof callback == 'undefined') {
|
|
2573
|
-
return new core(function (resolve, reject) {
|
|
2574
|
-
reject(ex);
|
|
2575
|
-
});
|
|
2576
|
-
} else {
|
|
2577
|
-
asap_1(function () {
|
|
2578
|
-
callback.call(ctx, ex);
|
|
2579
|
-
});
|
|
2580
|
-
}
|
|
2581
|
-
}
|
|
2582
|
-
}
|
|
2583
|
-
};
|
|
2584
|
-
|
|
2585
|
-
core.prototype.nodeify = function (callback, ctx) {
|
|
2586
|
-
if (typeof callback != 'function') return this;
|
|
2587
|
-
|
|
2588
|
-
this.then(function (value) {
|
|
2589
|
-
asap_1(function () {
|
|
2590
|
-
callback.call(ctx, null, value);
|
|
2591
|
-
});
|
|
2592
|
-
}, function (err) {
|
|
2593
|
-
asap_1(function () {
|
|
2594
|
-
callback.call(ctx, err);
|
|
2595
|
-
});
|
|
2596
|
-
});
|
|
2597
|
-
};
|
|
2598
|
-
|
|
2599
|
-
core.enableSynchronous = function () {
|
|
2600
|
-
core.prototype.isPending = function() {
|
|
2601
|
-
return this.getState() == 0;
|
|
2602
|
-
};
|
|
2603
|
-
|
|
2604
|
-
core.prototype.isFulfilled = function() {
|
|
2605
|
-
return this.getState() == 1;
|
|
2606
|
-
};
|
|
2607
|
-
|
|
2608
|
-
core.prototype.isRejected = function() {
|
|
2609
|
-
return this.getState() == 2;
|
|
2610
|
-
};
|
|
2611
|
-
|
|
2612
|
-
core.prototype.getValue = function () {
|
|
2613
|
-
if (this._83 === 3) {
|
|
2614
|
-
return this._18.getValue();
|
|
2615
|
-
}
|
|
2616
|
-
|
|
2617
|
-
if (!this.isFulfilled()) {
|
|
2618
|
-
throw new Error('Cannot get a value of an unfulfilled promise.');
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
return this._18;
|
|
2622
|
-
};
|
|
2623
|
-
|
|
2624
|
-
core.prototype.getReason = function () {
|
|
2625
|
-
if (this._83 === 3) {
|
|
2626
|
-
return this._18.getReason();
|
|
2627
|
-
}
|
|
2628
|
-
|
|
2629
|
-
if (!this.isRejected()) {
|
|
2630
|
-
throw new Error('Cannot get a rejection reason of a non-rejected promise.');
|
|
2631
|
-
}
|
|
2632
|
-
|
|
2633
|
-
return this._18;
|
|
2634
|
-
};
|
|
2635
|
-
|
|
2636
|
-
core.prototype.getState = function () {
|
|
2637
|
-
if (this._83 === 3) {
|
|
2638
|
-
return this._18.getState();
|
|
2639
|
-
}
|
|
2640
|
-
if (this._83 === -1 || this._83 === -2) {
|
|
2641
|
-
return 0;
|
|
2642
|
-
}
|
|
2643
|
-
|
|
2644
|
-
return this._83;
|
|
2645
|
-
};
|
|
2646
|
-
};
|
|
2647
|
-
|
|
2648
|
-
core.disableSynchronous = function() {
|
|
2649
|
-
core.prototype.isPending = undefined;
|
|
2650
|
-
core.prototype.isFulfilled = undefined;
|
|
2651
|
-
core.prototype.isRejected = undefined;
|
|
2652
|
-
core.prototype.getValue = undefined;
|
|
2653
|
-
core.prototype.getReason = undefined;
|
|
2654
|
-
core.prototype.getState = undefined;
|
|
2655
|
-
};
|
|
2656
|
-
|
|
2657
|
-
var lib = core;
|
|
2658
|
-
|
|
2659
|
-
var promise = lib;
|
|
2660
|
-
|
|
2661
|
-
/**
|
|
2662
|
-
* @license
|
|
2663
|
-
* Copyright 2016 The AMP HTML Authors. All Rights Reserved.
|
|
2664
|
-
*
|
|
2665
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2666
|
-
* you may not use this file except in compliance with the License.
|
|
2667
|
-
* You may obtain a copy of the License at
|
|
2668
|
-
*
|
|
2669
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2670
|
-
*
|
|
2671
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
2672
|
-
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
2673
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2674
|
-
* See the License for the specific language governing permissions and
|
|
2675
|
-
* limitations under the license.
|
|
2676
|
-
*/
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
const DEFAULT_USER_AGENT = 'amphtml-validator';
|
|
2691
|
-
|
|
2692
|
-
/**
|
|
2693
|
-
* Determines if str begins with prefix.
|
|
2694
|
-
* @param {string} str
|
|
2695
|
-
* @param {string} prefix
|
|
2696
|
-
* @return {boolean}
|
|
2697
|
-
*/
|
|
2698
|
-
function hasPrefix(str, prefix) {
|
|
2699
|
-
return str.indexOf(prefix) == 0;
|
|
2700
|
-
}
|
|
2701
|
-
|
|
2702
|
-
/**
|
|
2703
|
-
* Convenience function to detect whether an argument is a URL. If not,
|
|
2704
|
-
* it may be a local file.
|
|
2705
|
-
* @param {string} url
|
|
2706
|
-
* @return {boolean}
|
|
2707
|
-
*/
|
|
2708
|
-
function isHttpOrHttpsUrl(url) {
|
|
2709
|
-
return hasPrefix(url, 'http://') || hasPrefix(url, 'https://');
|
|
2710
|
-
}
|
|
2711
|
-
|
|
2712
|
-
/**
|
|
2713
|
-
* Creates a promise which reads from a file.
|
|
2714
|
-
* @param {string} name
|
|
2715
|
-
* @return {Promise<string>}
|
|
2716
|
-
*/
|
|
2717
|
-
function readFromFile(name) {
|
|
2718
|
-
return new promise(function(resolve, reject) {
|
|
2719
|
-
fs.readFile(name, 'utf8', function(err, data) {
|
|
2720
|
-
if (err) {
|
|
2721
|
-
reject(err);
|
|
2722
|
-
} else {
|
|
2723
|
-
resolve(data.trim());
|
|
2724
|
-
}
|
|
2725
|
-
});
|
|
2726
|
-
});
|
|
2727
|
-
}
|
|
2728
|
-
|
|
2729
|
-
/**
|
|
2730
|
-
* Creates a promise which reads from a stream.
|
|
2731
|
-
* @param {string} name
|
|
2732
|
-
* @param {!stream.Readable} readable
|
|
2733
|
-
* @return {Promise<string>}
|
|
2734
|
-
*/
|
|
2735
|
-
function readFromReadable(name, readable) {
|
|
2736
|
-
return new promise(function(resolve, reject) {
|
|
2737
|
-
const chunks = [];
|
|
2738
|
-
readable.setEncoding('utf8');
|
|
2739
|
-
readable.on('data', function(chunk) {
|
|
2740
|
-
chunks.push(chunk);
|
|
2741
|
-
});
|
|
2742
|
-
readable.on('end', function() {
|
|
2743
|
-
resolve(chunks.join(''));
|
|
2744
|
-
});
|
|
2745
|
-
readable.on('error', function(error) {
|
|
2746
|
-
reject(new Error('Could not read from ' + name + ' - ' + error.message));
|
|
2747
|
-
});
|
|
2748
|
-
});
|
|
2749
|
-
}
|
|
2750
|
-
|
|
2751
|
-
/**
|
|
2752
|
-
* Creates a promise which reads from standard input. Even though it would
|
|
2753
|
-
* be easy to make a function that just returns the data, we return a promise
|
|
2754
|
-
* for consistency with readFromUrl and readFromFile.
|
|
2755
|
-
* @return {Promise<string>}
|
|
2756
|
-
*/
|
|
2757
|
-
function readFromStdin() {
|
|
2758
|
-
return readFromReadable('stdin', process.stdin).then(function(data) {
|
|
2759
|
-
process.stdin.resume();
|
|
2760
|
-
return data;
|
|
2761
|
-
});
|
|
2762
|
-
}
|
|
2763
|
-
|
|
2764
|
-
/**
|
|
2765
|
-
* Creates a promise which reads from a URL or more precisely, fetches
|
|
2766
|
-
* the contents located at the URL by using the 'http' or 'https' module.
|
|
2767
|
-
* Any HTTP status other than 200 is interpreted as an error.
|
|
2768
|
-
* @param {string} url
|
|
2769
|
-
* @param {string} userAgent
|
|
2770
|
-
* @return {Promise<string>}
|
|
2771
|
-
*/
|
|
2772
|
-
function readFromUrl(url, userAgent) {
|
|
2773
|
-
return new promise(function(resolve, reject) {
|
|
2774
|
-
const clientModule = hasPrefix(url, 'http://') ? http : https;
|
|
2775
|
-
const req = clientModule.request(url, function(response) {
|
|
2776
|
-
if (response.statusCode !== 200) {
|
|
2777
|
-
// https://nodejs.org/api/http.html says: "[...] However, if
|
|
2778
|
-
// you add a 'response' event handler, then you must consume
|
|
2779
|
-
// the data from the response object, either by calling
|
|
2780
|
-
// response.read() whenever there is a 'readable' event, or by
|
|
2781
|
-
// adding a 'data' handler, or by calling the .resume()
|
|
2782
|
-
// method."
|
|
2783
|
-
response.resume();
|
|
2784
|
-
reject(new Error(
|
|
2785
|
-
'Unable to fetch ' + url + ' - HTTP Status ' +
|
|
2786
|
-
response.statusCode));
|
|
2787
|
-
} else {
|
|
2788
|
-
resolve(response);
|
|
2789
|
-
}
|
|
2790
|
-
});
|
|
2791
|
-
req.setHeader('User-Agent', userAgent);
|
|
2792
|
-
req.on('error', function(error) { // E.g., DNS resolution errors.
|
|
2793
|
-
reject(
|
|
2794
|
-
new Error('Unable to fetch ' + url + ' - ' + error.message));
|
|
2795
|
-
});
|
|
2796
|
-
req.end();
|
|
2797
|
-
})
|
|
2798
|
-
.then(readFromReadable.bind(null, url));
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2801
|
-
/**
|
|
2802
|
-
* ValidationResult is the record computed by the validator for each
|
|
2803
|
-
* document. It contains an overall status (PASS/FAIL) and the list of
|
|
2804
|
-
* errors, if any. This class corresponds to the ValidationResult
|
|
2805
|
-
* message in validator.proto in this directory.
|
|
2806
|
-
* @export
|
|
2807
|
-
* @constructor
|
|
2808
|
-
*/
|
|
2809
|
-
function ValidationResult() {
|
|
2810
|
-
/**
|
|
2811
|
-
* Possible values are 'UNKNOWN', 'PASS', and 'FAIL'.
|
|
2812
|
-
* @type {string}
|
|
2813
|
-
*/
|
|
2814
|
-
this.status = 'UNKNOWN';
|
|
2815
|
-
/** @type {!Array<!ValidationError>} */
|
|
2816
|
-
this.errors = [];
|
|
2817
|
-
}
|
|
2818
|
-
|
|
2819
|
-
/**
|
|
2820
|
-
* Each validation error describes a specific problem in a validated
|
|
2821
|
-
* document. This class corresponds to the ValidationError message in
|
|
2822
|
-
* validator.proto in this directory.
|
|
2823
|
-
* @export
|
|
2824
|
-
* @constructor
|
|
2825
|
-
*/
|
|
2826
|
-
function ValidationError() {
|
|
2827
|
-
/**
|
|
2828
|
-
* The severity of the error - possible values are 'UNKNOWN_SEVERITY',
|
|
2829
|
-
* 'ERROR', and 'WARNING'.
|
|
2830
|
-
*/
|
|
2831
|
-
this.severity = 'UNKNOWN_SEVERITY';
|
|
2832
|
-
/**
|
|
2833
|
-
* The line number at which the error was seen (1 is the first line).
|
|
2834
|
-
*/
|
|
2835
|
-
this.line = 1;
|
|
2836
|
-
/**
|
|
2837
|
-
* The column number at which the error was seen (0 is the first column).
|
|
2838
|
-
*/
|
|
2839
|
-
this.col = 0;
|
|
2840
|
-
/**
|
|
2841
|
-
* A human-readable error message for the validation error.
|
|
2842
|
-
* If you find yourself trying to write a parser against this string
|
|
2843
|
-
* to scrape out some detail, consider looking at the code and params
|
|
2844
|
-
* fields below.
|
|
2845
|
-
* @type {string}
|
|
2846
|
-
*/
|
|
2847
|
-
this.message = '';
|
|
2848
|
-
/**
|
|
2849
|
-
* The spec URL is often added by the validator to provide additional
|
|
2850
|
-
* context for the error. In a user interface this would be shown
|
|
2851
|
-
* as a "Learn more" link.
|
|
2852
|
-
* @type {string}
|
|
2853
|
-
*/
|
|
2854
|
-
this.specUrl = null;
|
|
2855
|
-
/**
|
|
2856
|
-
* This field is only useful when scripting against the validator,
|
|
2857
|
-
* it should not be displayed in a user interface as it adds nothing
|
|
2858
|
-
* for humans to read over the message field (see above).
|
|
2859
|
-
* Possible values are the codes listed in ValidationError.Code - see
|
|
2860
|
-
* validator.proto. Examples: 'UNKNOWN_CODE', 'MANDATORY_TAG_MISSING',
|
|
2861
|
-
* 'TAG_REQUIRED_BY_MISSING'. For each of these codes there is a
|
|
2862
|
-
* format string in validator-main.protoascii (look for error_formats),
|
|
2863
|
-
* which is used to assemble the message from the strings in params.
|
|
2864
|
-
* @type {string}
|
|
2865
|
-
*/
|
|
2866
|
-
this.code = 'UNKNOWN_CODE';
|
|
2867
|
-
/**
|
|
2868
|
-
* This field is only useful when scripting against the validator,
|
|
2869
|
-
* it should not be displayed in a user interface as it adds nothing
|
|
2870
|
-
* for humans to read over the message field (see above).
|
|
2871
|
-
* @type {!Array<string>}
|
|
2872
|
-
*/
|
|
2873
|
-
this.params = [];
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2876
|
-
/**
|
|
2877
|
-
* The validator instance is a proxy object to a precompiled
|
|
2878
|
-
* validator.js script - in practice the script was either downloaded
|
|
2879
|
-
* from 'https://cdn.ampproject.org/v0/validator.js' or read from a
|
|
2880
|
-
* local file.
|
|
2881
|
-
* @param {string} scriptContents
|
|
2882
|
-
* @throws {!Error}
|
|
2883
|
-
* @constructor
|
|
2884
|
-
*/
|
|
2885
|
-
function Validator(scriptContents) {
|
|
2886
|
-
// The 'sandbox' is a Javascript object (dictionary) which holds
|
|
2887
|
-
// the results of evaluating the validatorJs / scriptContents, so
|
|
2888
|
-
// basically, it holds functions, prototypes, etc. As a
|
|
2889
|
-
// side-effect of evaluating, the VM will compile this code and
|
|
2890
|
-
// it's worth holding onto it. Hence, this validate function is
|
|
2891
|
-
// reached via 2 codepaths - either the sandbox came from the
|
|
2892
|
-
// cache, precompiledByValidatorJs - or we just varructed it
|
|
2893
|
-
// after downloading and evaluating the script. The API is fancier
|
|
2894
|
-
// here, vm.Script / vm.createContext / vm.runInContext and all
|
|
2895
|
-
// that, but it's quite similar to a Javascript eval.
|
|
2896
|
-
this.sandbox = vm.createContext();
|
|
2897
|
-
try {
|
|
2898
|
-
new vm.Script(scriptContents).runInContext(this.sandbox);
|
|
2899
|
-
} catch (error) {
|
|
2900
|
-
throw new Error('Could not instantiate validator.js - ' + error.message);
|
|
2901
|
-
}
|
|
2902
|
-
}
|
|
2903
|
-
|
|
2904
|
-
/**
|
|
2905
|
-
* Validates the provided inputString; the htmlFormat can be 'AMP' or
|
|
2906
|
-
* 'AMP4ADS'; it defaults to 'AMP' if not specified.
|
|
2907
|
-
* @param {string} inputString
|
|
2908
|
-
* @param {string=} htmlFormat
|
|
2909
|
-
* @return {!ValidationResult}
|
|
2910
|
-
* @export
|
|
2911
|
-
*/
|
|
2912
|
-
Validator.prototype.validateString = function(inputString, htmlFormat) {
|
|
2913
|
-
const internalResult =
|
|
2914
|
-
this.sandbox.amp.validator.validateString(inputString, htmlFormat);
|
|
2915
|
-
const result = new ValidationResult();
|
|
2916
|
-
result.status = internalResult.status;
|
|
2917
|
-
for (let ii = 0; ii < internalResult.errors.length; ii++) {
|
|
2918
|
-
const internalError = internalResult.errors[ii];
|
|
2919
|
-
const error = new ValidationError();
|
|
2920
|
-
error.severity = internalError.severity;
|
|
2921
|
-
error.line = internalError.line;
|
|
2922
|
-
error.col = internalError.col;
|
|
2923
|
-
error.message =
|
|
2924
|
-
this.sandbox.amp.validator.renderErrorMessage(internalError);
|
|
2925
|
-
error.specUrl = internalError.specUrl;
|
|
2926
|
-
error.code = internalError.code;
|
|
2927
|
-
error.params = internalError.params;
|
|
2928
|
-
result.errors.push(error);
|
|
2929
|
-
}
|
|
2930
|
-
return result;
|
|
2931
|
-
};
|
|
2932
|
-
|
|
2933
|
-
/**
|
|
2934
|
-
* A global static map used by the getInstance function to avoid loading
|
|
2935
|
-
* AMP Validators more than once.
|
|
2936
|
-
* @type {!Object<string, Validator>}
|
|
2937
|
-
*/
|
|
2938
|
-
const instanceByValidatorJs = {};
|
|
2939
|
-
|
|
2940
|
-
/**
|
|
2941
|
-
* Provided a URL or a filename from which to fetch the validator.js
|
|
2942
|
-
* file, fetches, instantiates, and caches the validator instance
|
|
2943
|
-
* asynchronously. If you prefer to implement your own fetching /
|
|
2944
|
-
* caching logic, you may want to consider newInstance() instead,
|
|
2945
|
-
* which is synchronous and much simpler.
|
|
2946
|
-
*
|
|
2947
|
-
* @param {string=} opt_validatorJs
|
|
2948
|
-
* @param {string=} opt_userAgent
|
|
2949
|
-
* @return {!Promise<Validator>}
|
|
2950
|
-
* @export
|
|
2951
|
-
*/
|
|
2952
|
-
function getInstance(opt_validatorJs, opt_userAgent) {
|
|
2953
|
-
const validatorJs =
|
|
2954
|
-
opt_validatorJs || 'https://cdn.ampproject.org/v0/validator.js';
|
|
2955
|
-
const userAgent = opt_userAgent || DEFAULT_USER_AGENT;
|
|
2956
|
-
if (instanceByValidatorJs.hasOwnProperty(validatorJs)) {
|
|
2957
|
-
return promise.resolve(instanceByValidatorJs[validatorJs]);
|
|
2958
|
-
}
|
|
2959
|
-
const validatorJsPromise = isHttpOrHttpsUrl(validatorJs) ?
|
|
2960
|
-
readFromUrl(validatorJs, userAgent) :
|
|
2961
|
-
readFromFile(validatorJs);
|
|
2962
|
-
return validatorJsPromise.then(function(scriptContents) {
|
|
2963
|
-
let instance;
|
|
2964
|
-
try {
|
|
2965
|
-
instance = new Validator(scriptContents);
|
|
2966
|
-
} catch (error) {
|
|
2967
|
-
// It may be useful to cache errors and exceptions encountered
|
|
2968
|
-
// here, but for now we don't do this for e.g. http errors when
|
|
2969
|
-
// fetching the validator, so we shouldn't do it for syntax
|
|
2970
|
-
// errors etc. either (which lead to the varructor throwing an error).
|
|
2971
|
-
throw error;
|
|
2972
|
-
}
|
|
2973
|
-
instanceByValidatorJs[validatorJs] = instance;
|
|
2974
|
-
return instance;
|
|
2975
|
-
});
|
|
2976
|
-
}
|
|
2977
|
-
var getInstance_1 = getInstance;
|
|
2978
|
-
|
|
2979
|
-
/**
|
|
2980
|
-
* Provided the contents of the validator.js file, e.g. as downloaded from
|
|
2981
|
-
* 'https://cdn.ampproject.org/v0/validator.js', returns a new validator
|
|
2982
|
-
* instance. The tradeoff between this function and getInstance() is that this
|
|
2983
|
-
* function is synchronous but requires the contents of the validator.js
|
|
2984
|
-
* file as a parameter, while getInstance is asynchronous, fetches files
|
|
2985
|
-
* from disk or the web, and caches them.
|
|
2986
|
-
*
|
|
2987
|
-
* @param {string} validatorJsContents
|
|
2988
|
-
* @return {!Validator}
|
|
2989
|
-
* @export
|
|
2990
|
-
*/
|
|
2991
|
-
function newInstance(validatorJsContents) {
|
|
2992
|
-
return new Validator(validatorJsContents);
|
|
2993
|
-
}
|
|
2994
|
-
var newInstance_1 = newInstance;
|
|
2995
|
-
|
|
2996
|
-
// A note on emitting output to the console and process exit status:
|
|
2997
|
-
// Node.js prior to 0.11.8 did not support process.exitCode
|
|
2998
|
-
// (https://nodejs.org/api/process.html#process_process_exitcode), which
|
|
2999
|
-
// makes it difficult to emit output and errors from multiple callbacks
|
|
3000
|
-
// and set the appropriate exit code. We use the following workaround:
|
|
3001
|
-
// process.<<stream>>(<<some output>>, function() { process.exit(<<code>>); });
|
|
3002
|
-
// This will flush the appropriate stream (stdout or stderr) and then
|
|
3003
|
-
// exit with the provided code. For now, this makes the CLI work with
|
|
3004
|
-
// Node.js versions as old as v0.10.25.
|
|
3005
|
-
|
|
3006
|
-
/**
|
|
3007
|
-
* Logs a validation result to the console using process.stdout and
|
|
3008
|
-
* process.stderr as is appropriate.
|
|
3009
|
-
* @param {string} filename
|
|
3010
|
-
* @param {!ValidationResult} validationResult
|
|
3011
|
-
* @param {boolean} color
|
|
3012
|
-
*/
|
|
3013
|
-
function logValidationResult(filename, validationResult, color) {
|
|
3014
|
-
if (validationResult.status === 'PASS') {
|
|
3015
|
-
process.stdout.write(
|
|
3016
|
-
filename + ': ' + (color ? safe.green('PASS') : 'PASS') + '\n');
|
|
3017
|
-
}
|
|
3018
|
-
for (let ii = 0; ii < validationResult.errors.length; ii++) {
|
|
3019
|
-
const error = validationResult.errors[ii];
|
|
3020
|
-
let msg = filename + ':' + error.line + ':' + error.col + ' ';
|
|
3021
|
-
if (color) {
|
|
3022
|
-
msg += (error.severity === 'ERROR' ? safe.red : safe.magenta)(
|
|
3023
|
-
error.message);
|
|
3024
|
-
} else {
|
|
3025
|
-
msg += error.message;
|
|
3026
|
-
}
|
|
3027
|
-
if (error.specUrl) {
|
|
3028
|
-
msg += ' (see ' + error.specUrl + ')';
|
|
3029
|
-
}
|
|
3030
|
-
// TODO(powdercloud): Should we distinguish error.severity === 'WARNING' ?
|
|
3031
|
-
process.stderr.write(msg + '\n');
|
|
3032
|
-
}
|
|
3033
|
-
}
|
|
3034
|
-
|
|
3035
|
-
/**
|
|
3036
|
-
* Main entry point into the command line tool.
|
|
3037
|
-
*/
|
|
3038
|
-
function main() {
|
|
3039
|
-
commander
|
|
3040
|
-
.usage(
|
|
3041
|
-
'[options] <fileOrUrlOrMinus...>\n\n' +
|
|
3042
|
-
' Validates the files or urls provided as arguments. If "-" is\n' +
|
|
3043
|
-
' specified, reads from stdin instead.')
|
|
3044
|
-
.option(
|
|
3045
|
-
'--validator_js <fileOrUrl>',
|
|
3046
|
-
'The Validator Javascript.\n' +
|
|
3047
|
-
' Latest published version by default, or\n' +
|
|
3048
|
-
' dist/validator_minified.js (built with build.py)\n' +
|
|
3049
|
-
' for development.',
|
|
3050
|
-
'https://cdn.ampproject.org/v0/validator.js')
|
|
3051
|
-
.option(
|
|
3052
|
-
'--user-agent <userAgent>', 'User agent string to use in requests.',
|
|
3053
|
-
DEFAULT_USER_AGENT)
|
|
3054
|
-
.option(
|
|
3055
|
-
'--html_format <AMP|AMP4ADS|AMP4EMAIL>',
|
|
3056
|
-
'The input format to be validated.\n' +
|
|
3057
|
-
' AMP by default.',
|
|
3058
|
-
'AMP')
|
|
3059
|
-
.option(
|
|
3060
|
-
'--format <color|text|json>',
|
|
3061
|
-
'How to format the output.\n' +
|
|
3062
|
-
' "color" displays errors/warnings/success in\n' +
|
|
3063
|
-
' red/orange/green.\n' +
|
|
3064
|
-
' "text" avoids color (e.g., useful in terminals not\n' +
|
|
3065
|
-
' supporting color).\n' +
|
|
3066
|
-
' "json" emits json corresponding to the ValidationResult\n' +
|
|
3067
|
-
' message in validator.proto.',
|
|
3068
|
-
'color')
|
|
3069
|
-
.parse(process.argv);
|
|
3070
|
-
if (commander.args.length === 0) {
|
|
3071
|
-
commander.outputHelp();
|
|
3072
|
-
process.exit(1);
|
|
3073
|
-
}
|
|
3074
|
-
if (commander.html_format !== 'AMP' && commander.html_format !== 'AMP4ADS' &&
|
|
3075
|
-
commander.html_format !== 'AMP4EMAIL') {
|
|
3076
|
-
process.stderr.write(
|
|
3077
|
-
'--html_format must be set to "AMP", "AMP4ADS", or "AMP4EMAIL".\n',
|
|
3078
|
-
function() {
|
|
3079
|
-
process.exit(1);
|
|
3080
|
-
});
|
|
3081
|
-
}
|
|
3082
|
-
if (commander.format !== 'color' && commander.format !== 'text' &&
|
|
3083
|
-
commander.format !== 'json') {
|
|
3084
|
-
process.stderr.write(
|
|
3085
|
-
'--format must be set to "color", "text", or "json".\n', function() {
|
|
3086
|
-
process.exit(1);
|
|
3087
|
-
});
|
|
3088
|
-
}
|
|
3089
|
-
const inputs = [];
|
|
3090
|
-
for (let ii = 0; ii < commander.args.length; ii++) {
|
|
3091
|
-
const item = commander.args[ii];
|
|
3092
|
-
if (item === '-') {
|
|
3093
|
-
inputs.push(readFromStdin());
|
|
3094
|
-
} else if (isHttpOrHttpsUrl(item)) {
|
|
3095
|
-
inputs.push(readFromUrl(item, commander.userAgent));
|
|
3096
|
-
} else {
|
|
3097
|
-
inputs.push(readFromFile(item));
|
|
3098
|
-
}
|
|
3099
|
-
}
|
|
3100
|
-
getInstance(commander.validator_js, commander.userAgent)
|
|
3101
|
-
.then(function(validator) {
|
|
3102
|
-
promise.all(inputs)
|
|
3103
|
-
.then(function(resolvedInputs) {
|
|
3104
|
-
const jsonOut = {};
|
|
3105
|
-
let hasError = false;
|
|
3106
|
-
for (let ii = 0; ii < resolvedInputs.length; ii++) {
|
|
3107
|
-
const validationResult = validator.validateString(
|
|
3108
|
-
resolvedInputs[ii], commander.html_format);
|
|
3109
|
-
if (commander.format === 'json') {
|
|
3110
|
-
jsonOut[commander.args[ii]] = validationResult;
|
|
3111
|
-
} else {
|
|
3112
|
-
logValidationResult(
|
|
3113
|
-
commander.args[ii], validationResult,
|
|
3114
|
-
commander.format === 'color' ? true : false);
|
|
3115
|
-
}
|
|
3116
|
-
if (validationResult.status !== 'PASS') {
|
|
3117
|
-
hasError = true;
|
|
3118
|
-
}
|
|
3119
|
-
}
|
|
3120
|
-
if (commander.format === 'json') {
|
|
3121
|
-
process.stdout.write(
|
|
3122
|
-
JSON.stringify(jsonOut) + '\n', function() {
|
|
3123
|
-
process.exit(hasError ? 1 : 0);
|
|
3124
|
-
});
|
|
3125
|
-
} else if (hasError) {
|
|
3126
|
-
process.stderr.write('', function() {
|
|
3127
|
-
process.exit(1);
|
|
3128
|
-
});
|
|
3129
|
-
} else {
|
|
3130
|
-
process.stdout.write('', function() {
|
|
3131
|
-
process.exit(0);
|
|
3132
|
-
});
|
|
3133
|
-
}
|
|
3134
|
-
})
|
|
3135
|
-
.catch(function(error) {
|
|
3136
|
-
process.stderr.write(
|
|
3137
|
-
(commander.format == 'color' ? safe.red(error.message) :
|
|
3138
|
-
error.message) +
|
|
3139
|
-
'\n',
|
|
3140
|
-
function() {
|
|
3141
|
-
process.exit(1);
|
|
3142
|
-
});
|
|
3143
|
-
});
|
|
3144
|
-
})
|
|
3145
|
-
.catch(function(error) {
|
|
3146
|
-
process.stderr.write(
|
|
3147
|
-
(commander.format == 'color' ? safe.red(error.message) :
|
|
3148
|
-
error.message) +
|
|
3149
|
-
'\n',
|
|
3150
|
-
function() {
|
|
3151
|
-
process.exit(1);
|
|
3152
|
-
});
|
|
3153
|
-
});
|
|
3154
|
-
}
|
|
3155
|
-
|
|
3156
|
-
var main_1 = main;
|
|
3157
|
-
|
|
3158
|
-
var amphtmlValidator = {
|
|
3159
|
-
getInstance: getInstance_1,
|
|
3160
|
-
newInstance: newInstance_1,
|
|
3161
|
-
main: main_1
|
|
3162
|
-
};
|
|
3163
|
-
|
|
3164
|
-
/** @typedef {{ cwd?: string, port: number, config: import('../../types').ValidatedConfig }} Options */
|
|
3165
|
-
|
|
3166
|
-
/** @param {Options} opts */
|
|
3167
|
-
function dev(opts) {
|
|
3168
|
-
return new Watcher(opts).init();
|
|
3169
|
-
}
|
|
3170
|
-
|
|
3171
|
-
class Watcher extends EventEmitter {
|
|
3172
|
-
/** @param {Options} opts */
|
|
3173
|
-
constructor({ cwd = process.cwd(), port, config }) {
|
|
3174
|
-
super();
|
|
3175
|
-
|
|
3176
|
-
this.cwd = cwd;
|
|
3177
|
-
this.dir = path.resolve(cwd, '.svelte/dev');
|
|
3178
|
-
|
|
3179
|
-
this.port = port;
|
|
3180
|
-
this.config = config;
|
|
3181
|
-
|
|
3182
|
-
process.env.NODE_ENV = 'development';
|
|
3183
|
-
|
|
3184
|
-
process.on('exit', () => {
|
|
3185
|
-
this.close();
|
|
3186
|
-
});
|
|
3187
|
-
}
|
|
3188
|
-
|
|
3189
|
-
async init() {
|
|
3190
|
-
rimraf(this.dir);
|
|
3191
|
-
copy_assets(this.dir);
|
|
3192
|
-
process.env.VITE_SVELTEKIT_AMP = this.config.kit.amp ? 'true' : '';
|
|
3193
|
-
|
|
3194
|
-
await this.init_filewatcher();
|
|
3195
|
-
await this.init_server();
|
|
3196
|
-
|
|
3197
|
-
this.update();
|
|
3198
|
-
|
|
3199
|
-
return this;
|
|
3200
|
-
}
|
|
3201
|
-
|
|
3202
|
-
async init_filewatcher() {
|
|
3203
|
-
this.cheapwatch = new CheapWatch({
|
|
3204
|
-
dir: this.config.kit.files.routes,
|
|
3205
|
-
/** @type {({ path }: { path: string }) => boolean} */
|
|
3206
|
-
filter: ({ path }) => path.split('/').every((part) => !part.startsWith('_'))
|
|
3207
|
-
});
|
|
3208
|
-
|
|
3209
|
-
await this.cheapwatch.init();
|
|
3210
|
-
|
|
3211
|
-
// not sure why TS doesn't understand that CheapWatch extends EventEmitter
|
|
3212
|
-
this.cheapwatch.on('+', ({ isNew }) => {
|
|
3213
|
-
if (isNew) this.update();
|
|
3214
|
-
});
|
|
3215
|
-
|
|
3216
|
-
this.cheapwatch.on('-', () => {
|
|
3217
|
-
this.update();
|
|
3218
|
-
});
|
|
3219
|
-
}
|
|
3220
|
-
|
|
3221
|
-
async init_server() {
|
|
3222
|
-
/**
|
|
3223
|
-
* @type {vite.ViteDevServer}
|
|
3224
|
-
*/
|
|
3225
|
-
this.viteDevServer = await vite.createServer({
|
|
3226
|
-
root: this.cwd,
|
|
3227
|
-
resolve: {
|
|
3228
|
-
alias: {
|
|
3229
|
-
$app: path.resolve(`${this.dir}/runtime/app`)
|
|
3230
|
-
}
|
|
3231
|
-
},
|
|
3232
|
-
plugins: [
|
|
3233
|
-
svelte({
|
|
3234
|
-
emitCss: true,
|
|
3235
|
-
compilerOptions: {
|
|
3236
|
-
dev: true,
|
|
3237
|
-
hydratable: true
|
|
3238
|
-
},
|
|
3239
|
-
hot: true,
|
|
3240
|
-
extensions: this.config.extensions
|
|
3241
|
-
})
|
|
3242
|
-
],
|
|
3243
|
-
publicDir: this.config.kit.files.assets,
|
|
3244
|
-
server: {
|
|
3245
|
-
middlewareMode: true
|
|
3246
|
-
}
|
|
3247
|
-
});
|
|
3248
|
-
|
|
3249
|
-
const validator = this.config.kit.amp && (await amphtmlValidator.getInstance());
|
|
3250
|
-
|
|
3251
|
-
this.server = http.createServer((req, res) => {
|
|
3252
|
-
this.viteDevServer.middlewares(req, res, async () => {
|
|
3253
|
-
try {
|
|
3254
|
-
const parsed = parse(req.url);
|
|
3255
|
-
|
|
3256
|
-
if (req.url === '/favicon.ico') return;
|
|
3257
|
-
|
|
3258
|
-
// handle dynamic requests - i.e. pages and endpoints
|
|
3259
|
-
const template = fs.readFileSync(this.config.kit.files.template, 'utf-8');
|
|
3260
|
-
|
|
3261
|
-
const setup = await this.viteDevServer
|
|
3262
|
-
.ssrLoadModule(`/${this.config.kit.files.setup}`)
|
|
3263
|
-
.catch(() => ({}));
|
|
3264
|
-
|
|
3265
|
-
let root;
|
|
3266
|
-
|
|
3267
|
-
try {
|
|
3268
|
-
root = (await this.viteDevServer.ssrLoadModule(`/${this.dir}/generated/root.svelte`))
|
|
3269
|
-
.default;
|
|
3270
|
-
} catch (e) {
|
|
3271
|
-
res.statusCode = 500;
|
|
3272
|
-
res.end(e.stack);
|
|
3273
|
-
return;
|
|
3274
|
-
}
|
|
3275
|
-
|
|
3276
|
-
const body = await get_body(req);
|
|
3277
|
-
|
|
3278
|
-
const rendered = await ssr(
|
|
3279
|
-
{
|
|
3280
|
-
headers: req.headers,
|
|
3281
|
-
method: req.method,
|
|
3282
|
-
path: parsed.pathname,
|
|
3283
|
-
query: new URLSearchParams(parsed.query),
|
|
3284
|
-
body
|
|
3285
|
-
},
|
|
3286
|
-
{
|
|
3287
|
-
paths: this.config.kit.paths,
|
|
3288
|
-
template: ({ head, body }) => {
|
|
3289
|
-
let rendered = template
|
|
3290
|
-
.replace('%svelte.head%', () => head)
|
|
3291
|
-
.replace('%svelte.body%', () => body);
|
|
3292
|
-
|
|
3293
|
-
if (this.config.kit.amp) {
|
|
3294
|
-
const result = validator.validateString(rendered);
|
|
3295
|
-
|
|
3296
|
-
if (result.status !== 'PASS') {
|
|
3297
|
-
const lines = rendered.split('\n');
|
|
3298
|
-
|
|
3299
|
-
/** @param {string} str */
|
|
3300
|
-
const escape = (str) =>
|
|
3301
|
-
str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
3302
|
-
|
|
3303
|
-
rendered = `<!doctype html>
|
|
3304
|
-
<head>
|
|
3305
|
-
<meta charset="utf-8" />
|
|
3306
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
3307
|
-
<style>
|
|
3308
|
-
body {
|
|
3309
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
3310
|
-
color: #333;
|
|
3311
|
-
}
|
|
3312
|
-
|
|
3313
|
-
pre {
|
|
3314
|
-
background: #f4f4f4;
|
|
3315
|
-
padding: 1em;
|
|
3316
|
-
overflow-x: auto;
|
|
3317
|
-
}
|
|
3318
|
-
</style>
|
|
3319
|
-
</head>
|
|
3320
|
-
<h1>AMP validation failed</h1>
|
|
3321
|
-
|
|
3322
|
-
${result.errors
|
|
3323
|
-
.map(
|
|
3324
|
-
(error) => `
|
|
3325
|
-
<h2>${error.severity}</h2>
|
|
3326
|
-
<p>Line ${error.line}, column ${error.col}: ${error.message} (<a href="${error.specUrl}">${
|
|
3327
|
-
error.code
|
|
3328
|
-
}</a>)</p>
|
|
3329
|
-
<pre>${escape(lines[error.line - 1])}</pre>
|
|
3330
|
-
`
|
|
3331
|
-
)
|
|
3332
|
-
.join('\n\n')}
|
|
3333
|
-
`;
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
|
|
3337
|
-
return rendered;
|
|
3338
|
-
},
|
|
3339
|
-
manifest: this.manifest,
|
|
3340
|
-
target: this.config.kit.target,
|
|
3341
|
-
entry: '/.svelte/dev/runtime/internal/start.js',
|
|
3342
|
-
dev: true,
|
|
3343
|
-
amp: this.config.kit.amp,
|
|
3344
|
-
root,
|
|
3345
|
-
setup,
|
|
3346
|
-
only_prerender: false,
|
|
3347
|
-
start_global: this.config.kit.startGlobal,
|
|
3348
|
-
host: this.config.kit.host,
|
|
3349
|
-
host_header: this.config.kit.hostHeader,
|
|
3350
|
-
get_stack: (error) => {
|
|
3351
|
-
this.viteDevServer.ssrFixStacktrace(error);
|
|
3352
|
-
return error.stack;
|
|
3353
|
-
},
|
|
3354
|
-
get_static_file: (file) =>
|
|
3355
|
-
fs.readFileSync(path.join(this.config.kit.files.assets, file)),
|
|
3356
|
-
get_amp_css: (url) => '' // TODO: implement this
|
|
3357
|
-
}
|
|
3358
|
-
);
|
|
3359
|
-
|
|
3360
|
-
if (rendered) {
|
|
3361
|
-
res.writeHead(rendered.status, rendered.headers);
|
|
3362
|
-
res.end(rendered.body);
|
|
3363
|
-
} else {
|
|
3364
|
-
res.statusCode = 404;
|
|
3365
|
-
res.end('Not found');
|
|
3366
|
-
}
|
|
3367
|
-
} catch (e) {
|
|
3368
|
-
this.viteDevServer.ssrFixStacktrace(e);
|
|
3369
|
-
res.end(e.stack);
|
|
3370
|
-
}
|
|
3371
|
-
});
|
|
3372
|
-
});
|
|
3373
|
-
|
|
3374
|
-
this.server.listen(this.port);
|
|
3375
|
-
}
|
|
3376
|
-
|
|
3377
|
-
update() {
|
|
3378
|
-
const manifest_data = create_manifest_data({
|
|
3379
|
-
config: this.config,
|
|
3380
|
-
output: this.dir,
|
|
3381
|
-
cwd: this.cwd
|
|
3382
|
-
});
|
|
3383
|
-
|
|
3384
|
-
create_app({
|
|
3385
|
-
manifest_data,
|
|
3386
|
-
output: this.dir,
|
|
3387
|
-
cwd: this.cwd
|
|
3388
|
-
});
|
|
3389
|
-
|
|
3390
|
-
const common_css_deps = new Set();
|
|
3391
|
-
|
|
3392
|
-
/**
|
|
3393
|
-
* @param {string} file
|
|
3394
|
-
*/
|
|
3395
|
-
const load = async (file) => {
|
|
3396
|
-
const url = path.resolve(this.cwd, file);
|
|
3397
|
-
|
|
3398
|
-
const mod = await this.viteDevServer.ssrLoadModule(url);
|
|
3399
|
-
const node = await this.viteDevServer.moduleGraph.getModuleByUrl(url);
|
|
3400
|
-
|
|
3401
|
-
const deps = new Set();
|
|
3402
|
-
find_deps(node, deps);
|
|
3403
|
-
|
|
3404
|
-
const css = new Set();
|
|
3405
|
-
for (const dep of deps) {
|
|
3406
|
-
// TODO what about .scss files, etc?
|
|
3407
|
-
if (dep.file.endsWith('.css')) {
|
|
3408
|
-
try {
|
|
3409
|
-
const mod = await this.viteDevServer.ssrLoadModule(dep.url);
|
|
3410
|
-
css.add(mod.default);
|
|
3411
|
-
} catch {
|
|
3412
|
-
// this can happen with dynamically imported modules, I think
|
|
3413
|
-
// because the Vite module graph doesn't distinguish between
|
|
3414
|
-
// static and dynamic imports? TODO investigate, submit fix
|
|
3415
|
-
}
|
|
3416
|
-
}
|
|
3417
|
-
}
|
|
3418
|
-
|
|
3419
|
-
return { mod, css };
|
|
3420
|
-
};
|
|
3421
|
-
|
|
3422
|
-
/**
|
|
3423
|
-
* @param {import('vite').ModuleNode} node
|
|
3424
|
-
* @param {Set<import('vite').ModuleNode>} deps
|
|
3425
|
-
*/
|
|
3426
|
-
const find_deps = (node, deps) => {
|
|
3427
|
-
for (const dep of node.importedModules) {
|
|
3428
|
-
if (!deps.has(dep)) {
|
|
3429
|
-
deps.add(dep);
|
|
3430
|
-
find_deps(dep, deps);
|
|
3431
|
-
}
|
|
3432
|
-
}
|
|
3433
|
-
};
|
|
3434
|
-
|
|
3435
|
-
this.manifest = {
|
|
3436
|
-
assets: manifest_data.assets,
|
|
3437
|
-
layout: async () => {
|
|
3438
|
-
const { mod, css } = await load(manifest_data.layout);
|
|
3439
|
-
css.forEach((mod) => {
|
|
3440
|
-
common_css_deps.add(mod);
|
|
3441
|
-
});
|
|
3442
|
-
return mod;
|
|
3443
|
-
},
|
|
3444
|
-
error: async () => {
|
|
3445
|
-
const { mod, css } = await load(manifest_data.error);
|
|
3446
|
-
css.forEach((mod) => {
|
|
3447
|
-
common_css_deps.add(mod);
|
|
3448
|
-
});
|
|
3449
|
-
return mod;
|
|
3450
|
-
},
|
|
3451
|
-
pages: manifest_data.pages.map((data) => {
|
|
3452
|
-
// This is a bit of a hack, but it means we can inject the correct <style>
|
|
3453
|
-
// contents without needing to do any analysis before loading
|
|
3454
|
-
const css_deps = new Set();
|
|
3455
|
-
|
|
3456
|
-
return {
|
|
3457
|
-
pattern: data.pattern,
|
|
3458
|
-
params: get_params(data.params),
|
|
3459
|
-
parts: data.parts.map((file) => async () => {
|
|
3460
|
-
const { mod, css } = await load(file);
|
|
3461
|
-
|
|
3462
|
-
css.forEach((mod) => {
|
|
3463
|
-
css_deps.add(mod);
|
|
3464
|
-
});
|
|
3465
|
-
|
|
3466
|
-
return mod;
|
|
3467
|
-
}),
|
|
3468
|
-
get style() {
|
|
3469
|
-
// TODO is it possible to inject <link> elements with
|
|
3470
|
-
// the current Vite plugin? would be better than this
|
|
3471
|
-
return [...common_css_deps, ...css_deps].join('\n');
|
|
3472
|
-
},
|
|
3473
|
-
css: [],
|
|
3474
|
-
js: []
|
|
3475
|
-
};
|
|
3476
|
-
}),
|
|
3477
|
-
endpoints: manifest_data.endpoints.map((data) => ({
|
|
3478
|
-
pattern: data.pattern,
|
|
3479
|
-
params: get_params(data.params),
|
|
3480
|
-
load: async () => {
|
|
3481
|
-
const url = path.resolve(this.cwd, data.file);
|
|
3482
|
-
return await this.viteDevServer.ssrLoadModule(url);
|
|
3483
|
-
}
|
|
3484
|
-
}))
|
|
3485
|
-
};
|
|
3486
|
-
}
|
|
3487
|
-
|
|
3488
|
-
close() {
|
|
3489
|
-
if (this.closed) return;
|
|
3490
|
-
this.closed = true;
|
|
3491
|
-
|
|
3492
|
-
this.viteDevServer.close();
|
|
3493
|
-
this.server.close();
|
|
3494
|
-
this.cheapwatch.close();
|
|
3495
|
-
}
|
|
3496
|
-
}
|
|
3497
|
-
|
|
3498
|
-
/** @param {string[]} array */
|
|
3499
|
-
function get_params(array) {
|
|
3500
|
-
// given an array of params like `['x', 'y', 'z']` for
|
|
3501
|
-
// src/routes/[x]/[y]/[z]/svelte, create a function
|
|
3502
|
-
// that turns a RegExpExecArray into ({ x, y, z })
|
|
3503
|
-
|
|
3504
|
-
/** @param {RegExpExecArray} match */
|
|
3505
|
-
const fn = (match) => {
|
|
3506
|
-
/** @type {Record<string, string | string[]>} */
|
|
3507
|
-
const params = {};
|
|
3508
|
-
array.forEach((key, i) => {
|
|
3509
|
-
if (key.startsWith('...')) {
|
|
3510
|
-
params[key.slice(3)] = decodeURIComponent(match[i + 1]).split('/');
|
|
3511
|
-
} else {
|
|
3512
|
-
params[key] = decodeURIComponent(match[i + 1]);
|
|
3513
|
-
}
|
|
3514
|
-
});
|
|
3515
|
-
return params;
|
|
3516
|
-
};
|
|
3517
|
-
|
|
3518
|
-
return fn;
|
|
3519
|
-
}
|
|
3520
|
-
|
|
3521
|
-
export { dev };
|