Showing
132 changed files
with
19387 additions
and
6 deletions
node_modules/.bin/ejs
0 → 100644
1 | +#!/bin/sh | ||
2 | +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") | ||
3 | + | ||
4 | +case `uname` in | ||
5 | + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; | ||
6 | +esac | ||
7 | + | ||
8 | +if [ -x "$basedir/node" ]; then | ||
9 | + exec "$basedir/node" "$basedir/../ejs/bin/cli.js" "$@" | ||
10 | +else | ||
11 | + exec node "$basedir/../ejs/bin/cli.js" "$@" | ||
12 | +fi |
node_modules/.bin/ejs.cmd
0 → 100644
1 | +@ECHO off | ||
2 | +GOTO start | ||
3 | +:find_dp0 | ||
4 | +SET dp0=%~dp0 | ||
5 | +EXIT /b | ||
6 | +:start | ||
7 | +SETLOCAL | ||
8 | +CALL :find_dp0 | ||
9 | + | ||
10 | +IF EXIST "%dp0%\node.exe" ( | ||
11 | + SET "_prog=%dp0%\node.exe" | ||
12 | +) ELSE ( | ||
13 | + SET "_prog=node" | ||
14 | + SET PATHEXT=%PATHEXT:;.JS;=;% | ||
15 | +) | ||
16 | + | ||
17 | +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ejs\bin\cli.js" %* |
node_modules/.bin/ejs.ps1
0 → 100644
1 | +#!/usr/bin/env pwsh | ||
2 | +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent | ||
3 | + | ||
4 | +$exe="" | ||
5 | +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { | ||
6 | + # Fix case when both the Windows and Linux builds of Node | ||
7 | + # are installed in the same directory | ||
8 | + $exe=".exe" | ||
9 | +} | ||
10 | +$ret=0 | ||
11 | +if (Test-Path "$basedir/node$exe") { | ||
12 | + # Support pipeline input | ||
13 | + if ($MyInvocation.ExpectingInput) { | ||
14 | + $input | & "$basedir/node$exe" "$basedir/../ejs/bin/cli.js" $args | ||
15 | + } else { | ||
16 | + & "$basedir/node$exe" "$basedir/../ejs/bin/cli.js" $args | ||
17 | + } | ||
18 | + $ret=$LASTEXITCODE | ||
19 | +} else { | ||
20 | + # Support pipeline input | ||
21 | + if ($MyInvocation.ExpectingInput) { | ||
22 | + $input | & "node$exe" "$basedir/../ejs/bin/cli.js" $args | ||
23 | + } else { | ||
24 | + & "node$exe" "$basedir/../ejs/bin/cli.js" $args | ||
25 | + } | ||
26 | + $ret=$LASTEXITCODE | ||
27 | +} | ||
28 | +exit $ret |
node_modules/.bin/jake
0 → 100644
1 | +#!/bin/sh | ||
2 | +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") | ||
3 | + | ||
4 | +case `uname` in | ||
5 | + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; | ||
6 | +esac | ||
7 | + | ||
8 | +if [ -x "$basedir/node" ]; then | ||
9 | + exec "$basedir/node" "$basedir/../jake/bin/cli.js" "$@" | ||
10 | +else | ||
11 | + exec node "$basedir/../jake/bin/cli.js" "$@" | ||
12 | +fi |
node_modules/.bin/jake.cmd
0 → 100644
1 | +@ECHO off | ||
2 | +GOTO start | ||
3 | +:find_dp0 | ||
4 | +SET dp0=%~dp0 | ||
5 | +EXIT /b | ||
6 | +:start | ||
7 | +SETLOCAL | ||
8 | +CALL :find_dp0 | ||
9 | + | ||
10 | +IF EXIST "%dp0%\node.exe" ( | ||
11 | + SET "_prog=%dp0%\node.exe" | ||
12 | +) ELSE ( | ||
13 | + SET "_prog=node" | ||
14 | + SET PATHEXT=%PATHEXT:;.JS;=;% | ||
15 | +) | ||
16 | + | ||
17 | +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\jake\bin\cli.js" %* |
node_modules/.bin/jake.ps1
0 → 100644
1 | +#!/usr/bin/env pwsh | ||
2 | +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent | ||
3 | + | ||
4 | +$exe="" | ||
5 | +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { | ||
6 | + # Fix case when both the Windows and Linux builds of Node | ||
7 | + # are installed in the same directory | ||
8 | + $exe=".exe" | ||
9 | +} | ||
10 | +$ret=0 | ||
11 | +if (Test-Path "$basedir/node$exe") { | ||
12 | + # Support pipeline input | ||
13 | + if ($MyInvocation.ExpectingInput) { | ||
14 | + $input | & "$basedir/node$exe" "$basedir/../jake/bin/cli.js" $args | ||
15 | + } else { | ||
16 | + & "$basedir/node$exe" "$basedir/../jake/bin/cli.js" $args | ||
17 | + } | ||
18 | + $ret=$LASTEXITCODE | ||
19 | +} else { | ||
20 | + # Support pipeline input | ||
21 | + if ($MyInvocation.ExpectingInput) { | ||
22 | + $input | & "node$exe" "$basedir/../jake/bin/cli.js" $args | ||
23 | + } else { | ||
24 | + & "node$exe" "$basedir/../jake/bin/cli.js" $args | ||
25 | + } | ||
26 | + $ret=$LASTEXITCODE | ||
27 | +} | ||
28 | +exit $ret |
... | @@ -16,11 +16,32 @@ | ... | @@ -16,11 +16,32 @@ |
16 | "node": ">= 0.6" | 16 | "node": ">= 0.6" |
17 | } | 17 | } |
18 | }, | 18 | }, |
19 | + "node_modules/ansi-styles": { | ||
20 | + "version": "3.2.1", | ||
21 | + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", | ||
22 | + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", | ||
23 | + "dependencies": { | ||
24 | + "color-convert": "^1.9.0" | ||
25 | + }, | ||
26 | + "engines": { | ||
27 | + "node": ">=4" | ||
28 | + } | ||
29 | + }, | ||
19 | "node_modules/array-flatten": { | 30 | "node_modules/array-flatten": { |
20 | "version": "1.1.1", | 31 | "version": "1.1.1", |
21 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", | 32 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", |
22 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" | 33 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" |
23 | }, | 34 | }, |
35 | + "node_modules/async": { | ||
36 | + "version": "0.9.2", | ||
37 | + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", | ||
38 | + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" | ||
39 | + }, | ||
40 | + "node_modules/balanced-match": { | ||
41 | + "version": "1.0.2", | ||
42 | + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | ||
43 | + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" | ||
44 | + }, | ||
24 | "node_modules/bl": { | 45 | "node_modules/bl": { |
25 | "version": "2.2.1", | 46 | "version": "2.2.1", |
26 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", | 47 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", |
... | @@ -50,6 +71,15 @@ | ... | @@ -50,6 +71,15 @@ |
50 | "node": ">= 0.8" | 71 | "node": ">= 0.8" |
51 | } | 72 | } |
52 | }, | 73 | }, |
74 | + "node_modules/brace-expansion": { | ||
75 | + "version": "1.1.11", | ||
76 | + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||
77 | + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | ||
78 | + "dependencies": { | ||
79 | + "balanced-match": "^1.0.0", | ||
80 | + "concat-map": "0.0.1" | ||
81 | + } | ||
82 | + }, | ||
53 | "node_modules/bson": { | 83 | "node_modules/bson": { |
54 | "version": "1.1.6", | 84 | "version": "1.1.6", |
55 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", | 85 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", |
... | @@ -66,6 +96,37 @@ | ... | @@ -66,6 +96,37 @@ |
66 | "node": ">= 0.8" | 96 | "node": ">= 0.8" |
67 | } | 97 | } |
68 | }, | 98 | }, |
99 | + "node_modules/chalk": { | ||
100 | + "version": "2.4.2", | ||
101 | + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", | ||
102 | + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", | ||
103 | + "dependencies": { | ||
104 | + "ansi-styles": "^3.2.1", | ||
105 | + "escape-string-regexp": "^1.0.5", | ||
106 | + "supports-color": "^5.3.0" | ||
107 | + }, | ||
108 | + "engines": { | ||
109 | + "node": ">=4" | ||
110 | + } | ||
111 | + }, | ||
112 | + "node_modules/color-convert": { | ||
113 | + "version": "1.9.3", | ||
114 | + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", | ||
115 | + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", | ||
116 | + "dependencies": { | ||
117 | + "color-name": "1.1.3" | ||
118 | + } | ||
119 | + }, | ||
120 | + "node_modules/color-name": { | ||
121 | + "version": "1.1.3", | ||
122 | + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", | ||
123 | + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" | ||
124 | + }, | ||
125 | + "node_modules/concat-map": { | ||
126 | + "version": "0.0.1", | ||
127 | + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||
128 | + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" | ||
129 | + }, | ||
69 | "node_modules/content-disposition": { | 130 | "node_modules/content-disposition": { |
70 | "version": "0.5.3", | 131 | "version": "0.5.3", |
71 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", | 132 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", |
... | @@ -137,6 +198,20 @@ | ... | @@ -137,6 +198,20 @@ |
137 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | 198 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
138 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" | 199 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" |
139 | }, | 200 | }, |
201 | + "node_modules/ejs": { | ||
202 | + "version": "3.1.6", | ||
203 | + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", | ||
204 | + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", | ||
205 | + "dependencies": { | ||
206 | + "jake": "^10.6.1" | ||
207 | + }, | ||
208 | + "bin": { | ||
209 | + "ejs": "bin/cli.js" | ||
210 | + }, | ||
211 | + "engines": { | ||
212 | + "node": ">=0.10.0" | ||
213 | + } | ||
214 | + }, | ||
140 | "node_modules/encodeurl": { | 215 | "node_modules/encodeurl": { |
141 | "version": "1.0.2", | 216 | "version": "1.0.2", |
142 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", | 217 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", |
... | @@ -150,6 +225,14 @@ | ... | @@ -150,6 +225,14 @@ |
150 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", | 225 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", |
151 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" | 226 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" |
152 | }, | 227 | }, |
228 | + "node_modules/escape-string-regexp": { | ||
229 | + "version": "1.0.5", | ||
230 | + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||
231 | + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", | ||
232 | + "engines": { | ||
233 | + "node": ">=0.8.0" | ||
234 | + } | ||
235 | + }, | ||
153 | "node_modules/etag": { | 236 | "node_modules/etag": { |
154 | "version": "1.8.1", | 237 | "version": "1.8.1", |
155 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", | 238 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", |
... | @@ -198,6 +281,14 @@ | ... | @@ -198,6 +281,14 @@ |
198 | "node": ">= 0.10.0" | 281 | "node": ">= 0.10.0" |
199 | } | 282 | } |
200 | }, | 283 | }, |
284 | + "node_modules/filelist": { | ||
285 | + "version": "1.0.2", | ||
286 | + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", | ||
287 | + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", | ||
288 | + "dependencies": { | ||
289 | + "minimatch": "^3.0.4" | ||
290 | + } | ||
291 | + }, | ||
201 | "node_modules/finalhandler": { | 292 | "node_modules/finalhandler": { |
202 | "version": "1.1.2", | 293 | "version": "1.1.2", |
203 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", | 294 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", |
... | @@ -231,6 +322,14 @@ | ... | @@ -231,6 +322,14 @@ |
231 | "node": ">= 0.6" | 322 | "node": ">= 0.6" |
232 | } | 323 | } |
233 | }, | 324 | }, |
325 | + "node_modules/has-flag": { | ||
326 | + "version": "3.0.0", | ||
327 | + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", | ||
328 | + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", | ||
329 | + "engines": { | ||
330 | + "node": ">=4" | ||
331 | + } | ||
332 | + }, | ||
234 | "node_modules/http-errors": { | 333 | "node_modules/http-errors": { |
235 | "version": "1.7.2", | 334 | "version": "1.7.2", |
236 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", | 335 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", |
... | @@ -275,6 +374,23 @@ | ... | @@ -275,6 +374,23 @@ |
275 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | 374 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", |
276 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" | 375 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" |
277 | }, | 376 | }, |
377 | + "node_modules/jake": { | ||
378 | + "version": "10.8.2", | ||
379 | + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", | ||
380 | + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", | ||
381 | + "dependencies": { | ||
382 | + "async": "0.9.x", | ||
383 | + "chalk": "^2.4.2", | ||
384 | + "filelist": "^1.0.1", | ||
385 | + "minimatch": "^3.0.4" | ||
386 | + }, | ||
387 | + "bin": { | ||
388 | + "jake": "bin/cli.js" | ||
389 | + }, | ||
390 | + "engines": { | ||
391 | + "node": "*" | ||
392 | + } | ||
393 | + }, | ||
278 | "node_modules/media-typer": { | 394 | "node_modules/media-typer": { |
279 | "version": "0.3.0", | 395 | "version": "0.3.0", |
280 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", | 396 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", |
... | @@ -332,6 +448,17 @@ | ... | @@ -332,6 +448,17 @@ |
332 | "node": ">= 0.6" | 448 | "node": ">= 0.6" |
333 | } | 449 | } |
334 | }, | 450 | }, |
451 | + "node_modules/minimatch": { | ||
452 | + "version": "3.0.4", | ||
453 | + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | ||
454 | + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", | ||
455 | + "dependencies": { | ||
456 | + "brace-expansion": "^1.1.7" | ||
457 | + }, | ||
458 | + "engines": { | ||
459 | + "node": "*" | ||
460 | + } | ||
461 | + }, | ||
335 | "node_modules/mongodb": { | 462 | "node_modules/mongodb": { |
336 | "version": "3.6.4", | 463 | "version": "3.6.4", |
337 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", | 464 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", |
... | @@ -587,6 +714,17 @@ | ... | @@ -587,6 +714,17 @@ |
587 | "safe-buffer": "~5.1.0" | 714 | "safe-buffer": "~5.1.0" |
588 | } | 715 | } |
589 | }, | 716 | }, |
717 | + "node_modules/supports-color": { | ||
718 | + "version": "5.5.0", | ||
719 | + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", | ||
720 | + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", | ||
721 | + "dependencies": { | ||
722 | + "has-flag": "^3.0.0" | ||
723 | + }, | ||
724 | + "engines": { | ||
725 | + "node": ">=4" | ||
726 | + } | ||
727 | + }, | ||
590 | "node_modules/toidentifier": { | 728 | "node_modules/toidentifier": { |
591 | "version": "1.0.0", | 729 | "version": "1.0.0", |
592 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", | 730 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", | ... | ... |
node_modules/ansi-styles/index.js
0 → 100644
1 | +'use strict'; | ||
2 | +const colorConvert = require('color-convert'); | ||
3 | + | ||
4 | +const wrapAnsi16 = (fn, offset) => function () { | ||
5 | + const code = fn.apply(colorConvert, arguments); | ||
6 | + return `\u001B[${code + offset}m`; | ||
7 | +}; | ||
8 | + | ||
9 | +const wrapAnsi256 = (fn, offset) => function () { | ||
10 | + const code = fn.apply(colorConvert, arguments); | ||
11 | + return `\u001B[${38 + offset};5;${code}m`; | ||
12 | +}; | ||
13 | + | ||
14 | +const wrapAnsi16m = (fn, offset) => function () { | ||
15 | + const rgb = fn.apply(colorConvert, arguments); | ||
16 | + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; | ||
17 | +}; | ||
18 | + | ||
19 | +function assembleStyles() { | ||
20 | + const codes = new Map(); | ||
21 | + const styles = { | ||
22 | + modifier: { | ||
23 | + reset: [0, 0], | ||
24 | + // 21 isn't widely supported and 22 does the same thing | ||
25 | + bold: [1, 22], | ||
26 | + dim: [2, 22], | ||
27 | + italic: [3, 23], | ||
28 | + underline: [4, 24], | ||
29 | + inverse: [7, 27], | ||
30 | + hidden: [8, 28], | ||
31 | + strikethrough: [9, 29] | ||
32 | + }, | ||
33 | + color: { | ||
34 | + black: [30, 39], | ||
35 | + red: [31, 39], | ||
36 | + green: [32, 39], | ||
37 | + yellow: [33, 39], | ||
38 | + blue: [34, 39], | ||
39 | + magenta: [35, 39], | ||
40 | + cyan: [36, 39], | ||
41 | + white: [37, 39], | ||
42 | + gray: [90, 39], | ||
43 | + | ||
44 | + // Bright color | ||
45 | + redBright: [91, 39], | ||
46 | + greenBright: [92, 39], | ||
47 | + yellowBright: [93, 39], | ||
48 | + blueBright: [94, 39], | ||
49 | + magentaBright: [95, 39], | ||
50 | + cyanBright: [96, 39], | ||
51 | + whiteBright: [97, 39] | ||
52 | + }, | ||
53 | + bgColor: { | ||
54 | + bgBlack: [40, 49], | ||
55 | + bgRed: [41, 49], | ||
56 | + bgGreen: [42, 49], | ||
57 | + bgYellow: [43, 49], | ||
58 | + bgBlue: [44, 49], | ||
59 | + bgMagenta: [45, 49], | ||
60 | + bgCyan: [46, 49], | ||
61 | + bgWhite: [47, 49], | ||
62 | + | ||
63 | + // Bright color | ||
64 | + bgBlackBright: [100, 49], | ||
65 | + bgRedBright: [101, 49], | ||
66 | + bgGreenBright: [102, 49], | ||
67 | + bgYellowBright: [103, 49], | ||
68 | + bgBlueBright: [104, 49], | ||
69 | + bgMagentaBright: [105, 49], | ||
70 | + bgCyanBright: [106, 49], | ||
71 | + bgWhiteBright: [107, 49] | ||
72 | + } | ||
73 | + }; | ||
74 | + | ||
75 | + // Fix humans | ||
76 | + styles.color.grey = styles.color.gray; | ||
77 | + | ||
78 | + for (const groupName of Object.keys(styles)) { | ||
79 | + const group = styles[groupName]; | ||
80 | + | ||
81 | + for (const styleName of Object.keys(group)) { | ||
82 | + const style = group[styleName]; | ||
83 | + | ||
84 | + styles[styleName] = { | ||
85 | + open: `\u001B[${style[0]}m`, | ||
86 | + close: `\u001B[${style[1]}m` | ||
87 | + }; | ||
88 | + | ||
89 | + group[styleName] = styles[styleName]; | ||
90 | + | ||
91 | + codes.set(style[0], style[1]); | ||
92 | + } | ||
93 | + | ||
94 | + Object.defineProperty(styles, groupName, { | ||
95 | + value: group, | ||
96 | + enumerable: false | ||
97 | + }); | ||
98 | + | ||
99 | + Object.defineProperty(styles, 'codes', { | ||
100 | + value: codes, | ||
101 | + enumerable: false | ||
102 | + }); | ||
103 | + } | ||
104 | + | ||
105 | + const ansi2ansi = n => n; | ||
106 | + const rgb2rgb = (r, g, b) => [r, g, b]; | ||
107 | + | ||
108 | + styles.color.close = '\u001B[39m'; | ||
109 | + styles.bgColor.close = '\u001B[49m'; | ||
110 | + | ||
111 | + styles.color.ansi = { | ||
112 | + ansi: wrapAnsi16(ansi2ansi, 0) | ||
113 | + }; | ||
114 | + styles.color.ansi256 = { | ||
115 | + ansi256: wrapAnsi256(ansi2ansi, 0) | ||
116 | + }; | ||
117 | + styles.color.ansi16m = { | ||
118 | + rgb: wrapAnsi16m(rgb2rgb, 0) | ||
119 | + }; | ||
120 | + | ||
121 | + styles.bgColor.ansi = { | ||
122 | + ansi: wrapAnsi16(ansi2ansi, 10) | ||
123 | + }; | ||
124 | + styles.bgColor.ansi256 = { | ||
125 | + ansi256: wrapAnsi256(ansi2ansi, 10) | ||
126 | + }; | ||
127 | + styles.bgColor.ansi16m = { | ||
128 | + rgb: wrapAnsi16m(rgb2rgb, 10) | ||
129 | + }; | ||
130 | + | ||
131 | + for (let key of Object.keys(colorConvert)) { | ||
132 | + if (typeof colorConvert[key] !== 'object') { | ||
133 | + continue; | ||
134 | + } | ||
135 | + | ||
136 | + const suite = colorConvert[key]; | ||
137 | + | ||
138 | + if (key === 'ansi16') { | ||
139 | + key = 'ansi'; | ||
140 | + } | ||
141 | + | ||
142 | + if ('ansi16' in suite) { | ||
143 | + styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); | ||
144 | + styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); | ||
145 | + } | ||
146 | + | ||
147 | + if ('ansi256' in suite) { | ||
148 | + styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); | ||
149 | + styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); | ||
150 | + } | ||
151 | + | ||
152 | + if ('rgb' in suite) { | ||
153 | + styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); | ||
154 | + styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); | ||
155 | + } | ||
156 | + } | ||
157 | + | ||
158 | + return styles; | ||
159 | +} | ||
160 | + | ||
161 | +// Make the export immutable | ||
162 | +Object.defineProperty(module, 'exports', { | ||
163 | + enumerable: true, | ||
164 | + get: assembleStyles | ||
165 | +}); |
node_modules/ansi-styles/license
0 → 100644
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
6 | + | ||
7 | +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
8 | + | ||
9 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
node_modules/ansi-styles/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "ansi-styles", | ||
3 | + "version": "3.2.1", | ||
4 | + "description": "ANSI escape codes for styling strings in the terminal", | ||
5 | + "license": "MIT", | ||
6 | + "repository": "chalk/ansi-styles", | ||
7 | + "author": { | ||
8 | + "name": "Sindre Sorhus", | ||
9 | + "email": "sindresorhus@gmail.com", | ||
10 | + "url": "sindresorhus.com" | ||
11 | + }, | ||
12 | + "engines": { | ||
13 | + "node": ">=4" | ||
14 | + }, | ||
15 | + "scripts": { | ||
16 | + "test": "xo && ava", | ||
17 | + "screenshot": "svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor" | ||
18 | + }, | ||
19 | + "files": [ | ||
20 | + "index.js" | ||
21 | + ], | ||
22 | + "keywords": [ | ||
23 | + "ansi", | ||
24 | + "styles", | ||
25 | + "color", | ||
26 | + "colour", | ||
27 | + "colors", | ||
28 | + "terminal", | ||
29 | + "console", | ||
30 | + "cli", | ||
31 | + "string", | ||
32 | + "tty", | ||
33 | + "escape", | ||
34 | + "formatting", | ||
35 | + "rgb", | ||
36 | + "256", | ||
37 | + "shell", | ||
38 | + "xterm", | ||
39 | + "log", | ||
40 | + "logging", | ||
41 | + "command-line", | ||
42 | + "text" | ||
43 | + ], | ||
44 | + "dependencies": { | ||
45 | + "color-convert": "^1.9.0" | ||
46 | + }, | ||
47 | + "devDependencies": { | ||
48 | + "ava": "*", | ||
49 | + "babel-polyfill": "^6.23.0", | ||
50 | + "svg-term-cli": "^2.1.1", | ||
51 | + "xo": "*" | ||
52 | + }, | ||
53 | + "ava": { | ||
54 | + "require": "babel-polyfill" | ||
55 | + } | ||
56 | +} |
node_modules/ansi-styles/readme.md
0 → 100644
1 | +# ansi-styles [![Build Status](https://travis-ci.org/chalk/ansi-styles.svg?branch=master)](https://travis-ci.org/chalk/ansi-styles) | ||
2 | + | ||
3 | +> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal | ||
4 | + | ||
5 | +You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings. | ||
6 | + | ||
7 | +<img src="https://cdn.rawgit.com/chalk/ansi-styles/8261697c95bf34b6c7767e2cbe9941a851d59385/screenshot.svg" width="900"> | ||
8 | + | ||
9 | + | ||
10 | +## Install | ||
11 | + | ||
12 | +``` | ||
13 | +$ npm install ansi-styles | ||
14 | +``` | ||
15 | + | ||
16 | + | ||
17 | +## Usage | ||
18 | + | ||
19 | +```js | ||
20 | +const style = require('ansi-styles'); | ||
21 | + | ||
22 | +console.log(`${style.green.open}Hello world!${style.green.close}`); | ||
23 | + | ||
24 | + | ||
25 | +// Color conversion between 16/256/truecolor | ||
26 | +// NOTE: If conversion goes to 16 colors or 256 colors, the original color | ||
27 | +// may be degraded to fit that color palette. This means terminals | ||
28 | +// that do not support 16 million colors will best-match the | ||
29 | +// original color. | ||
30 | +console.log(style.bgColor.ansi.hsl(120, 80, 72) + 'Hello world!' + style.bgColor.close); | ||
31 | +console.log(style.color.ansi256.rgb(199, 20, 250) + 'Hello world!' + style.color.close); | ||
32 | +console.log(style.color.ansi16m.hex('#ABCDEF') + 'Hello world!' + style.color.close); | ||
33 | +``` | ||
34 | + | ||
35 | +## API | ||
36 | + | ||
37 | +Each style has an `open` and `close` property. | ||
38 | + | ||
39 | + | ||
40 | +## Styles | ||
41 | + | ||
42 | +### Modifiers | ||
43 | + | ||
44 | +- `reset` | ||
45 | +- `bold` | ||
46 | +- `dim` | ||
47 | +- `italic` *(Not widely supported)* | ||
48 | +- `underline` | ||
49 | +- `inverse` | ||
50 | +- `hidden` | ||
51 | +- `strikethrough` *(Not widely supported)* | ||
52 | + | ||
53 | +### Colors | ||
54 | + | ||
55 | +- `black` | ||
56 | +- `red` | ||
57 | +- `green` | ||
58 | +- `yellow` | ||
59 | +- `blue` | ||
60 | +- `magenta` | ||
61 | +- `cyan` | ||
62 | +- `white` | ||
63 | +- `gray` ("bright black") | ||
64 | +- `redBright` | ||
65 | +- `greenBright` | ||
66 | +- `yellowBright` | ||
67 | +- `blueBright` | ||
68 | +- `magentaBright` | ||
69 | +- `cyanBright` | ||
70 | +- `whiteBright` | ||
71 | + | ||
72 | +### Background colors | ||
73 | + | ||
74 | +- `bgBlack` | ||
75 | +- `bgRed` | ||
76 | +- `bgGreen` | ||
77 | +- `bgYellow` | ||
78 | +- `bgBlue` | ||
79 | +- `bgMagenta` | ||
80 | +- `bgCyan` | ||
81 | +- `bgWhite` | ||
82 | +- `bgBlackBright` | ||
83 | +- `bgRedBright` | ||
84 | +- `bgGreenBright` | ||
85 | +- `bgYellowBright` | ||
86 | +- `bgBlueBright` | ||
87 | +- `bgMagentaBright` | ||
88 | +- `bgCyanBright` | ||
89 | +- `bgWhiteBright` | ||
90 | + | ||
91 | + | ||
92 | +## Advanced usage | ||
93 | + | ||
94 | +By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module. | ||
95 | + | ||
96 | +- `style.modifier` | ||
97 | +- `style.color` | ||
98 | +- `style.bgColor` | ||
99 | + | ||
100 | +###### Example | ||
101 | + | ||
102 | +```js | ||
103 | +console.log(style.color.green.open); | ||
104 | +``` | ||
105 | + | ||
106 | +Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `style.codes`, which returns a `Map` with the open codes as keys and close codes as values. | ||
107 | + | ||
108 | +###### Example | ||
109 | + | ||
110 | +```js | ||
111 | +console.log(style.codes.get(36)); | ||
112 | +//=> 39 | ||
113 | +``` | ||
114 | + | ||
115 | + | ||
116 | +## [256 / 16 million (TrueColor) support](https://gist.github.com/XVilka/8346728) | ||
117 | + | ||
118 | +`ansi-styles` uses the [`color-convert`](https://github.com/Qix-/color-convert) package to allow for converting between various colors and ANSI escapes, with support for 256 and 16 million colors. | ||
119 | + | ||
120 | +To use these, call the associated conversion function with the intended output, for example: | ||
121 | + | ||
122 | +```js | ||
123 | +style.color.ansi.rgb(100, 200, 15); // RGB to 16 color ansi foreground code | ||
124 | +style.bgColor.ansi.rgb(100, 200, 15); // RGB to 16 color ansi background code | ||
125 | + | ||
126 | +style.color.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code | ||
127 | +style.bgColor.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code | ||
128 | + | ||
129 | +style.color.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color foreground code | ||
130 | +style.bgColor.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color background code | ||
131 | +``` | ||
132 | + | ||
133 | + | ||
134 | +## Related | ||
135 | + | ||
136 | +- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal | ||
137 | + | ||
138 | + | ||
139 | +## Maintainers | ||
140 | + | ||
141 | +- [Sindre Sorhus](https://github.com/sindresorhus) | ||
142 | +- [Josh Junon](https://github.com/qix-) | ||
143 | + | ||
144 | + | ||
145 | +## License | ||
146 | + | ||
147 | +MIT |
node_modules/async/.travis.yml
0 → 100644
node_modules/async/LICENSE
0 → 100644
1 | +Copyright (c) 2010-2014 Caolan McMahon | ||
2 | + | ||
3 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | +of this software and associated documentation files (the "Software"), to deal | ||
5 | +in the Software without restriction, including without limitation the rights | ||
6 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
7 | +copies of the Software, and to permit persons to whom the Software is | ||
8 | +furnished to do so, subject to the following conditions: | ||
9 | + | ||
10 | +The above copyright notice and this permission notice shall be included in | ||
11 | +all copies or substantial portions of the Software. | ||
12 | + | ||
13 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
18 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
19 | +THE SOFTWARE. |
node_modules/async/README.md
0 → 100644
1 | +# Async.js | ||
2 | + | ||
3 | +[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) | ||
4 | + | ||
5 | + | ||
6 | +Async is a utility module which provides straight-forward, powerful functions | ||
7 | +for working with asynchronous JavaScript. Although originally designed for | ||
8 | +use with [Node.js](http://nodejs.org) and installable via `npm install async`, | ||
9 | +it can also be used directly in the browser. | ||
10 | + | ||
11 | +Async is also installable via: | ||
12 | + | ||
13 | +- [bower](http://bower.io/): `bower install async` | ||
14 | +- [component](https://github.com/component/component): `component install | ||
15 | + caolan/async` | ||
16 | +- [jam](http://jamjs.org/): `jam install async` | ||
17 | +- [spm](http://spmjs.io/): `spm install async` | ||
18 | + | ||
19 | +Async provides around 20 functions that include the usual 'functional' | ||
20 | +suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns | ||
21 | +for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these | ||
22 | +functions assume you follow the Node.js convention of providing a single | ||
23 | +callback as the last argument of your `async` function. | ||
24 | + | ||
25 | + | ||
26 | +## Quick Examples | ||
27 | + | ||
28 | +```javascript | ||
29 | +async.map(['file1','file2','file3'], fs.stat, function(err, results){ | ||
30 | + // results is now an array of stats for each file | ||
31 | +}); | ||
32 | + | ||
33 | +async.filter(['file1','file2','file3'], fs.exists, function(results){ | ||
34 | + // results now equals an array of the existing files | ||
35 | +}); | ||
36 | + | ||
37 | +async.parallel([ | ||
38 | + function(){ ... }, | ||
39 | + function(){ ... } | ||
40 | +], callback); | ||
41 | + | ||
42 | +async.series([ | ||
43 | + function(){ ... }, | ||
44 | + function(){ ... } | ||
45 | +]); | ||
46 | +``` | ||
47 | + | ||
48 | +There are many more functions available so take a look at the docs below for a | ||
49 | +full list. This module aims to be comprehensive, so if you feel anything is | ||
50 | +missing please create a GitHub issue for it. | ||
51 | + | ||
52 | +## Common Pitfalls | ||
53 | + | ||
54 | +### Binding a context to an iterator | ||
55 | + | ||
56 | +This section is really about `bind`, not about `async`. If you are wondering how to | ||
57 | +make `async` execute your iterators in a given context, or are confused as to why | ||
58 | +a method of another library isn't working as an iterator, study this example: | ||
59 | + | ||
60 | +```js | ||
61 | +// Here is a simple object with an (unnecessarily roundabout) squaring method | ||
62 | +var AsyncSquaringLibrary = { | ||
63 | + squareExponent: 2, | ||
64 | + square: function(number, callback){ | ||
65 | + var result = Math.pow(number, this.squareExponent); | ||
66 | + setTimeout(function(){ | ||
67 | + callback(null, result); | ||
68 | + }, 200); | ||
69 | + } | ||
70 | +}; | ||
71 | + | ||
72 | +async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ | ||
73 | + // result is [NaN, NaN, NaN] | ||
74 | + // This fails because the `this.squareExponent` expression in the square | ||
75 | + // function is not evaluated in the context of AsyncSquaringLibrary, and is | ||
76 | + // therefore undefined. | ||
77 | +}); | ||
78 | + | ||
79 | +async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ | ||
80 | + // result is [1, 4, 9] | ||
81 | + // With the help of bind we can attach a context to the iterator before | ||
82 | + // passing it to async. Now the square function will be executed in its | ||
83 | + // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` | ||
84 | + // will be as expected. | ||
85 | +}); | ||
86 | +``` | ||
87 | + | ||
88 | +## Download | ||
89 | + | ||
90 | +The source is available for download from | ||
91 | +[GitHub](http://github.com/caolan/async). | ||
92 | +Alternatively, you can install using Node Package Manager (`npm`): | ||
93 | + | ||
94 | + npm install async | ||
95 | + | ||
96 | +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed | ||
97 | + | ||
98 | +## In the Browser | ||
99 | + | ||
100 | +So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. | ||
101 | + | ||
102 | +Usage: | ||
103 | + | ||
104 | +```html | ||
105 | +<script type="text/javascript" src="async.js"></script> | ||
106 | +<script type="text/javascript"> | ||
107 | + | ||
108 | + async.map(data, asyncProcess, function(err, results){ | ||
109 | + alert(results); | ||
110 | + }); | ||
111 | + | ||
112 | +</script> | ||
113 | +``` | ||
114 | + | ||
115 | +## Documentation | ||
116 | + | ||
117 | +### Collections | ||
118 | + | ||
119 | +* [`each`](#each) | ||
120 | +* [`eachSeries`](#eachSeries) | ||
121 | +* [`eachLimit`](#eachLimit) | ||
122 | +* [`map`](#map) | ||
123 | +* [`mapSeries`](#mapSeries) | ||
124 | +* [`mapLimit`](#mapLimit) | ||
125 | +* [`filter`](#filter) | ||
126 | +* [`filterSeries`](#filterSeries) | ||
127 | +* [`reject`](#reject) | ||
128 | +* [`rejectSeries`](#rejectSeries) | ||
129 | +* [`reduce`](#reduce) | ||
130 | +* [`reduceRight`](#reduceRight) | ||
131 | +* [`detect`](#detect) | ||
132 | +* [`detectSeries`](#detectSeries) | ||
133 | +* [`sortBy`](#sortBy) | ||
134 | +* [`some`](#some) | ||
135 | +* [`every`](#every) | ||
136 | +* [`concat`](#concat) | ||
137 | +* [`concatSeries`](#concatSeries) | ||
138 | + | ||
139 | +### Control Flow | ||
140 | + | ||
141 | +* [`series`](#seriestasks-callback) | ||
142 | +* [`parallel`](#parallel) | ||
143 | +* [`parallelLimit`](#parallellimittasks-limit-callback) | ||
144 | +* [`whilst`](#whilst) | ||
145 | +* [`doWhilst`](#doWhilst) | ||
146 | +* [`until`](#until) | ||
147 | +* [`doUntil`](#doUntil) | ||
148 | +* [`forever`](#forever) | ||
149 | +* [`waterfall`](#waterfall) | ||
150 | +* [`compose`](#compose) | ||
151 | +* [`seq`](#seq) | ||
152 | +* [`applyEach`](#applyEach) | ||
153 | +* [`applyEachSeries`](#applyEachSeries) | ||
154 | +* [`queue`](#queue) | ||
155 | +* [`priorityQueue`](#priorityQueue) | ||
156 | +* [`cargo`](#cargo) | ||
157 | +* [`auto`](#auto) | ||
158 | +* [`retry`](#retry) | ||
159 | +* [`iterator`](#iterator) | ||
160 | +* [`apply`](#apply) | ||
161 | +* [`nextTick`](#nextTick) | ||
162 | +* [`times`](#times) | ||
163 | +* [`timesSeries`](#timesSeries) | ||
164 | + | ||
165 | +### Utils | ||
166 | + | ||
167 | +* [`memoize`](#memoize) | ||
168 | +* [`unmemoize`](#unmemoize) | ||
169 | +* [`log`](#log) | ||
170 | +* [`dir`](#dir) | ||
171 | +* [`noConflict`](#noConflict) | ||
172 | + | ||
173 | + | ||
174 | +## Collections | ||
175 | + | ||
176 | +<a name="forEach" /> | ||
177 | +<a name="each" /> | ||
178 | +### each(arr, iterator, callback) | ||
179 | + | ||
180 | +Applies the function `iterator` to each item in `arr`, in parallel. | ||
181 | +The `iterator` is called with an item from the list, and a callback for when it | ||
182 | +has finished. If the `iterator` passes an error to its `callback`, the main | ||
183 | +`callback` (for the `each` function) is immediately called with the error. | ||
184 | + | ||
185 | +Note, that since this function applies `iterator` to each item in parallel, | ||
186 | +there is no guarantee that the iterator functions will complete in order. | ||
187 | + | ||
188 | +__Arguments__ | ||
189 | + | ||
190 | +* `arr` - An array to iterate over. | ||
191 | +* `iterator(item, callback)` - A function to apply to each item in `arr`. | ||
192 | + The iterator is passed a `callback(err)` which must be called once it has | ||
193 | + completed. If no error has occurred, the `callback` should be run without | ||
194 | + arguments or with an explicit `null` argument. | ||
195 | +* `callback(err)` - A callback which is called when all `iterator` functions | ||
196 | + have finished, or an error occurs. | ||
197 | + | ||
198 | +__Examples__ | ||
199 | + | ||
200 | + | ||
201 | +```js | ||
202 | +// assuming openFiles is an array of file names and saveFile is a function | ||
203 | +// to save the modified contents of that file: | ||
204 | + | ||
205 | +async.each(openFiles, saveFile, function(err){ | ||
206 | + // if any of the saves produced an error, err would equal that error | ||
207 | +}); | ||
208 | +``` | ||
209 | + | ||
210 | +```js | ||
211 | +// assuming openFiles is an array of file names | ||
212 | + | ||
213 | +async.each(openFiles, function(file, callback) { | ||
214 | + | ||
215 | + // Perform operation on file here. | ||
216 | + console.log('Processing file ' + file); | ||
217 | + | ||
218 | + if( file.length > 32 ) { | ||
219 | + console.log('This file name is too long'); | ||
220 | + callback('File name too long'); | ||
221 | + } else { | ||
222 | + // Do work to process file here | ||
223 | + console.log('File processed'); | ||
224 | + callback(); | ||
225 | + } | ||
226 | +}, function(err){ | ||
227 | + // if any of the file processing produced an error, err would equal that error | ||
228 | + if( err ) { | ||
229 | + // One of the iterations produced an error. | ||
230 | + // All processing will now stop. | ||
231 | + console.log('A file failed to process'); | ||
232 | + } else { | ||
233 | + console.log('All files have been processed successfully'); | ||
234 | + } | ||
235 | +}); | ||
236 | +``` | ||
237 | + | ||
238 | +--------------------------------------- | ||
239 | + | ||
240 | +<a name="forEachSeries" /> | ||
241 | +<a name="eachSeries" /> | ||
242 | +### eachSeries(arr, iterator, callback) | ||
243 | + | ||
244 | +The same as [`each`](#each), only `iterator` is applied to each item in `arr` in | ||
245 | +series. The next `iterator` is only called once the current one has completed. | ||
246 | +This means the `iterator` functions will complete in order. | ||
247 | + | ||
248 | + | ||
249 | +--------------------------------------- | ||
250 | + | ||
251 | +<a name="forEachLimit" /> | ||
252 | +<a name="eachLimit" /> | ||
253 | +### eachLimit(arr, limit, iterator, callback) | ||
254 | + | ||
255 | +The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously | ||
256 | +running at any time. | ||
257 | + | ||
258 | +Note that the items in `arr` are not processed in batches, so there is no guarantee that | ||
259 | +the first `limit` `iterator` functions will complete before any others are started. | ||
260 | + | ||
261 | +__Arguments__ | ||
262 | + | ||
263 | +* `arr` - An array to iterate over. | ||
264 | +* `limit` - The maximum number of `iterator`s to run at any time. | ||
265 | +* `iterator(item, callback)` - A function to apply to each item in `arr`. | ||
266 | + The iterator is passed a `callback(err)` which must be called once it has | ||
267 | + completed. If no error has occurred, the callback should be run without | ||
268 | + arguments or with an explicit `null` argument. | ||
269 | +* `callback(err)` - A callback which is called when all `iterator` functions | ||
270 | + have finished, or an error occurs. | ||
271 | + | ||
272 | +__Example__ | ||
273 | + | ||
274 | +```js | ||
275 | +// Assume documents is an array of JSON objects and requestApi is a | ||
276 | +// function that interacts with a rate-limited REST api. | ||
277 | + | ||
278 | +async.eachLimit(documents, 20, requestApi, function(err){ | ||
279 | + // if any of the saves produced an error, err would equal that error | ||
280 | +}); | ||
281 | +``` | ||
282 | + | ||
283 | +--------------------------------------- | ||
284 | + | ||
285 | +<a name="map" /> | ||
286 | +### map(arr, iterator, callback) | ||
287 | + | ||
288 | +Produces a new array of values by mapping each value in `arr` through | ||
289 | +the `iterator` function. The `iterator` is called with an item from `arr` and a | ||
290 | +callback for when it has finished processing. Each of these callback takes 2 arguments: | ||
291 | +an `error`, and the transformed item from `arr`. If `iterator` passes an error to his | ||
292 | +callback, the main `callback` (for the `map` function) is immediately called with the error. | ||
293 | + | ||
294 | +Note, that since this function applies the `iterator` to each item in parallel, | ||
295 | +there is no guarantee that the `iterator` functions will complete in order. | ||
296 | +However, the results array will be in the same order as the original `arr`. | ||
297 | + | ||
298 | +__Arguments__ | ||
299 | + | ||
300 | +* `arr` - An array to iterate over. | ||
301 | +* `iterator(item, callback)` - A function to apply to each item in `arr`. | ||
302 | + The iterator is passed a `callback(err, transformed)` which must be called once | ||
303 | + it has completed with an error (which can be `null`) and a transformed item. | ||
304 | +* `callback(err, results)` - A callback which is called when all `iterator` | ||
305 | + functions have finished, or an error occurs. Results is an array of the | ||
306 | + transformed items from the `arr`. | ||
307 | + | ||
308 | +__Example__ | ||
309 | + | ||
310 | +```js | ||
311 | +async.map(['file1','file2','file3'], fs.stat, function(err, results){ | ||
312 | + // results is now an array of stats for each file | ||
313 | +}); | ||
314 | +``` | ||
315 | + | ||
316 | +--------------------------------------- | ||
317 | + | ||
318 | +<a name="mapSeries" /> | ||
319 | +### mapSeries(arr, iterator, callback) | ||
320 | + | ||
321 | +The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in | ||
322 | +series. The next `iterator` is only called once the current one has completed. | ||
323 | +The results array will be in the same order as the original. | ||
324 | + | ||
325 | + | ||
326 | +--------------------------------------- | ||
327 | + | ||
328 | +<a name="mapLimit" /> | ||
329 | +### mapLimit(arr, limit, iterator, callback) | ||
330 | + | ||
331 | +The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously | ||
332 | +running at any time. | ||
333 | + | ||
334 | +Note that the items are not processed in batches, so there is no guarantee that | ||
335 | +the first `limit` `iterator` functions will complete before any others are started. | ||
336 | + | ||
337 | +__Arguments__ | ||
338 | + | ||
339 | +* `arr` - An array to iterate over. | ||
340 | +* `limit` - The maximum number of `iterator`s to run at any time. | ||
341 | +* `iterator(item, callback)` - A function to apply to each item in `arr`. | ||
342 | + The iterator is passed a `callback(err, transformed)` which must be called once | ||
343 | + it has completed with an error (which can be `null`) and a transformed item. | ||
344 | +* `callback(err, results)` - A callback which is called when all `iterator` | ||
345 | + calls have finished, or an error occurs. The result is an array of the | ||
346 | + transformed items from the original `arr`. | ||
347 | + | ||
348 | +__Example__ | ||
349 | + | ||
350 | +```js | ||
351 | +async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){ | ||
352 | + // results is now an array of stats for each file | ||
353 | +}); | ||
354 | +``` | ||
355 | + | ||
356 | +--------------------------------------- | ||
357 | + | ||
358 | +<a name="select" /> | ||
359 | +<a name="filter" /> | ||
360 | +### filter(arr, iterator, callback) | ||
361 | + | ||
362 | +__Alias:__ `select` | ||
363 | + | ||
364 | +Returns a new array of all the values in `arr` which pass an async truth test. | ||
365 | +_The callback for each `iterator` call only accepts a single argument of `true` or | ||
366 | +`false`; it does not accept an error argument first!_ This is in-line with the | ||
367 | +way node libraries work with truth tests like `fs.exists`. This operation is | ||
368 | +performed in parallel, but the results array will be in the same order as the | ||
369 | +original. | ||
370 | + | ||
371 | +__Arguments__ | ||
372 | + | ||
373 | +* `arr` - An array to iterate over. | ||
374 | +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. | ||
375 | + The `iterator` is passed a `callback(truthValue)`, which must be called with a | ||
376 | + boolean argument once it has completed. | ||
377 | +* `callback(results)` - A callback which is called after all the `iterator` | ||
378 | + functions have finished. | ||
379 | + | ||
380 | +__Example__ | ||
381 | + | ||
382 | +```js | ||
383 | +async.filter(['file1','file2','file3'], fs.exists, function(results){ | ||
384 | + // results now equals an array of the existing files | ||
385 | +}); | ||
386 | +``` | ||
387 | + | ||
388 | +--------------------------------------- | ||
389 | + | ||
390 | +<a name="selectSeries" /> | ||
391 | +<a name="filterSeries" /> | ||
392 | +### filterSeries(arr, iterator, callback) | ||
393 | + | ||
394 | +__Alias:__ `selectSeries` | ||
395 | + | ||
396 | +The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in | ||
397 | +series. The next `iterator` is only called once the current one has completed. | ||
398 | +The results array will be in the same order as the original. | ||
399 | + | ||
400 | +--------------------------------------- | ||
401 | + | ||
402 | +<a name="reject" /> | ||
403 | +### reject(arr, iterator, callback) | ||
404 | + | ||
405 | +The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. | ||
406 | + | ||
407 | +--------------------------------------- | ||
408 | + | ||
409 | +<a name="rejectSeries" /> | ||
410 | +### rejectSeries(arr, iterator, callback) | ||
411 | + | ||
412 | +The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr` | ||
413 | +in series. | ||
414 | + | ||
415 | + | ||
416 | +--------------------------------------- | ||
417 | + | ||
418 | +<a name="reduce" /> | ||
419 | +### reduce(arr, memo, iterator, callback) | ||
420 | + | ||
421 | +__Aliases:__ `inject`, `foldl` | ||
422 | + | ||
423 | +Reduces `arr` into a single value using an async `iterator` to return | ||
424 | +each successive step. `memo` is the initial state of the reduction. | ||
425 | +This function only operates in series. | ||
426 | + | ||
427 | +For performance reasons, it may make sense to split a call to this function into | ||
428 | +a parallel map, and then use the normal `Array.prototype.reduce` on the results. | ||
429 | +This function is for situations where each step in the reduction needs to be async; | ||
430 | +if you can get the data before reducing it, then it's probably a good idea to do so. | ||
431 | + | ||
432 | +__Arguments__ | ||
433 | + | ||
434 | +* `arr` - An array to iterate over. | ||
435 | +* `memo` - The initial state of the reduction. | ||
436 | +* `iterator(memo, item, callback)` - A function applied to each item in the | ||
437 | + array to produce the next step in the reduction. The `iterator` is passed a | ||
438 | + `callback(err, reduction)` which accepts an optional error as its first | ||
439 | + argument, and the state of the reduction as the second. If an error is | ||
440 | + passed to the callback, the reduction is stopped and the main `callback` is | ||
441 | + immediately called with the error. | ||
442 | +* `callback(err, result)` - A callback which is called after all the `iterator` | ||
443 | + functions have finished. Result is the reduced value. | ||
444 | + | ||
445 | +__Example__ | ||
446 | + | ||
447 | +```js | ||
448 | +async.reduce([1,2,3], 0, function(memo, item, callback){ | ||
449 | + // pointless async: | ||
450 | + process.nextTick(function(){ | ||
451 | + callback(null, memo + item) | ||
452 | + }); | ||
453 | +}, function(err, result){ | ||
454 | + // result is now equal to the last value of memo, which is 6 | ||
455 | +}); | ||
456 | +``` | ||
457 | + | ||
458 | +--------------------------------------- | ||
459 | + | ||
460 | +<a name="reduceRight" /> | ||
461 | +### reduceRight(arr, memo, iterator, callback) | ||
462 | + | ||
463 | +__Alias:__ `foldr` | ||
464 | + | ||
465 | +Same as [`reduce`](#reduce), only operates on `arr` in reverse order. | ||
466 | + | ||
467 | + | ||
468 | +--------------------------------------- | ||
469 | + | ||
470 | +<a name="detect" /> | ||
471 | +### detect(arr, iterator, callback) | ||
472 | + | ||
473 | +Returns the first value in `arr` that passes an async truth test. The | ||
474 | +`iterator` is applied in parallel, meaning the first iterator to return `true` will | ||
475 | +fire the detect `callback` with that result. That means the result might not be | ||
476 | +the first item in the original `arr` (in terms of order) that passes the test. | ||
477 | + | ||
478 | +If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries). | ||
479 | + | ||
480 | +__Arguments__ | ||
481 | + | ||
482 | +* `arr` - An array to iterate over. | ||
483 | +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. | ||
484 | + The iterator is passed a `callback(truthValue)` which must be called with a | ||
485 | + boolean argument once it has completed. | ||
486 | +* `callback(result)` - A callback which is called as soon as any iterator returns | ||
487 | + `true`, or after all the `iterator` functions have finished. Result will be | ||
488 | + the first item in the array that passes the truth test (iterator) or the | ||
489 | + value `undefined` if none passed. | ||
490 | + | ||
491 | +__Example__ | ||
492 | + | ||
493 | +```js | ||
494 | +async.detect(['file1','file2','file3'], fs.exists, function(result){ | ||
495 | + // result now equals the first file in the list that exists | ||
496 | +}); | ||
497 | +``` | ||
498 | + | ||
499 | +--------------------------------------- | ||
500 | + | ||
501 | +<a name="detectSeries" /> | ||
502 | +### detectSeries(arr, iterator, callback) | ||
503 | + | ||
504 | +The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr` | ||
505 | +in series. This means the result is always the first in the original `arr` (in | ||
506 | +terms of array order) that passes the truth test. | ||
507 | + | ||
508 | + | ||
509 | +--------------------------------------- | ||
510 | + | ||
511 | +<a name="sortBy" /> | ||
512 | +### sortBy(arr, iterator, callback) | ||
513 | + | ||
514 | +Sorts a list by the results of running each `arr` value through an async `iterator`. | ||
515 | + | ||
516 | +__Arguments__ | ||
517 | + | ||
518 | +* `arr` - An array to iterate over. | ||
519 | +* `iterator(item, callback)` - A function to apply to each item in `arr`. | ||
520 | + The iterator is passed a `callback(err, sortValue)` which must be called once it | ||
521 | + has completed with an error (which can be `null`) and a value to use as the sort | ||
522 | + criteria. | ||
523 | +* `callback(err, results)` - A callback which is called after all the `iterator` | ||
524 | + functions have finished, or an error occurs. Results is the items from | ||
525 | + the original `arr` sorted by the values returned by the `iterator` calls. | ||
526 | + | ||
527 | +__Example__ | ||
528 | + | ||
529 | +```js | ||
530 | +async.sortBy(['file1','file2','file3'], function(file, callback){ | ||
531 | + fs.stat(file, function(err, stats){ | ||
532 | + callback(err, stats.mtime); | ||
533 | + }); | ||
534 | +}, function(err, results){ | ||
535 | + // results is now the original array of files sorted by | ||
536 | + // modified date | ||
537 | +}); | ||
538 | +``` | ||
539 | + | ||
540 | +__Sort Order__ | ||
541 | + | ||
542 | +By modifying the callback parameter the sorting order can be influenced: | ||
543 | + | ||
544 | +```js | ||
545 | +//ascending order | ||
546 | +async.sortBy([1,9,3,5], function(x, callback){ | ||
547 | + callback(null, x); | ||
548 | +}, function(err,result){ | ||
549 | + //result callback | ||
550 | +} ); | ||
551 | + | ||
552 | +//descending order | ||
553 | +async.sortBy([1,9,3,5], function(x, callback){ | ||
554 | + callback(null, x*-1); //<- x*-1 instead of x, turns the order around | ||
555 | +}, function(err,result){ | ||
556 | + //result callback | ||
557 | +} ); | ||
558 | +``` | ||
559 | + | ||
560 | +--------------------------------------- | ||
561 | + | ||
562 | +<a name="some" /> | ||
563 | +### some(arr, iterator, callback) | ||
564 | + | ||
565 | +__Alias:__ `any` | ||
566 | + | ||
567 | +Returns `true` if at least one element in the `arr` satisfies an async test. | ||
568 | +_The callback for each iterator call only accepts a single argument of `true` or | ||
569 | +`false`; it does not accept an error argument first!_ This is in-line with the | ||
570 | +way node libraries work with truth tests like `fs.exists`. Once any iterator | ||
571 | +call returns `true`, the main `callback` is immediately called. | ||
572 | + | ||
573 | +__Arguments__ | ||
574 | + | ||
575 | +* `arr` - An array to iterate over. | ||
576 | +* `iterator(item, callback)` - A truth test to apply to each item in the array | ||
577 | + in parallel. The iterator is passed a callback(truthValue) which must be | ||
578 | + called with a boolean argument once it has completed. | ||
579 | +* `callback(result)` - A callback which is called as soon as any iterator returns | ||
580 | + `true`, or after all the iterator functions have finished. Result will be | ||
581 | + either `true` or `false` depending on the values of the async tests. | ||
582 | + | ||
583 | +__Example__ | ||
584 | + | ||
585 | +```js | ||
586 | +async.some(['file1','file2','file3'], fs.exists, function(result){ | ||
587 | + // if result is true then at least one of the files exists | ||
588 | +}); | ||
589 | +``` | ||
590 | + | ||
591 | +--------------------------------------- | ||
592 | + | ||
593 | +<a name="every" /> | ||
594 | +### every(arr, iterator, callback) | ||
595 | + | ||
596 | +__Alias:__ `all` | ||
597 | + | ||
598 | +Returns `true` if every element in `arr` satisfies an async test. | ||
599 | +_The callback for each `iterator` call only accepts a single argument of `true` or | ||
600 | +`false`; it does not accept an error argument first!_ This is in-line with the | ||
601 | +way node libraries work with truth tests like `fs.exists`. | ||
602 | + | ||
603 | +__Arguments__ | ||
604 | + | ||
605 | +* `arr` - An array to iterate over. | ||
606 | +* `iterator(item, callback)` - A truth test to apply to each item in the array | ||
607 | + in parallel. The iterator is passed a callback(truthValue) which must be | ||
608 | + called with a boolean argument once it has completed. | ||
609 | +* `callback(result)` - A callback which is called after all the `iterator` | ||
610 | + functions have finished. Result will be either `true` or `false` depending on | ||
611 | + the values of the async tests. | ||
612 | + | ||
613 | +__Example__ | ||
614 | + | ||
615 | +```js | ||
616 | +async.every(['file1','file2','file3'], fs.exists, function(result){ | ||
617 | + // if result is true then every file exists | ||
618 | +}); | ||
619 | +``` | ||
620 | + | ||
621 | +--------------------------------------- | ||
622 | + | ||
623 | +<a name="concat" /> | ||
624 | +### concat(arr, iterator, callback) | ||
625 | + | ||
626 | +Applies `iterator` to each item in `arr`, concatenating the results. Returns the | ||
627 | +concatenated list. The `iterator`s are called in parallel, and the results are | ||
628 | +concatenated as they return. There is no guarantee that the results array will | ||
629 | +be returned in the original order of `arr` passed to the `iterator` function. | ||
630 | + | ||
631 | +__Arguments__ | ||
632 | + | ||
633 | +* `arr` - An array to iterate over. | ||
634 | +* `iterator(item, callback)` - A function to apply to each item in `arr`. | ||
635 | + The iterator is passed a `callback(err, results)` which must be called once it | ||
636 | + has completed with an error (which can be `null`) and an array of results. | ||
637 | +* `callback(err, results)` - A callback which is called after all the `iterator` | ||
638 | + functions have finished, or an error occurs. Results is an array containing | ||
639 | + the concatenated results of the `iterator` function. | ||
640 | + | ||
641 | +__Example__ | ||
642 | + | ||
643 | +```js | ||
644 | +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ | ||
645 | + // files is now a list of filenames that exist in the 3 directories | ||
646 | +}); | ||
647 | +``` | ||
648 | + | ||
649 | +--------------------------------------- | ||
650 | + | ||
651 | +<a name="concatSeries" /> | ||
652 | +### concatSeries(arr, iterator, callback) | ||
653 | + | ||
654 | +Same as [`concat`](#concat), but executes in series instead of parallel. | ||
655 | + | ||
656 | + | ||
657 | +## Control Flow | ||
658 | + | ||
659 | +<a name="series" /> | ||
660 | +### series(tasks, [callback]) | ||
661 | + | ||
662 | +Run the functions in the `tasks` array in series, each one running once the previous | ||
663 | +function has completed. If any functions in the series pass an error to its | ||
664 | +callback, no more functions are run, and `callback` is immediately called with the value of the error. | ||
665 | +Otherwise, `callback` receives an array of results when `tasks` have completed. | ||
666 | + | ||
667 | +It is also possible to use an object instead of an array. Each property will be | ||
668 | +run as a function, and the results will be passed to the final `callback` as an object | ||
669 | +instead of an array. This can be a more readable way of handling results from | ||
670 | +[`series`](#series). | ||
671 | + | ||
672 | +**Note** that while many implementations preserve the order of object properties, the | ||
673 | +[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) | ||
674 | +explicitly states that | ||
675 | + | ||
676 | +> The mechanics and order of enumerating the properties is not specified. | ||
677 | + | ||
678 | +So if you rely on the order in which your series of functions are executed, and want | ||
679 | +this to work on all platforms, consider using an array. | ||
680 | + | ||
681 | +__Arguments__ | ||
682 | + | ||
683 | +* `tasks` - An array or object containing functions to run, each function is passed | ||
684 | + a `callback(err, result)` it must call on completion with an error `err` (which can | ||
685 | + be `null`) and an optional `result` value. | ||
686 | +* `callback(err, results)` - An optional callback to run once all the functions | ||
687 | + have completed. This function gets a results array (or object) containing all | ||
688 | + the result arguments passed to the `task` callbacks. | ||
689 | + | ||
690 | +__Example__ | ||
691 | + | ||
692 | +```js | ||
693 | +async.series([ | ||
694 | + function(callback){ | ||
695 | + // do some stuff ... | ||
696 | + callback(null, 'one'); | ||
697 | + }, | ||
698 | + function(callback){ | ||
699 | + // do some more stuff ... | ||
700 | + callback(null, 'two'); | ||
701 | + } | ||
702 | +], | ||
703 | +// optional callback | ||
704 | +function(err, results){ | ||
705 | + // results is now equal to ['one', 'two'] | ||
706 | +}); | ||
707 | + | ||
708 | + | ||
709 | +// an example using an object instead of an array | ||
710 | +async.series({ | ||
711 | + one: function(callback){ | ||
712 | + setTimeout(function(){ | ||
713 | + callback(null, 1); | ||
714 | + }, 200); | ||
715 | + }, | ||
716 | + two: function(callback){ | ||
717 | + setTimeout(function(){ | ||
718 | + callback(null, 2); | ||
719 | + }, 100); | ||
720 | + } | ||
721 | +}, | ||
722 | +function(err, results) { | ||
723 | + // results is now equal to: {one: 1, two: 2} | ||
724 | +}); | ||
725 | +``` | ||
726 | + | ||
727 | +--------------------------------------- | ||
728 | + | ||
729 | +<a name="parallel" /> | ||
730 | +### parallel(tasks, [callback]) | ||
731 | + | ||
732 | +Run the `tasks` array of functions in parallel, without waiting until the previous | ||
733 | +function has completed. If any of the functions pass an error to its | ||
734 | +callback, the main `callback` is immediately called with the value of the error. | ||
735 | +Once the `tasks` have completed, the results are passed to the final `callback` as an | ||
736 | +array. | ||
737 | + | ||
738 | +It is also possible to use an object instead of an array. Each property will be | ||
739 | +run as a function and the results will be passed to the final `callback` as an object | ||
740 | +instead of an array. This can be a more readable way of handling results from | ||
741 | +[`parallel`](#parallel). | ||
742 | + | ||
743 | + | ||
744 | +__Arguments__ | ||
745 | + | ||
746 | +* `tasks` - An array or object containing functions to run. Each function is passed | ||
747 | + a `callback(err, result)` which it must call on completion with an error `err` | ||
748 | + (which can be `null`) and an optional `result` value. | ||
749 | +* `callback(err, results)` - An optional callback to run once all the functions | ||
750 | + have completed. This function gets a results array (or object) containing all | ||
751 | + the result arguments passed to the task callbacks. | ||
752 | + | ||
753 | +__Example__ | ||
754 | + | ||
755 | +```js | ||
756 | +async.parallel([ | ||
757 | + function(callback){ | ||
758 | + setTimeout(function(){ | ||
759 | + callback(null, 'one'); | ||
760 | + }, 200); | ||
761 | + }, | ||
762 | + function(callback){ | ||
763 | + setTimeout(function(){ | ||
764 | + callback(null, 'two'); | ||
765 | + }, 100); | ||
766 | + } | ||
767 | +], | ||
768 | +// optional callback | ||
769 | +function(err, results){ | ||
770 | + // the results array will equal ['one','two'] even though | ||
771 | + // the second function had a shorter timeout. | ||
772 | +}); | ||
773 | + | ||
774 | + | ||
775 | +// an example using an object instead of an array | ||
776 | +async.parallel({ | ||
777 | + one: function(callback){ | ||
778 | + setTimeout(function(){ | ||
779 | + callback(null, 1); | ||
780 | + }, 200); | ||
781 | + }, | ||
782 | + two: function(callback){ | ||
783 | + setTimeout(function(){ | ||
784 | + callback(null, 2); | ||
785 | + }, 100); | ||
786 | + } | ||
787 | +}, | ||
788 | +function(err, results) { | ||
789 | + // results is now equals to: {one: 1, two: 2} | ||
790 | +}); | ||
791 | +``` | ||
792 | + | ||
793 | +--------------------------------------- | ||
794 | + | ||
795 | +<a name="parallelLimit" /> | ||
796 | +### parallelLimit(tasks, limit, [callback]) | ||
797 | + | ||
798 | +The same as [`parallel`](#parallel), only `tasks` are executed in parallel | ||
799 | +with a maximum of `limit` tasks executing at any time. | ||
800 | + | ||
801 | +Note that the `tasks` are not executed in batches, so there is no guarantee that | ||
802 | +the first `limit` tasks will complete before any others are started. | ||
803 | + | ||
804 | +__Arguments__ | ||
805 | + | ||
806 | +* `tasks` - An array or object containing functions to run, each function is passed | ||
807 | + a `callback(err, result)` it must call on completion with an error `err` (which can | ||
808 | + be `null`) and an optional `result` value. | ||
809 | +* `limit` - The maximum number of `tasks` to run at any time. | ||
810 | +* `callback(err, results)` - An optional callback to run once all the functions | ||
811 | + have completed. This function gets a results array (or object) containing all | ||
812 | + the result arguments passed to the `task` callbacks. | ||
813 | + | ||
814 | +--------------------------------------- | ||
815 | + | ||
816 | +<a name="whilst" /> | ||
817 | +### whilst(test, fn, callback) | ||
818 | + | ||
819 | +Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, | ||
820 | +or an error occurs. | ||
821 | + | ||
822 | +__Arguments__ | ||
823 | + | ||
824 | +* `test()` - synchronous truth test to perform before each execution of `fn`. | ||
825 | +* `fn(callback)` - A function which is called each time `test` passes. The function is | ||
826 | + passed a `callback(err)`, which must be called once it has completed with an | ||
827 | + optional `err` argument. | ||
828 | +* `callback(err)` - A callback which is called after the test fails and repeated | ||
829 | + execution of `fn` has stopped. | ||
830 | + | ||
831 | +__Example__ | ||
832 | + | ||
833 | +```js | ||
834 | +var count = 0; | ||
835 | + | ||
836 | +async.whilst( | ||
837 | + function () { return count < 5; }, | ||
838 | + function (callback) { | ||
839 | + count++; | ||
840 | + setTimeout(callback, 1000); | ||
841 | + }, | ||
842 | + function (err) { | ||
843 | + // 5 seconds have passed | ||
844 | + } | ||
845 | +); | ||
846 | +``` | ||
847 | + | ||
848 | +--------------------------------------- | ||
849 | + | ||
850 | +<a name="doWhilst" /> | ||
851 | +### doWhilst(fn, test, callback) | ||
852 | + | ||
853 | +The post-check version of [`whilst`](#whilst). To reflect the difference in | ||
854 | +the order of operations, the arguments `test` and `fn` are switched. | ||
855 | + | ||
856 | +`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. | ||
857 | + | ||
858 | +--------------------------------------- | ||
859 | + | ||
860 | +<a name="until" /> | ||
861 | +### until(test, fn, callback) | ||
862 | + | ||
863 | +Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, | ||
864 | +or an error occurs. | ||
865 | + | ||
866 | +The inverse of [`whilst`](#whilst). | ||
867 | + | ||
868 | +--------------------------------------- | ||
869 | + | ||
870 | +<a name="doUntil" /> | ||
871 | +### doUntil(fn, test, callback) | ||
872 | + | ||
873 | +Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. | ||
874 | + | ||
875 | +--------------------------------------- | ||
876 | + | ||
877 | +<a name="forever" /> | ||
878 | +### forever(fn, errback) | ||
879 | + | ||
880 | +Calls the asynchronous function `fn` with a callback parameter that allows it to | ||
881 | +call itself again, in series, indefinitely. | ||
882 | + | ||
883 | +If an error is passed to the callback then `errback` is called with the | ||
884 | +error, and execution stops, otherwise it will never be called. | ||
885 | + | ||
886 | +```js | ||
887 | +async.forever( | ||
888 | + function(next) { | ||
889 | + // next is suitable for passing to things that need a callback(err [, whatever]); | ||
890 | + // it will result in this function being called again. | ||
891 | + }, | ||
892 | + function(err) { | ||
893 | + // if next is called with a value in its first parameter, it will appear | ||
894 | + // in here as 'err', and execution will stop. | ||
895 | + } | ||
896 | +); | ||
897 | +``` | ||
898 | + | ||
899 | +--------------------------------------- | ||
900 | + | ||
901 | +<a name="waterfall" /> | ||
902 | +### waterfall(tasks, [callback]) | ||
903 | + | ||
904 | +Runs the `tasks` array of functions in series, each passing their results to the next in | ||
905 | +the array. However, if any of the `tasks` pass an error to their own callback, the | ||
906 | +next function is not executed, and the main `callback` is immediately called with | ||
907 | +the error. | ||
908 | + | ||
909 | +__Arguments__ | ||
910 | + | ||
911 | +* `tasks` - An array of functions to run, each function is passed a | ||
912 | + `callback(err, result1, result2, ...)` it must call on completion. The first | ||
913 | + argument is an error (which can be `null`) and any further arguments will be | ||
914 | + passed as arguments in order to the next task. | ||
915 | +* `callback(err, [results])` - An optional callback to run once all the functions | ||
916 | + have completed. This will be passed the results of the last task's callback. | ||
917 | + | ||
918 | + | ||
919 | + | ||
920 | +__Example__ | ||
921 | + | ||
922 | +```js | ||
923 | +async.waterfall([ | ||
924 | + function(callback) { | ||
925 | + callback(null, 'one', 'two'); | ||
926 | + }, | ||
927 | + function(arg1, arg2, callback) { | ||
928 | + // arg1 now equals 'one' and arg2 now equals 'two' | ||
929 | + callback(null, 'three'); | ||
930 | + }, | ||
931 | + function(arg1, callback) { | ||
932 | + // arg1 now equals 'three' | ||
933 | + callback(null, 'done'); | ||
934 | + } | ||
935 | +], function (err, result) { | ||
936 | + // result now equals 'done' | ||
937 | +}); | ||
938 | +``` | ||
939 | + | ||
940 | +--------------------------------------- | ||
941 | +<a name="compose" /> | ||
942 | +### compose(fn1, fn2...) | ||
943 | + | ||
944 | +Creates a function which is a composition of the passed asynchronous | ||
945 | +functions. Each function consumes the return value of the function that | ||
946 | +follows. Composing functions `f()`, `g()`, and `h()` would produce the result of | ||
947 | +`f(g(h()))`, only this version uses callbacks to obtain the return values. | ||
948 | + | ||
949 | +Each function is executed with the `this` binding of the composed function. | ||
950 | + | ||
951 | +__Arguments__ | ||
952 | + | ||
953 | +* `functions...` - the asynchronous functions to compose | ||
954 | + | ||
955 | + | ||
956 | +__Example__ | ||
957 | + | ||
958 | +```js | ||
959 | +function add1(n, callback) { | ||
960 | + setTimeout(function () { | ||
961 | + callback(null, n + 1); | ||
962 | + }, 10); | ||
963 | +} | ||
964 | + | ||
965 | +function mul3(n, callback) { | ||
966 | + setTimeout(function () { | ||
967 | + callback(null, n * 3); | ||
968 | + }, 10); | ||
969 | +} | ||
970 | + | ||
971 | +var add1mul3 = async.compose(mul3, add1); | ||
972 | + | ||
973 | +add1mul3(4, function (err, result) { | ||
974 | + // result now equals 15 | ||
975 | +}); | ||
976 | +``` | ||
977 | + | ||
978 | +--------------------------------------- | ||
979 | +<a name="seq" /> | ||
980 | +### seq(fn1, fn2...) | ||
981 | + | ||
982 | +Version of the compose function that is more natural to read. | ||
983 | +Each function consumes the return value of the previous function. | ||
984 | +It is the equivalent of [`compose`](#compose) with the arguments reversed. | ||
985 | + | ||
986 | +Each function is executed with the `this` binding of the composed function. | ||
987 | + | ||
988 | +__Arguments__ | ||
989 | + | ||
990 | +* functions... - the asynchronous functions to compose | ||
991 | + | ||
992 | + | ||
993 | +__Example__ | ||
994 | + | ||
995 | +```js | ||
996 | +// Requires lodash (or underscore), express3 and dresende's orm2. | ||
997 | +// Part of an app, that fetches cats of the logged user. | ||
998 | +// This example uses `seq` function to avoid overnesting and error | ||
999 | +// handling clutter. | ||
1000 | +app.get('/cats', function(request, response) { | ||
1001 | + var User = request.models.User; | ||
1002 | + async.seq( | ||
1003 | + _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) | ||
1004 | + function(user, fn) { | ||
1005 | + user.getCats(fn); // 'getCats' has signature (callback(err, data)) | ||
1006 | + } | ||
1007 | + )(req.session.user_id, function (err, cats) { | ||
1008 | + if (err) { | ||
1009 | + console.error(err); | ||
1010 | + response.json({ status: 'error', message: err.message }); | ||
1011 | + } else { | ||
1012 | + response.json({ status: 'ok', message: 'Cats found', data: cats }); | ||
1013 | + } | ||
1014 | + }); | ||
1015 | +}); | ||
1016 | +``` | ||
1017 | + | ||
1018 | +--------------------------------------- | ||
1019 | +<a name="applyEach" /> | ||
1020 | +### applyEach(fns, args..., callback) | ||
1021 | + | ||
1022 | +Applies the provided arguments to each function in the array, calling | ||
1023 | +`callback` after all functions have completed. If you only provide the first | ||
1024 | +argument, then it will return a function which lets you pass in the | ||
1025 | +arguments as if it were a single function call. | ||
1026 | + | ||
1027 | +__Arguments__ | ||
1028 | + | ||
1029 | +* `fns` - the asynchronous functions to all call with the same arguments | ||
1030 | +* `args...` - any number of separate arguments to pass to the function | ||
1031 | +* `callback` - the final argument should be the callback, called when all | ||
1032 | + functions have completed processing | ||
1033 | + | ||
1034 | + | ||
1035 | +__Example__ | ||
1036 | + | ||
1037 | +```js | ||
1038 | +async.applyEach([enableSearch, updateSchema], 'bucket', callback); | ||
1039 | + | ||
1040 | +// partial application example: | ||
1041 | +async.each( | ||
1042 | + buckets, | ||
1043 | + async.applyEach([enableSearch, updateSchema]), | ||
1044 | + callback | ||
1045 | +); | ||
1046 | +``` | ||
1047 | + | ||
1048 | +--------------------------------------- | ||
1049 | + | ||
1050 | +<a name="applyEachSeries" /> | ||
1051 | +### applyEachSeries(arr, iterator, callback) | ||
1052 | + | ||
1053 | +The same as [`applyEach`](#applyEach) only the functions are applied in series. | ||
1054 | + | ||
1055 | +--------------------------------------- | ||
1056 | + | ||
1057 | +<a name="queue" /> | ||
1058 | +### queue(worker, concurrency) | ||
1059 | + | ||
1060 | +Creates a `queue` object with the specified `concurrency`. Tasks added to the | ||
1061 | +`queue` are processed in parallel (up to the `concurrency` limit). If all | ||
1062 | +`worker`s are in progress, the task is queued until one becomes available. | ||
1063 | +Once a `worker` completes a `task`, that `task`'s callback is called. | ||
1064 | + | ||
1065 | +__Arguments__ | ||
1066 | + | ||
1067 | +* `worker(task, callback)` - An asynchronous function for processing a queued | ||
1068 | + task, which must call its `callback(err)` argument when finished, with an | ||
1069 | + optional `error` as an argument. | ||
1070 | +* `concurrency` - An `integer` for determining how many `worker` functions should be | ||
1071 | + run in parallel. | ||
1072 | + | ||
1073 | +__Queue objects__ | ||
1074 | + | ||
1075 | +The `queue` object returned by this function has the following properties and | ||
1076 | +methods: | ||
1077 | + | ||
1078 | +* `length()` - a function returning the number of items waiting to be processed. | ||
1079 | +* `started` - a function returning whether or not any items have been pushed and processed by the queue | ||
1080 | +* `running()` - a function returning the number of items currently being processed. | ||
1081 | +* `idle()` - a function returning false if there are items waiting or being processed, or true if not. | ||
1082 | +* `concurrency` - an integer for determining how many `worker` functions should be | ||
1083 | + run in parallel. This property can be changed after a `queue` is created to | ||
1084 | + alter the concurrency on-the-fly. | ||
1085 | +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once | ||
1086 | + the `worker` has finished processing the task. Instead of a single task, a `tasks` array | ||
1087 | + can be submitted. The respective callback is used for every task in the list. | ||
1088 | +* `unshift(task, [callback])` - add a new task to the front of the `queue`. | ||
1089 | +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, | ||
1090 | + and further tasks will be queued. | ||
1091 | +* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. | ||
1092 | +* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. | ||
1093 | +* `paused` - a boolean for determining whether the queue is in a paused state | ||
1094 | +* `pause()` - a function that pauses the processing of tasks until `resume()` is called. | ||
1095 | +* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. | ||
1096 | +* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle. | ||
1097 | + | ||
1098 | +__Example__ | ||
1099 | + | ||
1100 | +```js | ||
1101 | +// create a queue object with concurrency 2 | ||
1102 | + | ||
1103 | +var q = async.queue(function (task, callback) { | ||
1104 | + console.log('hello ' + task.name); | ||
1105 | + callback(); | ||
1106 | +}, 2); | ||
1107 | + | ||
1108 | + | ||
1109 | +// assign a callback | ||
1110 | +q.drain = function() { | ||
1111 | + console.log('all items have been processed'); | ||
1112 | +} | ||
1113 | + | ||
1114 | +// add some items to the queue | ||
1115 | + | ||
1116 | +q.push({name: 'foo'}, function (err) { | ||
1117 | + console.log('finished processing foo'); | ||
1118 | +}); | ||
1119 | +q.push({name: 'bar'}, function (err) { | ||
1120 | + console.log('finished processing bar'); | ||
1121 | +}); | ||
1122 | + | ||
1123 | +// add some items to the queue (batch-wise) | ||
1124 | + | ||
1125 | +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { | ||
1126 | + console.log('finished processing item'); | ||
1127 | +}); | ||
1128 | + | ||
1129 | +// add some items to the front of the queue | ||
1130 | + | ||
1131 | +q.unshift({name: 'bar'}, function (err) { | ||
1132 | + console.log('finished processing bar'); | ||
1133 | +}); | ||
1134 | +``` | ||
1135 | + | ||
1136 | + | ||
1137 | +--------------------------------------- | ||
1138 | + | ||
1139 | +<a name="priorityQueue" /> | ||
1140 | +### priorityQueue(worker, concurrency) | ||
1141 | + | ||
1142 | +The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: | ||
1143 | + | ||
1144 | +* `push(task, priority, [callback])` - `priority` should be a number. If an array of | ||
1145 | + `tasks` is given, all tasks will be assigned the same priority. | ||
1146 | +* The `unshift` method was removed. | ||
1147 | + | ||
1148 | +--------------------------------------- | ||
1149 | + | ||
1150 | +<a name="cargo" /> | ||
1151 | +### cargo(worker, [payload]) | ||
1152 | + | ||
1153 | +Creates a `cargo` object with the specified payload. Tasks added to the | ||
1154 | +cargo will be processed altogether (up to the `payload` limit). If the | ||
1155 | +`worker` is in progress, the task is queued until it becomes available. Once | ||
1156 | +the `worker` has completed some tasks, each callback of those tasks is called. | ||
1157 | +Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work. | ||
1158 | + | ||
1159 | +While [queue](#queue) passes only one task to one of a group of workers | ||
1160 | +at a time, cargo passes an array of tasks to a single worker, repeating | ||
1161 | +when the worker is finished. | ||
1162 | + | ||
1163 | +__Arguments__ | ||
1164 | + | ||
1165 | +* `worker(tasks, callback)` - An asynchronous function for processing an array of | ||
1166 | + queued tasks, which must call its `callback(err)` argument when finished, with | ||
1167 | + an optional `err` argument. | ||
1168 | +* `payload` - An optional `integer` for determining how many tasks should be | ||
1169 | + processed per round; if omitted, the default is unlimited. | ||
1170 | + | ||
1171 | +__Cargo objects__ | ||
1172 | + | ||
1173 | +The `cargo` object returned by this function has the following properties and | ||
1174 | +methods: | ||
1175 | + | ||
1176 | +* `length()` - A function returning the number of items waiting to be processed. | ||
1177 | +* `payload` - An `integer` for determining how many tasks should be | ||
1178 | + process per round. This property can be changed after a `cargo` is created to | ||
1179 | + alter the payload on-the-fly. | ||
1180 | +* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called | ||
1181 | + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` | ||
1182 | + can be submitted. The respective callback is used for every task in the list. | ||
1183 | +* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. | ||
1184 | +* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. | ||
1185 | +* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. | ||
1186 | + | ||
1187 | +__Example__ | ||
1188 | + | ||
1189 | +```js | ||
1190 | +// create a cargo object with payload 2 | ||
1191 | + | ||
1192 | +var cargo = async.cargo(function (tasks, callback) { | ||
1193 | + for(var i=0; i<tasks.length; i++){ | ||
1194 | + console.log('hello ' + tasks[i].name); | ||
1195 | + } | ||
1196 | + callback(); | ||
1197 | +}, 2); | ||
1198 | + | ||
1199 | + | ||
1200 | +// add some items | ||
1201 | + | ||
1202 | +cargo.push({name: 'foo'}, function (err) { | ||
1203 | + console.log('finished processing foo'); | ||
1204 | +}); | ||
1205 | +cargo.push({name: 'bar'}, function (err) { | ||
1206 | + console.log('finished processing bar'); | ||
1207 | +}); | ||
1208 | +cargo.push({name: 'baz'}, function (err) { | ||
1209 | + console.log('finished processing baz'); | ||
1210 | +}); | ||
1211 | +``` | ||
1212 | + | ||
1213 | +--------------------------------------- | ||
1214 | + | ||
1215 | +<a name="auto" /> | ||
1216 | +### auto(tasks, [callback]) | ||
1217 | + | ||
1218 | +Determines the best order for running the functions in `tasks`, based on their | ||
1219 | +requirements. Each function can optionally depend on other functions being completed | ||
1220 | +first, and each function is run as soon as its requirements are satisfied. | ||
1221 | + | ||
1222 | +If any of the functions pass an error to their callback, it will not | ||
1223 | +complete (so any other functions depending on it will not run), and the main | ||
1224 | +`callback` is immediately called with the error. Functions also receive an | ||
1225 | +object containing the results of functions which have completed so far. | ||
1226 | + | ||
1227 | +Note, all functions are called with a `results` object as a second argument, | ||
1228 | +so it is unsafe to pass functions in the `tasks` object which cannot handle the | ||
1229 | +extra argument. | ||
1230 | + | ||
1231 | +For example, this snippet of code: | ||
1232 | + | ||
1233 | +```js | ||
1234 | +async.auto({ | ||
1235 | + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') | ||
1236 | +}, callback); | ||
1237 | +``` | ||
1238 | + | ||
1239 | +will have the effect of calling `readFile` with the results object as the last | ||
1240 | +argument, which will fail: | ||
1241 | + | ||
1242 | +```js | ||
1243 | +fs.readFile('data.txt', 'utf-8', cb, {}); | ||
1244 | +``` | ||
1245 | + | ||
1246 | +Instead, wrap the call to `readFile` in a function which does not forward the | ||
1247 | +`results` object: | ||
1248 | + | ||
1249 | +```js | ||
1250 | +async.auto({ | ||
1251 | + readData: function(cb, results){ | ||
1252 | + fs.readFile('data.txt', 'utf-8', cb); | ||
1253 | + } | ||
1254 | +}, callback); | ||
1255 | +``` | ||
1256 | + | ||
1257 | +__Arguments__ | ||
1258 | + | ||
1259 | +* `tasks` - An object. Each of its properties is either a function or an array of | ||
1260 | + requirements, with the function itself the last item in the array. The object's key | ||
1261 | + of a property serves as the name of the task defined by that property, | ||
1262 | + i.e. can be used when specifying requirements for other tasks. | ||
1263 | + The function receives two arguments: (1) a `callback(err, result)` which must be | ||
1264 | + called when finished, passing an `error` (which can be `null`) and the result of | ||
1265 | + the function's execution, and (2) a `results` object, containing the results of | ||
1266 | + the previously executed functions. | ||
1267 | +* `callback(err, results)` - An optional callback which is called when all the | ||
1268 | + tasks have been completed. It receives the `err` argument if any `tasks` | ||
1269 | + pass an error to their callback. Results are always returned; however, if | ||
1270 | + an error occurs, no further `tasks` will be performed, and the results | ||
1271 | + object will only contain partial results. | ||
1272 | + | ||
1273 | + | ||
1274 | +__Example__ | ||
1275 | + | ||
1276 | +```js | ||
1277 | +async.auto({ | ||
1278 | + get_data: function(callback){ | ||
1279 | + console.log('in get_data'); | ||
1280 | + // async code to get some data | ||
1281 | + callback(null, 'data', 'converted to array'); | ||
1282 | + }, | ||
1283 | + make_folder: function(callback){ | ||
1284 | + console.log('in make_folder'); | ||
1285 | + // async code to create a directory to store a file in | ||
1286 | + // this is run at the same time as getting the data | ||
1287 | + callback(null, 'folder'); | ||
1288 | + }, | ||
1289 | + write_file: ['get_data', 'make_folder', function(callback, results){ | ||
1290 | + console.log('in write_file', JSON.stringify(results)); | ||
1291 | + // once there is some data and the directory exists, | ||
1292 | + // write the data to a file in the directory | ||
1293 | + callback(null, 'filename'); | ||
1294 | + }], | ||
1295 | + email_link: ['write_file', function(callback, results){ | ||
1296 | + console.log('in email_link', JSON.stringify(results)); | ||
1297 | + // once the file is written let's email a link to it... | ||
1298 | + // results.write_file contains the filename returned by write_file. | ||
1299 | + callback(null, {'file':results.write_file, 'email':'user@example.com'}); | ||
1300 | + }] | ||
1301 | +}, function(err, results) { | ||
1302 | + console.log('err = ', err); | ||
1303 | + console.log('results = ', results); | ||
1304 | +}); | ||
1305 | +``` | ||
1306 | + | ||
1307 | +This is a fairly trivial example, but to do this using the basic parallel and | ||
1308 | +series functions would look like this: | ||
1309 | + | ||
1310 | +```js | ||
1311 | +async.parallel([ | ||
1312 | + function(callback){ | ||
1313 | + console.log('in get_data'); | ||
1314 | + // async code to get some data | ||
1315 | + callback(null, 'data', 'converted to array'); | ||
1316 | + }, | ||
1317 | + function(callback){ | ||
1318 | + console.log('in make_folder'); | ||
1319 | + // async code to create a directory to store a file in | ||
1320 | + // this is run at the same time as getting the data | ||
1321 | + callback(null, 'folder'); | ||
1322 | + } | ||
1323 | +], | ||
1324 | +function(err, results){ | ||
1325 | + async.series([ | ||
1326 | + function(callback){ | ||
1327 | + console.log('in write_file', JSON.stringify(results)); | ||
1328 | + // once there is some data and the directory exists, | ||
1329 | + // write the data to a file in the directory | ||
1330 | + results.push('filename'); | ||
1331 | + callback(null); | ||
1332 | + }, | ||
1333 | + function(callback){ | ||
1334 | + console.log('in email_link', JSON.stringify(results)); | ||
1335 | + // once the file is written let's email a link to it... | ||
1336 | + callback(null, {'file':results.pop(), 'email':'user@example.com'}); | ||
1337 | + } | ||
1338 | + ]); | ||
1339 | +}); | ||
1340 | +``` | ||
1341 | + | ||
1342 | +For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding | ||
1343 | +new tasks much easier (and the code more readable). | ||
1344 | + | ||
1345 | + | ||
1346 | +--------------------------------------- | ||
1347 | + | ||
1348 | +<a name="retry" /> | ||
1349 | +### retry([times = 5], task, [callback]) | ||
1350 | + | ||
1351 | +Attempts to get a successful response from `task` no more than `times` times before | ||
1352 | +returning an error. If the task is successful, the `callback` will be passed the result | ||
1353 | +of the successful task. If all attempts fail, the callback will be passed the error and | ||
1354 | +result (if any) of the final attempt. | ||
1355 | + | ||
1356 | +__Arguments__ | ||
1357 | + | ||
1358 | +* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5. | ||
1359 | +* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` | ||
1360 | + which must be called when finished, passing `err` (which can be `null`) and the `result` of | ||
1361 | + the function's execution, and (2) a `results` object, containing the results of | ||
1362 | + the previously executed functions (if nested inside another control flow). | ||
1363 | +* `callback(err, results)` - An optional callback which is called when the | ||
1364 | + task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. | ||
1365 | + | ||
1366 | +The [`retry`](#retry) function can be used as a stand-alone control flow by passing a | ||
1367 | +callback, as shown below: | ||
1368 | + | ||
1369 | +```js | ||
1370 | +async.retry(3, apiMethod, function(err, result) { | ||
1371 | + // do something with the result | ||
1372 | +}); | ||
1373 | +``` | ||
1374 | + | ||
1375 | +It can also be embeded within other control flow functions to retry individual methods | ||
1376 | +that are not as reliable, like this: | ||
1377 | + | ||
1378 | +```js | ||
1379 | +async.auto({ | ||
1380 | + users: api.getUsers.bind(api), | ||
1381 | + payments: async.retry(3, api.getPayments.bind(api)) | ||
1382 | +}, function(err, results) { | ||
1383 | + // do something with the results | ||
1384 | +}); | ||
1385 | +``` | ||
1386 | + | ||
1387 | + | ||
1388 | +--------------------------------------- | ||
1389 | + | ||
1390 | +<a name="iterator" /> | ||
1391 | +### iterator(tasks) | ||
1392 | + | ||
1393 | +Creates an iterator function which calls the next function in the `tasks` array, | ||
1394 | +returning a continuation to call the next one after that. It's also possible to | ||
1395 | +“peek” at the next iterator with `iterator.next()`. | ||
1396 | + | ||
1397 | +This function is used internally by the `async` module, but can be useful when | ||
1398 | +you want to manually control the flow of functions in series. | ||
1399 | + | ||
1400 | +__Arguments__ | ||
1401 | + | ||
1402 | +* `tasks` - An array of functions to run. | ||
1403 | + | ||
1404 | +__Example__ | ||
1405 | + | ||
1406 | +```js | ||
1407 | +var iterator = async.iterator([ | ||
1408 | + function(){ sys.p('one'); }, | ||
1409 | + function(){ sys.p('two'); }, | ||
1410 | + function(){ sys.p('three'); } | ||
1411 | +]); | ||
1412 | + | ||
1413 | +node> var iterator2 = iterator(); | ||
1414 | +'one' | ||
1415 | +node> var iterator3 = iterator2(); | ||
1416 | +'two' | ||
1417 | +node> iterator3(); | ||
1418 | +'three' | ||
1419 | +node> var nextfn = iterator2.next(); | ||
1420 | +node> nextfn(); | ||
1421 | +'three' | ||
1422 | +``` | ||
1423 | + | ||
1424 | +--------------------------------------- | ||
1425 | + | ||
1426 | +<a name="apply" /> | ||
1427 | +### apply(function, arguments..) | ||
1428 | + | ||
1429 | +Creates a continuation function with some arguments already applied. | ||
1430 | + | ||
1431 | +Useful as a shorthand when combined with other control flow functions. Any arguments | ||
1432 | +passed to the returned function are added to the arguments originally passed | ||
1433 | +to apply. | ||
1434 | + | ||
1435 | +__Arguments__ | ||
1436 | + | ||
1437 | +* `function` - The function you want to eventually apply all arguments to. | ||
1438 | +* `arguments...` - Any number of arguments to automatically apply when the | ||
1439 | + continuation is called. | ||
1440 | + | ||
1441 | +__Example__ | ||
1442 | + | ||
1443 | +```js | ||
1444 | +// using apply | ||
1445 | + | ||
1446 | +async.parallel([ | ||
1447 | + async.apply(fs.writeFile, 'testfile1', 'test1'), | ||
1448 | + async.apply(fs.writeFile, 'testfile2', 'test2'), | ||
1449 | +]); | ||
1450 | + | ||
1451 | + | ||
1452 | +// the same process without using apply | ||
1453 | + | ||
1454 | +async.parallel([ | ||
1455 | + function(callback){ | ||
1456 | + fs.writeFile('testfile1', 'test1', callback); | ||
1457 | + }, | ||
1458 | + function(callback){ | ||
1459 | + fs.writeFile('testfile2', 'test2', callback); | ||
1460 | + } | ||
1461 | +]); | ||
1462 | +``` | ||
1463 | + | ||
1464 | +It's possible to pass any number of additional arguments when calling the | ||
1465 | +continuation: | ||
1466 | + | ||
1467 | +```js | ||
1468 | +node> var fn = async.apply(sys.puts, 'one'); | ||
1469 | +node> fn('two', 'three'); | ||
1470 | +one | ||
1471 | +two | ||
1472 | +three | ||
1473 | +``` | ||
1474 | + | ||
1475 | +--------------------------------------- | ||
1476 | + | ||
1477 | +<a name="nextTick" /> | ||
1478 | +### nextTick(callback), setImmediate(callback) | ||
1479 | + | ||
1480 | +Calls `callback` on a later loop around the event loop. In Node.js this just | ||
1481 | +calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)` | ||
1482 | +if available, otherwise `setTimeout(callback, 0)`, which means other higher priority | ||
1483 | +events may precede the execution of `callback`. | ||
1484 | + | ||
1485 | +This is used internally for browser-compatibility purposes. | ||
1486 | + | ||
1487 | +__Arguments__ | ||
1488 | + | ||
1489 | +* `callback` - The function to call on a later loop around the event loop. | ||
1490 | + | ||
1491 | +__Example__ | ||
1492 | + | ||
1493 | +```js | ||
1494 | +var call_order = []; | ||
1495 | +async.nextTick(function(){ | ||
1496 | + call_order.push('two'); | ||
1497 | + // call_order now equals ['one','two'] | ||
1498 | +}); | ||
1499 | +call_order.push('one') | ||
1500 | +``` | ||
1501 | + | ||
1502 | +<a name="times" /> | ||
1503 | +### times(n, callback) | ||
1504 | + | ||
1505 | +Calls the `callback` function `n` times, and accumulates results in the same manner | ||
1506 | +you would use with [`map`](#map). | ||
1507 | + | ||
1508 | +__Arguments__ | ||
1509 | + | ||
1510 | +* `n` - The number of times to run the function. | ||
1511 | +* `callback` - The function to call `n` times. | ||
1512 | + | ||
1513 | +__Example__ | ||
1514 | + | ||
1515 | +```js | ||
1516 | +// Pretend this is some complicated async factory | ||
1517 | +var createUser = function(id, callback) { | ||
1518 | + callback(null, { | ||
1519 | + id: 'user' + id | ||
1520 | + }) | ||
1521 | +} | ||
1522 | +// generate 5 users | ||
1523 | +async.times(5, function(n, next){ | ||
1524 | + createUser(n, function(err, user) { | ||
1525 | + next(err, user) | ||
1526 | + }) | ||
1527 | +}, function(err, users) { | ||
1528 | + // we should now have 5 users | ||
1529 | +}); | ||
1530 | +``` | ||
1531 | + | ||
1532 | +<a name="timesSeries" /> | ||
1533 | +### timesSeries(n, callback) | ||
1534 | + | ||
1535 | +The same as [`times`](#times), only the iterator is applied to each item in `arr` in | ||
1536 | +series. The next `iterator` is only called once the current one has completed. | ||
1537 | +The results array will be in the same order as the original. | ||
1538 | + | ||
1539 | + | ||
1540 | +## Utils | ||
1541 | + | ||
1542 | +<a name="memoize" /> | ||
1543 | +### memoize(fn, [hasher]) | ||
1544 | + | ||
1545 | +Caches the results of an `async` function. When creating a hash to store function | ||
1546 | +results against, the callback is omitted from the hash and an optional hash | ||
1547 | +function can be used. | ||
1548 | + | ||
1549 | +The cache of results is exposed as the `memo` property of the function returned | ||
1550 | +by `memoize`. | ||
1551 | + | ||
1552 | +__Arguments__ | ||
1553 | + | ||
1554 | +* `fn` - The function to proxy and cache results from. | ||
1555 | +* `hasher` - Tn optional function for generating a custom hash for storing | ||
1556 | + results. It has all the arguments applied to it apart from the callback, and | ||
1557 | + must be synchronous. | ||
1558 | + | ||
1559 | +__Example__ | ||
1560 | + | ||
1561 | +```js | ||
1562 | +var slow_fn = function (name, callback) { | ||
1563 | + // do something | ||
1564 | + callback(null, result); | ||
1565 | +}; | ||
1566 | +var fn = async.memoize(slow_fn); | ||
1567 | + | ||
1568 | +// fn can now be used as if it were slow_fn | ||
1569 | +fn('some name', function () { | ||
1570 | + // callback | ||
1571 | +}); | ||
1572 | +``` | ||
1573 | + | ||
1574 | +<a name="unmemoize" /> | ||
1575 | +### unmemoize(fn) | ||
1576 | + | ||
1577 | +Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized | ||
1578 | +form. Handy for testing. | ||
1579 | + | ||
1580 | +__Arguments__ | ||
1581 | + | ||
1582 | +* `fn` - the memoized function | ||
1583 | + | ||
1584 | +<a name="log" /> | ||
1585 | +### log(function, arguments) | ||
1586 | + | ||
1587 | +Logs the result of an `async` function to the `console`. Only works in Node.js or | ||
1588 | +in browsers that support `console.log` and `console.error` (such as FF and Chrome). | ||
1589 | +If multiple arguments are returned from the async function, `console.log` is | ||
1590 | +called on each argument in order. | ||
1591 | + | ||
1592 | +__Arguments__ | ||
1593 | + | ||
1594 | +* `function` - The function you want to eventually apply all arguments to. | ||
1595 | +* `arguments...` - Any number of arguments to apply to the function. | ||
1596 | + | ||
1597 | +__Example__ | ||
1598 | + | ||
1599 | +```js | ||
1600 | +var hello = function(name, callback){ | ||
1601 | + setTimeout(function(){ | ||
1602 | + callback(null, 'hello ' + name); | ||
1603 | + }, 1000); | ||
1604 | +}; | ||
1605 | +``` | ||
1606 | +```js | ||
1607 | +node> async.log(hello, 'world'); | ||
1608 | +'hello world' | ||
1609 | +``` | ||
1610 | + | ||
1611 | +--------------------------------------- | ||
1612 | + | ||
1613 | +<a name="dir" /> | ||
1614 | +### dir(function, arguments) | ||
1615 | + | ||
1616 | +Logs the result of an `async` function to the `console` using `console.dir` to | ||
1617 | +display the properties of the resulting object. Only works in Node.js or | ||
1618 | +in browsers that support `console.dir` and `console.error` (such as FF and Chrome). | ||
1619 | +If multiple arguments are returned from the async function, `console.dir` is | ||
1620 | +called on each argument in order. | ||
1621 | + | ||
1622 | +__Arguments__ | ||
1623 | + | ||
1624 | +* `function` - The function you want to eventually apply all arguments to. | ||
1625 | +* `arguments...` - Any number of arguments to apply to the function. | ||
1626 | + | ||
1627 | +__Example__ | ||
1628 | + | ||
1629 | +```js | ||
1630 | +var hello = function(name, callback){ | ||
1631 | + setTimeout(function(){ | ||
1632 | + callback(null, {hello: name}); | ||
1633 | + }, 1000); | ||
1634 | +}; | ||
1635 | +``` | ||
1636 | +```js | ||
1637 | +node> async.dir(hello, 'world'); | ||
1638 | +{hello: 'world'} | ||
1639 | +``` | ||
1640 | + | ||
1641 | +--------------------------------------- | ||
1642 | + | ||
1643 | +<a name="noConflict" /> | ||
1644 | +### noConflict() | ||
1645 | + | ||
1646 | +Changes the value of `async` back to its original value, returning a reference to the | ||
1647 | +`async` object. |
node_modules/async/bower.json
0 → 100644
1 | +{ | ||
2 | + "name": "async", | ||
3 | + "description": "Higher-order functions and common patterns for asynchronous code", | ||
4 | + "version": "0.9.2", | ||
5 | + "main": "lib/async.js", | ||
6 | + "keywords": [ | ||
7 | + "async", | ||
8 | + "callback", | ||
9 | + "utility", | ||
10 | + "module" | ||
11 | + ], | ||
12 | + "license": "MIT", | ||
13 | + "repository": { | ||
14 | + "type": "git", | ||
15 | + "url": "https://github.com/caolan/async.git" | ||
16 | + }, | ||
17 | + "devDependencies": { | ||
18 | + "nodeunit": ">0.0.0", | ||
19 | + "uglify-js": "1.2.x", | ||
20 | + "nodelint": ">0.0.0", | ||
21 | + "lodash": ">=2.4.1" | ||
22 | + }, | ||
23 | + "moduleType": [ | ||
24 | + "amd", | ||
25 | + "globals", | ||
26 | + "node" | ||
27 | + ], | ||
28 | + "ignore": [ | ||
29 | + "**/.*", | ||
30 | + "node_modules", | ||
31 | + "bower_components", | ||
32 | + "test", | ||
33 | + "tests" | ||
34 | + ], | ||
35 | + "authors": [ | ||
36 | + "Caolan McMahon" | ||
37 | + ] | ||
38 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/async/component.json
0 → 100644
1 | +{ | ||
2 | + "name": "async", | ||
3 | + "description": "Higher-order functions and common patterns for asynchronous code", | ||
4 | + "version": "0.9.2", | ||
5 | + "keywords": [ | ||
6 | + "async", | ||
7 | + "callback", | ||
8 | + "utility", | ||
9 | + "module" | ||
10 | + ], | ||
11 | + "license": "MIT", | ||
12 | + "repository": "caolan/async", | ||
13 | + "scripts": [ | ||
14 | + "lib/async.js" | ||
15 | + ] | ||
16 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/async/lib/async.js
0 → 100644
1 | +/*! | ||
2 | + * async | ||
3 | + * https://github.com/caolan/async | ||
4 | + * | ||
5 | + * Copyright 2010-2014 Caolan McMahon | ||
6 | + * Released under the MIT license | ||
7 | + */ | ||
8 | +/*jshint onevar: false, indent:4 */ | ||
9 | +/*global setImmediate: false, setTimeout: false, console: false */ | ||
10 | +(function () { | ||
11 | + | ||
12 | + var async = {}; | ||
13 | + | ||
14 | + // global on the server, window in the browser | ||
15 | + var root, previous_async; | ||
16 | + | ||
17 | + root = this; | ||
18 | + if (root != null) { | ||
19 | + previous_async = root.async; | ||
20 | + } | ||
21 | + | ||
22 | + async.noConflict = function () { | ||
23 | + root.async = previous_async; | ||
24 | + return async; | ||
25 | + }; | ||
26 | + | ||
27 | + function only_once(fn) { | ||
28 | + var called = false; | ||
29 | + return function() { | ||
30 | + if (called) throw new Error("Callback was already called."); | ||
31 | + called = true; | ||
32 | + fn.apply(root, arguments); | ||
33 | + } | ||
34 | + } | ||
35 | + | ||
36 | + //// cross-browser compatiblity functions //// | ||
37 | + | ||
38 | + var _toString = Object.prototype.toString; | ||
39 | + | ||
40 | + var _isArray = Array.isArray || function (obj) { | ||
41 | + return _toString.call(obj) === '[object Array]'; | ||
42 | + }; | ||
43 | + | ||
44 | + var _each = function (arr, iterator) { | ||
45 | + for (var i = 0; i < arr.length; i += 1) { | ||
46 | + iterator(arr[i], i, arr); | ||
47 | + } | ||
48 | + }; | ||
49 | + | ||
50 | + var _map = function (arr, iterator) { | ||
51 | + if (arr.map) { | ||
52 | + return arr.map(iterator); | ||
53 | + } | ||
54 | + var results = []; | ||
55 | + _each(arr, function (x, i, a) { | ||
56 | + results.push(iterator(x, i, a)); | ||
57 | + }); | ||
58 | + return results; | ||
59 | + }; | ||
60 | + | ||
61 | + var _reduce = function (arr, iterator, memo) { | ||
62 | + if (arr.reduce) { | ||
63 | + return arr.reduce(iterator, memo); | ||
64 | + } | ||
65 | + _each(arr, function (x, i, a) { | ||
66 | + memo = iterator(memo, x, i, a); | ||
67 | + }); | ||
68 | + return memo; | ||
69 | + }; | ||
70 | + | ||
71 | + var _keys = function (obj) { | ||
72 | + if (Object.keys) { | ||
73 | + return Object.keys(obj); | ||
74 | + } | ||
75 | + var keys = []; | ||
76 | + for (var k in obj) { | ||
77 | + if (obj.hasOwnProperty(k)) { | ||
78 | + keys.push(k); | ||
79 | + } | ||
80 | + } | ||
81 | + return keys; | ||
82 | + }; | ||
83 | + | ||
84 | + //// exported async module functions //// | ||
85 | + | ||
86 | + //// nextTick implementation with browser-compatible fallback //// | ||
87 | + if (typeof process === 'undefined' || !(process.nextTick)) { | ||
88 | + if (typeof setImmediate === 'function') { | ||
89 | + async.nextTick = function (fn) { | ||
90 | + // not a direct alias for IE10 compatibility | ||
91 | + setImmediate(fn); | ||
92 | + }; | ||
93 | + async.setImmediate = async.nextTick; | ||
94 | + } | ||
95 | + else { | ||
96 | + async.nextTick = function (fn) { | ||
97 | + setTimeout(fn, 0); | ||
98 | + }; | ||
99 | + async.setImmediate = async.nextTick; | ||
100 | + } | ||
101 | + } | ||
102 | + else { | ||
103 | + async.nextTick = process.nextTick; | ||
104 | + if (typeof setImmediate !== 'undefined') { | ||
105 | + async.setImmediate = function (fn) { | ||
106 | + // not a direct alias for IE10 compatibility | ||
107 | + setImmediate(fn); | ||
108 | + }; | ||
109 | + } | ||
110 | + else { | ||
111 | + async.setImmediate = async.nextTick; | ||
112 | + } | ||
113 | + } | ||
114 | + | ||
115 | + async.each = function (arr, iterator, callback) { | ||
116 | + callback = callback || function () {}; | ||
117 | + if (!arr.length) { | ||
118 | + return callback(); | ||
119 | + } | ||
120 | + var completed = 0; | ||
121 | + _each(arr, function (x) { | ||
122 | + iterator(x, only_once(done) ); | ||
123 | + }); | ||
124 | + function done(err) { | ||
125 | + if (err) { | ||
126 | + callback(err); | ||
127 | + callback = function () {}; | ||
128 | + } | ||
129 | + else { | ||
130 | + completed += 1; | ||
131 | + if (completed >= arr.length) { | ||
132 | + callback(); | ||
133 | + } | ||
134 | + } | ||
135 | + } | ||
136 | + }; | ||
137 | + async.forEach = async.each; | ||
138 | + | ||
139 | + async.eachSeries = function (arr, iterator, callback) { | ||
140 | + callback = callback || function () {}; | ||
141 | + if (!arr.length) { | ||
142 | + return callback(); | ||
143 | + } | ||
144 | + var completed = 0; | ||
145 | + var iterate = function () { | ||
146 | + iterator(arr[completed], function (err) { | ||
147 | + if (err) { | ||
148 | + callback(err); | ||
149 | + callback = function () {}; | ||
150 | + } | ||
151 | + else { | ||
152 | + completed += 1; | ||
153 | + if (completed >= arr.length) { | ||
154 | + callback(); | ||
155 | + } | ||
156 | + else { | ||
157 | + iterate(); | ||
158 | + } | ||
159 | + } | ||
160 | + }); | ||
161 | + }; | ||
162 | + iterate(); | ||
163 | + }; | ||
164 | + async.forEachSeries = async.eachSeries; | ||
165 | + | ||
166 | + async.eachLimit = function (arr, limit, iterator, callback) { | ||
167 | + var fn = _eachLimit(limit); | ||
168 | + fn.apply(null, [arr, iterator, callback]); | ||
169 | + }; | ||
170 | + async.forEachLimit = async.eachLimit; | ||
171 | + | ||
172 | + var _eachLimit = function (limit) { | ||
173 | + | ||
174 | + return function (arr, iterator, callback) { | ||
175 | + callback = callback || function () {}; | ||
176 | + if (!arr.length || limit <= 0) { | ||
177 | + return callback(); | ||
178 | + } | ||
179 | + var completed = 0; | ||
180 | + var started = 0; | ||
181 | + var running = 0; | ||
182 | + | ||
183 | + (function replenish () { | ||
184 | + if (completed >= arr.length) { | ||
185 | + return callback(); | ||
186 | + } | ||
187 | + | ||
188 | + while (running < limit && started < arr.length) { | ||
189 | + started += 1; | ||
190 | + running += 1; | ||
191 | + iterator(arr[started - 1], function (err) { | ||
192 | + if (err) { | ||
193 | + callback(err); | ||
194 | + callback = function () {}; | ||
195 | + } | ||
196 | + else { | ||
197 | + completed += 1; | ||
198 | + running -= 1; | ||
199 | + if (completed >= arr.length) { | ||
200 | + callback(); | ||
201 | + } | ||
202 | + else { | ||
203 | + replenish(); | ||
204 | + } | ||
205 | + } | ||
206 | + }); | ||
207 | + } | ||
208 | + })(); | ||
209 | + }; | ||
210 | + }; | ||
211 | + | ||
212 | + | ||
213 | + var doParallel = function (fn) { | ||
214 | + return function () { | ||
215 | + var args = Array.prototype.slice.call(arguments); | ||
216 | + return fn.apply(null, [async.each].concat(args)); | ||
217 | + }; | ||
218 | + }; | ||
219 | + var doParallelLimit = function(limit, fn) { | ||
220 | + return function () { | ||
221 | + var args = Array.prototype.slice.call(arguments); | ||
222 | + return fn.apply(null, [_eachLimit(limit)].concat(args)); | ||
223 | + }; | ||
224 | + }; | ||
225 | + var doSeries = function (fn) { | ||
226 | + return function () { | ||
227 | + var args = Array.prototype.slice.call(arguments); | ||
228 | + return fn.apply(null, [async.eachSeries].concat(args)); | ||
229 | + }; | ||
230 | + }; | ||
231 | + | ||
232 | + | ||
233 | + var _asyncMap = function (eachfn, arr, iterator, callback) { | ||
234 | + arr = _map(arr, function (x, i) { | ||
235 | + return {index: i, value: x}; | ||
236 | + }); | ||
237 | + if (!callback) { | ||
238 | + eachfn(arr, function (x, callback) { | ||
239 | + iterator(x.value, function (err) { | ||
240 | + callback(err); | ||
241 | + }); | ||
242 | + }); | ||
243 | + } else { | ||
244 | + var results = []; | ||
245 | + eachfn(arr, function (x, callback) { | ||
246 | + iterator(x.value, function (err, v) { | ||
247 | + results[x.index] = v; | ||
248 | + callback(err); | ||
249 | + }); | ||
250 | + }, function (err) { | ||
251 | + callback(err, results); | ||
252 | + }); | ||
253 | + } | ||
254 | + }; | ||
255 | + async.map = doParallel(_asyncMap); | ||
256 | + async.mapSeries = doSeries(_asyncMap); | ||
257 | + async.mapLimit = function (arr, limit, iterator, callback) { | ||
258 | + return _mapLimit(limit)(arr, iterator, callback); | ||
259 | + }; | ||
260 | + | ||
261 | + var _mapLimit = function(limit) { | ||
262 | + return doParallelLimit(limit, _asyncMap); | ||
263 | + }; | ||
264 | + | ||
265 | + // reduce only has a series version, as doing reduce in parallel won't | ||
266 | + // work in many situations. | ||
267 | + async.reduce = function (arr, memo, iterator, callback) { | ||
268 | + async.eachSeries(arr, function (x, callback) { | ||
269 | + iterator(memo, x, function (err, v) { | ||
270 | + memo = v; | ||
271 | + callback(err); | ||
272 | + }); | ||
273 | + }, function (err) { | ||
274 | + callback(err, memo); | ||
275 | + }); | ||
276 | + }; | ||
277 | + // inject alias | ||
278 | + async.inject = async.reduce; | ||
279 | + // foldl alias | ||
280 | + async.foldl = async.reduce; | ||
281 | + | ||
282 | + async.reduceRight = function (arr, memo, iterator, callback) { | ||
283 | + var reversed = _map(arr, function (x) { | ||
284 | + return x; | ||
285 | + }).reverse(); | ||
286 | + async.reduce(reversed, memo, iterator, callback); | ||
287 | + }; | ||
288 | + // foldr alias | ||
289 | + async.foldr = async.reduceRight; | ||
290 | + | ||
291 | + var _filter = function (eachfn, arr, iterator, callback) { | ||
292 | + var results = []; | ||
293 | + arr = _map(arr, function (x, i) { | ||
294 | + return {index: i, value: x}; | ||
295 | + }); | ||
296 | + eachfn(arr, function (x, callback) { | ||
297 | + iterator(x.value, function (v) { | ||
298 | + if (v) { | ||
299 | + results.push(x); | ||
300 | + } | ||
301 | + callback(); | ||
302 | + }); | ||
303 | + }, function (err) { | ||
304 | + callback(_map(results.sort(function (a, b) { | ||
305 | + return a.index - b.index; | ||
306 | + }), function (x) { | ||
307 | + return x.value; | ||
308 | + })); | ||
309 | + }); | ||
310 | + }; | ||
311 | + async.filter = doParallel(_filter); | ||
312 | + async.filterSeries = doSeries(_filter); | ||
313 | + // select alias | ||
314 | + async.select = async.filter; | ||
315 | + async.selectSeries = async.filterSeries; | ||
316 | + | ||
317 | + var _reject = function (eachfn, arr, iterator, callback) { | ||
318 | + var results = []; | ||
319 | + arr = _map(arr, function (x, i) { | ||
320 | + return {index: i, value: x}; | ||
321 | + }); | ||
322 | + eachfn(arr, function (x, callback) { | ||
323 | + iterator(x.value, function (v) { | ||
324 | + if (!v) { | ||
325 | + results.push(x); | ||
326 | + } | ||
327 | + callback(); | ||
328 | + }); | ||
329 | + }, function (err) { | ||
330 | + callback(_map(results.sort(function (a, b) { | ||
331 | + return a.index - b.index; | ||
332 | + }), function (x) { | ||
333 | + return x.value; | ||
334 | + })); | ||
335 | + }); | ||
336 | + }; | ||
337 | + async.reject = doParallel(_reject); | ||
338 | + async.rejectSeries = doSeries(_reject); | ||
339 | + | ||
340 | + var _detect = function (eachfn, arr, iterator, main_callback) { | ||
341 | + eachfn(arr, function (x, callback) { | ||
342 | + iterator(x, function (result) { | ||
343 | + if (result) { | ||
344 | + main_callback(x); | ||
345 | + main_callback = function () {}; | ||
346 | + } | ||
347 | + else { | ||
348 | + callback(); | ||
349 | + } | ||
350 | + }); | ||
351 | + }, function (err) { | ||
352 | + main_callback(); | ||
353 | + }); | ||
354 | + }; | ||
355 | + async.detect = doParallel(_detect); | ||
356 | + async.detectSeries = doSeries(_detect); | ||
357 | + | ||
358 | + async.some = function (arr, iterator, main_callback) { | ||
359 | + async.each(arr, function (x, callback) { | ||
360 | + iterator(x, function (v) { | ||
361 | + if (v) { | ||
362 | + main_callback(true); | ||
363 | + main_callback = function () {}; | ||
364 | + } | ||
365 | + callback(); | ||
366 | + }); | ||
367 | + }, function (err) { | ||
368 | + main_callback(false); | ||
369 | + }); | ||
370 | + }; | ||
371 | + // any alias | ||
372 | + async.any = async.some; | ||
373 | + | ||
374 | + async.every = function (arr, iterator, main_callback) { | ||
375 | + async.each(arr, function (x, callback) { | ||
376 | + iterator(x, function (v) { | ||
377 | + if (!v) { | ||
378 | + main_callback(false); | ||
379 | + main_callback = function () {}; | ||
380 | + } | ||
381 | + callback(); | ||
382 | + }); | ||
383 | + }, function (err) { | ||
384 | + main_callback(true); | ||
385 | + }); | ||
386 | + }; | ||
387 | + // all alias | ||
388 | + async.all = async.every; | ||
389 | + | ||
390 | + async.sortBy = function (arr, iterator, callback) { | ||
391 | + async.map(arr, function (x, callback) { | ||
392 | + iterator(x, function (err, criteria) { | ||
393 | + if (err) { | ||
394 | + callback(err); | ||
395 | + } | ||
396 | + else { | ||
397 | + callback(null, {value: x, criteria: criteria}); | ||
398 | + } | ||
399 | + }); | ||
400 | + }, function (err, results) { | ||
401 | + if (err) { | ||
402 | + return callback(err); | ||
403 | + } | ||
404 | + else { | ||
405 | + var fn = function (left, right) { | ||
406 | + var a = left.criteria, b = right.criteria; | ||
407 | + return a < b ? -1 : a > b ? 1 : 0; | ||
408 | + }; | ||
409 | + callback(null, _map(results.sort(fn), function (x) { | ||
410 | + return x.value; | ||
411 | + })); | ||
412 | + } | ||
413 | + }); | ||
414 | + }; | ||
415 | + | ||
416 | + async.auto = function (tasks, callback) { | ||
417 | + callback = callback || function () {}; | ||
418 | + var keys = _keys(tasks); | ||
419 | + var remainingTasks = keys.length | ||
420 | + if (!remainingTasks) { | ||
421 | + return callback(); | ||
422 | + } | ||
423 | + | ||
424 | + var results = {}; | ||
425 | + | ||
426 | + var listeners = []; | ||
427 | + var addListener = function (fn) { | ||
428 | + listeners.unshift(fn); | ||
429 | + }; | ||
430 | + var removeListener = function (fn) { | ||
431 | + for (var i = 0; i < listeners.length; i += 1) { | ||
432 | + if (listeners[i] === fn) { | ||
433 | + listeners.splice(i, 1); | ||
434 | + return; | ||
435 | + } | ||
436 | + } | ||
437 | + }; | ||
438 | + var taskComplete = function () { | ||
439 | + remainingTasks-- | ||
440 | + _each(listeners.slice(0), function (fn) { | ||
441 | + fn(); | ||
442 | + }); | ||
443 | + }; | ||
444 | + | ||
445 | + addListener(function () { | ||
446 | + if (!remainingTasks) { | ||
447 | + var theCallback = callback; | ||
448 | + // prevent final callback from calling itself if it errors | ||
449 | + callback = function () {}; | ||
450 | + | ||
451 | + theCallback(null, results); | ||
452 | + } | ||
453 | + }); | ||
454 | + | ||
455 | + _each(keys, function (k) { | ||
456 | + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; | ||
457 | + var taskCallback = function (err) { | ||
458 | + var args = Array.prototype.slice.call(arguments, 1); | ||
459 | + if (args.length <= 1) { | ||
460 | + args = args[0]; | ||
461 | + } | ||
462 | + if (err) { | ||
463 | + var safeResults = {}; | ||
464 | + _each(_keys(results), function(rkey) { | ||
465 | + safeResults[rkey] = results[rkey]; | ||
466 | + }); | ||
467 | + safeResults[k] = args; | ||
468 | + callback(err, safeResults); | ||
469 | + // stop subsequent errors hitting callback multiple times | ||
470 | + callback = function () {}; | ||
471 | + } | ||
472 | + else { | ||
473 | + results[k] = args; | ||
474 | + async.setImmediate(taskComplete); | ||
475 | + } | ||
476 | + }; | ||
477 | + var requires = task.slice(0, Math.abs(task.length - 1)) || []; | ||
478 | + var ready = function () { | ||
479 | + return _reduce(requires, function (a, x) { | ||
480 | + return (a && results.hasOwnProperty(x)); | ||
481 | + }, true) && !results.hasOwnProperty(k); | ||
482 | + }; | ||
483 | + if (ready()) { | ||
484 | + task[task.length - 1](taskCallback, results); | ||
485 | + } | ||
486 | + else { | ||
487 | + var listener = function () { | ||
488 | + if (ready()) { | ||
489 | + removeListener(listener); | ||
490 | + task[task.length - 1](taskCallback, results); | ||
491 | + } | ||
492 | + }; | ||
493 | + addListener(listener); | ||
494 | + } | ||
495 | + }); | ||
496 | + }; | ||
497 | + | ||
498 | + async.retry = function(times, task, callback) { | ||
499 | + var DEFAULT_TIMES = 5; | ||
500 | + var attempts = []; | ||
501 | + // Use defaults if times not passed | ||
502 | + if (typeof times === 'function') { | ||
503 | + callback = task; | ||
504 | + task = times; | ||
505 | + times = DEFAULT_TIMES; | ||
506 | + } | ||
507 | + // Make sure times is a number | ||
508 | + times = parseInt(times, 10) || DEFAULT_TIMES; | ||
509 | + var wrappedTask = function(wrappedCallback, wrappedResults) { | ||
510 | + var retryAttempt = function(task, finalAttempt) { | ||
511 | + return function(seriesCallback) { | ||
512 | + task(function(err, result){ | ||
513 | + seriesCallback(!err || finalAttempt, {err: err, result: result}); | ||
514 | + }, wrappedResults); | ||
515 | + }; | ||
516 | + }; | ||
517 | + while (times) { | ||
518 | + attempts.push(retryAttempt(task, !(times-=1))); | ||
519 | + } | ||
520 | + async.series(attempts, function(done, data){ | ||
521 | + data = data[data.length - 1]; | ||
522 | + (wrappedCallback || callback)(data.err, data.result); | ||
523 | + }); | ||
524 | + } | ||
525 | + // If a callback is passed, run this as a controll flow | ||
526 | + return callback ? wrappedTask() : wrappedTask | ||
527 | + }; | ||
528 | + | ||
529 | + async.waterfall = function (tasks, callback) { | ||
530 | + callback = callback || function () {}; | ||
531 | + if (!_isArray(tasks)) { | ||
532 | + var err = new Error('First argument to waterfall must be an array of functions'); | ||
533 | + return callback(err); | ||
534 | + } | ||
535 | + if (!tasks.length) { | ||
536 | + return callback(); | ||
537 | + } | ||
538 | + var wrapIterator = function (iterator) { | ||
539 | + return function (err) { | ||
540 | + if (err) { | ||
541 | + callback.apply(null, arguments); | ||
542 | + callback = function () {}; | ||
543 | + } | ||
544 | + else { | ||
545 | + var args = Array.prototype.slice.call(arguments, 1); | ||
546 | + var next = iterator.next(); | ||
547 | + if (next) { | ||
548 | + args.push(wrapIterator(next)); | ||
549 | + } | ||
550 | + else { | ||
551 | + args.push(callback); | ||
552 | + } | ||
553 | + async.setImmediate(function () { | ||
554 | + iterator.apply(null, args); | ||
555 | + }); | ||
556 | + } | ||
557 | + }; | ||
558 | + }; | ||
559 | + wrapIterator(async.iterator(tasks))(); | ||
560 | + }; | ||
561 | + | ||
562 | + var _parallel = function(eachfn, tasks, callback) { | ||
563 | + callback = callback || function () {}; | ||
564 | + if (_isArray(tasks)) { | ||
565 | + eachfn.map(tasks, function (fn, callback) { | ||
566 | + if (fn) { | ||
567 | + fn(function (err) { | ||
568 | + var args = Array.prototype.slice.call(arguments, 1); | ||
569 | + if (args.length <= 1) { | ||
570 | + args = args[0]; | ||
571 | + } | ||
572 | + callback.call(null, err, args); | ||
573 | + }); | ||
574 | + } | ||
575 | + }, callback); | ||
576 | + } | ||
577 | + else { | ||
578 | + var results = {}; | ||
579 | + eachfn.each(_keys(tasks), function (k, callback) { | ||
580 | + tasks[k](function (err) { | ||
581 | + var args = Array.prototype.slice.call(arguments, 1); | ||
582 | + if (args.length <= 1) { | ||
583 | + args = args[0]; | ||
584 | + } | ||
585 | + results[k] = args; | ||
586 | + callback(err); | ||
587 | + }); | ||
588 | + }, function (err) { | ||
589 | + callback(err, results); | ||
590 | + }); | ||
591 | + } | ||
592 | + }; | ||
593 | + | ||
594 | + async.parallel = function (tasks, callback) { | ||
595 | + _parallel({ map: async.map, each: async.each }, tasks, callback); | ||
596 | + }; | ||
597 | + | ||
598 | + async.parallelLimit = function(tasks, limit, callback) { | ||
599 | + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); | ||
600 | + }; | ||
601 | + | ||
602 | + async.series = function (tasks, callback) { | ||
603 | + callback = callback || function () {}; | ||
604 | + if (_isArray(tasks)) { | ||
605 | + async.mapSeries(tasks, function (fn, callback) { | ||
606 | + if (fn) { | ||
607 | + fn(function (err) { | ||
608 | + var args = Array.prototype.slice.call(arguments, 1); | ||
609 | + if (args.length <= 1) { | ||
610 | + args = args[0]; | ||
611 | + } | ||
612 | + callback.call(null, err, args); | ||
613 | + }); | ||
614 | + } | ||
615 | + }, callback); | ||
616 | + } | ||
617 | + else { | ||
618 | + var results = {}; | ||
619 | + async.eachSeries(_keys(tasks), function (k, callback) { | ||
620 | + tasks[k](function (err) { | ||
621 | + var args = Array.prototype.slice.call(arguments, 1); | ||
622 | + if (args.length <= 1) { | ||
623 | + args = args[0]; | ||
624 | + } | ||
625 | + results[k] = args; | ||
626 | + callback(err); | ||
627 | + }); | ||
628 | + }, function (err) { | ||
629 | + callback(err, results); | ||
630 | + }); | ||
631 | + } | ||
632 | + }; | ||
633 | + | ||
634 | + async.iterator = function (tasks) { | ||
635 | + var makeCallback = function (index) { | ||
636 | + var fn = function () { | ||
637 | + if (tasks.length) { | ||
638 | + tasks[index].apply(null, arguments); | ||
639 | + } | ||
640 | + return fn.next(); | ||
641 | + }; | ||
642 | + fn.next = function () { | ||
643 | + return (index < tasks.length - 1) ? makeCallback(index + 1): null; | ||
644 | + }; | ||
645 | + return fn; | ||
646 | + }; | ||
647 | + return makeCallback(0); | ||
648 | + }; | ||
649 | + | ||
650 | + async.apply = function (fn) { | ||
651 | + var args = Array.prototype.slice.call(arguments, 1); | ||
652 | + return function () { | ||
653 | + return fn.apply( | ||
654 | + null, args.concat(Array.prototype.slice.call(arguments)) | ||
655 | + ); | ||
656 | + }; | ||
657 | + }; | ||
658 | + | ||
659 | + var _concat = function (eachfn, arr, fn, callback) { | ||
660 | + var r = []; | ||
661 | + eachfn(arr, function (x, cb) { | ||
662 | + fn(x, function (err, y) { | ||
663 | + r = r.concat(y || []); | ||
664 | + cb(err); | ||
665 | + }); | ||
666 | + }, function (err) { | ||
667 | + callback(err, r); | ||
668 | + }); | ||
669 | + }; | ||
670 | + async.concat = doParallel(_concat); | ||
671 | + async.concatSeries = doSeries(_concat); | ||
672 | + | ||
673 | + async.whilst = function (test, iterator, callback) { | ||
674 | + if (test()) { | ||
675 | + iterator(function (err) { | ||
676 | + if (err) { | ||
677 | + return callback(err); | ||
678 | + } | ||
679 | + async.whilst(test, iterator, callback); | ||
680 | + }); | ||
681 | + } | ||
682 | + else { | ||
683 | + callback(); | ||
684 | + } | ||
685 | + }; | ||
686 | + | ||
687 | + async.doWhilst = function (iterator, test, callback) { | ||
688 | + iterator(function (err) { | ||
689 | + if (err) { | ||
690 | + return callback(err); | ||
691 | + } | ||
692 | + var args = Array.prototype.slice.call(arguments, 1); | ||
693 | + if (test.apply(null, args)) { | ||
694 | + async.doWhilst(iterator, test, callback); | ||
695 | + } | ||
696 | + else { | ||
697 | + callback(); | ||
698 | + } | ||
699 | + }); | ||
700 | + }; | ||
701 | + | ||
702 | + async.until = function (test, iterator, callback) { | ||
703 | + if (!test()) { | ||
704 | + iterator(function (err) { | ||
705 | + if (err) { | ||
706 | + return callback(err); | ||
707 | + } | ||
708 | + async.until(test, iterator, callback); | ||
709 | + }); | ||
710 | + } | ||
711 | + else { | ||
712 | + callback(); | ||
713 | + } | ||
714 | + }; | ||
715 | + | ||
716 | + async.doUntil = function (iterator, test, callback) { | ||
717 | + iterator(function (err) { | ||
718 | + if (err) { | ||
719 | + return callback(err); | ||
720 | + } | ||
721 | + var args = Array.prototype.slice.call(arguments, 1); | ||
722 | + if (!test.apply(null, args)) { | ||
723 | + async.doUntil(iterator, test, callback); | ||
724 | + } | ||
725 | + else { | ||
726 | + callback(); | ||
727 | + } | ||
728 | + }); | ||
729 | + }; | ||
730 | + | ||
731 | + async.queue = function (worker, concurrency) { | ||
732 | + if (concurrency === undefined) { | ||
733 | + concurrency = 1; | ||
734 | + } | ||
735 | + function _insert(q, data, pos, callback) { | ||
736 | + if (!q.started){ | ||
737 | + q.started = true; | ||
738 | + } | ||
739 | + if (!_isArray(data)) { | ||
740 | + data = [data]; | ||
741 | + } | ||
742 | + if(data.length == 0) { | ||
743 | + // call drain immediately if there are no tasks | ||
744 | + return async.setImmediate(function() { | ||
745 | + if (q.drain) { | ||
746 | + q.drain(); | ||
747 | + } | ||
748 | + }); | ||
749 | + } | ||
750 | + _each(data, function(task) { | ||
751 | + var item = { | ||
752 | + data: task, | ||
753 | + callback: typeof callback === 'function' ? callback : null | ||
754 | + }; | ||
755 | + | ||
756 | + if (pos) { | ||
757 | + q.tasks.unshift(item); | ||
758 | + } else { | ||
759 | + q.tasks.push(item); | ||
760 | + } | ||
761 | + | ||
762 | + if (q.saturated && q.tasks.length === q.concurrency) { | ||
763 | + q.saturated(); | ||
764 | + } | ||
765 | + async.setImmediate(q.process); | ||
766 | + }); | ||
767 | + } | ||
768 | + | ||
769 | + var workers = 0; | ||
770 | + var q = { | ||
771 | + tasks: [], | ||
772 | + concurrency: concurrency, | ||
773 | + saturated: null, | ||
774 | + empty: null, | ||
775 | + drain: null, | ||
776 | + started: false, | ||
777 | + paused: false, | ||
778 | + push: function (data, callback) { | ||
779 | + _insert(q, data, false, callback); | ||
780 | + }, | ||
781 | + kill: function () { | ||
782 | + q.drain = null; | ||
783 | + q.tasks = []; | ||
784 | + }, | ||
785 | + unshift: function (data, callback) { | ||
786 | + _insert(q, data, true, callback); | ||
787 | + }, | ||
788 | + process: function () { | ||
789 | + if (!q.paused && workers < q.concurrency && q.tasks.length) { | ||
790 | + var task = q.tasks.shift(); | ||
791 | + if (q.empty && q.tasks.length === 0) { | ||
792 | + q.empty(); | ||
793 | + } | ||
794 | + workers += 1; | ||
795 | + var next = function () { | ||
796 | + workers -= 1; | ||
797 | + if (task.callback) { | ||
798 | + task.callback.apply(task, arguments); | ||
799 | + } | ||
800 | + if (q.drain && q.tasks.length + workers === 0) { | ||
801 | + q.drain(); | ||
802 | + } | ||
803 | + q.process(); | ||
804 | + }; | ||
805 | + var cb = only_once(next); | ||
806 | + worker(task.data, cb); | ||
807 | + } | ||
808 | + }, | ||
809 | + length: function () { | ||
810 | + return q.tasks.length; | ||
811 | + }, | ||
812 | + running: function () { | ||
813 | + return workers; | ||
814 | + }, | ||
815 | + idle: function() { | ||
816 | + return q.tasks.length + workers === 0; | ||
817 | + }, | ||
818 | + pause: function () { | ||
819 | + if (q.paused === true) { return; } | ||
820 | + q.paused = true; | ||
821 | + }, | ||
822 | + resume: function () { | ||
823 | + if (q.paused === false) { return; } | ||
824 | + q.paused = false; | ||
825 | + // Need to call q.process once per concurrent | ||
826 | + // worker to preserve full concurrency after pause | ||
827 | + for (var w = 1; w <= q.concurrency; w++) { | ||
828 | + async.setImmediate(q.process); | ||
829 | + } | ||
830 | + } | ||
831 | + }; | ||
832 | + return q; | ||
833 | + }; | ||
834 | + | ||
835 | + async.priorityQueue = function (worker, concurrency) { | ||
836 | + | ||
837 | + function _compareTasks(a, b){ | ||
838 | + return a.priority - b.priority; | ||
839 | + }; | ||
840 | + | ||
841 | + function _binarySearch(sequence, item, compare) { | ||
842 | + var beg = -1, | ||
843 | + end = sequence.length - 1; | ||
844 | + while (beg < end) { | ||
845 | + var mid = beg + ((end - beg + 1) >>> 1); | ||
846 | + if (compare(item, sequence[mid]) >= 0) { | ||
847 | + beg = mid; | ||
848 | + } else { | ||
849 | + end = mid - 1; | ||
850 | + } | ||
851 | + } | ||
852 | + return beg; | ||
853 | + } | ||
854 | + | ||
855 | + function _insert(q, data, priority, callback) { | ||
856 | + if (!q.started){ | ||
857 | + q.started = true; | ||
858 | + } | ||
859 | + if (!_isArray(data)) { | ||
860 | + data = [data]; | ||
861 | + } | ||
862 | + if(data.length == 0) { | ||
863 | + // call drain immediately if there are no tasks | ||
864 | + return async.setImmediate(function() { | ||
865 | + if (q.drain) { | ||
866 | + q.drain(); | ||
867 | + } | ||
868 | + }); | ||
869 | + } | ||
870 | + _each(data, function(task) { | ||
871 | + var item = { | ||
872 | + data: task, | ||
873 | + priority: priority, | ||
874 | + callback: typeof callback === 'function' ? callback : null | ||
875 | + }; | ||
876 | + | ||
877 | + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); | ||
878 | + | ||
879 | + if (q.saturated && q.tasks.length === q.concurrency) { | ||
880 | + q.saturated(); | ||
881 | + } | ||
882 | + async.setImmediate(q.process); | ||
883 | + }); | ||
884 | + } | ||
885 | + | ||
886 | + // Start with a normal queue | ||
887 | + var q = async.queue(worker, concurrency); | ||
888 | + | ||
889 | + // Override push to accept second parameter representing priority | ||
890 | + q.push = function (data, priority, callback) { | ||
891 | + _insert(q, data, priority, callback); | ||
892 | + }; | ||
893 | + | ||
894 | + // Remove unshift function | ||
895 | + delete q.unshift; | ||
896 | + | ||
897 | + return q; | ||
898 | + }; | ||
899 | + | ||
900 | + async.cargo = function (worker, payload) { | ||
901 | + var working = false, | ||
902 | + tasks = []; | ||
903 | + | ||
904 | + var cargo = { | ||
905 | + tasks: tasks, | ||
906 | + payload: payload, | ||
907 | + saturated: null, | ||
908 | + empty: null, | ||
909 | + drain: null, | ||
910 | + drained: true, | ||
911 | + push: function (data, callback) { | ||
912 | + if (!_isArray(data)) { | ||
913 | + data = [data]; | ||
914 | + } | ||
915 | + _each(data, function(task) { | ||
916 | + tasks.push({ | ||
917 | + data: task, | ||
918 | + callback: typeof callback === 'function' ? callback : null | ||
919 | + }); | ||
920 | + cargo.drained = false; | ||
921 | + if (cargo.saturated && tasks.length === payload) { | ||
922 | + cargo.saturated(); | ||
923 | + } | ||
924 | + }); | ||
925 | + async.setImmediate(cargo.process); | ||
926 | + }, | ||
927 | + process: function process() { | ||
928 | + if (working) return; | ||
929 | + if (tasks.length === 0) { | ||
930 | + if(cargo.drain && !cargo.drained) cargo.drain(); | ||
931 | + cargo.drained = true; | ||
932 | + return; | ||
933 | + } | ||
934 | + | ||
935 | + var ts = typeof payload === 'number' | ||
936 | + ? tasks.splice(0, payload) | ||
937 | + : tasks.splice(0, tasks.length); | ||
938 | + | ||
939 | + var ds = _map(ts, function (task) { | ||
940 | + return task.data; | ||
941 | + }); | ||
942 | + | ||
943 | + if(cargo.empty) cargo.empty(); | ||
944 | + working = true; | ||
945 | + worker(ds, function () { | ||
946 | + working = false; | ||
947 | + | ||
948 | + var args = arguments; | ||
949 | + _each(ts, function (data) { | ||
950 | + if (data.callback) { | ||
951 | + data.callback.apply(null, args); | ||
952 | + } | ||
953 | + }); | ||
954 | + | ||
955 | + process(); | ||
956 | + }); | ||
957 | + }, | ||
958 | + length: function () { | ||
959 | + return tasks.length; | ||
960 | + }, | ||
961 | + running: function () { | ||
962 | + return working; | ||
963 | + } | ||
964 | + }; | ||
965 | + return cargo; | ||
966 | + }; | ||
967 | + | ||
968 | + var _console_fn = function (name) { | ||
969 | + return function (fn) { | ||
970 | + var args = Array.prototype.slice.call(arguments, 1); | ||
971 | + fn.apply(null, args.concat([function (err) { | ||
972 | + var args = Array.prototype.slice.call(arguments, 1); | ||
973 | + if (typeof console !== 'undefined') { | ||
974 | + if (err) { | ||
975 | + if (console.error) { | ||
976 | + console.error(err); | ||
977 | + } | ||
978 | + } | ||
979 | + else if (console[name]) { | ||
980 | + _each(args, function (x) { | ||
981 | + console[name](x); | ||
982 | + }); | ||
983 | + } | ||
984 | + } | ||
985 | + }])); | ||
986 | + }; | ||
987 | + }; | ||
988 | + async.log = _console_fn('log'); | ||
989 | + async.dir = _console_fn('dir'); | ||
990 | + /*async.info = _console_fn('info'); | ||
991 | + async.warn = _console_fn('warn'); | ||
992 | + async.error = _console_fn('error');*/ | ||
993 | + | ||
994 | + async.memoize = function (fn, hasher) { | ||
995 | + var memo = {}; | ||
996 | + var queues = {}; | ||
997 | + hasher = hasher || function (x) { | ||
998 | + return x; | ||
999 | + }; | ||
1000 | + var memoized = function () { | ||
1001 | + var args = Array.prototype.slice.call(arguments); | ||
1002 | + var callback = args.pop(); | ||
1003 | + var key = hasher.apply(null, args); | ||
1004 | + if (key in memo) { | ||
1005 | + async.nextTick(function () { | ||
1006 | + callback.apply(null, memo[key]); | ||
1007 | + }); | ||
1008 | + } | ||
1009 | + else if (key in queues) { | ||
1010 | + queues[key].push(callback); | ||
1011 | + } | ||
1012 | + else { | ||
1013 | + queues[key] = [callback]; | ||
1014 | + fn.apply(null, args.concat([function () { | ||
1015 | + memo[key] = arguments; | ||
1016 | + var q = queues[key]; | ||
1017 | + delete queues[key]; | ||
1018 | + for (var i = 0, l = q.length; i < l; i++) { | ||
1019 | + q[i].apply(null, arguments); | ||
1020 | + } | ||
1021 | + }])); | ||
1022 | + } | ||
1023 | + }; | ||
1024 | + memoized.memo = memo; | ||
1025 | + memoized.unmemoized = fn; | ||
1026 | + return memoized; | ||
1027 | + }; | ||
1028 | + | ||
1029 | + async.unmemoize = function (fn) { | ||
1030 | + return function () { | ||
1031 | + return (fn.unmemoized || fn).apply(null, arguments); | ||
1032 | + }; | ||
1033 | + }; | ||
1034 | + | ||
1035 | + async.times = function (count, iterator, callback) { | ||
1036 | + var counter = []; | ||
1037 | + for (var i = 0; i < count; i++) { | ||
1038 | + counter.push(i); | ||
1039 | + } | ||
1040 | + return async.map(counter, iterator, callback); | ||
1041 | + }; | ||
1042 | + | ||
1043 | + async.timesSeries = function (count, iterator, callback) { | ||
1044 | + var counter = []; | ||
1045 | + for (var i = 0; i < count; i++) { | ||
1046 | + counter.push(i); | ||
1047 | + } | ||
1048 | + return async.mapSeries(counter, iterator, callback); | ||
1049 | + }; | ||
1050 | + | ||
1051 | + async.seq = function (/* functions... */) { | ||
1052 | + var fns = arguments; | ||
1053 | + return function () { | ||
1054 | + var that = this; | ||
1055 | + var args = Array.prototype.slice.call(arguments); | ||
1056 | + var callback = args.pop(); | ||
1057 | + async.reduce(fns, args, function (newargs, fn, cb) { | ||
1058 | + fn.apply(that, newargs.concat([function () { | ||
1059 | + var err = arguments[0]; | ||
1060 | + var nextargs = Array.prototype.slice.call(arguments, 1); | ||
1061 | + cb(err, nextargs); | ||
1062 | + }])) | ||
1063 | + }, | ||
1064 | + function (err, results) { | ||
1065 | + callback.apply(that, [err].concat(results)); | ||
1066 | + }); | ||
1067 | + }; | ||
1068 | + }; | ||
1069 | + | ||
1070 | + async.compose = function (/* functions... */) { | ||
1071 | + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); | ||
1072 | + }; | ||
1073 | + | ||
1074 | + var _applyEach = function (eachfn, fns /*args...*/) { | ||
1075 | + var go = function () { | ||
1076 | + var that = this; | ||
1077 | + var args = Array.prototype.slice.call(arguments); | ||
1078 | + var callback = args.pop(); | ||
1079 | + return eachfn(fns, function (fn, cb) { | ||
1080 | + fn.apply(that, args.concat([cb])); | ||
1081 | + }, | ||
1082 | + callback); | ||
1083 | + }; | ||
1084 | + if (arguments.length > 2) { | ||
1085 | + var args = Array.prototype.slice.call(arguments, 2); | ||
1086 | + return go.apply(this, args); | ||
1087 | + } | ||
1088 | + else { | ||
1089 | + return go; | ||
1090 | + } | ||
1091 | + }; | ||
1092 | + async.applyEach = doParallel(_applyEach); | ||
1093 | + async.applyEachSeries = doSeries(_applyEach); | ||
1094 | + | ||
1095 | + async.forever = function (fn, callback) { | ||
1096 | + function next(err) { | ||
1097 | + if (err) { | ||
1098 | + if (callback) { | ||
1099 | + return callback(err); | ||
1100 | + } | ||
1101 | + throw err; | ||
1102 | + } | ||
1103 | + fn(next); | ||
1104 | + } | ||
1105 | + next(); | ||
1106 | + }; | ||
1107 | + | ||
1108 | + // Node.js | ||
1109 | + if (typeof module !== 'undefined' && module.exports) { | ||
1110 | + module.exports = async; | ||
1111 | + } | ||
1112 | + // AMD / RequireJS | ||
1113 | + else if (typeof define !== 'undefined' && define.amd) { | ||
1114 | + define([], function () { | ||
1115 | + return async; | ||
1116 | + }); | ||
1117 | + } | ||
1118 | + // included directly via <script> tag | ||
1119 | + else { | ||
1120 | + root.async = async; | ||
1121 | + } | ||
1122 | + | ||
1123 | +}()); |
node_modules/async/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "async", | ||
3 | + "description": "Higher-order functions and common patterns for asynchronous code", | ||
4 | + "main": "lib/async.js", | ||
5 | + "author": "Caolan McMahon", | ||
6 | + "version": "0.9.2", | ||
7 | + "keywords": [ | ||
8 | + "async", | ||
9 | + "callback", | ||
10 | + "utility", | ||
11 | + "module" | ||
12 | + ], | ||
13 | + "repository": { | ||
14 | + "type": "git", | ||
15 | + "url": "https://github.com/caolan/async.git" | ||
16 | + }, | ||
17 | + "bugs": { | ||
18 | + "url": "https://github.com/caolan/async/issues" | ||
19 | + }, | ||
20 | + "license": "MIT", | ||
21 | + "devDependencies": { | ||
22 | + "nodeunit": ">0.0.0", | ||
23 | + "uglify-js": "1.2.x", | ||
24 | + "nodelint": ">0.0.0", | ||
25 | + "lodash": ">=2.4.1" | ||
26 | + }, | ||
27 | + "jam": { | ||
28 | + "main": "lib/async.js", | ||
29 | + "include": [ | ||
30 | + "lib/async.js", | ||
31 | + "README.md", | ||
32 | + "LICENSE" | ||
33 | + ], | ||
34 | + "categories": [ | ||
35 | + "Utilities" | ||
36 | + ] | ||
37 | + }, | ||
38 | + "scripts": { | ||
39 | + "test": "nodeunit test/test-async.js" | ||
40 | + }, | ||
41 | + "spm": { | ||
42 | + "main": "lib/async.js" | ||
43 | + }, | ||
44 | + "volo": { | ||
45 | + "main": "lib/async.js", | ||
46 | + "ignore": [ | ||
47 | + "**/.*", | ||
48 | + "node_modules", | ||
49 | + "bower_components", | ||
50 | + "test", | ||
51 | + "tests" | ||
52 | + ] | ||
53 | + } | ||
54 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +#!/usr/bin/env node | ||
2 | + | ||
3 | +// This should probably be its own module but complaints about bower/etc. | ||
4 | +// support keep coming up and I'd rather just enable the workflow here for now | ||
5 | +// and figure out where this should live later. -- @beaugunderson | ||
6 | + | ||
7 | +var fs = require('fs'); | ||
8 | +var _ = require('lodash'); | ||
9 | + | ||
10 | +var packageJson = require('../package.json'); | ||
11 | + | ||
12 | +var IGNORES = ['**/.*', 'node_modules', 'bower_components', 'test', 'tests']; | ||
13 | +var INCLUDES = ['lib/async.js', 'README.md', 'LICENSE']; | ||
14 | +var REPOSITORY_NAME = 'caolan/async'; | ||
15 | + | ||
16 | +packageJson.jam = { | ||
17 | + main: packageJson.main, | ||
18 | + include: INCLUDES, | ||
19 | + categories: ['Utilities'] | ||
20 | +}; | ||
21 | + | ||
22 | +packageJson.spm = { | ||
23 | + main: packageJson.main | ||
24 | +}; | ||
25 | + | ||
26 | +packageJson.volo = { | ||
27 | + main: packageJson.main, | ||
28 | + ignore: IGNORES | ||
29 | +}; | ||
30 | + | ||
31 | +var bowerSpecific = { | ||
32 | + moduleType: ['amd', 'globals', 'node'], | ||
33 | + ignore: IGNORES, | ||
34 | + authors: [packageJson.author] | ||
35 | +}; | ||
36 | + | ||
37 | +var bowerInclude = ['name', 'description', 'version', 'main', 'keywords', | ||
38 | + 'license', 'homepage', 'repository', 'devDependencies']; | ||
39 | + | ||
40 | +var componentSpecific = { | ||
41 | + repository: REPOSITORY_NAME, | ||
42 | + scripts: [packageJson.main] | ||
43 | +}; | ||
44 | + | ||
45 | +var componentInclude = ['name', 'description', 'version', 'keywords', | ||
46 | + 'license']; | ||
47 | + | ||
48 | +var bowerJson = _.merge({}, _.pick(packageJson, bowerInclude), bowerSpecific); | ||
49 | +var componentJson = _.merge({}, _.pick(packageJson, componentInclude), componentSpecific); | ||
50 | + | ||
51 | +fs.writeFileSync('./bower.json', JSON.stringify(bowerJson, null, 2)); | ||
52 | +fs.writeFileSync('./component.json', JSON.stringify(componentJson, null, 2)); | ||
53 | +fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2)); |
node_modules/balanced-match/LICENSE.md
0 → 100644
1 | +(MIT) | ||
2 | + | ||
3 | +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
6 | +this software and associated documentation files (the "Software"), to deal in | ||
7 | +the Software without restriction, including without limitation the rights to | ||
8 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
9 | +of the Software, and to permit persons to whom the Software is furnished to do | ||
10 | +so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | +SOFTWARE. |
node_modules/balanced-match/README.md
0 → 100644
1 | +# balanced-match | ||
2 | + | ||
3 | +Match balanced string pairs, like `{` and `}` or `<b>` and `</b>`. Supports regular expressions as well! | ||
4 | + | ||
5 | +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) | ||
6 | +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) | ||
7 | + | ||
8 | +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) | ||
9 | + | ||
10 | +## Example | ||
11 | + | ||
12 | +Get the first matching pair of braces: | ||
13 | + | ||
14 | +```js | ||
15 | +var balanced = require('balanced-match'); | ||
16 | + | ||
17 | +console.log(balanced('{', '}', 'pre{in{nested}}post')); | ||
18 | +console.log(balanced('{', '}', 'pre{first}between{second}post')); | ||
19 | +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); | ||
20 | +``` | ||
21 | + | ||
22 | +The matches are: | ||
23 | + | ||
24 | +```bash | ||
25 | +$ node example.js | ||
26 | +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } | ||
27 | +{ start: 3, | ||
28 | + end: 9, | ||
29 | + pre: 'pre', | ||
30 | + body: 'first', | ||
31 | + post: 'between{second}post' } | ||
32 | +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } | ||
33 | +``` | ||
34 | + | ||
35 | +## API | ||
36 | + | ||
37 | +### var m = balanced(a, b, str) | ||
38 | + | ||
39 | +For the first non-nested matching pair of `a` and `b` in `str`, return an | ||
40 | +object with those keys: | ||
41 | + | ||
42 | +* **start** the index of the first match of `a` | ||
43 | +* **end** the index of the matching `b` | ||
44 | +* **pre** the preamble, `a` and `b` not included | ||
45 | +* **body** the match, `a` and `b` not included | ||
46 | +* **post** the postscript, `a` and `b` not included | ||
47 | + | ||
48 | +If there's no match, `undefined` will be returned. | ||
49 | + | ||
50 | +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. | ||
51 | + | ||
52 | +### var r = balanced.range(a, b, str) | ||
53 | + | ||
54 | +For the first non-nested matching pair of `a` and `b` in `str`, return an | ||
55 | +array with indexes: `[ <a index>, <b index> ]`. | ||
56 | + | ||
57 | +If there's no match, `undefined` will be returned. | ||
58 | + | ||
59 | +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. | ||
60 | + | ||
61 | +## Installation | ||
62 | + | ||
63 | +With [npm](https://npmjs.org) do: | ||
64 | + | ||
65 | +```bash | ||
66 | +npm install balanced-match | ||
67 | +``` | ||
68 | + | ||
69 | +## Security contact information | ||
70 | + | ||
71 | +To report a security vulnerability, please use the | ||
72 | +[Tidelift security contact](https://tidelift.com/security). | ||
73 | +Tidelift will coordinate the fix and disclosure. | ||
74 | + | ||
75 | +## License | ||
76 | + | ||
77 | +(MIT) | ||
78 | + | ||
79 | +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> | ||
80 | + | ||
81 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
82 | +this software and associated documentation files (the "Software"), to deal in | ||
83 | +the Software without restriction, including without limitation the rights to | ||
84 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
85 | +of the Software, and to permit persons to whom the Software is furnished to do | ||
86 | +so, subject to the following conditions: | ||
87 | + | ||
88 | +The above copyright notice and this permission notice shall be included in all | ||
89 | +copies or substantial portions of the Software. | ||
90 | + | ||
91 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
92 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
93 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
94 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
95 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
96 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
97 | +SOFTWARE. |
node_modules/balanced-match/index.js
0 → 100644
1 | +'use strict'; | ||
2 | +module.exports = balanced; | ||
3 | +function balanced(a, b, str) { | ||
4 | + if (a instanceof RegExp) a = maybeMatch(a, str); | ||
5 | + if (b instanceof RegExp) b = maybeMatch(b, str); | ||
6 | + | ||
7 | + var r = range(a, b, str); | ||
8 | + | ||
9 | + return r && { | ||
10 | + start: r[0], | ||
11 | + end: r[1], | ||
12 | + pre: str.slice(0, r[0]), | ||
13 | + body: str.slice(r[0] + a.length, r[1]), | ||
14 | + post: str.slice(r[1] + b.length) | ||
15 | + }; | ||
16 | +} | ||
17 | + | ||
18 | +function maybeMatch(reg, str) { | ||
19 | + var m = str.match(reg); | ||
20 | + return m ? m[0] : null; | ||
21 | +} | ||
22 | + | ||
23 | +balanced.range = range; | ||
24 | +function range(a, b, str) { | ||
25 | + var begs, beg, left, right, result; | ||
26 | + var ai = str.indexOf(a); | ||
27 | + var bi = str.indexOf(b, ai + 1); | ||
28 | + var i = ai; | ||
29 | + | ||
30 | + if (ai >= 0 && bi > 0) { | ||
31 | + if(a===b) { | ||
32 | + return [ai, bi]; | ||
33 | + } | ||
34 | + begs = []; | ||
35 | + left = str.length; | ||
36 | + | ||
37 | + while (i >= 0 && !result) { | ||
38 | + if (i == ai) { | ||
39 | + begs.push(i); | ||
40 | + ai = str.indexOf(a, i + 1); | ||
41 | + } else if (begs.length == 1) { | ||
42 | + result = [ begs.pop(), bi ]; | ||
43 | + } else { | ||
44 | + beg = begs.pop(); | ||
45 | + if (beg < left) { | ||
46 | + left = beg; | ||
47 | + right = bi; | ||
48 | + } | ||
49 | + | ||
50 | + bi = str.indexOf(b, i + 1); | ||
51 | + } | ||
52 | + | ||
53 | + i = ai < bi && ai >= 0 ? ai : bi; | ||
54 | + } | ||
55 | + | ||
56 | + if (begs.length) { | ||
57 | + result = [ left, right ]; | ||
58 | + } | ||
59 | + } | ||
60 | + | ||
61 | + return result; | ||
62 | +} |
node_modules/balanced-match/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "balanced-match", | ||
3 | + "description": "Match balanced character pairs, like \"{\" and \"}\"", | ||
4 | + "version": "1.0.2", | ||
5 | + "repository": { | ||
6 | + "type": "git", | ||
7 | + "url": "git://github.com/juliangruber/balanced-match.git" | ||
8 | + }, | ||
9 | + "homepage": "https://github.com/juliangruber/balanced-match", | ||
10 | + "main": "index.js", | ||
11 | + "scripts": { | ||
12 | + "test": "tape test/test.js", | ||
13 | + "bench": "matcha test/bench.js" | ||
14 | + }, | ||
15 | + "devDependencies": { | ||
16 | + "matcha": "^0.7.0", | ||
17 | + "tape": "^4.6.0" | ||
18 | + }, | ||
19 | + "keywords": [ | ||
20 | + "match", | ||
21 | + "regexp", | ||
22 | + "test", | ||
23 | + "balanced", | ||
24 | + "parse" | ||
25 | + ], | ||
26 | + "author": { | ||
27 | + "name": "Julian Gruber", | ||
28 | + "email": "mail@juliangruber.com", | ||
29 | + "url": "http://juliangruber.com" | ||
30 | + }, | ||
31 | + "license": "MIT", | ||
32 | + "testling": { | ||
33 | + "files": "test/*.js", | ||
34 | + "browsers": [ | ||
35 | + "ie/8..latest", | ||
36 | + "firefox/20..latest", | ||
37 | + "firefox/nightly", | ||
38 | + "chrome/25..latest", | ||
39 | + "chrome/canary", | ||
40 | + "opera/12..latest", | ||
41 | + "opera/next", | ||
42 | + "safari/5.1..latest", | ||
43 | + "ipad/6.0..latest", | ||
44 | + "iphone/6.0..latest", | ||
45 | + "android-browser/4.2..latest" | ||
46 | + ] | ||
47 | + } | ||
48 | +} |
node_modules/brace-expansion/LICENSE
0 → 100644
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | +of this software and associated documentation files (the "Software"), to deal | ||
7 | +in the Software without restriction, including without limitation the rights | ||
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | +copies of the Software, and to permit persons to whom the Software is | ||
10 | +furnished to do so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in all | ||
13 | +copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | +SOFTWARE. |
node_modules/brace-expansion/README.md
0 → 100644
1 | +# brace-expansion | ||
2 | + | ||
3 | +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), | ||
4 | +as known from sh/bash, in JavaScript. | ||
5 | + | ||
6 | +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) | ||
7 | +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) | ||
8 | +[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) | ||
9 | + | ||
10 | +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) | ||
11 | + | ||
12 | +## Example | ||
13 | + | ||
14 | +```js | ||
15 | +var expand = require('brace-expansion'); | ||
16 | + | ||
17 | +expand('file-{a,b,c}.jpg') | ||
18 | +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] | ||
19 | + | ||
20 | +expand('-v{,,}') | ||
21 | +// => ['-v', '-v', '-v'] | ||
22 | + | ||
23 | +expand('file{0..2}.jpg') | ||
24 | +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] | ||
25 | + | ||
26 | +expand('file-{a..c}.jpg') | ||
27 | +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] | ||
28 | + | ||
29 | +expand('file{2..0}.jpg') | ||
30 | +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] | ||
31 | + | ||
32 | +expand('file{0..4..2}.jpg') | ||
33 | +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] | ||
34 | + | ||
35 | +expand('file-{a..e..2}.jpg') | ||
36 | +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] | ||
37 | + | ||
38 | +expand('file{00..10..5}.jpg') | ||
39 | +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] | ||
40 | + | ||
41 | +expand('{{A..C},{a..c}}') | ||
42 | +// => ['A', 'B', 'C', 'a', 'b', 'c'] | ||
43 | + | ||
44 | +expand('ppp{,config,oe{,conf}}') | ||
45 | +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] | ||
46 | +``` | ||
47 | + | ||
48 | +## API | ||
49 | + | ||
50 | +```js | ||
51 | +var expand = require('brace-expansion'); | ||
52 | +``` | ||
53 | + | ||
54 | +### var expanded = expand(str) | ||
55 | + | ||
56 | +Return an array of all possible and valid expansions of `str`. If none are | ||
57 | +found, `[str]` is returned. | ||
58 | + | ||
59 | +Valid expansions are: | ||
60 | + | ||
61 | +```js | ||
62 | +/^(.*,)+(.+)?$/ | ||
63 | +// {a,b,...} | ||
64 | +``` | ||
65 | + | ||
66 | +A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. | ||
67 | + | ||
68 | +```js | ||
69 | +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ | ||
70 | +// {x..y[..incr]} | ||
71 | +``` | ||
72 | + | ||
73 | +A numeric sequence from `x` to `y` inclusive, with optional increment. | ||
74 | +If `x` or `y` start with a leading `0`, all the numbers will be padded | ||
75 | +to have equal length. Negative numbers and backwards iteration work too. | ||
76 | + | ||
77 | +```js | ||
78 | +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ | ||
79 | +// {x..y[..incr]} | ||
80 | +``` | ||
81 | + | ||
82 | +An alphabetic sequence from `x` to `y` inclusive, with optional increment. | ||
83 | +`x` and `y` must be exactly one character, and if given, `incr` must be a | ||
84 | +number. | ||
85 | + | ||
86 | +For compatibility reasons, the string `${` is not eligible for brace expansion. | ||
87 | + | ||
88 | +## Installation | ||
89 | + | ||
90 | +With [npm](https://npmjs.org) do: | ||
91 | + | ||
92 | +```bash | ||
93 | +npm install brace-expansion | ||
94 | +``` | ||
95 | + | ||
96 | +## Contributors | ||
97 | + | ||
98 | +- [Julian Gruber](https://github.com/juliangruber) | ||
99 | +- [Isaac Z. Schlueter](https://github.com/isaacs) | ||
100 | + | ||
101 | +## Sponsors | ||
102 | + | ||
103 | +This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! | ||
104 | + | ||
105 | +Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! | ||
106 | + | ||
107 | +## License | ||
108 | + | ||
109 | +(MIT) | ||
110 | + | ||
111 | +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> | ||
112 | + | ||
113 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
114 | +this software and associated documentation files (the "Software"), to deal in | ||
115 | +the Software without restriction, including without limitation the rights to | ||
116 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
117 | +of the Software, and to permit persons to whom the Software is furnished to do | ||
118 | +so, subject to the following conditions: | ||
119 | + | ||
120 | +The above copyright notice and this permission notice shall be included in all | ||
121 | +copies or substantial portions of the Software. | ||
122 | + | ||
123 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
124 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
125 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
126 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
127 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
128 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
129 | +SOFTWARE. |
node_modules/brace-expansion/index.js
0 → 100644
1 | +var concatMap = require('concat-map'); | ||
2 | +var balanced = require('balanced-match'); | ||
3 | + | ||
4 | +module.exports = expandTop; | ||
5 | + | ||
6 | +var escSlash = '\0SLASH'+Math.random()+'\0'; | ||
7 | +var escOpen = '\0OPEN'+Math.random()+'\0'; | ||
8 | +var escClose = '\0CLOSE'+Math.random()+'\0'; | ||
9 | +var escComma = '\0COMMA'+Math.random()+'\0'; | ||
10 | +var escPeriod = '\0PERIOD'+Math.random()+'\0'; | ||
11 | + | ||
12 | +function numeric(str) { | ||
13 | + return parseInt(str, 10) == str | ||
14 | + ? parseInt(str, 10) | ||
15 | + : str.charCodeAt(0); | ||
16 | +} | ||
17 | + | ||
18 | +function escapeBraces(str) { | ||
19 | + return str.split('\\\\').join(escSlash) | ||
20 | + .split('\\{').join(escOpen) | ||
21 | + .split('\\}').join(escClose) | ||
22 | + .split('\\,').join(escComma) | ||
23 | + .split('\\.').join(escPeriod); | ||
24 | +} | ||
25 | + | ||
26 | +function unescapeBraces(str) { | ||
27 | + return str.split(escSlash).join('\\') | ||
28 | + .split(escOpen).join('{') | ||
29 | + .split(escClose).join('}') | ||
30 | + .split(escComma).join(',') | ||
31 | + .split(escPeriod).join('.'); | ||
32 | +} | ||
33 | + | ||
34 | + | ||
35 | +// Basically just str.split(","), but handling cases | ||
36 | +// where we have nested braced sections, which should be | ||
37 | +// treated as individual members, like {a,{b,c},d} | ||
38 | +function parseCommaParts(str) { | ||
39 | + if (!str) | ||
40 | + return ['']; | ||
41 | + | ||
42 | + var parts = []; | ||
43 | + var m = balanced('{', '}', str); | ||
44 | + | ||
45 | + if (!m) | ||
46 | + return str.split(','); | ||
47 | + | ||
48 | + var pre = m.pre; | ||
49 | + var body = m.body; | ||
50 | + var post = m.post; | ||
51 | + var p = pre.split(','); | ||
52 | + | ||
53 | + p[p.length-1] += '{' + body + '}'; | ||
54 | + var postParts = parseCommaParts(post); | ||
55 | + if (post.length) { | ||
56 | + p[p.length-1] += postParts.shift(); | ||
57 | + p.push.apply(p, postParts); | ||
58 | + } | ||
59 | + | ||
60 | + parts.push.apply(parts, p); | ||
61 | + | ||
62 | + return parts; | ||
63 | +} | ||
64 | + | ||
65 | +function expandTop(str) { | ||
66 | + if (!str) | ||
67 | + return []; | ||
68 | + | ||
69 | + // I don't know why Bash 4.3 does this, but it does. | ||
70 | + // Anything starting with {} will have the first two bytes preserved | ||
71 | + // but *only* at the top level, so {},a}b will not expand to anything, | ||
72 | + // but a{},b}c will be expanded to [a}c,abc]. | ||
73 | + // One could argue that this is a bug in Bash, but since the goal of | ||
74 | + // this module is to match Bash's rules, we escape a leading {} | ||
75 | + if (str.substr(0, 2) === '{}') { | ||
76 | + str = '\\{\\}' + str.substr(2); | ||
77 | + } | ||
78 | + | ||
79 | + return expand(escapeBraces(str), true).map(unescapeBraces); | ||
80 | +} | ||
81 | + | ||
82 | +function identity(e) { | ||
83 | + return e; | ||
84 | +} | ||
85 | + | ||
86 | +function embrace(str) { | ||
87 | + return '{' + str + '}'; | ||
88 | +} | ||
89 | +function isPadded(el) { | ||
90 | + return /^-?0\d/.test(el); | ||
91 | +} | ||
92 | + | ||
93 | +function lte(i, y) { | ||
94 | + return i <= y; | ||
95 | +} | ||
96 | +function gte(i, y) { | ||
97 | + return i >= y; | ||
98 | +} | ||
99 | + | ||
100 | +function expand(str, isTop) { | ||
101 | + var expansions = []; | ||
102 | + | ||
103 | + var m = balanced('{', '}', str); | ||
104 | + if (!m || /\$$/.test(m.pre)) return [str]; | ||
105 | + | ||
106 | + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); | ||
107 | + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); | ||
108 | + var isSequence = isNumericSequence || isAlphaSequence; | ||
109 | + var isOptions = m.body.indexOf(',') >= 0; | ||
110 | + if (!isSequence && !isOptions) { | ||
111 | + // {a},b} | ||
112 | + if (m.post.match(/,.*\}/)) { | ||
113 | + str = m.pre + '{' + m.body + escClose + m.post; | ||
114 | + return expand(str); | ||
115 | + } | ||
116 | + return [str]; | ||
117 | + } | ||
118 | + | ||
119 | + var n; | ||
120 | + if (isSequence) { | ||
121 | + n = m.body.split(/\.\./); | ||
122 | + } else { | ||
123 | + n = parseCommaParts(m.body); | ||
124 | + if (n.length === 1) { | ||
125 | + // x{{a,b}}y ==> x{a}y x{b}y | ||
126 | + n = expand(n[0], false).map(embrace); | ||
127 | + if (n.length === 1) { | ||
128 | + var post = m.post.length | ||
129 | + ? expand(m.post, false) | ||
130 | + : ['']; | ||
131 | + return post.map(function(p) { | ||
132 | + return m.pre + n[0] + p; | ||
133 | + }); | ||
134 | + } | ||
135 | + } | ||
136 | + } | ||
137 | + | ||
138 | + // at this point, n is the parts, and we know it's not a comma set | ||
139 | + // with a single entry. | ||
140 | + | ||
141 | + // no need to expand pre, since it is guaranteed to be free of brace-sets | ||
142 | + var pre = m.pre; | ||
143 | + var post = m.post.length | ||
144 | + ? expand(m.post, false) | ||
145 | + : ['']; | ||
146 | + | ||
147 | + var N; | ||
148 | + | ||
149 | + if (isSequence) { | ||
150 | + var x = numeric(n[0]); | ||
151 | + var y = numeric(n[1]); | ||
152 | + var width = Math.max(n[0].length, n[1].length) | ||
153 | + var incr = n.length == 3 | ||
154 | + ? Math.abs(numeric(n[2])) | ||
155 | + : 1; | ||
156 | + var test = lte; | ||
157 | + var reverse = y < x; | ||
158 | + if (reverse) { | ||
159 | + incr *= -1; | ||
160 | + test = gte; | ||
161 | + } | ||
162 | + var pad = n.some(isPadded); | ||
163 | + | ||
164 | + N = []; | ||
165 | + | ||
166 | + for (var i = x; test(i, y); i += incr) { | ||
167 | + var c; | ||
168 | + if (isAlphaSequence) { | ||
169 | + c = String.fromCharCode(i); | ||
170 | + if (c === '\\') | ||
171 | + c = ''; | ||
172 | + } else { | ||
173 | + c = String(i); | ||
174 | + if (pad) { | ||
175 | + var need = width - c.length; | ||
176 | + if (need > 0) { | ||
177 | + var z = new Array(need + 1).join('0'); | ||
178 | + if (i < 0) | ||
179 | + c = '-' + z + c.slice(1); | ||
180 | + else | ||
181 | + c = z + c; | ||
182 | + } | ||
183 | + } | ||
184 | + } | ||
185 | + N.push(c); | ||
186 | + } | ||
187 | + } else { | ||
188 | + N = concatMap(n, function(el) { return expand(el, false) }); | ||
189 | + } | ||
190 | + | ||
191 | + for (var j = 0; j < N.length; j++) { | ||
192 | + for (var k = 0; k < post.length; k++) { | ||
193 | + var expansion = pre + N[j] + post[k]; | ||
194 | + if (!isTop || isSequence || expansion) | ||
195 | + expansions.push(expansion); | ||
196 | + } | ||
197 | + } | ||
198 | + | ||
199 | + return expansions; | ||
200 | +} | ||
201 | + |
node_modules/brace-expansion/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "brace-expansion", | ||
3 | + "description": "Brace expansion as known from sh/bash", | ||
4 | + "version": "1.1.11", | ||
5 | + "repository": { | ||
6 | + "type": "git", | ||
7 | + "url": "git://github.com/juliangruber/brace-expansion.git" | ||
8 | + }, | ||
9 | + "homepage": "https://github.com/juliangruber/brace-expansion", | ||
10 | + "main": "index.js", | ||
11 | + "scripts": { | ||
12 | + "test": "tape test/*.js", | ||
13 | + "gentest": "bash test/generate.sh", | ||
14 | + "bench": "matcha test/perf/bench.js" | ||
15 | + }, | ||
16 | + "dependencies": { | ||
17 | + "balanced-match": "^1.0.0", | ||
18 | + "concat-map": "0.0.1" | ||
19 | + }, | ||
20 | + "devDependencies": { | ||
21 | + "matcha": "^0.7.0", | ||
22 | + "tape": "^4.6.0" | ||
23 | + }, | ||
24 | + "keywords": [], | ||
25 | + "author": { | ||
26 | + "name": "Julian Gruber", | ||
27 | + "email": "mail@juliangruber.com", | ||
28 | + "url": "http://juliangruber.com" | ||
29 | + }, | ||
30 | + "license": "MIT", | ||
31 | + "testling": { | ||
32 | + "files": "test/*.js", | ||
33 | + "browsers": [ | ||
34 | + "ie/8..latest", | ||
35 | + "firefox/20..latest", | ||
36 | + "firefox/nightly", | ||
37 | + "chrome/25..latest", | ||
38 | + "chrome/canary", | ||
39 | + "opera/12..latest", | ||
40 | + "opera/next", | ||
41 | + "safari/5.1..latest", | ||
42 | + "ipad/6.0..latest", | ||
43 | + "iphone/6.0..latest", | ||
44 | + "android-browser/4.2..latest" | ||
45 | + ] | ||
46 | + } | ||
47 | +} |
node_modules/chalk/index.js
0 → 100644
1 | +'use strict'; | ||
2 | +const escapeStringRegexp = require('escape-string-regexp'); | ||
3 | +const ansiStyles = require('ansi-styles'); | ||
4 | +const stdoutColor = require('supports-color').stdout; | ||
5 | + | ||
6 | +const template = require('./templates.js'); | ||
7 | + | ||
8 | +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); | ||
9 | + | ||
10 | +// `supportsColor.level` → `ansiStyles.color[name]` mapping | ||
11 | +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; | ||
12 | + | ||
13 | +// `color-convert` models to exclude from the Chalk API due to conflicts and such | ||
14 | +const skipModels = new Set(['gray']); | ||
15 | + | ||
16 | +const styles = Object.create(null); | ||
17 | + | ||
18 | +function applyOptions(obj, options) { | ||
19 | + options = options || {}; | ||
20 | + | ||
21 | + // Detect level if not set manually | ||
22 | + const scLevel = stdoutColor ? stdoutColor.level : 0; | ||
23 | + obj.level = options.level === undefined ? scLevel : options.level; | ||
24 | + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; | ||
25 | +} | ||
26 | + | ||
27 | +function Chalk(options) { | ||
28 | + // We check for this.template here since calling `chalk.constructor()` | ||
29 | + // by itself will have a `this` of a previously constructed chalk object | ||
30 | + if (!this || !(this instanceof Chalk) || this.template) { | ||
31 | + const chalk = {}; | ||
32 | + applyOptions(chalk, options); | ||
33 | + | ||
34 | + chalk.template = function () { | ||
35 | + const args = [].slice.call(arguments); | ||
36 | + return chalkTag.apply(null, [chalk.template].concat(args)); | ||
37 | + }; | ||
38 | + | ||
39 | + Object.setPrototypeOf(chalk, Chalk.prototype); | ||
40 | + Object.setPrototypeOf(chalk.template, chalk); | ||
41 | + | ||
42 | + chalk.template.constructor = Chalk; | ||
43 | + | ||
44 | + return chalk.template; | ||
45 | + } | ||
46 | + | ||
47 | + applyOptions(this, options); | ||
48 | +} | ||
49 | + | ||
50 | +// Use bright blue on Windows as the normal blue color is illegible | ||
51 | +if (isSimpleWindowsTerm) { | ||
52 | + ansiStyles.blue.open = '\u001B[94m'; | ||
53 | +} | ||
54 | + | ||
55 | +for (const key of Object.keys(ansiStyles)) { | ||
56 | + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); | ||
57 | + | ||
58 | + styles[key] = { | ||
59 | + get() { | ||
60 | + const codes = ansiStyles[key]; | ||
61 | + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); | ||
62 | + } | ||
63 | + }; | ||
64 | +} | ||
65 | + | ||
66 | +styles.visible = { | ||
67 | + get() { | ||
68 | + return build.call(this, this._styles || [], true, 'visible'); | ||
69 | + } | ||
70 | +}; | ||
71 | + | ||
72 | +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); | ||
73 | +for (const model of Object.keys(ansiStyles.color.ansi)) { | ||
74 | + if (skipModels.has(model)) { | ||
75 | + continue; | ||
76 | + } | ||
77 | + | ||
78 | + styles[model] = { | ||
79 | + get() { | ||
80 | + const level = this.level; | ||
81 | + return function () { | ||
82 | + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); | ||
83 | + const codes = { | ||
84 | + open, | ||
85 | + close: ansiStyles.color.close, | ||
86 | + closeRe: ansiStyles.color.closeRe | ||
87 | + }; | ||
88 | + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); | ||
89 | + }; | ||
90 | + } | ||
91 | + }; | ||
92 | +} | ||
93 | + | ||
94 | +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); | ||
95 | +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { | ||
96 | + if (skipModels.has(model)) { | ||
97 | + continue; | ||
98 | + } | ||
99 | + | ||
100 | + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); | ||
101 | + styles[bgModel] = { | ||
102 | + get() { | ||
103 | + const level = this.level; | ||
104 | + return function () { | ||
105 | + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); | ||
106 | + const codes = { | ||
107 | + open, | ||
108 | + close: ansiStyles.bgColor.close, | ||
109 | + closeRe: ansiStyles.bgColor.closeRe | ||
110 | + }; | ||
111 | + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); | ||
112 | + }; | ||
113 | + } | ||
114 | + }; | ||
115 | +} | ||
116 | + | ||
117 | +const proto = Object.defineProperties(() => {}, styles); | ||
118 | + | ||
119 | +function build(_styles, _empty, key) { | ||
120 | + const builder = function () { | ||
121 | + return applyStyle.apply(builder, arguments); | ||
122 | + }; | ||
123 | + | ||
124 | + builder._styles = _styles; | ||
125 | + builder._empty = _empty; | ||
126 | + | ||
127 | + const self = this; | ||
128 | + | ||
129 | + Object.defineProperty(builder, 'level', { | ||
130 | + enumerable: true, | ||
131 | + get() { | ||
132 | + return self.level; | ||
133 | + }, | ||
134 | + set(level) { | ||
135 | + self.level = level; | ||
136 | + } | ||
137 | + }); | ||
138 | + | ||
139 | + Object.defineProperty(builder, 'enabled', { | ||
140 | + enumerable: true, | ||
141 | + get() { | ||
142 | + return self.enabled; | ||
143 | + }, | ||
144 | + set(enabled) { | ||
145 | + self.enabled = enabled; | ||
146 | + } | ||
147 | + }); | ||
148 | + | ||
149 | + // See below for fix regarding invisible grey/dim combination on Windows | ||
150 | + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; | ||
151 | + | ||
152 | + // `__proto__` is used because we must return a function, but there is | ||
153 | + // no way to create a function with a different prototype | ||
154 | + builder.__proto__ = proto; // eslint-disable-line no-proto | ||
155 | + | ||
156 | + return builder; | ||
157 | +} | ||
158 | + | ||
159 | +function applyStyle() { | ||
160 | + // Support varags, but simply cast to string in case there's only one arg | ||
161 | + const args = arguments; | ||
162 | + const argsLen = args.length; | ||
163 | + let str = String(arguments[0]); | ||
164 | + | ||
165 | + if (argsLen === 0) { | ||
166 | + return ''; | ||
167 | + } | ||
168 | + | ||
169 | + if (argsLen > 1) { | ||
170 | + // Don't slice `arguments`, it prevents V8 optimizations | ||
171 | + for (let a = 1; a < argsLen; a++) { | ||
172 | + str += ' ' + args[a]; | ||
173 | + } | ||
174 | + } | ||
175 | + | ||
176 | + if (!this.enabled || this.level <= 0 || !str) { | ||
177 | + return this._empty ? '' : str; | ||
178 | + } | ||
179 | + | ||
180 | + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, | ||
181 | + // see https://github.com/chalk/chalk/issues/58 | ||
182 | + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. | ||
183 | + const originalDim = ansiStyles.dim.open; | ||
184 | + if (isSimpleWindowsTerm && this.hasGrey) { | ||
185 | + ansiStyles.dim.open = ''; | ||
186 | + } | ||
187 | + | ||
188 | + for (const code of this._styles.slice().reverse()) { | ||
189 | + // Replace any instances already present with a re-opening code | ||
190 | + // otherwise only the part of the string until said closing code | ||
191 | + // will be colored, and the rest will simply be 'plain'. | ||
192 | + str = code.open + str.replace(code.closeRe, code.open) + code.close; | ||
193 | + | ||
194 | + // Close the styling before a linebreak and reopen | ||
195 | + // after next line to fix a bleed issue on macOS | ||
196 | + // https://github.com/chalk/chalk/pull/92 | ||
197 | + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); | ||
198 | + } | ||
199 | + | ||
200 | + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue | ||
201 | + ansiStyles.dim.open = originalDim; | ||
202 | + | ||
203 | + return str; | ||
204 | +} | ||
205 | + | ||
206 | +function chalkTag(chalk, strings) { | ||
207 | + if (!Array.isArray(strings)) { | ||
208 | + // If chalk() was called by itself or with a string, | ||
209 | + // return the string itself as a string. | ||
210 | + return [].slice.call(arguments, 1).join(' '); | ||
211 | + } | ||
212 | + | ||
213 | + const args = [].slice.call(arguments, 2); | ||
214 | + const parts = [strings.raw[0]]; | ||
215 | + | ||
216 | + for (let i = 1; i < strings.length; i++) { | ||
217 | + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); | ||
218 | + parts.push(String(strings.raw[i])); | ||
219 | + } | ||
220 | + | ||
221 | + return template(chalk, parts.join('')); | ||
222 | +} | ||
223 | + | ||
224 | +Object.defineProperties(Chalk.prototype, styles); | ||
225 | + | ||
226 | +module.exports = Chalk(); // eslint-disable-line new-cap | ||
227 | +module.exports.supportsColor = stdoutColor; | ||
228 | +module.exports.default = module.exports; // For TypeScript |
node_modules/chalk/index.js.flow
0 → 100644
1 | +// @flow strict | ||
2 | + | ||
3 | +type TemplateStringsArray = $ReadOnlyArray<string>; | ||
4 | + | ||
5 | +export type Level = $Values<{ | ||
6 | + None: 0, | ||
7 | + Basic: 1, | ||
8 | + Ansi256: 2, | ||
9 | + TrueColor: 3 | ||
10 | +}>; | ||
11 | + | ||
12 | +export type ChalkOptions = {| | ||
13 | + enabled?: boolean, | ||
14 | + level?: Level | ||
15 | +|}; | ||
16 | + | ||
17 | +export type ColorSupport = {| | ||
18 | + level: Level, | ||
19 | + hasBasic: boolean, | ||
20 | + has256: boolean, | ||
21 | + has16m: boolean | ||
22 | +|}; | ||
23 | + | ||
24 | +export interface Chalk { | ||
25 | + (...text: string[]): string, | ||
26 | + (text: TemplateStringsArray, ...placeholders: string[]): string, | ||
27 | + constructor(options?: ChalkOptions): Chalk, | ||
28 | + enabled: boolean, | ||
29 | + level: Level, | ||
30 | + rgb(r: number, g: number, b: number): Chalk, | ||
31 | + hsl(h: number, s: number, l: number): Chalk, | ||
32 | + hsv(h: number, s: number, v: number): Chalk, | ||
33 | + hwb(h: number, w: number, b: number): Chalk, | ||
34 | + bgHex(color: string): Chalk, | ||
35 | + bgKeyword(color: string): Chalk, | ||
36 | + bgRgb(r: number, g: number, b: number): Chalk, | ||
37 | + bgHsl(h: number, s: number, l: number): Chalk, | ||
38 | + bgHsv(h: number, s: number, v: number): Chalk, | ||
39 | + bgHwb(h: number, w: number, b: number): Chalk, | ||
40 | + hex(color: string): Chalk, | ||
41 | + keyword(color: string): Chalk, | ||
42 | + | ||
43 | + +reset: Chalk, | ||
44 | + +bold: Chalk, | ||
45 | + +dim: Chalk, | ||
46 | + +italic: Chalk, | ||
47 | + +underline: Chalk, | ||
48 | + +inverse: Chalk, | ||
49 | + +hidden: Chalk, | ||
50 | + +strikethrough: Chalk, | ||
51 | + | ||
52 | + +visible: Chalk, | ||
53 | + | ||
54 | + +black: Chalk, | ||
55 | + +red: Chalk, | ||
56 | + +green: Chalk, | ||
57 | + +yellow: Chalk, | ||
58 | + +blue: Chalk, | ||
59 | + +magenta: Chalk, | ||
60 | + +cyan: Chalk, | ||
61 | + +white: Chalk, | ||
62 | + +gray: Chalk, | ||
63 | + +grey: Chalk, | ||
64 | + +blackBright: Chalk, | ||
65 | + +redBright: Chalk, | ||
66 | + +greenBright: Chalk, | ||
67 | + +yellowBright: Chalk, | ||
68 | + +blueBright: Chalk, | ||
69 | + +magentaBright: Chalk, | ||
70 | + +cyanBright: Chalk, | ||
71 | + +whiteBright: Chalk, | ||
72 | + | ||
73 | + +bgBlack: Chalk, | ||
74 | + +bgRed: Chalk, | ||
75 | + +bgGreen: Chalk, | ||
76 | + +bgYellow: Chalk, | ||
77 | + +bgBlue: Chalk, | ||
78 | + +bgMagenta: Chalk, | ||
79 | + +bgCyan: Chalk, | ||
80 | + +bgWhite: Chalk, | ||
81 | + +bgBlackBright: Chalk, | ||
82 | + +bgRedBright: Chalk, | ||
83 | + +bgGreenBright: Chalk, | ||
84 | + +bgYellowBright: Chalk, | ||
85 | + +bgBlueBright: Chalk, | ||
86 | + +bgMagentaBright: Chalk, | ||
87 | + +bgCyanBright: Chalk, | ||
88 | + +bgWhiteBrigh: Chalk, | ||
89 | + | ||
90 | + supportsColor: ColorSupport | ||
91 | +}; | ||
92 | + | ||
93 | +declare module.exports: Chalk; |
node_modules/chalk/license
0 → 100644
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
6 | + | ||
7 | +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
8 | + | ||
9 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
node_modules/chalk/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "chalk", | ||
3 | + "version": "2.4.2", | ||
4 | + "description": "Terminal string styling done right", | ||
5 | + "license": "MIT", | ||
6 | + "repository": "chalk/chalk", | ||
7 | + "engines": { | ||
8 | + "node": ">=4" | ||
9 | + }, | ||
10 | + "scripts": { | ||
11 | + "test": "xo && tsc --project types && flow --max-warnings=0 && nyc ava", | ||
12 | + "bench": "matcha benchmark.js", | ||
13 | + "coveralls": "nyc report --reporter=text-lcov | coveralls" | ||
14 | + }, | ||
15 | + "files": [ | ||
16 | + "index.js", | ||
17 | + "templates.js", | ||
18 | + "types/index.d.ts", | ||
19 | + "index.js.flow" | ||
20 | + ], | ||
21 | + "keywords": [ | ||
22 | + "color", | ||
23 | + "colour", | ||
24 | + "colors", | ||
25 | + "terminal", | ||
26 | + "console", | ||
27 | + "cli", | ||
28 | + "string", | ||
29 | + "str", | ||
30 | + "ansi", | ||
31 | + "style", | ||
32 | + "styles", | ||
33 | + "tty", | ||
34 | + "formatting", | ||
35 | + "rgb", | ||
36 | + "256", | ||
37 | + "shell", | ||
38 | + "xterm", | ||
39 | + "log", | ||
40 | + "logging", | ||
41 | + "command-line", | ||
42 | + "text" | ||
43 | + ], | ||
44 | + "dependencies": { | ||
45 | + "ansi-styles": "^3.2.1", | ||
46 | + "escape-string-regexp": "^1.0.5", | ||
47 | + "supports-color": "^5.3.0" | ||
48 | + }, | ||
49 | + "devDependencies": { | ||
50 | + "ava": "*", | ||
51 | + "coveralls": "^3.0.0", | ||
52 | + "execa": "^0.9.0", | ||
53 | + "flow-bin": "^0.68.0", | ||
54 | + "import-fresh": "^2.0.0", | ||
55 | + "matcha": "^0.7.0", | ||
56 | + "nyc": "^11.0.2", | ||
57 | + "resolve-from": "^4.0.0", | ||
58 | + "typescript": "^2.5.3", | ||
59 | + "xo": "*" | ||
60 | + }, | ||
61 | + "types": "types/index.d.ts", | ||
62 | + "xo": { | ||
63 | + "envs": [ | ||
64 | + "node", | ||
65 | + "mocha" | ||
66 | + ], | ||
67 | + "ignores": [ | ||
68 | + "test/_flow.js" | ||
69 | + ] | ||
70 | + } | ||
71 | +} |
node_modules/chalk/readme.md
0 → 100644
1 | +<h1 align="center"> | ||
2 | + <br> | ||
3 | + <br> | ||
4 | + <img width="320" src="media/logo.svg" alt="Chalk"> | ||
5 | + <br> | ||
6 | + <br> | ||
7 | + <br> | ||
8 | +</h1> | ||
9 | + | ||
10 | +> Terminal string styling done right | ||
11 | + | ||
12 | +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) | ||
13 | + | ||
14 | +### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) | ||
15 | + | ||
16 | +<img src="https://cdn.rawgit.com/chalk/ansi-styles/8261697c95bf34b6c7767e2cbe9941a851d59385/screenshot.svg" alt="" width="900"> | ||
17 | + | ||
18 | + | ||
19 | +## Highlights | ||
20 | + | ||
21 | +- Expressive API | ||
22 | +- Highly performant | ||
23 | +- Ability to nest styles | ||
24 | +- [256/Truecolor color support](#256-and-truecolor-color-support) | ||
25 | +- Auto-detects color support | ||
26 | +- Doesn't extend `String.prototype` | ||
27 | +- Clean and focused | ||
28 | +- Actively maintained | ||
29 | +- [Used by ~23,000 packages](https://www.npmjs.com/browse/depended/chalk) as of December 31, 2017 | ||
30 | + | ||
31 | + | ||
32 | +## Install | ||
33 | + | ||
34 | +```console | ||
35 | +$ npm install chalk | ||
36 | +``` | ||
37 | + | ||
38 | +<a href="https://www.patreon.com/sindresorhus"> | ||
39 | + <img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160"> | ||
40 | +</a> | ||
41 | + | ||
42 | + | ||
43 | +## Usage | ||
44 | + | ||
45 | +```js | ||
46 | +const chalk = require('chalk'); | ||
47 | + | ||
48 | +console.log(chalk.blue('Hello world!')); | ||
49 | +``` | ||
50 | + | ||
51 | +Chalk comes with an easy to use composable API where you just chain and nest the styles you want. | ||
52 | + | ||
53 | +```js | ||
54 | +const chalk = require('chalk'); | ||
55 | +const log = console.log; | ||
56 | + | ||
57 | +// Combine styled and normal strings | ||
58 | +log(chalk.blue('Hello') + ' World' + chalk.red('!')); | ||
59 | + | ||
60 | +// Compose multiple styles using the chainable API | ||
61 | +log(chalk.blue.bgRed.bold('Hello world!')); | ||
62 | + | ||
63 | +// Pass in multiple arguments | ||
64 | +log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz')); | ||
65 | + | ||
66 | +// Nest styles | ||
67 | +log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!')); | ||
68 | + | ||
69 | +// Nest styles of the same type even (color, underline, background) | ||
70 | +log(chalk.green( | ||
71 | + 'I am a green line ' + | ||
72 | + chalk.blue.underline.bold('with a blue substring') + | ||
73 | + ' that becomes green again!' | ||
74 | +)); | ||
75 | + | ||
76 | +// ES2015 template literal | ||
77 | +log(` | ||
78 | +CPU: ${chalk.red('90%')} | ||
79 | +RAM: ${chalk.green('40%')} | ||
80 | +DISK: ${chalk.yellow('70%')} | ||
81 | +`); | ||
82 | + | ||
83 | +// ES2015 tagged template literal | ||
84 | +log(chalk` | ||
85 | +CPU: {red ${cpu.totalPercent}%} | ||
86 | +RAM: {green ${ram.used / ram.total * 100}%} | ||
87 | +DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} | ||
88 | +`); | ||
89 | + | ||
90 | +// Use RGB colors in terminal emulators that support it. | ||
91 | +log(chalk.keyword('orange')('Yay for orange colored text!')); | ||
92 | +log(chalk.rgb(123, 45, 67).underline('Underlined reddish color')); | ||
93 | +log(chalk.hex('#DEADED').bold('Bold gray!')); | ||
94 | +``` | ||
95 | + | ||
96 | +Easily define your own themes: | ||
97 | + | ||
98 | +```js | ||
99 | +const chalk = require('chalk'); | ||
100 | + | ||
101 | +const error = chalk.bold.red; | ||
102 | +const warning = chalk.keyword('orange'); | ||
103 | + | ||
104 | +console.log(error('Error!')); | ||
105 | +console.log(warning('Warning!')); | ||
106 | +``` | ||
107 | + | ||
108 | +Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args): | ||
109 | + | ||
110 | +```js | ||
111 | +const name = 'Sindre'; | ||
112 | +console.log(chalk.green('Hello %s'), name); | ||
113 | +//=> 'Hello Sindre' | ||
114 | +``` | ||
115 | + | ||
116 | + | ||
117 | +## API | ||
118 | + | ||
119 | +### chalk.`<style>[.<style>...](string, [string...])` | ||
120 | + | ||
121 | +Example: `chalk.red.bold.underline('Hello', 'world');` | ||
122 | + | ||
123 | +Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`. | ||
124 | + | ||
125 | +Multiple arguments will be separated by space. | ||
126 | + | ||
127 | +### chalk.enabled | ||
128 | + | ||
129 | +Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property. | ||
130 | + | ||
131 | +Chalk is enabled by default unless explicitly disabled via the constructor or `chalk.level` is `0`. | ||
132 | + | ||
133 | +If you need to change this in a reusable module, create a new instance: | ||
134 | + | ||
135 | +```js | ||
136 | +const ctx = new chalk.constructor({enabled: false}); | ||
137 | +``` | ||
138 | + | ||
139 | +### chalk.level | ||
140 | + | ||
141 | +Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers. | ||
142 | + | ||
143 | +If you need to change this in a reusable module, create a new instance: | ||
144 | + | ||
145 | +```js | ||
146 | +const ctx = new chalk.constructor({level: 0}); | ||
147 | +``` | ||
148 | + | ||
149 | +Levels are as follows: | ||
150 | + | ||
151 | +0. All colors disabled | ||
152 | +1. Basic color support (16 colors) | ||
153 | +2. 256 color support | ||
154 | +3. Truecolor support (16 million colors) | ||
155 | + | ||
156 | +### chalk.supportsColor | ||
157 | + | ||
158 | +Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience. | ||
159 | + | ||
160 | +Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. | ||
161 | + | ||
162 | +Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. | ||
163 | + | ||
164 | + | ||
165 | +## Styles | ||
166 | + | ||
167 | +### Modifiers | ||
168 | + | ||
169 | +- `reset` | ||
170 | +- `bold` | ||
171 | +- `dim` | ||
172 | +- `italic` *(Not widely supported)* | ||
173 | +- `underline` | ||
174 | +- `inverse` | ||
175 | +- `hidden` | ||
176 | +- `strikethrough` *(Not widely supported)* | ||
177 | +- `visible` (Text is emitted only if enabled) | ||
178 | + | ||
179 | +### Colors | ||
180 | + | ||
181 | +- `black` | ||
182 | +- `red` | ||
183 | +- `green` | ||
184 | +- `yellow` | ||
185 | +- `blue` *(On Windows the bright version is used since normal blue is illegible)* | ||
186 | +- `magenta` | ||
187 | +- `cyan` | ||
188 | +- `white` | ||
189 | +- `gray` ("bright black") | ||
190 | +- `redBright` | ||
191 | +- `greenBright` | ||
192 | +- `yellowBright` | ||
193 | +- `blueBright` | ||
194 | +- `magentaBright` | ||
195 | +- `cyanBright` | ||
196 | +- `whiteBright` | ||
197 | + | ||
198 | +### Background colors | ||
199 | + | ||
200 | +- `bgBlack` | ||
201 | +- `bgRed` | ||
202 | +- `bgGreen` | ||
203 | +- `bgYellow` | ||
204 | +- `bgBlue` | ||
205 | +- `bgMagenta` | ||
206 | +- `bgCyan` | ||
207 | +- `bgWhite` | ||
208 | +- `bgBlackBright` | ||
209 | +- `bgRedBright` | ||
210 | +- `bgGreenBright` | ||
211 | +- `bgYellowBright` | ||
212 | +- `bgBlueBright` | ||
213 | +- `bgMagentaBright` | ||
214 | +- `bgCyanBright` | ||
215 | +- `bgWhiteBright` | ||
216 | + | ||
217 | + | ||
218 | +## Tagged template literal | ||
219 | + | ||
220 | +Chalk can be used as a [tagged template literal](http://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals). | ||
221 | + | ||
222 | +```js | ||
223 | +const chalk = require('chalk'); | ||
224 | + | ||
225 | +const miles = 18; | ||
226 | +const calculateFeet = miles => miles * 5280; | ||
227 | + | ||
228 | +console.log(chalk` | ||
229 | + There are {bold 5280 feet} in a mile. | ||
230 | + In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}. | ||
231 | +`); | ||
232 | +``` | ||
233 | + | ||
234 | +Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`). | ||
235 | + | ||
236 | +Template styles are chained exactly like normal Chalk styles. The following two statements are equivalent: | ||
237 | + | ||
238 | +```js | ||
239 | +console.log(chalk.bold.rgb(10, 100, 200)('Hello!')); | ||
240 | +console.log(chalk`{bold.rgb(10,100,200) Hello!}`); | ||
241 | +``` | ||
242 | + | ||
243 | +Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain spaces between parameters. | ||
244 | + | ||
245 | +All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped. | ||
246 | + | ||
247 | + | ||
248 | +## 256 and Truecolor color support | ||
249 | + | ||
250 | +Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps. | ||
251 | + | ||
252 | +Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red). | ||
253 | + | ||
254 | +Examples: | ||
255 | + | ||
256 | +- `chalk.hex('#DEADED').underline('Hello, world!')` | ||
257 | +- `chalk.keyword('orange')('Some orange text')` | ||
258 | +- `chalk.rgb(15, 100, 204).inverse('Hello!')` | ||
259 | + | ||
260 | +Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `keyword` for foreground colors and `bgKeyword` for background colors). | ||
261 | + | ||
262 | +- `chalk.bgHex('#DEADED').underline('Hello, world!')` | ||
263 | +- `chalk.bgKeyword('orange')('Some orange text')` | ||
264 | +- `chalk.bgRgb(15, 100, 204).inverse('Hello!')` | ||
265 | + | ||
266 | +The following color models can be used: | ||
267 | + | ||
268 | +- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')` | ||
269 | +- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')` | ||
270 | +- [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')` | ||
271 | +- [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')` | ||
272 | +- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')` | ||
273 | +- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hwb(32, 0, 50).bold('Orange!')` | ||
274 | +- `ansi16` | ||
275 | +- `ansi256` | ||
276 | + | ||
277 | + | ||
278 | +## Windows | ||
279 | + | ||
280 | +If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`. | ||
281 | + | ||
282 | + | ||
283 | +## Origin story | ||
284 | + | ||
285 | +[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative. | ||
286 | + | ||
287 | + | ||
288 | +## Related | ||
289 | + | ||
290 | +- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module | ||
291 | +- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal | ||
292 | +- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color | ||
293 | +- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes | ||
294 | +- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream | ||
295 | +- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes | ||
296 | +- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes | ||
297 | +- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes | ||
298 | +- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes | ||
299 | +- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models | ||
300 | +- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal | ||
301 | +- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings | ||
302 | +- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings | ||
303 | +- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal | ||
304 | + | ||
305 | + | ||
306 | +## Maintainers | ||
307 | + | ||
308 | +- [Sindre Sorhus](https://github.com/sindresorhus) | ||
309 | +- [Josh Junon](https://github.com/qix-) | ||
310 | + | ||
311 | + | ||
312 | +## License | ||
313 | + | ||
314 | +MIT |
node_modules/chalk/templates.js
0 → 100644
1 | +'use strict'; | ||
2 | +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; | ||
3 | +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; | ||
4 | +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; | ||
5 | +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; | ||
6 | + | ||
7 | +const ESCAPES = new Map([ | ||
8 | + ['n', '\n'], | ||
9 | + ['r', '\r'], | ||
10 | + ['t', '\t'], | ||
11 | + ['b', '\b'], | ||
12 | + ['f', '\f'], | ||
13 | + ['v', '\v'], | ||
14 | + ['0', '\0'], | ||
15 | + ['\\', '\\'], | ||
16 | + ['e', '\u001B'], | ||
17 | + ['a', '\u0007'] | ||
18 | +]); | ||
19 | + | ||
20 | +function unescape(c) { | ||
21 | + if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { | ||
22 | + return String.fromCharCode(parseInt(c.slice(1), 16)); | ||
23 | + } | ||
24 | + | ||
25 | + return ESCAPES.get(c) || c; | ||
26 | +} | ||
27 | + | ||
28 | +function parseArguments(name, args) { | ||
29 | + const results = []; | ||
30 | + const chunks = args.trim().split(/\s*,\s*/g); | ||
31 | + let matches; | ||
32 | + | ||
33 | + for (const chunk of chunks) { | ||
34 | + if (!isNaN(chunk)) { | ||
35 | + results.push(Number(chunk)); | ||
36 | + } else if ((matches = chunk.match(STRING_REGEX))) { | ||
37 | + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); | ||
38 | + } else { | ||
39 | + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); | ||
40 | + } | ||
41 | + } | ||
42 | + | ||
43 | + return results; | ||
44 | +} | ||
45 | + | ||
46 | +function parseStyle(style) { | ||
47 | + STYLE_REGEX.lastIndex = 0; | ||
48 | + | ||
49 | + const results = []; | ||
50 | + let matches; | ||
51 | + | ||
52 | + while ((matches = STYLE_REGEX.exec(style)) !== null) { | ||
53 | + const name = matches[1]; | ||
54 | + | ||
55 | + if (matches[2]) { | ||
56 | + const args = parseArguments(name, matches[2]); | ||
57 | + results.push([name].concat(args)); | ||
58 | + } else { | ||
59 | + results.push([name]); | ||
60 | + } | ||
61 | + } | ||
62 | + | ||
63 | + return results; | ||
64 | +} | ||
65 | + | ||
66 | +function buildStyle(chalk, styles) { | ||
67 | + const enabled = {}; | ||
68 | + | ||
69 | + for (const layer of styles) { | ||
70 | + for (const style of layer.styles) { | ||
71 | + enabled[style[0]] = layer.inverse ? null : style.slice(1); | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
75 | + let current = chalk; | ||
76 | + for (const styleName of Object.keys(enabled)) { | ||
77 | + if (Array.isArray(enabled[styleName])) { | ||
78 | + if (!(styleName in current)) { | ||
79 | + throw new Error(`Unknown Chalk style: ${styleName}`); | ||
80 | + } | ||
81 | + | ||
82 | + if (enabled[styleName].length > 0) { | ||
83 | + current = current[styleName].apply(current, enabled[styleName]); | ||
84 | + } else { | ||
85 | + current = current[styleName]; | ||
86 | + } | ||
87 | + } | ||
88 | + } | ||
89 | + | ||
90 | + return current; | ||
91 | +} | ||
92 | + | ||
93 | +module.exports = (chalk, tmp) => { | ||
94 | + const styles = []; | ||
95 | + const chunks = []; | ||
96 | + let chunk = []; | ||
97 | + | ||
98 | + // eslint-disable-next-line max-params | ||
99 | + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { | ||
100 | + if (escapeChar) { | ||
101 | + chunk.push(unescape(escapeChar)); | ||
102 | + } else if (style) { | ||
103 | + const str = chunk.join(''); | ||
104 | + chunk = []; | ||
105 | + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); | ||
106 | + styles.push({inverse, styles: parseStyle(style)}); | ||
107 | + } else if (close) { | ||
108 | + if (styles.length === 0) { | ||
109 | + throw new Error('Found extraneous } in Chalk template literal'); | ||
110 | + } | ||
111 | + | ||
112 | + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); | ||
113 | + chunk = []; | ||
114 | + styles.pop(); | ||
115 | + } else { | ||
116 | + chunk.push(chr); | ||
117 | + } | ||
118 | + }); | ||
119 | + | ||
120 | + chunks.push(chunk.join('')); | ||
121 | + | ||
122 | + if (styles.length > 0) { | ||
123 | + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; | ||
124 | + throw new Error(errMsg); | ||
125 | + } | ||
126 | + | ||
127 | + return chunks.join(''); | ||
128 | +}; |
node_modules/chalk/types/index.d.ts
0 → 100644
1 | +// Type definitions for Chalk | ||
2 | +// Definitions by: Thomas Sauer <https://github.com/t-sauer> | ||
3 | + | ||
4 | +export const enum Level { | ||
5 | + None = 0, | ||
6 | + Basic = 1, | ||
7 | + Ansi256 = 2, | ||
8 | + TrueColor = 3 | ||
9 | +} | ||
10 | + | ||
11 | +export interface ChalkOptions { | ||
12 | + enabled?: boolean; | ||
13 | + level?: Level; | ||
14 | +} | ||
15 | + | ||
16 | +export interface ChalkConstructor { | ||
17 | + new (options?: ChalkOptions): Chalk; | ||
18 | + (options?: ChalkOptions): Chalk; | ||
19 | +} | ||
20 | + | ||
21 | +export interface ColorSupport { | ||
22 | + level: Level; | ||
23 | + hasBasic: boolean; | ||
24 | + has256: boolean; | ||
25 | + has16m: boolean; | ||
26 | +} | ||
27 | + | ||
28 | +export interface Chalk { | ||
29 | + (...text: string[]): string; | ||
30 | + (text: TemplateStringsArray, ...placeholders: string[]): string; | ||
31 | + constructor: ChalkConstructor; | ||
32 | + enabled: boolean; | ||
33 | + level: Level; | ||
34 | + rgb(r: number, g: number, b: number): this; | ||
35 | + hsl(h: number, s: number, l: number): this; | ||
36 | + hsv(h: number, s: number, v: number): this; | ||
37 | + hwb(h: number, w: number, b: number): this; | ||
38 | + bgHex(color: string): this; | ||
39 | + bgKeyword(color: string): this; | ||
40 | + bgRgb(r: number, g: number, b: number): this; | ||
41 | + bgHsl(h: number, s: number, l: number): this; | ||
42 | + bgHsv(h: number, s: number, v: number): this; | ||
43 | + bgHwb(h: number, w: number, b: number): this; | ||
44 | + hex(color: string): this; | ||
45 | + keyword(color: string): this; | ||
46 | + | ||
47 | + readonly reset: this; | ||
48 | + readonly bold: this; | ||
49 | + readonly dim: this; | ||
50 | + readonly italic: this; | ||
51 | + readonly underline: this; | ||
52 | + readonly inverse: this; | ||
53 | + readonly hidden: this; | ||
54 | + readonly strikethrough: this; | ||
55 | + | ||
56 | + readonly visible: this; | ||
57 | + | ||
58 | + readonly black: this; | ||
59 | + readonly red: this; | ||
60 | + readonly green: this; | ||
61 | + readonly yellow: this; | ||
62 | + readonly blue: this; | ||
63 | + readonly magenta: this; | ||
64 | + readonly cyan: this; | ||
65 | + readonly white: this; | ||
66 | + readonly gray: this; | ||
67 | + readonly grey: this; | ||
68 | + readonly blackBright: this; | ||
69 | + readonly redBright: this; | ||
70 | + readonly greenBright: this; | ||
71 | + readonly yellowBright: this; | ||
72 | + readonly blueBright: this; | ||
73 | + readonly magentaBright: this; | ||
74 | + readonly cyanBright: this; | ||
75 | + readonly whiteBright: this; | ||
76 | + | ||
77 | + readonly bgBlack: this; | ||
78 | + readonly bgRed: this; | ||
79 | + readonly bgGreen: this; | ||
80 | + readonly bgYellow: this; | ||
81 | + readonly bgBlue: this; | ||
82 | + readonly bgMagenta: this; | ||
83 | + readonly bgCyan: this; | ||
84 | + readonly bgWhite: this; | ||
85 | + readonly bgBlackBright: this; | ||
86 | + readonly bgRedBright: this; | ||
87 | + readonly bgGreenBright: this; | ||
88 | + readonly bgYellowBright: this; | ||
89 | + readonly bgBlueBright: this; | ||
90 | + readonly bgMagentaBright: this; | ||
91 | + readonly bgCyanBright: this; | ||
92 | + readonly bgWhiteBright: this; | ||
93 | +} | ||
94 | + | ||
95 | +declare const chalk: Chalk & { supportsColor: ColorSupport }; | ||
96 | + | ||
97 | +export default chalk |
node_modules/color-convert/CHANGELOG.md
0 → 100644
1 | +# 1.0.0 - 2016-01-07 | ||
2 | + | ||
3 | +- Removed: unused speed test | ||
4 | +- Added: Automatic routing between previously unsupported conversions | ||
5 | +([#27](https://github.com/Qix-/color-convert/pull/27)) | ||
6 | +- Removed: `xxx2xxx()` and `xxx2xxxRaw()` functions | ||
7 | +([#27](https://github.com/Qix-/color-convert/pull/27)) | ||
8 | +- Removed: `convert()` class | ||
9 | +([#27](https://github.com/Qix-/color-convert/pull/27)) | ||
10 | +- Changed: all functions to lookup dictionary | ||
11 | +([#27](https://github.com/Qix-/color-convert/pull/27)) | ||
12 | +- Changed: `ansi` to `ansi256` | ||
13 | +([#27](https://github.com/Qix-/color-convert/pull/27)) | ||
14 | +- Fixed: argument grouping for functions requiring only one argument | ||
15 | +([#27](https://github.com/Qix-/color-convert/pull/27)) | ||
16 | + | ||
17 | +# 0.6.0 - 2015-07-23 | ||
18 | + | ||
19 | +- Added: methods to handle | ||
20 | +[ANSI](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 16/256 colors: | ||
21 | + - rgb2ansi16 | ||
22 | + - rgb2ansi | ||
23 | + - hsl2ansi16 | ||
24 | + - hsl2ansi | ||
25 | + - hsv2ansi16 | ||
26 | + - hsv2ansi | ||
27 | + - hwb2ansi16 | ||
28 | + - hwb2ansi | ||
29 | + - cmyk2ansi16 | ||
30 | + - cmyk2ansi | ||
31 | + - keyword2ansi16 | ||
32 | + - keyword2ansi | ||
33 | + - ansi162rgb | ||
34 | + - ansi162hsl | ||
35 | + - ansi162hsv | ||
36 | + - ansi162hwb | ||
37 | + - ansi162cmyk | ||
38 | + - ansi162keyword | ||
39 | + - ansi2rgb | ||
40 | + - ansi2hsl | ||
41 | + - ansi2hsv | ||
42 | + - ansi2hwb | ||
43 | + - ansi2cmyk | ||
44 | + - ansi2keyword | ||
45 | +([#18](https://github.com/harthur/color-convert/pull/18)) | ||
46 | + | ||
47 | +# 0.5.3 - 2015-06-02 | ||
48 | + | ||
49 | +- Fixed: hsl2hsv does not return `NaN` anymore when using `[0,0,0]` | ||
50 | +([#15](https://github.com/harthur/color-convert/issues/15)) | ||
51 | + | ||
52 | +--- | ||
53 | + | ||
54 | +Check out commit logs for older releases |
node_modules/color-convert/LICENSE
0 → 100644
1 | +Copyright (c) 2011-2016 Heather Arthur <fayearthur@gmail.com> | ||
2 | + | ||
3 | +Permission is hereby granted, free of charge, to any person obtaining | ||
4 | +a copy of this software and associated documentation files (the | ||
5 | +"Software"), to deal in the Software without restriction, including | ||
6 | +without limitation the rights to use, copy, modify, merge, publish, | ||
7 | +distribute, sublicense, and/or sell copies of the Software, and to | ||
8 | +permit persons to whom the Software is furnished to do so, subject to | ||
9 | +the following conditions: | ||
10 | + | ||
11 | +The above copyright notice and this permission notice shall be | ||
12 | +included in all copies or substantial portions of the Software. | ||
13 | + | ||
14 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
15 | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
16 | +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
17 | +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
18 | +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
19 | +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
20 | +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
21 | + |
node_modules/color-convert/README.md
0 → 100644
1 | +# color-convert | ||
2 | + | ||
3 | +[![Build Status](https://travis-ci.org/Qix-/color-convert.svg?branch=master)](https://travis-ci.org/Qix-/color-convert) | ||
4 | + | ||
5 | +Color-convert is a color conversion library for JavaScript and node. | ||
6 | +It converts all ways between `rgb`, `hsl`, `hsv`, `hwb`, `cmyk`, `ansi`, `ansi16`, `hex` strings, and CSS `keyword`s (will round to closest): | ||
7 | + | ||
8 | +```js | ||
9 | +var convert = require('color-convert'); | ||
10 | + | ||
11 | +convert.rgb.hsl(140, 200, 100); // [96, 48, 59] | ||
12 | +convert.keyword.rgb('blue'); // [0, 0, 255] | ||
13 | + | ||
14 | +var rgbChannels = convert.rgb.channels; // 3 | ||
15 | +var cmykChannels = convert.cmyk.channels; // 4 | ||
16 | +var ansiChannels = convert.ansi16.channels; // 1 | ||
17 | +``` | ||
18 | + | ||
19 | +# Install | ||
20 | + | ||
21 | +```console | ||
22 | +$ npm install color-convert | ||
23 | +``` | ||
24 | + | ||
25 | +# API | ||
26 | + | ||
27 | +Simply get the property of the _from_ and _to_ conversion that you're looking for. | ||
28 | + | ||
29 | +All functions have a rounded and unrounded variant. By default, return values are rounded. To get the unrounded (raw) results, simply tack on `.raw` to the function. | ||
30 | + | ||
31 | +All 'from' functions have a hidden property called `.channels` that indicates the number of channels the function expects (not including alpha). | ||
32 | + | ||
33 | +```js | ||
34 | +var convert = require('color-convert'); | ||
35 | + | ||
36 | +// Hex to LAB | ||
37 | +convert.hex.lab('DEADBF'); // [ 76, 21, -2 ] | ||
38 | +convert.hex.lab.raw('DEADBF'); // [ 75.56213190997677, 20.653827952644754, -2.290532499330533 ] | ||
39 | + | ||
40 | +// RGB to CMYK | ||
41 | +convert.rgb.cmyk(167, 255, 4); // [ 35, 0, 98, 0 ] | ||
42 | +convert.rgb.cmyk.raw(167, 255, 4); // [ 34.509803921568626, 0, 98.43137254901961, 0 ] | ||
43 | +``` | ||
44 | + | ||
45 | +### Arrays | ||
46 | +All functions that accept multiple arguments also support passing an array. | ||
47 | + | ||
48 | +Note that this does **not** apply to functions that convert from a color that only requires one value (e.g. `keyword`, `ansi256`, `hex`, etc.) | ||
49 | + | ||
50 | +```js | ||
51 | +var convert = require('color-convert'); | ||
52 | + | ||
53 | +convert.rgb.hex(123, 45, 67); // '7B2D43' | ||
54 | +convert.rgb.hex([123, 45, 67]); // '7B2D43' | ||
55 | +``` | ||
56 | + | ||
57 | +## Routing | ||
58 | + | ||
59 | +Conversions that don't have an _explicitly_ defined conversion (in [conversions.js](conversions.js)), but can be converted by means of sub-conversions (e.g. XYZ -> **RGB** -> CMYK), are automatically routed together. This allows just about any color model supported by `color-convert` to be converted to any other model, so long as a sub-conversion path exists. This is also true for conversions requiring more than one step in between (e.g. LCH -> **LAB** -> **XYZ** -> **RGB** -> Hex). | ||
60 | + | ||
61 | +Keep in mind that extensive conversions _may_ result in a loss of precision, and exist only to be complete. For a list of "direct" (single-step) conversions, see [conversions.js](conversions.js). | ||
62 | + | ||
63 | +# Contribute | ||
64 | + | ||
65 | +If there is a new model you would like to support, or want to add a direct conversion between two existing models, please send us a pull request. | ||
66 | + | ||
67 | +# License | ||
68 | +Copyright © 2011-2016, Heather Arthur and Josh Junon. Licensed under the [MIT License](LICENSE). |
node_modules/color-convert/conversions.js
0 → 100644
1 | +/* MIT license */ | ||
2 | +var cssKeywords = require('color-name'); | ||
3 | + | ||
4 | +// NOTE: conversions should only return primitive values (i.e. arrays, or | ||
5 | +// values that give correct `typeof` results). | ||
6 | +// do not use box values types (i.e. Number(), String(), etc.) | ||
7 | + | ||
8 | +var reverseKeywords = {}; | ||
9 | +for (var key in cssKeywords) { | ||
10 | + if (cssKeywords.hasOwnProperty(key)) { | ||
11 | + reverseKeywords[cssKeywords[key]] = key; | ||
12 | + } | ||
13 | +} | ||
14 | + | ||
15 | +var convert = module.exports = { | ||
16 | + rgb: {channels: 3, labels: 'rgb'}, | ||
17 | + hsl: {channels: 3, labels: 'hsl'}, | ||
18 | + hsv: {channels: 3, labels: 'hsv'}, | ||
19 | + hwb: {channels: 3, labels: 'hwb'}, | ||
20 | + cmyk: {channels: 4, labels: 'cmyk'}, | ||
21 | + xyz: {channels: 3, labels: 'xyz'}, | ||
22 | + lab: {channels: 3, labels: 'lab'}, | ||
23 | + lch: {channels: 3, labels: 'lch'}, | ||
24 | + hex: {channels: 1, labels: ['hex']}, | ||
25 | + keyword: {channels: 1, labels: ['keyword']}, | ||
26 | + ansi16: {channels: 1, labels: ['ansi16']}, | ||
27 | + ansi256: {channels: 1, labels: ['ansi256']}, | ||
28 | + hcg: {channels: 3, labels: ['h', 'c', 'g']}, | ||
29 | + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, | ||
30 | + gray: {channels: 1, labels: ['gray']} | ||
31 | +}; | ||
32 | + | ||
33 | +// hide .channels and .labels properties | ||
34 | +for (var model in convert) { | ||
35 | + if (convert.hasOwnProperty(model)) { | ||
36 | + if (!('channels' in convert[model])) { | ||
37 | + throw new Error('missing channels property: ' + model); | ||
38 | + } | ||
39 | + | ||
40 | + if (!('labels' in convert[model])) { | ||
41 | + throw new Error('missing channel labels property: ' + model); | ||
42 | + } | ||
43 | + | ||
44 | + if (convert[model].labels.length !== convert[model].channels) { | ||
45 | + throw new Error('channel and label counts mismatch: ' + model); | ||
46 | + } | ||
47 | + | ||
48 | + var channels = convert[model].channels; | ||
49 | + var labels = convert[model].labels; | ||
50 | + delete convert[model].channels; | ||
51 | + delete convert[model].labels; | ||
52 | + Object.defineProperty(convert[model], 'channels', {value: channels}); | ||
53 | + Object.defineProperty(convert[model], 'labels', {value: labels}); | ||
54 | + } | ||
55 | +} | ||
56 | + | ||
57 | +convert.rgb.hsl = function (rgb) { | ||
58 | + var r = rgb[0] / 255; | ||
59 | + var g = rgb[1] / 255; | ||
60 | + var b = rgb[2] / 255; | ||
61 | + var min = Math.min(r, g, b); | ||
62 | + var max = Math.max(r, g, b); | ||
63 | + var delta = max - min; | ||
64 | + var h; | ||
65 | + var s; | ||
66 | + var l; | ||
67 | + | ||
68 | + if (max === min) { | ||
69 | + h = 0; | ||
70 | + } else if (r === max) { | ||
71 | + h = (g - b) / delta; | ||
72 | + } else if (g === max) { | ||
73 | + h = 2 + (b - r) / delta; | ||
74 | + } else if (b === max) { | ||
75 | + h = 4 + (r - g) / delta; | ||
76 | + } | ||
77 | + | ||
78 | + h = Math.min(h * 60, 360); | ||
79 | + | ||
80 | + if (h < 0) { | ||
81 | + h += 360; | ||
82 | + } | ||
83 | + | ||
84 | + l = (min + max) / 2; | ||
85 | + | ||
86 | + if (max === min) { | ||
87 | + s = 0; | ||
88 | + } else if (l <= 0.5) { | ||
89 | + s = delta / (max + min); | ||
90 | + } else { | ||
91 | + s = delta / (2 - max - min); | ||
92 | + } | ||
93 | + | ||
94 | + return [h, s * 100, l * 100]; | ||
95 | +}; | ||
96 | + | ||
97 | +convert.rgb.hsv = function (rgb) { | ||
98 | + var rdif; | ||
99 | + var gdif; | ||
100 | + var bdif; | ||
101 | + var h; | ||
102 | + var s; | ||
103 | + | ||
104 | + var r = rgb[0] / 255; | ||
105 | + var g = rgb[1] / 255; | ||
106 | + var b = rgb[2] / 255; | ||
107 | + var v = Math.max(r, g, b); | ||
108 | + var diff = v - Math.min(r, g, b); | ||
109 | + var diffc = function (c) { | ||
110 | + return (v - c) / 6 / diff + 1 / 2; | ||
111 | + }; | ||
112 | + | ||
113 | + if (diff === 0) { | ||
114 | + h = s = 0; | ||
115 | + } else { | ||
116 | + s = diff / v; | ||
117 | + rdif = diffc(r); | ||
118 | + gdif = diffc(g); | ||
119 | + bdif = diffc(b); | ||
120 | + | ||
121 | + if (r === v) { | ||
122 | + h = bdif - gdif; | ||
123 | + } else if (g === v) { | ||
124 | + h = (1 / 3) + rdif - bdif; | ||
125 | + } else if (b === v) { | ||
126 | + h = (2 / 3) + gdif - rdif; | ||
127 | + } | ||
128 | + if (h < 0) { | ||
129 | + h += 1; | ||
130 | + } else if (h > 1) { | ||
131 | + h -= 1; | ||
132 | + } | ||
133 | + } | ||
134 | + | ||
135 | + return [ | ||
136 | + h * 360, | ||
137 | + s * 100, | ||
138 | + v * 100 | ||
139 | + ]; | ||
140 | +}; | ||
141 | + | ||
142 | +convert.rgb.hwb = function (rgb) { | ||
143 | + var r = rgb[0]; | ||
144 | + var g = rgb[1]; | ||
145 | + var b = rgb[2]; | ||
146 | + var h = convert.rgb.hsl(rgb)[0]; | ||
147 | + var w = 1 / 255 * Math.min(r, Math.min(g, b)); | ||
148 | + | ||
149 | + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); | ||
150 | + | ||
151 | + return [h, w * 100, b * 100]; | ||
152 | +}; | ||
153 | + | ||
154 | +convert.rgb.cmyk = function (rgb) { | ||
155 | + var r = rgb[0] / 255; | ||
156 | + var g = rgb[1] / 255; | ||
157 | + var b = rgb[2] / 255; | ||
158 | + var c; | ||
159 | + var m; | ||
160 | + var y; | ||
161 | + var k; | ||
162 | + | ||
163 | + k = Math.min(1 - r, 1 - g, 1 - b); | ||
164 | + c = (1 - r - k) / (1 - k) || 0; | ||
165 | + m = (1 - g - k) / (1 - k) || 0; | ||
166 | + y = (1 - b - k) / (1 - k) || 0; | ||
167 | + | ||
168 | + return [c * 100, m * 100, y * 100, k * 100]; | ||
169 | +}; | ||
170 | + | ||
171 | +/** | ||
172 | + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance | ||
173 | + * */ | ||
174 | +function comparativeDistance(x, y) { | ||
175 | + return ( | ||
176 | + Math.pow(x[0] - y[0], 2) + | ||
177 | + Math.pow(x[1] - y[1], 2) + | ||
178 | + Math.pow(x[2] - y[2], 2) | ||
179 | + ); | ||
180 | +} | ||
181 | + | ||
182 | +convert.rgb.keyword = function (rgb) { | ||
183 | + var reversed = reverseKeywords[rgb]; | ||
184 | + if (reversed) { | ||
185 | + return reversed; | ||
186 | + } | ||
187 | + | ||
188 | + var currentClosestDistance = Infinity; | ||
189 | + var currentClosestKeyword; | ||
190 | + | ||
191 | + for (var keyword in cssKeywords) { | ||
192 | + if (cssKeywords.hasOwnProperty(keyword)) { | ||
193 | + var value = cssKeywords[keyword]; | ||
194 | + | ||
195 | + // Compute comparative distance | ||
196 | + var distance = comparativeDistance(rgb, value); | ||
197 | + | ||
198 | + // Check if its less, if so set as closest | ||
199 | + if (distance < currentClosestDistance) { | ||
200 | + currentClosestDistance = distance; | ||
201 | + currentClosestKeyword = keyword; | ||
202 | + } | ||
203 | + } | ||
204 | + } | ||
205 | + | ||
206 | + return currentClosestKeyword; | ||
207 | +}; | ||
208 | + | ||
209 | +convert.keyword.rgb = function (keyword) { | ||
210 | + return cssKeywords[keyword]; | ||
211 | +}; | ||
212 | + | ||
213 | +convert.rgb.xyz = function (rgb) { | ||
214 | + var r = rgb[0] / 255; | ||
215 | + var g = rgb[1] / 255; | ||
216 | + var b = rgb[2] / 255; | ||
217 | + | ||
218 | + // assume sRGB | ||
219 | + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); | ||
220 | + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); | ||
221 | + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); | ||
222 | + | ||
223 | + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); | ||
224 | + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); | ||
225 | + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); | ||
226 | + | ||
227 | + return [x * 100, y * 100, z * 100]; | ||
228 | +}; | ||
229 | + | ||
230 | +convert.rgb.lab = function (rgb) { | ||
231 | + var xyz = convert.rgb.xyz(rgb); | ||
232 | + var x = xyz[0]; | ||
233 | + var y = xyz[1]; | ||
234 | + var z = xyz[2]; | ||
235 | + var l; | ||
236 | + var a; | ||
237 | + var b; | ||
238 | + | ||
239 | + x /= 95.047; | ||
240 | + y /= 100; | ||
241 | + z /= 108.883; | ||
242 | + | ||
243 | + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); | ||
244 | + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); | ||
245 | + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); | ||
246 | + | ||
247 | + l = (116 * y) - 16; | ||
248 | + a = 500 * (x - y); | ||
249 | + b = 200 * (y - z); | ||
250 | + | ||
251 | + return [l, a, b]; | ||
252 | +}; | ||
253 | + | ||
254 | +convert.hsl.rgb = function (hsl) { | ||
255 | + var h = hsl[0] / 360; | ||
256 | + var s = hsl[1] / 100; | ||
257 | + var l = hsl[2] / 100; | ||
258 | + var t1; | ||
259 | + var t2; | ||
260 | + var t3; | ||
261 | + var rgb; | ||
262 | + var val; | ||
263 | + | ||
264 | + if (s === 0) { | ||
265 | + val = l * 255; | ||
266 | + return [val, val, val]; | ||
267 | + } | ||
268 | + | ||
269 | + if (l < 0.5) { | ||
270 | + t2 = l * (1 + s); | ||
271 | + } else { | ||
272 | + t2 = l + s - l * s; | ||
273 | + } | ||
274 | + | ||
275 | + t1 = 2 * l - t2; | ||
276 | + | ||
277 | + rgb = [0, 0, 0]; | ||
278 | + for (var i = 0; i < 3; i++) { | ||
279 | + t3 = h + 1 / 3 * -(i - 1); | ||
280 | + if (t3 < 0) { | ||
281 | + t3++; | ||
282 | + } | ||
283 | + if (t3 > 1) { | ||
284 | + t3--; | ||
285 | + } | ||
286 | + | ||
287 | + if (6 * t3 < 1) { | ||
288 | + val = t1 + (t2 - t1) * 6 * t3; | ||
289 | + } else if (2 * t3 < 1) { | ||
290 | + val = t2; | ||
291 | + } else if (3 * t3 < 2) { | ||
292 | + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; | ||
293 | + } else { | ||
294 | + val = t1; | ||
295 | + } | ||
296 | + | ||
297 | + rgb[i] = val * 255; | ||
298 | + } | ||
299 | + | ||
300 | + return rgb; | ||
301 | +}; | ||
302 | + | ||
303 | +convert.hsl.hsv = function (hsl) { | ||
304 | + var h = hsl[0]; | ||
305 | + var s = hsl[1] / 100; | ||
306 | + var l = hsl[2] / 100; | ||
307 | + var smin = s; | ||
308 | + var lmin = Math.max(l, 0.01); | ||
309 | + var sv; | ||
310 | + var v; | ||
311 | + | ||
312 | + l *= 2; | ||
313 | + s *= (l <= 1) ? l : 2 - l; | ||
314 | + smin *= lmin <= 1 ? lmin : 2 - lmin; | ||
315 | + v = (l + s) / 2; | ||
316 | + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); | ||
317 | + | ||
318 | + return [h, sv * 100, v * 100]; | ||
319 | +}; | ||
320 | + | ||
321 | +convert.hsv.rgb = function (hsv) { | ||
322 | + var h = hsv[0] / 60; | ||
323 | + var s = hsv[1] / 100; | ||
324 | + var v = hsv[2] / 100; | ||
325 | + var hi = Math.floor(h) % 6; | ||
326 | + | ||
327 | + var f = h - Math.floor(h); | ||
328 | + var p = 255 * v * (1 - s); | ||
329 | + var q = 255 * v * (1 - (s * f)); | ||
330 | + var t = 255 * v * (1 - (s * (1 - f))); | ||
331 | + v *= 255; | ||
332 | + | ||
333 | + switch (hi) { | ||
334 | + case 0: | ||
335 | + return [v, t, p]; | ||
336 | + case 1: | ||
337 | + return [q, v, p]; | ||
338 | + case 2: | ||
339 | + return [p, v, t]; | ||
340 | + case 3: | ||
341 | + return [p, q, v]; | ||
342 | + case 4: | ||
343 | + return [t, p, v]; | ||
344 | + case 5: | ||
345 | + return [v, p, q]; | ||
346 | + } | ||
347 | +}; | ||
348 | + | ||
349 | +convert.hsv.hsl = function (hsv) { | ||
350 | + var h = hsv[0]; | ||
351 | + var s = hsv[1] / 100; | ||
352 | + var v = hsv[2] / 100; | ||
353 | + var vmin = Math.max(v, 0.01); | ||
354 | + var lmin; | ||
355 | + var sl; | ||
356 | + var l; | ||
357 | + | ||
358 | + l = (2 - s) * v; | ||
359 | + lmin = (2 - s) * vmin; | ||
360 | + sl = s * vmin; | ||
361 | + sl /= (lmin <= 1) ? lmin : 2 - lmin; | ||
362 | + sl = sl || 0; | ||
363 | + l /= 2; | ||
364 | + | ||
365 | + return [h, sl * 100, l * 100]; | ||
366 | +}; | ||
367 | + | ||
368 | +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb | ||
369 | +convert.hwb.rgb = function (hwb) { | ||
370 | + var h = hwb[0] / 360; | ||
371 | + var wh = hwb[1] / 100; | ||
372 | + var bl = hwb[2] / 100; | ||
373 | + var ratio = wh + bl; | ||
374 | + var i; | ||
375 | + var v; | ||
376 | + var f; | ||
377 | + var n; | ||
378 | + | ||
379 | + // wh + bl cant be > 1 | ||
380 | + if (ratio > 1) { | ||
381 | + wh /= ratio; | ||
382 | + bl /= ratio; | ||
383 | + } | ||
384 | + | ||
385 | + i = Math.floor(6 * h); | ||
386 | + v = 1 - bl; | ||
387 | + f = 6 * h - i; | ||
388 | + | ||
389 | + if ((i & 0x01) !== 0) { | ||
390 | + f = 1 - f; | ||
391 | + } | ||
392 | + | ||
393 | + n = wh + f * (v - wh); // linear interpolation | ||
394 | + | ||
395 | + var r; | ||
396 | + var g; | ||
397 | + var b; | ||
398 | + switch (i) { | ||
399 | + default: | ||
400 | + case 6: | ||
401 | + case 0: r = v; g = n; b = wh; break; | ||
402 | + case 1: r = n; g = v; b = wh; break; | ||
403 | + case 2: r = wh; g = v; b = n; break; | ||
404 | + case 3: r = wh; g = n; b = v; break; | ||
405 | + case 4: r = n; g = wh; b = v; break; | ||
406 | + case 5: r = v; g = wh; b = n; break; | ||
407 | + } | ||
408 | + | ||
409 | + return [r * 255, g * 255, b * 255]; | ||
410 | +}; | ||
411 | + | ||
412 | +convert.cmyk.rgb = function (cmyk) { | ||
413 | + var c = cmyk[0] / 100; | ||
414 | + var m = cmyk[1] / 100; | ||
415 | + var y = cmyk[2] / 100; | ||
416 | + var k = cmyk[3] / 100; | ||
417 | + var r; | ||
418 | + var g; | ||
419 | + var b; | ||
420 | + | ||
421 | + r = 1 - Math.min(1, c * (1 - k) + k); | ||
422 | + g = 1 - Math.min(1, m * (1 - k) + k); | ||
423 | + b = 1 - Math.min(1, y * (1 - k) + k); | ||
424 | + | ||
425 | + return [r * 255, g * 255, b * 255]; | ||
426 | +}; | ||
427 | + | ||
428 | +convert.xyz.rgb = function (xyz) { | ||
429 | + var x = xyz[0] / 100; | ||
430 | + var y = xyz[1] / 100; | ||
431 | + var z = xyz[2] / 100; | ||
432 | + var r; | ||
433 | + var g; | ||
434 | + var b; | ||
435 | + | ||
436 | + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); | ||
437 | + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); | ||
438 | + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); | ||
439 | + | ||
440 | + // assume sRGB | ||
441 | + r = r > 0.0031308 | ||
442 | + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) | ||
443 | + : r * 12.92; | ||
444 | + | ||
445 | + g = g > 0.0031308 | ||
446 | + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) | ||
447 | + : g * 12.92; | ||
448 | + | ||
449 | + b = b > 0.0031308 | ||
450 | + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) | ||
451 | + : b * 12.92; | ||
452 | + | ||
453 | + r = Math.min(Math.max(0, r), 1); | ||
454 | + g = Math.min(Math.max(0, g), 1); | ||
455 | + b = Math.min(Math.max(0, b), 1); | ||
456 | + | ||
457 | + return [r * 255, g * 255, b * 255]; | ||
458 | +}; | ||
459 | + | ||
460 | +convert.xyz.lab = function (xyz) { | ||
461 | + var x = xyz[0]; | ||
462 | + var y = xyz[1]; | ||
463 | + var z = xyz[2]; | ||
464 | + var l; | ||
465 | + var a; | ||
466 | + var b; | ||
467 | + | ||
468 | + x /= 95.047; | ||
469 | + y /= 100; | ||
470 | + z /= 108.883; | ||
471 | + | ||
472 | + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); | ||
473 | + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); | ||
474 | + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); | ||
475 | + | ||
476 | + l = (116 * y) - 16; | ||
477 | + a = 500 * (x - y); | ||
478 | + b = 200 * (y - z); | ||
479 | + | ||
480 | + return [l, a, b]; | ||
481 | +}; | ||
482 | + | ||
483 | +convert.lab.xyz = function (lab) { | ||
484 | + var l = lab[0]; | ||
485 | + var a = lab[1]; | ||
486 | + var b = lab[2]; | ||
487 | + var x; | ||
488 | + var y; | ||
489 | + var z; | ||
490 | + | ||
491 | + y = (l + 16) / 116; | ||
492 | + x = a / 500 + y; | ||
493 | + z = y - b / 200; | ||
494 | + | ||
495 | + var y2 = Math.pow(y, 3); | ||
496 | + var x2 = Math.pow(x, 3); | ||
497 | + var z2 = Math.pow(z, 3); | ||
498 | + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; | ||
499 | + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; | ||
500 | + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; | ||
501 | + | ||
502 | + x *= 95.047; | ||
503 | + y *= 100; | ||
504 | + z *= 108.883; | ||
505 | + | ||
506 | + return [x, y, z]; | ||
507 | +}; | ||
508 | + | ||
509 | +convert.lab.lch = function (lab) { | ||
510 | + var l = lab[0]; | ||
511 | + var a = lab[1]; | ||
512 | + var b = lab[2]; | ||
513 | + var hr; | ||
514 | + var h; | ||
515 | + var c; | ||
516 | + | ||
517 | + hr = Math.atan2(b, a); | ||
518 | + h = hr * 360 / 2 / Math.PI; | ||
519 | + | ||
520 | + if (h < 0) { | ||
521 | + h += 360; | ||
522 | + } | ||
523 | + | ||
524 | + c = Math.sqrt(a * a + b * b); | ||
525 | + | ||
526 | + return [l, c, h]; | ||
527 | +}; | ||
528 | + | ||
529 | +convert.lch.lab = function (lch) { | ||
530 | + var l = lch[0]; | ||
531 | + var c = lch[1]; | ||
532 | + var h = lch[2]; | ||
533 | + var a; | ||
534 | + var b; | ||
535 | + var hr; | ||
536 | + | ||
537 | + hr = h / 360 * 2 * Math.PI; | ||
538 | + a = c * Math.cos(hr); | ||
539 | + b = c * Math.sin(hr); | ||
540 | + | ||
541 | + return [l, a, b]; | ||
542 | +}; | ||
543 | + | ||
544 | +convert.rgb.ansi16 = function (args) { | ||
545 | + var r = args[0]; | ||
546 | + var g = args[1]; | ||
547 | + var b = args[2]; | ||
548 | + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization | ||
549 | + | ||
550 | + value = Math.round(value / 50); | ||
551 | + | ||
552 | + if (value === 0) { | ||
553 | + return 30; | ||
554 | + } | ||
555 | + | ||
556 | + var ansi = 30 | ||
557 | + + ((Math.round(b / 255) << 2) | ||
558 | + | (Math.round(g / 255) << 1) | ||
559 | + | Math.round(r / 255)); | ||
560 | + | ||
561 | + if (value === 2) { | ||
562 | + ansi += 60; | ||
563 | + } | ||
564 | + | ||
565 | + return ansi; | ||
566 | +}; | ||
567 | + | ||
568 | +convert.hsv.ansi16 = function (args) { | ||
569 | + // optimization here; we already know the value and don't need to get | ||
570 | + // it converted for us. | ||
571 | + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); | ||
572 | +}; | ||
573 | + | ||
574 | +convert.rgb.ansi256 = function (args) { | ||
575 | + var r = args[0]; | ||
576 | + var g = args[1]; | ||
577 | + var b = args[2]; | ||
578 | + | ||
579 | + // we use the extended greyscale palette here, with the exception of | ||
580 | + // black and white. normal palette only has 4 greyscale shades. | ||
581 | + if (r === g && g === b) { | ||
582 | + if (r < 8) { | ||
583 | + return 16; | ||
584 | + } | ||
585 | + | ||
586 | + if (r > 248) { | ||
587 | + return 231; | ||
588 | + } | ||
589 | + | ||
590 | + return Math.round(((r - 8) / 247) * 24) + 232; | ||
591 | + } | ||
592 | + | ||
593 | + var ansi = 16 | ||
594 | + + (36 * Math.round(r / 255 * 5)) | ||
595 | + + (6 * Math.round(g / 255 * 5)) | ||
596 | + + Math.round(b / 255 * 5); | ||
597 | + | ||
598 | + return ansi; | ||
599 | +}; | ||
600 | + | ||
601 | +convert.ansi16.rgb = function (args) { | ||
602 | + var color = args % 10; | ||
603 | + | ||
604 | + // handle greyscale | ||
605 | + if (color === 0 || color === 7) { | ||
606 | + if (args > 50) { | ||
607 | + color += 3.5; | ||
608 | + } | ||
609 | + | ||
610 | + color = color / 10.5 * 255; | ||
611 | + | ||
612 | + return [color, color, color]; | ||
613 | + } | ||
614 | + | ||
615 | + var mult = (~~(args > 50) + 1) * 0.5; | ||
616 | + var r = ((color & 1) * mult) * 255; | ||
617 | + var g = (((color >> 1) & 1) * mult) * 255; | ||
618 | + var b = (((color >> 2) & 1) * mult) * 255; | ||
619 | + | ||
620 | + return [r, g, b]; | ||
621 | +}; | ||
622 | + | ||
623 | +convert.ansi256.rgb = function (args) { | ||
624 | + // handle greyscale | ||
625 | + if (args >= 232) { | ||
626 | + var c = (args - 232) * 10 + 8; | ||
627 | + return [c, c, c]; | ||
628 | + } | ||
629 | + | ||
630 | + args -= 16; | ||
631 | + | ||
632 | + var rem; | ||
633 | + var r = Math.floor(args / 36) / 5 * 255; | ||
634 | + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; | ||
635 | + var b = (rem % 6) / 5 * 255; | ||
636 | + | ||
637 | + return [r, g, b]; | ||
638 | +}; | ||
639 | + | ||
640 | +convert.rgb.hex = function (args) { | ||
641 | + var integer = ((Math.round(args[0]) & 0xFF) << 16) | ||
642 | + + ((Math.round(args[1]) & 0xFF) << 8) | ||
643 | + + (Math.round(args[2]) & 0xFF); | ||
644 | + | ||
645 | + var string = integer.toString(16).toUpperCase(); | ||
646 | + return '000000'.substring(string.length) + string; | ||
647 | +}; | ||
648 | + | ||
649 | +convert.hex.rgb = function (args) { | ||
650 | + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); | ||
651 | + if (!match) { | ||
652 | + return [0, 0, 0]; | ||
653 | + } | ||
654 | + | ||
655 | + var colorString = match[0]; | ||
656 | + | ||
657 | + if (match[0].length === 3) { | ||
658 | + colorString = colorString.split('').map(function (char) { | ||
659 | + return char + char; | ||
660 | + }).join(''); | ||
661 | + } | ||
662 | + | ||
663 | + var integer = parseInt(colorString, 16); | ||
664 | + var r = (integer >> 16) & 0xFF; | ||
665 | + var g = (integer >> 8) & 0xFF; | ||
666 | + var b = integer & 0xFF; | ||
667 | + | ||
668 | + return [r, g, b]; | ||
669 | +}; | ||
670 | + | ||
671 | +convert.rgb.hcg = function (rgb) { | ||
672 | + var r = rgb[0] / 255; | ||
673 | + var g = rgb[1] / 255; | ||
674 | + var b = rgb[2] / 255; | ||
675 | + var max = Math.max(Math.max(r, g), b); | ||
676 | + var min = Math.min(Math.min(r, g), b); | ||
677 | + var chroma = (max - min); | ||
678 | + var grayscale; | ||
679 | + var hue; | ||
680 | + | ||
681 | + if (chroma < 1) { | ||
682 | + grayscale = min / (1 - chroma); | ||
683 | + } else { | ||
684 | + grayscale = 0; | ||
685 | + } | ||
686 | + | ||
687 | + if (chroma <= 0) { | ||
688 | + hue = 0; | ||
689 | + } else | ||
690 | + if (max === r) { | ||
691 | + hue = ((g - b) / chroma) % 6; | ||
692 | + } else | ||
693 | + if (max === g) { | ||
694 | + hue = 2 + (b - r) / chroma; | ||
695 | + } else { | ||
696 | + hue = 4 + (r - g) / chroma + 4; | ||
697 | + } | ||
698 | + | ||
699 | + hue /= 6; | ||
700 | + hue %= 1; | ||
701 | + | ||
702 | + return [hue * 360, chroma * 100, grayscale * 100]; | ||
703 | +}; | ||
704 | + | ||
705 | +convert.hsl.hcg = function (hsl) { | ||
706 | + var s = hsl[1] / 100; | ||
707 | + var l = hsl[2] / 100; | ||
708 | + var c = 1; | ||
709 | + var f = 0; | ||
710 | + | ||
711 | + if (l < 0.5) { | ||
712 | + c = 2.0 * s * l; | ||
713 | + } else { | ||
714 | + c = 2.0 * s * (1.0 - l); | ||
715 | + } | ||
716 | + | ||
717 | + if (c < 1.0) { | ||
718 | + f = (l - 0.5 * c) / (1.0 - c); | ||
719 | + } | ||
720 | + | ||
721 | + return [hsl[0], c * 100, f * 100]; | ||
722 | +}; | ||
723 | + | ||
724 | +convert.hsv.hcg = function (hsv) { | ||
725 | + var s = hsv[1] / 100; | ||
726 | + var v = hsv[2] / 100; | ||
727 | + | ||
728 | + var c = s * v; | ||
729 | + var f = 0; | ||
730 | + | ||
731 | + if (c < 1.0) { | ||
732 | + f = (v - c) / (1 - c); | ||
733 | + } | ||
734 | + | ||
735 | + return [hsv[0], c * 100, f * 100]; | ||
736 | +}; | ||
737 | + | ||
738 | +convert.hcg.rgb = function (hcg) { | ||
739 | + var h = hcg[0] / 360; | ||
740 | + var c = hcg[1] / 100; | ||
741 | + var g = hcg[2] / 100; | ||
742 | + | ||
743 | + if (c === 0.0) { | ||
744 | + return [g * 255, g * 255, g * 255]; | ||
745 | + } | ||
746 | + | ||
747 | + var pure = [0, 0, 0]; | ||
748 | + var hi = (h % 1) * 6; | ||
749 | + var v = hi % 1; | ||
750 | + var w = 1 - v; | ||
751 | + var mg = 0; | ||
752 | + | ||
753 | + switch (Math.floor(hi)) { | ||
754 | + case 0: | ||
755 | + pure[0] = 1; pure[1] = v; pure[2] = 0; break; | ||
756 | + case 1: | ||
757 | + pure[0] = w; pure[1] = 1; pure[2] = 0; break; | ||
758 | + case 2: | ||
759 | + pure[0] = 0; pure[1] = 1; pure[2] = v; break; | ||
760 | + case 3: | ||
761 | + pure[0] = 0; pure[1] = w; pure[2] = 1; break; | ||
762 | + case 4: | ||
763 | + pure[0] = v; pure[1] = 0; pure[2] = 1; break; | ||
764 | + default: | ||
765 | + pure[0] = 1; pure[1] = 0; pure[2] = w; | ||
766 | + } | ||
767 | + | ||
768 | + mg = (1.0 - c) * g; | ||
769 | + | ||
770 | + return [ | ||
771 | + (c * pure[0] + mg) * 255, | ||
772 | + (c * pure[1] + mg) * 255, | ||
773 | + (c * pure[2] + mg) * 255 | ||
774 | + ]; | ||
775 | +}; | ||
776 | + | ||
777 | +convert.hcg.hsv = function (hcg) { | ||
778 | + var c = hcg[1] / 100; | ||
779 | + var g = hcg[2] / 100; | ||
780 | + | ||
781 | + var v = c + g * (1.0 - c); | ||
782 | + var f = 0; | ||
783 | + | ||
784 | + if (v > 0.0) { | ||
785 | + f = c / v; | ||
786 | + } | ||
787 | + | ||
788 | + return [hcg[0], f * 100, v * 100]; | ||
789 | +}; | ||
790 | + | ||
791 | +convert.hcg.hsl = function (hcg) { | ||
792 | + var c = hcg[1] / 100; | ||
793 | + var g = hcg[2] / 100; | ||
794 | + | ||
795 | + var l = g * (1.0 - c) + 0.5 * c; | ||
796 | + var s = 0; | ||
797 | + | ||
798 | + if (l > 0.0 && l < 0.5) { | ||
799 | + s = c / (2 * l); | ||
800 | + } else | ||
801 | + if (l >= 0.5 && l < 1.0) { | ||
802 | + s = c / (2 * (1 - l)); | ||
803 | + } | ||
804 | + | ||
805 | + return [hcg[0], s * 100, l * 100]; | ||
806 | +}; | ||
807 | + | ||
808 | +convert.hcg.hwb = function (hcg) { | ||
809 | + var c = hcg[1] / 100; | ||
810 | + var g = hcg[2] / 100; | ||
811 | + var v = c + g * (1.0 - c); | ||
812 | + return [hcg[0], (v - c) * 100, (1 - v) * 100]; | ||
813 | +}; | ||
814 | + | ||
815 | +convert.hwb.hcg = function (hwb) { | ||
816 | + var w = hwb[1] / 100; | ||
817 | + var b = hwb[2] / 100; | ||
818 | + var v = 1 - b; | ||
819 | + var c = v - w; | ||
820 | + var g = 0; | ||
821 | + | ||
822 | + if (c < 1) { | ||
823 | + g = (v - c) / (1 - c); | ||
824 | + } | ||
825 | + | ||
826 | + return [hwb[0], c * 100, g * 100]; | ||
827 | +}; | ||
828 | + | ||
829 | +convert.apple.rgb = function (apple) { | ||
830 | + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; | ||
831 | +}; | ||
832 | + | ||
833 | +convert.rgb.apple = function (rgb) { | ||
834 | + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; | ||
835 | +}; | ||
836 | + | ||
837 | +convert.gray.rgb = function (args) { | ||
838 | + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; | ||
839 | +}; | ||
840 | + | ||
841 | +convert.gray.hsl = convert.gray.hsv = function (args) { | ||
842 | + return [0, 0, args[0]]; | ||
843 | +}; | ||
844 | + | ||
845 | +convert.gray.hwb = function (gray) { | ||
846 | + return [0, 100, gray[0]]; | ||
847 | +}; | ||
848 | + | ||
849 | +convert.gray.cmyk = function (gray) { | ||
850 | + return [0, 0, 0, gray[0]]; | ||
851 | +}; | ||
852 | + | ||
853 | +convert.gray.lab = function (gray) { | ||
854 | + return [gray[0], 0, 0]; | ||
855 | +}; | ||
856 | + | ||
857 | +convert.gray.hex = function (gray) { | ||
858 | + var val = Math.round(gray[0] / 100 * 255) & 0xFF; | ||
859 | + var integer = (val << 16) + (val << 8) + val; | ||
860 | + | ||
861 | + var string = integer.toString(16).toUpperCase(); | ||
862 | + return '000000'.substring(string.length) + string; | ||
863 | +}; | ||
864 | + | ||
865 | +convert.rgb.gray = function (rgb) { | ||
866 | + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; | ||
867 | + return [val / 255 * 100]; | ||
868 | +}; |
node_modules/color-convert/index.js
0 → 100644
1 | +var conversions = require('./conversions'); | ||
2 | +var route = require('./route'); | ||
3 | + | ||
4 | +var convert = {}; | ||
5 | + | ||
6 | +var models = Object.keys(conversions); | ||
7 | + | ||
8 | +function wrapRaw(fn) { | ||
9 | + var wrappedFn = function (args) { | ||
10 | + if (args === undefined || args === null) { | ||
11 | + return args; | ||
12 | + } | ||
13 | + | ||
14 | + if (arguments.length > 1) { | ||
15 | + args = Array.prototype.slice.call(arguments); | ||
16 | + } | ||
17 | + | ||
18 | + return fn(args); | ||
19 | + }; | ||
20 | + | ||
21 | + // preserve .conversion property if there is one | ||
22 | + if ('conversion' in fn) { | ||
23 | + wrappedFn.conversion = fn.conversion; | ||
24 | + } | ||
25 | + | ||
26 | + return wrappedFn; | ||
27 | +} | ||
28 | + | ||
29 | +function wrapRounded(fn) { | ||
30 | + var wrappedFn = function (args) { | ||
31 | + if (args === undefined || args === null) { | ||
32 | + return args; | ||
33 | + } | ||
34 | + | ||
35 | + if (arguments.length > 1) { | ||
36 | + args = Array.prototype.slice.call(arguments); | ||
37 | + } | ||
38 | + | ||
39 | + var result = fn(args); | ||
40 | + | ||
41 | + // we're assuming the result is an array here. | ||
42 | + // see notice in conversions.js; don't use box types | ||
43 | + // in conversion functions. | ||
44 | + if (typeof result === 'object') { | ||
45 | + for (var len = result.length, i = 0; i < len; i++) { | ||
46 | + result[i] = Math.round(result[i]); | ||
47 | + } | ||
48 | + } | ||
49 | + | ||
50 | + return result; | ||
51 | + }; | ||
52 | + | ||
53 | + // preserve .conversion property if there is one | ||
54 | + if ('conversion' in fn) { | ||
55 | + wrappedFn.conversion = fn.conversion; | ||
56 | + } | ||
57 | + | ||
58 | + return wrappedFn; | ||
59 | +} | ||
60 | + | ||
61 | +models.forEach(function (fromModel) { | ||
62 | + convert[fromModel] = {}; | ||
63 | + | ||
64 | + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); | ||
65 | + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); | ||
66 | + | ||
67 | + var routes = route(fromModel); | ||
68 | + var routeModels = Object.keys(routes); | ||
69 | + | ||
70 | + routeModels.forEach(function (toModel) { | ||
71 | + var fn = routes[toModel]; | ||
72 | + | ||
73 | + convert[fromModel][toModel] = wrapRounded(fn); | ||
74 | + convert[fromModel][toModel].raw = wrapRaw(fn); | ||
75 | + }); | ||
76 | +}); | ||
77 | + | ||
78 | +module.exports = convert; |
node_modules/color-convert/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "color-convert", | ||
3 | + "description": "Plain color conversion functions", | ||
4 | + "version": "1.9.3", | ||
5 | + "author": "Heather Arthur <fayearthur@gmail.com>", | ||
6 | + "license": "MIT", | ||
7 | + "repository": "Qix-/color-convert", | ||
8 | + "scripts": { | ||
9 | + "pretest": "xo", | ||
10 | + "test": "node test/basic.js" | ||
11 | + }, | ||
12 | + "keywords": [ | ||
13 | + "color", | ||
14 | + "colour", | ||
15 | + "convert", | ||
16 | + "converter", | ||
17 | + "conversion", | ||
18 | + "rgb", | ||
19 | + "hsl", | ||
20 | + "hsv", | ||
21 | + "hwb", | ||
22 | + "cmyk", | ||
23 | + "ansi", | ||
24 | + "ansi16" | ||
25 | + ], | ||
26 | + "files": [ | ||
27 | + "index.js", | ||
28 | + "conversions.js", | ||
29 | + "css-keywords.js", | ||
30 | + "route.js" | ||
31 | + ], | ||
32 | + "xo": { | ||
33 | + "rules": { | ||
34 | + "default-case": 0, | ||
35 | + "no-inline-comments": 0, | ||
36 | + "operator-linebreak": 0 | ||
37 | + } | ||
38 | + }, | ||
39 | + "devDependencies": { | ||
40 | + "chalk": "1.1.1", | ||
41 | + "xo": "0.11.2" | ||
42 | + }, | ||
43 | + "dependencies": { | ||
44 | + "color-name": "1.1.3" | ||
45 | + } | ||
46 | +} |
node_modules/color-convert/route.js
0 → 100644
1 | +var conversions = require('./conversions'); | ||
2 | + | ||
3 | +/* | ||
4 | + this function routes a model to all other models. | ||
5 | + | ||
6 | + all functions that are routed have a property `.conversion` attached | ||
7 | + to the returned synthetic function. This property is an array | ||
8 | + of strings, each with the steps in between the 'from' and 'to' | ||
9 | + color models (inclusive). | ||
10 | + | ||
11 | + conversions that are not possible simply are not included. | ||
12 | +*/ | ||
13 | + | ||
14 | +function buildGraph() { | ||
15 | + var graph = {}; | ||
16 | + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 | ||
17 | + var models = Object.keys(conversions); | ||
18 | + | ||
19 | + for (var len = models.length, i = 0; i < len; i++) { | ||
20 | + graph[models[i]] = { | ||
21 | + // http://jsperf.com/1-vs-infinity | ||
22 | + // micro-opt, but this is simple. | ||
23 | + distance: -1, | ||
24 | + parent: null | ||
25 | + }; | ||
26 | + } | ||
27 | + | ||
28 | + return graph; | ||
29 | +} | ||
30 | + | ||
31 | +// https://en.wikipedia.org/wiki/Breadth-first_search | ||
32 | +function deriveBFS(fromModel) { | ||
33 | + var graph = buildGraph(); | ||
34 | + var queue = [fromModel]; // unshift -> queue -> pop | ||
35 | + | ||
36 | + graph[fromModel].distance = 0; | ||
37 | + | ||
38 | + while (queue.length) { | ||
39 | + var current = queue.pop(); | ||
40 | + var adjacents = Object.keys(conversions[current]); | ||
41 | + | ||
42 | + for (var len = adjacents.length, i = 0; i < len; i++) { | ||
43 | + var adjacent = adjacents[i]; | ||
44 | + var node = graph[adjacent]; | ||
45 | + | ||
46 | + if (node.distance === -1) { | ||
47 | + node.distance = graph[current].distance + 1; | ||
48 | + node.parent = current; | ||
49 | + queue.unshift(adjacent); | ||
50 | + } | ||
51 | + } | ||
52 | + } | ||
53 | + | ||
54 | + return graph; | ||
55 | +} | ||
56 | + | ||
57 | +function link(from, to) { | ||
58 | + return function (args) { | ||
59 | + return to(from(args)); | ||
60 | + }; | ||
61 | +} | ||
62 | + | ||
63 | +function wrapConversion(toModel, graph) { | ||
64 | + var path = [graph[toModel].parent, toModel]; | ||
65 | + var fn = conversions[graph[toModel].parent][toModel]; | ||
66 | + | ||
67 | + var cur = graph[toModel].parent; | ||
68 | + while (graph[cur].parent) { | ||
69 | + path.unshift(graph[cur].parent); | ||
70 | + fn = link(conversions[graph[cur].parent][cur], fn); | ||
71 | + cur = graph[cur].parent; | ||
72 | + } | ||
73 | + | ||
74 | + fn.conversion = path; | ||
75 | + return fn; | ||
76 | +} | ||
77 | + | ||
78 | +module.exports = function (fromModel) { | ||
79 | + var graph = deriveBFS(fromModel); | ||
80 | + var conversion = {}; | ||
81 | + | ||
82 | + var models = Object.keys(graph); | ||
83 | + for (var len = models.length, i = 0; i < len; i++) { | ||
84 | + var toModel = models[i]; | ||
85 | + var node = graph[toModel]; | ||
86 | + | ||
87 | + if (node.parent === null) { | ||
88 | + // no possible conversion, or this node is the source model. | ||
89 | + continue; | ||
90 | + } | ||
91 | + | ||
92 | + conversion[toModel] = wrapConversion(toModel, graph); | ||
93 | + } | ||
94 | + | ||
95 | + return conversion; | ||
96 | +}; | ||
97 | + |
node_modules/color-name/.eslintrc.json
0 → 100644
1 | +{ | ||
2 | + "env": { | ||
3 | + "browser": true, | ||
4 | + "node": true, | ||
5 | + "commonjs": true, | ||
6 | + "es6": true | ||
7 | + }, | ||
8 | + "extends": "eslint:recommended", | ||
9 | + "rules": { | ||
10 | + "strict": 2, | ||
11 | + "indent": 0, | ||
12 | + "linebreak-style": 0, | ||
13 | + "quotes": 0, | ||
14 | + "semi": 0, | ||
15 | + "no-cond-assign": 1, | ||
16 | + "no-constant-condition": 1, | ||
17 | + "no-duplicate-case": 1, | ||
18 | + "no-empty": 1, | ||
19 | + "no-ex-assign": 1, | ||
20 | + "no-extra-boolean-cast": 1, | ||
21 | + "no-extra-semi": 1, | ||
22 | + "no-fallthrough": 1, | ||
23 | + "no-func-assign": 1, | ||
24 | + "no-global-assign": 1, | ||
25 | + "no-implicit-globals": 2, | ||
26 | + "no-inner-declarations": ["error", "functions"], | ||
27 | + "no-irregular-whitespace": 2, | ||
28 | + "no-loop-func": 1, | ||
29 | + "no-multi-str": 1, | ||
30 | + "no-mixed-spaces-and-tabs": 1, | ||
31 | + "no-proto": 1, | ||
32 | + "no-sequences": 1, | ||
33 | + "no-throw-literal": 1, | ||
34 | + "no-unmodified-loop-condition": 1, | ||
35 | + "no-useless-call": 1, | ||
36 | + "no-void": 1, | ||
37 | + "no-with": 2, | ||
38 | + "wrap-iife": 1, | ||
39 | + "no-redeclare": 1, | ||
40 | + "no-unused-vars": ["error", { "vars": "all", "args": "none" }], | ||
41 | + "no-sparse-arrays": 1 | ||
42 | + } | ||
43 | +} |
node_modules/color-name/.npmignore
0 → 100644
1 | +//this will affect all the git repos | ||
2 | +git config --global core.excludesfile ~/.gitignore | ||
3 | + | ||
4 | + | ||
5 | +//update files since .ignore won't if already tracked | ||
6 | +git rm --cached <file> | ||
7 | + | ||
8 | +# Compiled source # | ||
9 | +################### | ||
10 | +*.com | ||
11 | +*.class | ||
12 | +*.dll | ||
13 | +*.exe | ||
14 | +*.o | ||
15 | +*.so | ||
16 | + | ||
17 | +# Packages # | ||
18 | +############ | ||
19 | +# it's better to unpack these files and commit the raw source | ||
20 | +# git has its own built in compression methods | ||
21 | +*.7z | ||
22 | +*.dmg | ||
23 | +*.gz | ||
24 | +*.iso | ||
25 | +*.jar | ||
26 | +*.rar | ||
27 | +*.tar | ||
28 | +*.zip | ||
29 | + | ||
30 | +# Logs and databases # | ||
31 | +###################### | ||
32 | +*.log | ||
33 | +*.sql | ||
34 | +*.sqlite | ||
35 | + | ||
36 | +# OS generated files # | ||
37 | +###################### | ||
38 | +.DS_Store | ||
39 | +.DS_Store? | ||
40 | +._* | ||
41 | +.Spotlight-V100 | ||
42 | +.Trashes | ||
43 | +# Icon? | ||
44 | +ehthumbs.db | ||
45 | +Thumbs.db | ||
46 | +.cache | ||
47 | +.project | ||
48 | +.settings | ||
49 | +.tmproj | ||
50 | +*.esproj | ||
51 | +nbproject | ||
52 | + | ||
53 | +# Numerous always-ignore extensions # | ||
54 | +##################################### | ||
55 | +*.diff | ||
56 | +*.err | ||
57 | +*.orig | ||
58 | +*.rej | ||
59 | +*.swn | ||
60 | +*.swo | ||
61 | +*.swp | ||
62 | +*.vi | ||
63 | +*~ | ||
64 | +*.sass-cache | ||
65 | +*.grunt | ||
66 | +*.tmp | ||
67 | + | ||
68 | +# Dreamweaver added files # | ||
69 | +########################### | ||
70 | +_notes | ||
71 | +dwsync.xml | ||
72 | + | ||
73 | +# Komodo # | ||
74 | +########################### | ||
75 | +*.komodoproject | ||
76 | +.komodotools | ||
77 | + | ||
78 | +# Node # | ||
79 | +##################### | ||
80 | +node_modules | ||
81 | + | ||
82 | +# Bower # | ||
83 | +##################### | ||
84 | +bower_components | ||
85 | + | ||
86 | +# Folders to ignore # | ||
87 | +##################### | ||
88 | +.hg | ||
89 | +.svn | ||
90 | +.CVS | ||
91 | +intermediate | ||
92 | +publish | ||
93 | +.idea | ||
94 | +.graphics | ||
95 | +_test | ||
96 | +_archive | ||
97 | +uploads | ||
98 | +tmp | ||
99 | + | ||
100 | +# Vim files to ignore # | ||
101 | +####################### | ||
102 | +.VimballRecord | ||
103 | +.netrwhist | ||
104 | + | ||
105 | +bundle.* | ||
106 | + | ||
107 | +_demo | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/color-name/LICENSE
0 → 100644
1 | +The MIT License (MIT) | ||
2 | +Copyright (c) 2015 Dmitry Ivanov | ||
3 | + | ||
4 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
5 | + | ||
6 | +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
7 | + | ||
8 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/color-name/README.md
0 → 100644
1 | +A JSON with color names and its values. Based on http://dev.w3.org/csswg/css-color/#named-colors. | ||
2 | + | ||
3 | +[![NPM](https://nodei.co/npm/color-name.png?mini=true)](https://nodei.co/npm/color-name/) | ||
4 | + | ||
5 | + | ||
6 | +```js | ||
7 | +var colors = require('color-name'); | ||
8 | +colors.red //[255,0,0] | ||
9 | +``` | ||
10 | + | ||
11 | +<a href="LICENSE"><img src="https://upload.wikimedia.org/wikipedia/commons/0/0c/MIT_logo.svg" width="120"/></a> |
node_modules/color-name/index.js
0 → 100644
1 | +'use strict' | ||
2 | + | ||
3 | +module.exports = { | ||
4 | + "aliceblue": [240, 248, 255], | ||
5 | + "antiquewhite": [250, 235, 215], | ||
6 | + "aqua": [0, 255, 255], | ||
7 | + "aquamarine": [127, 255, 212], | ||
8 | + "azure": [240, 255, 255], | ||
9 | + "beige": [245, 245, 220], | ||
10 | + "bisque": [255, 228, 196], | ||
11 | + "black": [0, 0, 0], | ||
12 | + "blanchedalmond": [255, 235, 205], | ||
13 | + "blue": [0, 0, 255], | ||
14 | + "blueviolet": [138, 43, 226], | ||
15 | + "brown": [165, 42, 42], | ||
16 | + "burlywood": [222, 184, 135], | ||
17 | + "cadetblue": [95, 158, 160], | ||
18 | + "chartreuse": [127, 255, 0], | ||
19 | + "chocolate": [210, 105, 30], | ||
20 | + "coral": [255, 127, 80], | ||
21 | + "cornflowerblue": [100, 149, 237], | ||
22 | + "cornsilk": [255, 248, 220], | ||
23 | + "crimson": [220, 20, 60], | ||
24 | + "cyan": [0, 255, 255], | ||
25 | + "darkblue": [0, 0, 139], | ||
26 | + "darkcyan": [0, 139, 139], | ||
27 | + "darkgoldenrod": [184, 134, 11], | ||
28 | + "darkgray": [169, 169, 169], | ||
29 | + "darkgreen": [0, 100, 0], | ||
30 | + "darkgrey": [169, 169, 169], | ||
31 | + "darkkhaki": [189, 183, 107], | ||
32 | + "darkmagenta": [139, 0, 139], | ||
33 | + "darkolivegreen": [85, 107, 47], | ||
34 | + "darkorange": [255, 140, 0], | ||
35 | + "darkorchid": [153, 50, 204], | ||
36 | + "darkred": [139, 0, 0], | ||
37 | + "darksalmon": [233, 150, 122], | ||
38 | + "darkseagreen": [143, 188, 143], | ||
39 | + "darkslateblue": [72, 61, 139], | ||
40 | + "darkslategray": [47, 79, 79], | ||
41 | + "darkslategrey": [47, 79, 79], | ||
42 | + "darkturquoise": [0, 206, 209], | ||
43 | + "darkviolet": [148, 0, 211], | ||
44 | + "deeppink": [255, 20, 147], | ||
45 | + "deepskyblue": [0, 191, 255], | ||
46 | + "dimgray": [105, 105, 105], | ||
47 | + "dimgrey": [105, 105, 105], | ||
48 | + "dodgerblue": [30, 144, 255], | ||
49 | + "firebrick": [178, 34, 34], | ||
50 | + "floralwhite": [255, 250, 240], | ||
51 | + "forestgreen": [34, 139, 34], | ||
52 | + "fuchsia": [255, 0, 255], | ||
53 | + "gainsboro": [220, 220, 220], | ||
54 | + "ghostwhite": [248, 248, 255], | ||
55 | + "gold": [255, 215, 0], | ||
56 | + "goldenrod": [218, 165, 32], | ||
57 | + "gray": [128, 128, 128], | ||
58 | + "green": [0, 128, 0], | ||
59 | + "greenyellow": [173, 255, 47], | ||
60 | + "grey": [128, 128, 128], | ||
61 | + "honeydew": [240, 255, 240], | ||
62 | + "hotpink": [255, 105, 180], | ||
63 | + "indianred": [205, 92, 92], | ||
64 | + "indigo": [75, 0, 130], | ||
65 | + "ivory": [255, 255, 240], | ||
66 | + "khaki": [240, 230, 140], | ||
67 | + "lavender": [230, 230, 250], | ||
68 | + "lavenderblush": [255, 240, 245], | ||
69 | + "lawngreen": [124, 252, 0], | ||
70 | + "lemonchiffon": [255, 250, 205], | ||
71 | + "lightblue": [173, 216, 230], | ||
72 | + "lightcoral": [240, 128, 128], | ||
73 | + "lightcyan": [224, 255, 255], | ||
74 | + "lightgoldenrodyellow": [250, 250, 210], | ||
75 | + "lightgray": [211, 211, 211], | ||
76 | + "lightgreen": [144, 238, 144], | ||
77 | + "lightgrey": [211, 211, 211], | ||
78 | + "lightpink": [255, 182, 193], | ||
79 | + "lightsalmon": [255, 160, 122], | ||
80 | + "lightseagreen": [32, 178, 170], | ||
81 | + "lightskyblue": [135, 206, 250], | ||
82 | + "lightslategray": [119, 136, 153], | ||
83 | + "lightslategrey": [119, 136, 153], | ||
84 | + "lightsteelblue": [176, 196, 222], | ||
85 | + "lightyellow": [255, 255, 224], | ||
86 | + "lime": [0, 255, 0], | ||
87 | + "limegreen": [50, 205, 50], | ||
88 | + "linen": [250, 240, 230], | ||
89 | + "magenta": [255, 0, 255], | ||
90 | + "maroon": [128, 0, 0], | ||
91 | + "mediumaquamarine": [102, 205, 170], | ||
92 | + "mediumblue": [0, 0, 205], | ||
93 | + "mediumorchid": [186, 85, 211], | ||
94 | + "mediumpurple": [147, 112, 219], | ||
95 | + "mediumseagreen": [60, 179, 113], | ||
96 | + "mediumslateblue": [123, 104, 238], | ||
97 | + "mediumspringgreen": [0, 250, 154], | ||
98 | + "mediumturquoise": [72, 209, 204], | ||
99 | + "mediumvioletred": [199, 21, 133], | ||
100 | + "midnightblue": [25, 25, 112], | ||
101 | + "mintcream": [245, 255, 250], | ||
102 | + "mistyrose": [255, 228, 225], | ||
103 | + "moccasin": [255, 228, 181], | ||
104 | + "navajowhite": [255, 222, 173], | ||
105 | + "navy": [0, 0, 128], | ||
106 | + "oldlace": [253, 245, 230], | ||
107 | + "olive": [128, 128, 0], | ||
108 | + "olivedrab": [107, 142, 35], | ||
109 | + "orange": [255, 165, 0], | ||
110 | + "orangered": [255, 69, 0], | ||
111 | + "orchid": [218, 112, 214], | ||
112 | + "palegoldenrod": [238, 232, 170], | ||
113 | + "palegreen": [152, 251, 152], | ||
114 | + "paleturquoise": [175, 238, 238], | ||
115 | + "palevioletred": [219, 112, 147], | ||
116 | + "papayawhip": [255, 239, 213], | ||
117 | + "peachpuff": [255, 218, 185], | ||
118 | + "peru": [205, 133, 63], | ||
119 | + "pink": [255, 192, 203], | ||
120 | + "plum": [221, 160, 221], | ||
121 | + "powderblue": [176, 224, 230], | ||
122 | + "purple": [128, 0, 128], | ||
123 | + "rebeccapurple": [102, 51, 153], | ||
124 | + "red": [255, 0, 0], | ||
125 | + "rosybrown": [188, 143, 143], | ||
126 | + "royalblue": [65, 105, 225], | ||
127 | + "saddlebrown": [139, 69, 19], | ||
128 | + "salmon": [250, 128, 114], | ||
129 | + "sandybrown": [244, 164, 96], | ||
130 | + "seagreen": [46, 139, 87], | ||
131 | + "seashell": [255, 245, 238], | ||
132 | + "sienna": [160, 82, 45], | ||
133 | + "silver": [192, 192, 192], | ||
134 | + "skyblue": [135, 206, 235], | ||
135 | + "slateblue": [106, 90, 205], | ||
136 | + "slategray": [112, 128, 144], | ||
137 | + "slategrey": [112, 128, 144], | ||
138 | + "snow": [255, 250, 250], | ||
139 | + "springgreen": [0, 255, 127], | ||
140 | + "steelblue": [70, 130, 180], | ||
141 | + "tan": [210, 180, 140], | ||
142 | + "teal": [0, 128, 128], | ||
143 | + "thistle": [216, 191, 216], | ||
144 | + "tomato": [255, 99, 71], | ||
145 | + "turquoise": [64, 224, 208], | ||
146 | + "violet": [238, 130, 238], | ||
147 | + "wheat": [245, 222, 179], | ||
148 | + "white": [255, 255, 255], | ||
149 | + "whitesmoke": [245, 245, 245], | ||
150 | + "yellow": [255, 255, 0], | ||
151 | + "yellowgreen": [154, 205, 50] | ||
152 | +}; |
node_modules/color-name/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "color-name", | ||
3 | + "version": "1.1.3", | ||
4 | + "description": "A list of color names and its values", | ||
5 | + "main": "index.js", | ||
6 | + "scripts": { | ||
7 | + "test": "node test.js" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "git@github.com:dfcreative/color-name.git" | ||
12 | + }, | ||
13 | + "keywords": [ | ||
14 | + "color-name", | ||
15 | + "color", | ||
16 | + "color-keyword", | ||
17 | + "keyword" | ||
18 | + ], | ||
19 | + "author": "DY <dfcreative@gmail.com>", | ||
20 | + "license": "MIT", | ||
21 | + "bugs": { | ||
22 | + "url": "https://github.com/dfcreative/color-name/issues" | ||
23 | + }, | ||
24 | + "homepage": "https://github.com/dfcreative/color-name" | ||
25 | +} |
node_modules/color-name/test.js
0 → 100644
node_modules/concat-map/.travis.yml
0 → 100644
node_modules/concat-map/LICENSE
0 → 100644
1 | +This software is released under the MIT license: | ||
2 | + | ||
3 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
4 | +this software and associated documentation files (the "Software"), to deal in | ||
5 | +the Software without restriction, including without limitation the rights to | ||
6 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
7 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
8 | +subject to the following conditions: | ||
9 | + | ||
10 | +The above copyright notice and this permission notice shall be included in all | ||
11 | +copies or substantial portions of the Software. | ||
12 | + | ||
13 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
15 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
16 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
17 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
18 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
node_modules/concat-map/README.markdown
0 → 100644
1 | +concat-map | ||
2 | +========== | ||
3 | + | ||
4 | +Concatenative mapdashery. | ||
5 | + | ||
6 | +[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map) | ||
7 | + | ||
8 | +[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map) | ||
9 | + | ||
10 | +example | ||
11 | +======= | ||
12 | + | ||
13 | +``` js | ||
14 | +var concatMap = require('concat-map'); | ||
15 | +var xs = [ 1, 2, 3, 4, 5, 6 ]; | ||
16 | +var ys = concatMap(xs, function (x) { | ||
17 | + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; | ||
18 | +}); | ||
19 | +console.dir(ys); | ||
20 | +``` | ||
21 | + | ||
22 | +*** | ||
23 | + | ||
24 | +``` | ||
25 | +[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ] | ||
26 | +``` | ||
27 | + | ||
28 | +methods | ||
29 | +======= | ||
30 | + | ||
31 | +``` js | ||
32 | +var concatMap = require('concat-map') | ||
33 | +``` | ||
34 | + | ||
35 | +concatMap(xs, fn) | ||
36 | +----------------- | ||
37 | + | ||
38 | +Return an array of concatenated elements by calling `fn(x, i)` for each element | ||
39 | +`x` and each index `i` in the array `xs`. | ||
40 | + | ||
41 | +When `fn(x, i)` returns an array, its result will be concatenated with the | ||
42 | +result array. If `fn(x, i)` returns anything else, that value will be pushed | ||
43 | +onto the end of the result array. | ||
44 | + | ||
45 | +install | ||
46 | +======= | ||
47 | + | ||
48 | +With [npm](http://npmjs.org) do: | ||
49 | + | ||
50 | +``` | ||
51 | +npm install concat-map | ||
52 | +``` | ||
53 | + | ||
54 | +license | ||
55 | +======= | ||
56 | + | ||
57 | +MIT | ||
58 | + | ||
59 | +notes | ||
60 | +===== | ||
61 | + | ||
62 | +This module was written while sitting high above the ground in a tree. |
node_modules/concat-map/example/map.js
0 → 100644
node_modules/concat-map/index.js
0 → 100644
1 | +module.exports = function (xs, fn) { | ||
2 | + var res = []; | ||
3 | + for (var i = 0; i < xs.length; i++) { | ||
4 | + var x = fn(xs[i], i); | ||
5 | + if (isArray(x)) res.push.apply(res, x); | ||
6 | + else res.push(x); | ||
7 | + } | ||
8 | + return res; | ||
9 | +}; | ||
10 | + | ||
11 | +var isArray = Array.isArray || function (xs) { | ||
12 | + return Object.prototype.toString.call(xs) === '[object Array]'; | ||
13 | +}; |
node_modules/concat-map/package.json
0 → 100644
1 | +{ | ||
2 | + "name" : "concat-map", | ||
3 | + "description" : "concatenative mapdashery", | ||
4 | + "version" : "0.0.1", | ||
5 | + "repository" : { | ||
6 | + "type" : "git", | ||
7 | + "url" : "git://github.com/substack/node-concat-map.git" | ||
8 | + }, | ||
9 | + "main" : "index.js", | ||
10 | + "keywords" : [ | ||
11 | + "concat", | ||
12 | + "concatMap", | ||
13 | + "map", | ||
14 | + "functional", | ||
15 | + "higher-order" | ||
16 | + ], | ||
17 | + "directories" : { | ||
18 | + "example" : "example", | ||
19 | + "test" : "test" | ||
20 | + }, | ||
21 | + "scripts" : { | ||
22 | + "test" : "tape test/*.js" | ||
23 | + }, | ||
24 | + "devDependencies" : { | ||
25 | + "tape" : "~2.4.0" | ||
26 | + }, | ||
27 | + "license" : "MIT", | ||
28 | + "author" : { | ||
29 | + "name" : "James Halliday", | ||
30 | + "email" : "mail@substack.net", | ||
31 | + "url" : "http://substack.net" | ||
32 | + }, | ||
33 | + "testling" : { | ||
34 | + "files" : "test/*.js", | ||
35 | + "browsers" : { | ||
36 | + "ie" : [ 6, 7, 8, 9 ], | ||
37 | + "ff" : [ 3.5, 10, 15.0 ], | ||
38 | + "chrome" : [ 10, 22 ], | ||
39 | + "safari" : [ 5.1 ], | ||
40 | + "opera" : [ 12 ] | ||
41 | + } | ||
42 | + } | ||
43 | +} |
node_modules/concat-map/test/map.js
0 → 100644
1 | +var concatMap = require('../'); | ||
2 | +var test = require('tape'); | ||
3 | + | ||
4 | +test('empty or not', function (t) { | ||
5 | + var xs = [ 1, 2, 3, 4, 5, 6 ]; | ||
6 | + var ixes = []; | ||
7 | + var ys = concatMap(xs, function (x, ix) { | ||
8 | + ixes.push(ix); | ||
9 | + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; | ||
10 | + }); | ||
11 | + t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); | ||
12 | + t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); | ||
13 | + t.end(); | ||
14 | +}); | ||
15 | + | ||
16 | +test('always something', function (t) { | ||
17 | + var xs = [ 'a', 'b', 'c', 'd' ]; | ||
18 | + var ys = concatMap(xs, function (x) { | ||
19 | + return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; | ||
20 | + }); | ||
21 | + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); | ||
22 | + t.end(); | ||
23 | +}); | ||
24 | + | ||
25 | +test('scalars', function (t) { | ||
26 | + var xs = [ 'a', 'b', 'c', 'd' ]; | ||
27 | + var ys = concatMap(xs, function (x) { | ||
28 | + return x === 'b' ? [ 'B', 'B', 'B' ] : x; | ||
29 | + }); | ||
30 | + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); | ||
31 | + t.end(); | ||
32 | +}); | ||
33 | + | ||
34 | +test('undefs', function (t) { | ||
35 | + var xs = [ 'a', 'b', 'c', 'd' ]; | ||
36 | + var ys = concatMap(xs, function () {}); | ||
37 | + t.same(ys, [ undefined, undefined, undefined, undefined ]); | ||
38 | + t.end(); | ||
39 | +}); |
node_modules/ejs/LICENSE
0 → 100644
1 | + | ||
2 | + Apache License | ||
3 | + Version 2.0, January 2004 | ||
4 | + http://www.apache.org/licenses/ | ||
5 | + | ||
6 | + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
7 | + | ||
8 | + 1. Definitions. | ||
9 | + | ||
10 | + "License" shall mean the terms and conditions for use, reproduction, | ||
11 | + and distribution as defined by Sections 1 through 9 of this document. | ||
12 | + | ||
13 | + "Licensor" shall mean the copyright owner or entity authorized by | ||
14 | + the copyright owner that is granting the License. | ||
15 | + | ||
16 | + "Legal Entity" shall mean the union of the acting entity and all | ||
17 | + other entities that control, are controlled by, or are under common | ||
18 | + control with that entity. For the purposes of this definition, | ||
19 | + "control" means (i) the power, direct or indirect, to cause the | ||
20 | + direction or management of such entity, whether by contract or | ||
21 | + otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
22 | + outstanding shares, or (iii) beneficial ownership of such entity. | ||
23 | + | ||
24 | + "You" (or "Your") shall mean an individual or Legal Entity | ||
25 | + exercising permissions granted by this License. | ||
26 | + | ||
27 | + "Source" form shall mean the preferred form for making modifications, | ||
28 | + including but not limited to software source code, documentation | ||
29 | + source, and configuration files. | ||
30 | + | ||
31 | + "Object" form shall mean any form resulting from mechanical | ||
32 | + transformation or translation of a Source form, including but | ||
33 | + not limited to compiled object code, generated documentation, | ||
34 | + and conversions to other media types. | ||
35 | + | ||
36 | + "Work" shall mean the work of authorship, whether in Source or | ||
37 | + Object form, made available under the License, as indicated by a | ||
38 | + copyright notice that is included in or attached to the work | ||
39 | + (an example is provided in the Appendix below). | ||
40 | + | ||
41 | + "Derivative Works" shall mean any work, whether in Source or Object | ||
42 | + form, that is based on (or derived from) the Work and for which the | ||
43 | + editorial revisions, annotations, elaborations, or other modifications | ||
44 | + represent, as a whole, an original work of authorship. For the purposes | ||
45 | + of this License, Derivative Works shall not include works that remain | ||
46 | + separable from, or merely link (or bind by name) to the interfaces of, | ||
47 | + the Work and Derivative Works thereof. | ||
48 | + | ||
49 | + "Contribution" shall mean any work of authorship, including | ||
50 | + the original version of the Work and any modifications or additions | ||
51 | + to that Work or Derivative Works thereof, that is intentionally | ||
52 | + submitted to Licensor for inclusion in the Work by the copyright owner | ||
53 | + or by an individual or Legal Entity authorized to submit on behalf of | ||
54 | + the copyright owner. For the purposes of this definition, "submitted" | ||
55 | + means any form of electronic, verbal, or written communication sent | ||
56 | + to the Licensor or its representatives, including but not limited to | ||
57 | + communication on electronic mailing lists, source code control systems, | ||
58 | + and issue tracking systems that are managed by, or on behalf of, the | ||
59 | + Licensor for the purpose of discussing and improving the Work, but | ||
60 | + excluding communication that is conspicuously marked or otherwise | ||
61 | + designated in writing by the copyright owner as "Not a Contribution." | ||
62 | + | ||
63 | + "Contributor" shall mean Licensor and any individual or Legal Entity | ||
64 | + on behalf of whom a Contribution has been received by Licensor and | ||
65 | + subsequently incorporated within the Work. | ||
66 | + | ||
67 | + 2. Grant of Copyright License. Subject to the terms and conditions of | ||
68 | + this License, each Contributor hereby grants to You a perpetual, | ||
69 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
70 | + copyright license to reproduce, prepare Derivative Works of, | ||
71 | + publicly display, publicly perform, sublicense, and distribute the | ||
72 | + Work and such Derivative Works in Source or Object form. | ||
73 | + | ||
74 | + 3. Grant of Patent License. Subject to the terms and conditions of | ||
75 | + this License, each Contributor hereby grants to You a perpetual, | ||
76 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
77 | + (except as stated in this section) patent license to make, have made, | ||
78 | + use, offer to sell, sell, import, and otherwise transfer the Work, | ||
79 | + where such license applies only to those patent claims licensable | ||
80 | + by such Contributor that are necessarily infringed by their | ||
81 | + Contribution(s) alone or by combination of their Contribution(s) | ||
82 | + with the Work to which such Contribution(s) was submitted. If You | ||
83 | + institute patent litigation against any entity (including a | ||
84 | + cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
85 | + or a Contribution incorporated within the Work constitutes direct | ||
86 | + or contributory patent infringement, then any patent licenses | ||
87 | + granted to You under this License for that Work shall terminate | ||
88 | + as of the date such litigation is filed. | ||
89 | + | ||
90 | + 4. Redistribution. You may reproduce and distribute copies of the | ||
91 | + Work or Derivative Works thereof in any medium, with or without | ||
92 | + modifications, and in Source or Object form, provided that You | ||
93 | + meet the following conditions: | ||
94 | + | ||
95 | + (a) You must give any other recipients of the Work or | ||
96 | + Derivative Works a copy of this License; and | ||
97 | + | ||
98 | + (b) You must cause any modified files to carry prominent notices | ||
99 | + stating that You changed the files; and | ||
100 | + | ||
101 | + (c) You must retain, in the Source form of any Derivative Works | ||
102 | + that You distribute, all copyright, patent, trademark, and | ||
103 | + attribution notices from the Source form of the Work, | ||
104 | + excluding those notices that do not pertain to any part of | ||
105 | + the Derivative Works; and | ||
106 | + | ||
107 | + (d) If the Work includes a "NOTICE" text file as part of its | ||
108 | + distribution, then any Derivative Works that You distribute must | ||
109 | + include a readable copy of the attribution notices contained | ||
110 | + within such NOTICE file, excluding those notices that do not | ||
111 | + pertain to any part of the Derivative Works, in at least one | ||
112 | + of the following places: within a NOTICE text file distributed | ||
113 | + as part of the Derivative Works; within the Source form or | ||
114 | + documentation, if provided along with the Derivative Works; or, | ||
115 | + within a display generated by the Derivative Works, if and | ||
116 | + wherever such third-party notices normally appear. The contents | ||
117 | + of the NOTICE file are for informational purposes only and | ||
118 | + do not modify the License. You may add Your own attribution | ||
119 | + notices within Derivative Works that You distribute, alongside | ||
120 | + or as an addendum to the NOTICE text from the Work, provided | ||
121 | + that such additional attribution notices cannot be construed | ||
122 | + as modifying the License. | ||
123 | + | ||
124 | + You may add Your own copyright statement to Your modifications and | ||
125 | + may provide additional or different license terms and conditions | ||
126 | + for use, reproduction, or distribution of Your modifications, or | ||
127 | + for any such Derivative Works as a whole, provided Your use, | ||
128 | + reproduction, and distribution of the Work otherwise complies with | ||
129 | + the conditions stated in this License. | ||
130 | + | ||
131 | + 5. Submission of Contributions. Unless You explicitly state otherwise, | ||
132 | + any Contribution intentionally submitted for inclusion in the Work | ||
133 | + by You to the Licensor shall be under the terms and conditions of | ||
134 | + this License, without any additional terms or conditions. | ||
135 | + Notwithstanding the above, nothing herein shall supersede or modify | ||
136 | + the terms of any separate license agreement you may have executed | ||
137 | + with Licensor regarding such Contributions. | ||
138 | + | ||
139 | + 6. Trademarks. This License does not grant permission to use the trade | ||
140 | + names, trademarks, service marks, or product names of the Licensor, | ||
141 | + except as required for reasonable and customary use in describing the | ||
142 | + origin of the Work and reproducing the content of the NOTICE file. | ||
143 | + | ||
144 | + 7. Disclaimer of Warranty. Unless required by applicable law or | ||
145 | + agreed to in writing, Licensor provides the Work (and each | ||
146 | + Contributor provides its Contributions) on an "AS IS" BASIS, | ||
147 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
148 | + implied, including, without limitation, any warranties or conditions | ||
149 | + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
150 | + PARTICULAR PURPOSE. You are solely responsible for determining the | ||
151 | + appropriateness of using or redistributing the Work and assume any | ||
152 | + risks associated with Your exercise of permissions under this License. | ||
153 | + | ||
154 | + 8. Limitation of Liability. In no event and under no legal theory, | ||
155 | + whether in tort (including negligence), contract, or otherwise, | ||
156 | + unless required by applicable law (such as deliberate and grossly | ||
157 | + negligent acts) or agreed to in writing, shall any Contributor be | ||
158 | + liable to You for damages, including any direct, indirect, special, | ||
159 | + incidental, or consequential damages of any character arising as a | ||
160 | + result of this License or out of the use or inability to use the | ||
161 | + Work (including but not limited to damages for loss of goodwill, | ||
162 | + work stoppage, computer failure or malfunction, or any and all | ||
163 | + other commercial damages or losses), even if such Contributor | ||
164 | + has been advised of the possibility of such damages. | ||
165 | + | ||
166 | + 9. Accepting Warranty or Additional Liability. While redistributing | ||
167 | + the Work or Derivative Works thereof, You may choose to offer, | ||
168 | + and charge a fee for, acceptance of support, warranty, indemnity, | ||
169 | + or other liability obligations and/or rights consistent with this | ||
170 | + License. However, in accepting such obligations, You may act only | ||
171 | + on Your own behalf and on Your sole responsibility, not on behalf | ||
172 | + of any other Contributor, and only if You agree to indemnify, | ||
173 | + defend, and hold each Contributor harmless for any liability | ||
174 | + incurred by, or claims asserted against, such Contributor by reason | ||
175 | + of your accepting any such warranty or additional liability. | ||
176 | + | ||
177 | + END OF TERMS AND CONDITIONS | ||
178 | + | ||
179 | + APPENDIX: How to apply the Apache License to your work. | ||
180 | + | ||
181 | + To apply the Apache License to your work, attach the following | ||
182 | + boilerplate notice, with the fields enclosed by brackets "[]" | ||
183 | + replaced with your own identifying information. (Don't include | ||
184 | + the brackets!) The text should be enclosed in the appropriate | ||
185 | + comment syntax for the file format. We also recommend that a | ||
186 | + file or class name and description of purpose be included on the | ||
187 | + same "printed page" as the copyright notice for easier | ||
188 | + identification within third-party archives. | ||
189 | + | ||
190 | + Copyright [yyyy] [name of copyright owner] | ||
191 | + | ||
192 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
193 | + you may not use this file except in compliance with the License. | ||
194 | + You may obtain a copy of the License at | ||
195 | + | ||
196 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
197 | + | ||
198 | + Unless required by applicable law or agreed to in writing, software | ||
199 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
200 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
201 | + See the License for the specific language governing permissions and | ||
202 | + limitations under the License. |
node_modules/ejs/README.md
0 → 100644
1 | +Embedded JavaScript templates<br/> | ||
2 | +[![Build Status](https://img.shields.io/travis/mde/ejs/master.svg?style=flat)](https://travis-ci.org/mde/ejs) | ||
3 | +[![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs?type=dev) | ||
4 | +[![Known Vulnerabilities](https://snyk.io/test/npm/ejs/badge.svg?style=flat)](https://snyk.io/test/npm/ejs) | ||
5 | +============================= | ||
6 | + | ||
7 | +## Installation | ||
8 | + | ||
9 | +```bash | ||
10 | +$ npm install ejs | ||
11 | +``` | ||
12 | + | ||
13 | +## Features | ||
14 | + | ||
15 | + * Control flow with `<% %>` | ||
16 | + * Escaped output with `<%= %>` (escape function configurable) | ||
17 | + * Unescaped raw output with `<%- %>` | ||
18 | + * Newline-trim mode ('newline slurping') with `-%>` ending tag | ||
19 | + * Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>` | ||
20 | + * Custom delimiters (e.g. `[? ?]` instead of `<% %>`) | ||
21 | + * Includes | ||
22 | + * Client-side support | ||
23 | + * Static caching of intermediate JavaScript | ||
24 | + * Static caching of templates | ||
25 | + * Complies with the [Express](http://expressjs.com) view system | ||
26 | + | ||
27 | +## Example | ||
28 | + | ||
29 | +```ejs | ||
30 | +<% if (user) { %> | ||
31 | + <h2><%= user.name %></h2> | ||
32 | +<% } %> | ||
33 | +``` | ||
34 | + | ||
35 | +Try EJS online at: https://ionicabizau.github.io/ejs-playground/. | ||
36 | + | ||
37 | +## Basic usage | ||
38 | + | ||
39 | +```javascript | ||
40 | +let template = ejs.compile(str, options); | ||
41 | +template(data); | ||
42 | +// => Rendered HTML string | ||
43 | + | ||
44 | +ejs.render(str, data, options); | ||
45 | +// => Rendered HTML string | ||
46 | + | ||
47 | +ejs.renderFile(filename, data, options, function(err, str){ | ||
48 | + // str => Rendered HTML string | ||
49 | +}); | ||
50 | +``` | ||
51 | + | ||
52 | +It is also possible to use `ejs.render(dataAndOptions);` where you pass | ||
53 | +everything in a single object. In that case, you'll end up with local variables | ||
54 | +for all the passed options. However, be aware that your code could break if we | ||
55 | +add an option with the same name as one of your data object's properties. | ||
56 | +Therefore, we do not recommend using this shortcut. | ||
57 | + | ||
58 | +### Options | ||
59 | + | ||
60 | + - `cache` Compiled functions are cached, requires `filename` | ||
61 | + - `filename` The name of the file being rendered. Not required if you | ||
62 | + are using `renderFile()`. Used by `cache` to key caches, and for includes. | ||
63 | + - `root` Set project root for includes with an absolute path (e.g, /file.ejs). | ||
64 | + Can be array to try to resolve include from multiple directories. | ||
65 | + - `views` An array of paths to use when resolving includes with relative paths. | ||
66 | + - `context` Function execution context | ||
67 | + - `compileDebug` When `false` no debug instrumentation is compiled | ||
68 | + - `client` When `true`, compiles a function that can be rendered | ||
69 | + in the browser without needing to load the EJS Runtime | ||
70 | + ([ejs.min.js](https://github.com/mde/ejs/releases/latest)). | ||
71 | + - `delimiter` Character to use for inner delimiter, by default '%' | ||
72 | + - `openDelimiter` Character to use for opening delimiter, by default '<' | ||
73 | + - `closeDelimiter` Character to use for closing delimiter, by default '>' | ||
74 | + - `debug` Outputs generated function body | ||
75 | + - `strict` When set to `true`, generated function is in strict mode | ||
76 | + - `_with` Whether or not to use `with() {}` constructs. If `false` | ||
77 | + then the locals will be stored in the `locals` object. Set to `false` in strict mode. | ||
78 | + - `destructuredLocals` An array of local variables that are always destructured from | ||
79 | + the locals object, available even in strict mode. | ||
80 | + - `localsName` Name to use for the object storing local variables when not using | ||
81 | + `with` Defaults to `locals` | ||
82 | + - `rmWhitespace` Remove all safe-to-remove whitespace, including leading | ||
83 | + and trailing whitespace. It also enables a safer version of `-%>` line | ||
84 | + slurping for all scriptlet tags (it does not strip new lines of tags in | ||
85 | + the middle of a line). | ||
86 | + - `escape` The escaping function used with `<%=` construct. It is | ||
87 | + used in rendering and is `.toString()`ed in the generation of client functions. | ||
88 | + (By default escapes XML). | ||
89 | + - `outputFunctionName` Set to a string (e.g., 'echo' or 'print') for a function to print | ||
90 | + output inside scriptlet tags. | ||
91 | + - `async` When `true`, EJS will use an async function for rendering. (Depends | ||
92 | + on async/await support in the JS runtime. | ||
93 | + - `includer` Custom function to handle EJS includes, receives `(originalPath, parsedPath)` | ||
94 | + parameters, where `originalPath` is the path in include as-is and `parsedPath` is the | ||
95 | + previously resolved path. Should return an object `{ filename, template }`, | ||
96 | + you may return only one of the properties, where `filename` is the final parsed path and `template` | ||
97 | + is the included content. | ||
98 | + | ||
99 | +This project uses [JSDoc](http://usejsdoc.org/). For the full public API | ||
100 | +documentation, clone the repository and run `jake doc`. This will run JSDoc | ||
101 | +with the proper options and output the documentation to `out/`. If you want | ||
102 | +the both the public & private API docs, run `jake devdoc` instead. | ||
103 | + | ||
104 | +### Tags | ||
105 | + | ||
106 | + - `<%` 'Scriptlet' tag, for control-flow, no output | ||
107 | + - `<%_` 'Whitespace Slurping' Scriptlet tag, strips all whitespace before it | ||
108 | + - `<%=` Outputs the value into the template (escaped) | ||
109 | + - `<%-` Outputs the unescaped value into the template | ||
110 | + - `<%#` Comment tag, no execution, no output | ||
111 | + - `<%%` Outputs a literal '<%' | ||
112 | + - `%%>` Outputs a literal '%>' | ||
113 | + - `%>` Plain ending tag | ||
114 | + - `-%>` Trim-mode ('newline slurp') tag, trims following newline | ||
115 | + - `_%>` 'Whitespace Slurping' ending tag, removes all whitespace after it | ||
116 | + | ||
117 | +For the full syntax documentation, please see [docs/syntax.md](https://github.com/mde/ejs/blob/master/docs/syntax.md). | ||
118 | + | ||
119 | +### Includes | ||
120 | + | ||
121 | +Includes either have to be an absolute path, or, if not, are assumed as | ||
122 | +relative to the template with the `include` call. For example if you are | ||
123 | +including `./views/user/show.ejs` from `./views/users.ejs` you would | ||
124 | +use `<%- include('user/show') %>`. | ||
125 | + | ||
126 | +You must specify the `filename` option for the template with the `include` | ||
127 | +call unless you are using `renderFile()`. | ||
128 | + | ||
129 | +You'll likely want to use the raw output tag (`<%-`) with your include to avoid | ||
130 | +double-escaping the HTML output. | ||
131 | + | ||
132 | +```ejs | ||
133 | +<ul> | ||
134 | + <% users.forEach(function(user){ %> | ||
135 | + <%- include('user/show', {user: user}) %> | ||
136 | + <% }); %> | ||
137 | +</ul> | ||
138 | +``` | ||
139 | + | ||
140 | +Includes are inserted at runtime, so you can use variables for the path in the | ||
141 | +`include` call (for example `<%- include(somePath) %>`). Variables in your | ||
142 | +top-level data object are available to all your includes, but local variables | ||
143 | +need to be passed down. | ||
144 | + | ||
145 | +NOTE: Include preprocessor directives (`<% include user/show %>`) are | ||
146 | +not supported in v3.0+. | ||
147 | + | ||
148 | +## Custom delimiters | ||
149 | + | ||
150 | +Custom delimiters can be applied on a per-template basis, or globally: | ||
151 | + | ||
152 | +```javascript | ||
153 | +let ejs = require('ejs'), | ||
154 | + users = ['geddy', 'neil', 'alex']; | ||
155 | + | ||
156 | +// Just one template | ||
157 | +ejs.render('<p>[?= users.join(" | "); ?]</p>', {users: users}, {delimiter: '?', openDelimiter: '[', closeDelimiter: ']'}); | ||
158 | +// => '<p>geddy | neil | alex</p>' | ||
159 | + | ||
160 | +// Or globally | ||
161 | +ejs.delimiter = '?'; | ||
162 | +ejs.openDelimiter = '['; | ||
163 | +ejs.closeDelimiter = ']'; | ||
164 | +ejs.render('<p>[?= users.join(" | "); ?]</p>', {users: users}); | ||
165 | +// => '<p>geddy | neil | alex</p>' | ||
166 | +``` | ||
167 | + | ||
168 | +### Caching | ||
169 | + | ||
170 | +EJS ships with a basic in-process cache for caching the intermediate JavaScript | ||
171 | +functions used to render templates. It's easy to plug in LRU caching using | ||
172 | +Node's `lru-cache` library: | ||
173 | + | ||
174 | +```javascript | ||
175 | +let ejs = require('ejs'), | ||
176 | + LRU = require('lru-cache'); | ||
177 | +ejs.cache = LRU(100); // LRU cache with 100-item limit | ||
178 | +``` | ||
179 | + | ||
180 | +If you want to clear the EJS cache, call `ejs.clearCache`. If you're using the | ||
181 | +LRU cache and need a different limit, simple reset `ejs.cache` to a new instance | ||
182 | +of the LRU. | ||
183 | + | ||
184 | +### Custom file loader | ||
185 | + | ||
186 | +The default file loader is `fs.readFileSync`, if you want to customize it, you can set ejs.fileLoader. | ||
187 | + | ||
188 | +```javascript | ||
189 | +let ejs = require('ejs'); | ||
190 | +let myFileLoad = function (filePath) { | ||
191 | + return 'myFileLoad: ' + fs.readFileSync(filePath); | ||
192 | +}; | ||
193 | + | ||
194 | +ejs.fileLoader = myFileLoad; | ||
195 | +``` | ||
196 | + | ||
197 | +With this feature, you can preprocess the template before reading it. | ||
198 | + | ||
199 | +### Layouts | ||
200 | + | ||
201 | +EJS does not specifically support blocks, but layouts can be implemented by | ||
202 | +including headers and footers, like so: | ||
203 | + | ||
204 | + | ||
205 | +```ejs | ||
206 | +<%- include('header') -%> | ||
207 | +<h1> | ||
208 | + Title | ||
209 | +</h1> | ||
210 | +<p> | ||
211 | + My page | ||
212 | +</p> | ||
213 | +<%- include('footer') -%> | ||
214 | +``` | ||
215 | + | ||
216 | +## Client-side support | ||
217 | + | ||
218 | +Go to the [Latest Release](https://github.com/mde/ejs/releases/latest), download | ||
219 | +`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning | ||
220 | +the repository and running `jake build` (or `$(npm bin)/jake build` if jake is | ||
221 | +not installed globally). | ||
222 | + | ||
223 | +Include one of these files on your page, and `ejs` should be available globally. | ||
224 | + | ||
225 | +### Example | ||
226 | + | ||
227 | +```html | ||
228 | +<div id="output"></div> | ||
229 | +<script src="ejs.min.js"></script> | ||
230 | +<script> | ||
231 | + let people = ['geddy', 'neil', 'alex'], | ||
232 | + html = ejs.render('<%= people.join(", "); %>', {people: people}); | ||
233 | + // With jQuery: | ||
234 | + $('#output').html(html); | ||
235 | + // Vanilla JS: | ||
236 | + document.getElementById('output').innerHTML = html; | ||
237 | +</script> | ||
238 | +``` | ||
239 | + | ||
240 | +### Caveats | ||
241 | + | ||
242 | +Most of EJS will work as expected; however, there are a few things to note: | ||
243 | + | ||
244 | +1. Obviously, since you do not have access to the filesystem, `ejs.renderFile()` won't work. | ||
245 | +2. For the same reason, `include`s do not work unless you use an `include callback`. Here is an example: | ||
246 | + ```javascript | ||
247 | + let str = "Hello <%= include('file', {person: 'John'}); %>", | ||
248 | + fn = ejs.compile(str, {client: true}); | ||
249 | + | ||
250 | + fn(data, null, function(path, d){ // include callback | ||
251 | + // path -> 'file' | ||
252 | + // d -> {person: 'John'} | ||
253 | + // Put your code here | ||
254 | + // Return the contents of file as a string | ||
255 | + }); // returns rendered string | ||
256 | + ``` | ||
257 | + | ||
258 | +See the [examples folder](https://github.com/mde/ejs/tree/master/examples) for more details. | ||
259 | + | ||
260 | +## CLI | ||
261 | + | ||
262 | +EJS ships with a full-featured CLI. Options are similar to those used in JavaScript code: | ||
263 | + | ||
264 | + - `-o / --output-file FILE` Write the rendered output to FILE rather than stdout. | ||
265 | + - `-f / --data-file FILE` Must be JSON-formatted. Use parsed input from FILE as data for rendering. | ||
266 | + - `-i / --data-input STRING` Must be JSON-formatted and URI-encoded. Use parsed input from STRING as data for rendering. | ||
267 | + - `-m / --delimiter CHARACTER` Use CHARACTER with angle brackets for open/close (defaults to %). | ||
268 | + - `-p / --open-delimiter CHARACTER` Use CHARACTER instead of left angle bracket to open. | ||
269 | + - `-c / --close-delimiter CHARACTER` Use CHARACTER instead of right angle bracket to close. | ||
270 | + - `-s / --strict` When set to `true`, generated function is in strict mode | ||
271 | + - `-n / --no-with` Use 'locals' object for vars rather than using `with` (implies --strict). | ||
272 | + - `-l / --locals-name` Name to use for the object storing local variables when not using `with`. | ||
273 | + - `-w / --rm-whitespace` Remove all safe-to-remove whitespace, including leading and trailing whitespace. | ||
274 | + - `-d / --debug` Outputs generated function body | ||
275 | + - `-h / --help` Display this help message. | ||
276 | + - `-V/v / --version` Display the EJS version. | ||
277 | + | ||
278 | +Here are some examples of usage: | ||
279 | + | ||
280 | +```shell | ||
281 | +$ ejs -p [ -c ] ./template_file.ejs -o ./output.html | ||
282 | +$ ejs ./test/fixtures/user.ejs name=Lerxst | ||
283 | +$ ejs -n -l _ ./some_template.ejs -f ./data_file.json | ||
284 | +``` | ||
285 | + | ||
286 | +### Data input | ||
287 | + | ||
288 | +There is a variety of ways to pass the CLI data for rendering. | ||
289 | + | ||
290 | +Stdin: | ||
291 | + | ||
292 | +```shell | ||
293 | +$ ./test/fixtures/user_data.json | ejs ./test/fixtures/user.ejs | ||
294 | +$ ejs ./test/fixtures/user.ejs < test/fixtures/user_data.json | ||
295 | +``` | ||
296 | + | ||
297 | +A data file: | ||
298 | + | ||
299 | +```shell | ||
300 | +$ ejs ./test/fixtures/user.ejs -f ./user_data.json | ||
301 | +``` | ||
302 | + | ||
303 | +A command-line option (must be URI-encoded): | ||
304 | + | ||
305 | +```shell | ||
306 | +./bin/cli.js -i %7B%22name%22%3A%20%22foo%22%7D ./test/fixtures/user.ejs | ||
307 | +``` | ||
308 | + | ||
309 | +Or, passing values directly at the end of the invocation: | ||
310 | + | ||
311 | +```shell | ||
312 | +./bin/cli.js -m $ ./test/fixtures/user.ejs name=foo | ||
313 | +``` | ||
314 | + | ||
315 | +### Output | ||
316 | + | ||
317 | +The CLI by default send output to stdout, but you can use the `-o` or `--output-file` | ||
318 | +flag to specify a target file to send the output to. | ||
319 | + | ||
320 | +## IDE Integration with Syntax Highlighting | ||
321 | + | ||
322 | +VSCode:Javascript EJS by *DigitalBrainstem* | ||
323 | + | ||
324 | +## Related projects | ||
325 | + | ||
326 | +There are a number of implementations of EJS: | ||
327 | + | ||
328 | + * TJ's implementation, the v1 of this library: https://github.com/tj/ejs | ||
329 | + * EJS Embedded JavaScript Framework on Google Code: https://code.google.com/p/embeddedjavascript/ | ||
330 | + * Sam Stephenson's Ruby implementation: https://rubygems.org/gems/ejs | ||
331 | + * Erubis, an ERB implementation which also runs JavaScript: http://www.kuwata-lab.com/erubis/users-guide.04.html#lang-javascript | ||
332 | + * DigitalBrainstem EJS Language support: https://github.com/Digitalbrainstem/ejs-grammar | ||
333 | + | ||
334 | +## License | ||
335 | + | ||
336 | +Licensed under the Apache License, Version 2.0 | ||
337 | +(<http://www.apache.org/licenses/LICENSE-2.0>) | ||
338 | + | ||
339 | +- - - | ||
340 | +EJS Embedded JavaScript templates copyright 2112 | ||
341 | +mde@fleegix.org. |
node_modules/ejs/bin/cli.js
0 → 100644
1 | +#!/usr/bin/env node | ||
2 | +/* | ||
3 | + * EJS Embedded JavaScript templates | ||
4 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
5 | + * | ||
6 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + * you may not use this file except in compliance with the License. | ||
8 | + * You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, software | ||
13 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + * See the License for the specific language governing permissions and | ||
16 | + * limitations under the License. | ||
17 | + * | ||
18 | +*/ | ||
19 | + | ||
20 | + | ||
21 | +let program = require('jake').program; | ||
22 | +delete global.jake; // NO NOT WANT | ||
23 | +program.setTaskNames = function (n) { this.taskNames = n; }; | ||
24 | + | ||
25 | +let ejs = require('../lib/ejs'); | ||
26 | +let { hyphenToCamel } = require('../lib/utils'); | ||
27 | +let fs = require('fs'); | ||
28 | +let args = process.argv.slice(2); | ||
29 | +let usage = fs.readFileSync(`${__dirname}/../usage.txt`).toString(); | ||
30 | + | ||
31 | +const CLI_OPTS = [ | ||
32 | + { full: 'output-file', | ||
33 | + abbr: 'o', | ||
34 | + expectValue: true, | ||
35 | + }, | ||
36 | + { full: 'data-file', | ||
37 | + abbr: 'f', | ||
38 | + expectValue: true, | ||
39 | + }, | ||
40 | + { full: 'data-input', | ||
41 | + abbr: 'i', | ||
42 | + expectValue: true, | ||
43 | + }, | ||
44 | + { full: 'delimiter', | ||
45 | + abbr: 'm', | ||
46 | + expectValue: true, | ||
47 | + passThrough: true, | ||
48 | + }, | ||
49 | + { full: 'open-delimiter', | ||
50 | + abbr: 'p', | ||
51 | + expectValue: true, | ||
52 | + passThrough: true, | ||
53 | + }, | ||
54 | + { full: 'close-delimiter', | ||
55 | + abbr: 'c', | ||
56 | + expectValue: true, | ||
57 | + passThrough: true, | ||
58 | + }, | ||
59 | + { full: 'strict', | ||
60 | + abbr: 's', | ||
61 | + expectValue: false, | ||
62 | + allowValue: false, | ||
63 | + passThrough: true, | ||
64 | + }, | ||
65 | + { full: 'no-with', | ||
66 | + abbr: 'n', | ||
67 | + expectValue: false, | ||
68 | + allowValue: false, | ||
69 | + }, | ||
70 | + { full: 'locals-name', | ||
71 | + abbr: 'l', | ||
72 | + expectValue: true, | ||
73 | + passThrough: true, | ||
74 | + }, | ||
75 | + { full: 'rm-whitespace', | ||
76 | + abbr: 'w', | ||
77 | + expectValue: false, | ||
78 | + allowValue: false, | ||
79 | + passThrough: true, | ||
80 | + }, | ||
81 | + { full: 'debug', | ||
82 | + abbr: 'd', | ||
83 | + expectValue: false, | ||
84 | + allowValue: false, | ||
85 | + passThrough: true, | ||
86 | + }, | ||
87 | + { full: 'help', | ||
88 | + abbr: 'h', | ||
89 | + passThrough: true, | ||
90 | + }, | ||
91 | + { full: 'version', | ||
92 | + abbr: 'V', | ||
93 | + passThrough: true, | ||
94 | + }, | ||
95 | + // Alias lowercase v | ||
96 | + { full: 'version', | ||
97 | + abbr: 'v', | ||
98 | + passThrough: true, | ||
99 | + }, | ||
100 | +]; | ||
101 | + | ||
102 | +let preempts = { | ||
103 | + version: function () { | ||
104 | + program.die(ejs.VERSION); | ||
105 | + }, | ||
106 | + help: function () { | ||
107 | + program.die(usage); | ||
108 | + } | ||
109 | +}; | ||
110 | + | ||
111 | +let stdin = ''; | ||
112 | +process.stdin.setEncoding('utf8'); | ||
113 | +process.stdin.on('readable', () => { | ||
114 | + let chunk; | ||
115 | + while ((chunk = process.stdin.read()) !== null) { | ||
116 | + stdin += chunk; | ||
117 | + } | ||
118 | +}); | ||
119 | + | ||
120 | +function run() { | ||
121 | + | ||
122 | + program.availableOpts = CLI_OPTS; | ||
123 | + program.parseArgs(args); | ||
124 | + | ||
125 | + let templatePath = program.taskNames[0]; | ||
126 | + let pVals = program.envVars; | ||
127 | + let pOpts = {}; | ||
128 | + | ||
129 | + for (let p in program.opts) { | ||
130 | + let name = hyphenToCamel(p); | ||
131 | + pOpts[name] = program.opts[p]; | ||
132 | + } | ||
133 | + | ||
134 | + let opts = {}; | ||
135 | + let vals = {}; | ||
136 | + | ||
137 | + // Same-named 'passthrough' opts | ||
138 | + CLI_OPTS.forEach((opt) => { | ||
139 | + let optName = hyphenToCamel(opt.full); | ||
140 | + if (opt.passThrough && typeof pOpts[optName] != 'undefined') { | ||
141 | + opts[optName] = pOpts[optName]; | ||
142 | + } | ||
143 | + }); | ||
144 | + | ||
145 | + // Bail out for help/version | ||
146 | + for (let p in opts) { | ||
147 | + if (preempts[p]) { | ||
148 | + return preempts[p](); | ||
149 | + } | ||
150 | + } | ||
151 | + | ||
152 | + // Default to having views relative from the current working directory | ||
153 | + opts.views = ['.']; | ||
154 | + | ||
155 | + // Ensure there's a template to render | ||
156 | + if (!templatePath) { | ||
157 | + throw new Error('Please provide a template path. (Run ejs -h for help)'); | ||
158 | + } | ||
159 | + | ||
160 | + if (opts.strict) { | ||
161 | + pOpts.noWith = true; | ||
162 | + } | ||
163 | + if (pOpts.noWith) { | ||
164 | + opts._with = false; | ||
165 | + } | ||
166 | + | ||
167 | + // Grab and parse any input data, in order of precedence: | ||
168 | + // 1. Stdin | ||
169 | + // 2. CLI arg via -i | ||
170 | + // 3. Data file via -f | ||
171 | + // Any individual vals passed at the end (e.g., foo=bar) will override | ||
172 | + // any vals previously set | ||
173 | + let input; | ||
174 | + let err = new Error('Please do not pass data multiple ways. Pick one of stdin, -f, or -i.'); | ||
175 | + if (stdin) { | ||
176 | + input = stdin; | ||
177 | + } | ||
178 | + else if (pOpts.dataInput) { | ||
179 | + if (input) { | ||
180 | + throw err; | ||
181 | + } | ||
182 | + input = decodeURIComponent(pOpts.dataInput); | ||
183 | + } | ||
184 | + else if (pOpts.dataFile) { | ||
185 | + if (input) { | ||
186 | + throw err; | ||
187 | + } | ||
188 | + input = fs.readFileSync(pOpts.dataFile).toString(); | ||
189 | + } | ||
190 | + | ||
191 | + if (input) { | ||
192 | + vals = JSON.parse(input); | ||
193 | + } | ||
194 | + | ||
195 | + // Override / set any individual values passed from the command line | ||
196 | + for (let p in pVals) { | ||
197 | + vals[p] = pVals[p]; | ||
198 | + } | ||
199 | + | ||
200 | + let template = fs.readFileSync(templatePath).toString(); | ||
201 | + let output = ejs.render(template, vals, opts); | ||
202 | + if (pOpts.outputFile) { | ||
203 | + fs.writeFileSync(pOpts.outputFile, output); | ||
204 | + } | ||
205 | + else { | ||
206 | + process.stdout.write(output); | ||
207 | + } | ||
208 | + process.exit(); | ||
209 | +} | ||
210 | + | ||
211 | +// Defer execution so that stdin can be read if necessary | ||
212 | +setImmediate(run); |
node_modules/ejs/ejs.js
0 → 100644
1 | +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ejs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
2 | +/* | ||
3 | + * EJS Embedded JavaScript templates | ||
4 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
5 | + * | ||
6 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + * you may not use this file except in compliance with the License. | ||
8 | + * You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, software | ||
13 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + * See the License for the specific language governing permissions and | ||
16 | + * limitations under the License. | ||
17 | + * | ||
18 | +*/ | ||
19 | + | ||
20 | +'use strict'; | ||
21 | + | ||
22 | +/** | ||
23 | + * @file Embedded JavaScript templating engine. {@link http://ejs.co} | ||
24 | + * @author Matthew Eernisse <mde@fleegix.org> | ||
25 | + * @author Tiancheng "Timothy" Gu <timothygu99@gmail.com> | ||
26 | + * @project EJS | ||
27 | + * @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0} | ||
28 | + */ | ||
29 | + | ||
30 | +/** | ||
31 | + * EJS internal functions. | ||
32 | + * | ||
33 | + * Technically this "module" lies in the same file as {@link module:ejs}, for | ||
34 | + * the sake of organization all the private functions re grouped into this | ||
35 | + * module. | ||
36 | + * | ||
37 | + * @module ejs-internal | ||
38 | + * @private | ||
39 | + */ | ||
40 | + | ||
41 | +/** | ||
42 | + * Embedded JavaScript templating engine. | ||
43 | + * | ||
44 | + * @module ejs | ||
45 | + * @public | ||
46 | + */ | ||
47 | + | ||
48 | +var fs = require('fs'); | ||
49 | +var path = require('path'); | ||
50 | +var utils = require('./utils'); | ||
51 | + | ||
52 | +var scopeOptionWarned = false; | ||
53 | +/** @type {string} */ | ||
54 | +var _VERSION_STRING = require('../package.json').version; | ||
55 | +var _DEFAULT_OPEN_DELIMITER = '<'; | ||
56 | +var _DEFAULT_CLOSE_DELIMITER = '>'; | ||
57 | +var _DEFAULT_DELIMITER = '%'; | ||
58 | +var _DEFAULT_LOCALS_NAME = 'locals'; | ||
59 | +var _NAME = 'ejs'; | ||
60 | +var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'; | ||
61 | +var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug', | ||
62 | + 'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async']; | ||
63 | +// We don't allow 'cache' option to be passed in the data obj for | ||
64 | +// the normal `render` call, but this is where Express 2 & 3 put it | ||
65 | +// so we make an exception for `renderFile` | ||
66 | +var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache'); | ||
67 | +var _BOM = /^\uFEFF/; | ||
68 | + | ||
69 | +/** | ||
70 | + * EJS template function cache. This can be a LRU object from lru-cache NPM | ||
71 | + * module. By default, it is {@link module:utils.cache}, a simple in-process | ||
72 | + * cache that grows continuously. | ||
73 | + * | ||
74 | + * @type {Cache} | ||
75 | + */ | ||
76 | + | ||
77 | +exports.cache = utils.cache; | ||
78 | + | ||
79 | +/** | ||
80 | + * Custom file loader. Useful for template preprocessing or restricting access | ||
81 | + * to a certain part of the filesystem. | ||
82 | + * | ||
83 | + * @type {fileLoader} | ||
84 | + */ | ||
85 | + | ||
86 | +exports.fileLoader = fs.readFileSync; | ||
87 | + | ||
88 | +/** | ||
89 | + * Name of the object containing the locals. | ||
90 | + * | ||
91 | + * This variable is overridden by {@link Options}`.localsName` if it is not | ||
92 | + * `undefined`. | ||
93 | + * | ||
94 | + * @type {String} | ||
95 | + * @public | ||
96 | + */ | ||
97 | + | ||
98 | +exports.localsName = _DEFAULT_LOCALS_NAME; | ||
99 | + | ||
100 | +/** | ||
101 | + * Promise implementation -- defaults to the native implementation if available | ||
102 | + * This is mostly just for testability | ||
103 | + * | ||
104 | + * @type {PromiseConstructorLike} | ||
105 | + * @public | ||
106 | + */ | ||
107 | + | ||
108 | +exports.promiseImpl = (new Function('return this;'))().Promise; | ||
109 | + | ||
110 | +/** | ||
111 | + * Get the path to the included file from the parent file path and the | ||
112 | + * specified path. | ||
113 | + * | ||
114 | + * @param {String} name specified path | ||
115 | + * @param {String} filename parent file path | ||
116 | + * @param {Boolean} [isDir=false] whether the parent file path is a directory | ||
117 | + * @return {String} | ||
118 | + */ | ||
119 | +exports.resolveInclude = function(name, filename, isDir) { | ||
120 | + var dirname = path.dirname; | ||
121 | + var extname = path.extname; | ||
122 | + var resolve = path.resolve; | ||
123 | + var includePath = resolve(isDir ? filename : dirname(filename), name); | ||
124 | + var ext = extname(name); | ||
125 | + if (!ext) { | ||
126 | + includePath += '.ejs'; | ||
127 | + } | ||
128 | + return includePath; | ||
129 | +}; | ||
130 | + | ||
131 | +/** | ||
132 | + * Try to resolve file path on multiple directories | ||
133 | + * | ||
134 | + * @param {String} name specified path | ||
135 | + * @param {Array<String>} paths list of possible parent directory paths | ||
136 | + * @return {String} | ||
137 | + */ | ||
138 | +function resolvePaths(name, paths) { | ||
139 | + var filePath; | ||
140 | + if (paths.some(function (v) { | ||
141 | + filePath = exports.resolveInclude(name, v, true); | ||
142 | + return fs.existsSync(filePath); | ||
143 | + })) { | ||
144 | + return filePath; | ||
145 | + } | ||
146 | +} | ||
147 | + | ||
148 | +/** | ||
149 | + * Get the path to the included file by Options | ||
150 | + * | ||
151 | + * @param {String} path specified path | ||
152 | + * @param {Options} options compilation options | ||
153 | + * @return {String} | ||
154 | + */ | ||
155 | +function getIncludePath(path, options) { | ||
156 | + var includePath; | ||
157 | + var filePath; | ||
158 | + var views = options.views; | ||
159 | + var match = /^[A-Za-z]+:\\|^\//.exec(path); | ||
160 | + | ||
161 | + // Abs path | ||
162 | + if (match && match.length) { | ||
163 | + path = path.replace(/^\/*/, ''); | ||
164 | + if (Array.isArray(options.root)) { | ||
165 | + includePath = resolvePaths(path, options.root); | ||
166 | + } else { | ||
167 | + includePath = exports.resolveInclude(path, options.root || '/', true); | ||
168 | + } | ||
169 | + } | ||
170 | + // Relative paths | ||
171 | + else { | ||
172 | + // Look relative to a passed filename first | ||
173 | + if (options.filename) { | ||
174 | + filePath = exports.resolveInclude(path, options.filename); | ||
175 | + if (fs.existsSync(filePath)) { | ||
176 | + includePath = filePath; | ||
177 | + } | ||
178 | + } | ||
179 | + // Then look in any views directories | ||
180 | + if (!includePath && Array.isArray(views)) { | ||
181 | + includePath = resolvePaths(path, views); | ||
182 | + } | ||
183 | + if (!includePath && typeof options.includer !== 'function') { | ||
184 | + throw new Error('Could not find the include file "' + | ||
185 | + options.escapeFunction(path) + '"'); | ||
186 | + } | ||
187 | + } | ||
188 | + return includePath; | ||
189 | +} | ||
190 | + | ||
191 | +/** | ||
192 | + * Get the template from a string or a file, either compiled on-the-fly or | ||
193 | + * read from cache (if enabled), and cache the template if needed. | ||
194 | + * | ||
195 | + * If `template` is not set, the file specified in `options.filename` will be | ||
196 | + * read. | ||
197 | + * | ||
198 | + * If `options.cache` is true, this function reads the file from | ||
199 | + * `options.filename` so it must be set prior to calling this function. | ||
200 | + * | ||
201 | + * @memberof module:ejs-internal | ||
202 | + * @param {Options} options compilation options | ||
203 | + * @param {String} [template] template source | ||
204 | + * @return {(TemplateFunction|ClientFunction)} | ||
205 | + * Depending on the value of `options.client`, either type might be returned. | ||
206 | + * @static | ||
207 | + */ | ||
208 | + | ||
209 | +function handleCache(options, template) { | ||
210 | + var func; | ||
211 | + var filename = options.filename; | ||
212 | + var hasTemplate = arguments.length > 1; | ||
213 | + | ||
214 | + if (options.cache) { | ||
215 | + if (!filename) { | ||
216 | + throw new Error('cache option requires a filename'); | ||
217 | + } | ||
218 | + func = exports.cache.get(filename); | ||
219 | + if (func) { | ||
220 | + return func; | ||
221 | + } | ||
222 | + if (!hasTemplate) { | ||
223 | + template = fileLoader(filename).toString().replace(_BOM, ''); | ||
224 | + } | ||
225 | + } | ||
226 | + else if (!hasTemplate) { | ||
227 | + // istanbul ignore if: should not happen at all | ||
228 | + if (!filename) { | ||
229 | + throw new Error('Internal EJS error: no file name or template ' | ||
230 | + + 'provided'); | ||
231 | + } | ||
232 | + template = fileLoader(filename).toString().replace(_BOM, ''); | ||
233 | + } | ||
234 | + func = exports.compile(template, options); | ||
235 | + if (options.cache) { | ||
236 | + exports.cache.set(filename, func); | ||
237 | + } | ||
238 | + return func; | ||
239 | +} | ||
240 | + | ||
241 | +/** | ||
242 | + * Try calling handleCache with the given options and data and call the | ||
243 | + * callback with the result. If an error occurs, call the callback with | ||
244 | + * the error. Used by renderFile(). | ||
245 | + * | ||
246 | + * @memberof module:ejs-internal | ||
247 | + * @param {Options} options compilation options | ||
248 | + * @param {Object} data template data | ||
249 | + * @param {RenderFileCallback} cb callback | ||
250 | + * @static | ||
251 | + */ | ||
252 | + | ||
253 | +function tryHandleCache(options, data, cb) { | ||
254 | + var result; | ||
255 | + if (!cb) { | ||
256 | + if (typeof exports.promiseImpl == 'function') { | ||
257 | + return new exports.promiseImpl(function (resolve, reject) { | ||
258 | + try { | ||
259 | + result = handleCache(options)(data); | ||
260 | + resolve(result); | ||
261 | + } | ||
262 | + catch (err) { | ||
263 | + reject(err); | ||
264 | + } | ||
265 | + }); | ||
266 | + } | ||
267 | + else { | ||
268 | + throw new Error('Please provide a callback function'); | ||
269 | + } | ||
270 | + } | ||
271 | + else { | ||
272 | + try { | ||
273 | + result = handleCache(options)(data); | ||
274 | + } | ||
275 | + catch (err) { | ||
276 | + return cb(err); | ||
277 | + } | ||
278 | + | ||
279 | + cb(null, result); | ||
280 | + } | ||
281 | +} | ||
282 | + | ||
283 | +/** | ||
284 | + * fileLoader is independent | ||
285 | + * | ||
286 | + * @param {String} filePath ejs file path. | ||
287 | + * @return {String} The contents of the specified file. | ||
288 | + * @static | ||
289 | + */ | ||
290 | + | ||
291 | +function fileLoader(filePath){ | ||
292 | + return exports.fileLoader(filePath); | ||
293 | +} | ||
294 | + | ||
295 | +/** | ||
296 | + * Get the template function. | ||
297 | + * | ||
298 | + * If `options.cache` is `true`, then the template is cached. | ||
299 | + * | ||
300 | + * @memberof module:ejs-internal | ||
301 | + * @param {String} path path for the specified file | ||
302 | + * @param {Options} options compilation options | ||
303 | + * @return {(TemplateFunction|ClientFunction)} | ||
304 | + * Depending on the value of `options.client`, either type might be returned | ||
305 | + * @static | ||
306 | + */ | ||
307 | + | ||
308 | +function includeFile(path, options) { | ||
309 | + var opts = utils.shallowCopy({}, options); | ||
310 | + opts.filename = getIncludePath(path, opts); | ||
311 | + if (typeof options.includer === 'function') { | ||
312 | + var includerResult = options.includer(path, opts.filename); | ||
313 | + if (includerResult) { | ||
314 | + if (includerResult.filename) { | ||
315 | + opts.filename = includerResult.filename; | ||
316 | + } | ||
317 | + if (includerResult.template) { | ||
318 | + return handleCache(opts, includerResult.template); | ||
319 | + } | ||
320 | + } | ||
321 | + } | ||
322 | + return handleCache(opts); | ||
323 | +} | ||
324 | + | ||
325 | +/** | ||
326 | + * Re-throw the given `err` in context to the `str` of ejs, `filename`, and | ||
327 | + * `lineno`. | ||
328 | + * | ||
329 | + * @implements {RethrowCallback} | ||
330 | + * @memberof module:ejs-internal | ||
331 | + * @param {Error} err Error object | ||
332 | + * @param {String} str EJS source | ||
333 | + * @param {String} flnm file name of the EJS file | ||
334 | + * @param {Number} lineno line number of the error | ||
335 | + * @param {EscapeCallback} esc | ||
336 | + * @static | ||
337 | + */ | ||
338 | + | ||
339 | +function rethrow(err, str, flnm, lineno, esc) { | ||
340 | + var lines = str.split('\n'); | ||
341 | + var start = Math.max(lineno - 3, 0); | ||
342 | + var end = Math.min(lines.length, lineno + 3); | ||
343 | + var filename = esc(flnm); | ||
344 | + // Error context | ||
345 | + var context = lines.slice(start, end).map(function (line, i){ | ||
346 | + var curr = i + start + 1; | ||
347 | + return (curr == lineno ? ' >> ' : ' ') | ||
348 | + + curr | ||
349 | + + '| ' | ||
350 | + + line; | ||
351 | + }).join('\n'); | ||
352 | + | ||
353 | + // Alter exception message | ||
354 | + err.path = filename; | ||
355 | + err.message = (filename || 'ejs') + ':' | ||
356 | + + lineno + '\n' | ||
357 | + + context + '\n\n' | ||
358 | + + err.message; | ||
359 | + | ||
360 | + throw err; | ||
361 | +} | ||
362 | + | ||
363 | +function stripSemi(str){ | ||
364 | + return str.replace(/;(\s*$)/, '$1'); | ||
365 | +} | ||
366 | + | ||
367 | +/** | ||
368 | + * Compile the given `str` of ejs into a template function. | ||
369 | + * | ||
370 | + * @param {String} template EJS template | ||
371 | + * | ||
372 | + * @param {Options} [opts] compilation options | ||
373 | + * | ||
374 | + * @return {(TemplateFunction|ClientFunction)} | ||
375 | + * Depending on the value of `opts.client`, either type might be returned. | ||
376 | + * Note that the return type of the function also depends on the value of `opts.async`. | ||
377 | + * @public | ||
378 | + */ | ||
379 | + | ||
380 | +exports.compile = function compile(template, opts) { | ||
381 | + var templ; | ||
382 | + | ||
383 | + // v1 compat | ||
384 | + // 'scope' is 'context' | ||
385 | + // FIXME: Remove this in a future version | ||
386 | + if (opts && opts.scope) { | ||
387 | + if (!scopeOptionWarned){ | ||
388 | + console.warn('`scope` option is deprecated and will be removed in EJS 3'); | ||
389 | + scopeOptionWarned = true; | ||
390 | + } | ||
391 | + if (!opts.context) { | ||
392 | + opts.context = opts.scope; | ||
393 | + } | ||
394 | + delete opts.scope; | ||
395 | + } | ||
396 | + templ = new Template(template, opts); | ||
397 | + return templ.compile(); | ||
398 | +}; | ||
399 | + | ||
400 | +/** | ||
401 | + * Render the given `template` of ejs. | ||
402 | + * | ||
403 | + * If you would like to include options but not data, you need to explicitly | ||
404 | + * call this function with `data` being an empty object or `null`. | ||
405 | + * | ||
406 | + * @param {String} template EJS template | ||
407 | + * @param {Object} [data={}] template data | ||
408 | + * @param {Options} [opts={}] compilation and rendering options | ||
409 | + * @return {(String|Promise<String>)} | ||
410 | + * Return value type depends on `opts.async`. | ||
411 | + * @public | ||
412 | + */ | ||
413 | + | ||
414 | +exports.render = function (template, d, o) { | ||
415 | + var data = d || {}; | ||
416 | + var opts = o || {}; | ||
417 | + | ||
418 | + // No options object -- if there are optiony names | ||
419 | + // in the data, copy them to options | ||
420 | + if (arguments.length == 2) { | ||
421 | + utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA); | ||
422 | + } | ||
423 | + | ||
424 | + return handleCache(opts, template)(data); | ||
425 | +}; | ||
426 | + | ||
427 | +/** | ||
428 | + * Render an EJS file at the given `path` and callback `cb(err, str)`. | ||
429 | + * | ||
430 | + * If you would like to include options but not data, you need to explicitly | ||
431 | + * call this function with `data` being an empty object or `null`. | ||
432 | + * | ||
433 | + * @param {String} path path to the EJS file | ||
434 | + * @param {Object} [data={}] template data | ||
435 | + * @param {Options} [opts={}] compilation and rendering options | ||
436 | + * @param {RenderFileCallback} cb callback | ||
437 | + * @public | ||
438 | + */ | ||
439 | + | ||
440 | +exports.renderFile = function () { | ||
441 | + var args = Array.prototype.slice.call(arguments); | ||
442 | + var filename = args.shift(); | ||
443 | + var cb; | ||
444 | + var opts = {filename: filename}; | ||
445 | + var data; | ||
446 | + var viewOpts; | ||
447 | + | ||
448 | + // Do we have a callback? | ||
449 | + if (typeof arguments[arguments.length - 1] == 'function') { | ||
450 | + cb = args.pop(); | ||
451 | + } | ||
452 | + // Do we have data/opts? | ||
453 | + if (args.length) { | ||
454 | + // Should always have data obj | ||
455 | + data = args.shift(); | ||
456 | + // Normal passed opts (data obj + opts obj) | ||
457 | + if (args.length) { | ||
458 | + // Use shallowCopy so we don't pollute passed in opts obj with new vals | ||
459 | + utils.shallowCopy(opts, args.pop()); | ||
460 | + } | ||
461 | + // Special casing for Express (settings + opts-in-data) | ||
462 | + else { | ||
463 | + // Express 3 and 4 | ||
464 | + if (data.settings) { | ||
465 | + // Pull a few things from known locations | ||
466 | + if (data.settings.views) { | ||
467 | + opts.views = data.settings.views; | ||
468 | + } | ||
469 | + if (data.settings['view cache']) { | ||
470 | + opts.cache = true; | ||
471 | + } | ||
472 | + // Undocumented after Express 2, but still usable, esp. for | ||
473 | + // items that are unsafe to be passed along with data, like `root` | ||
474 | + viewOpts = data.settings['view options']; | ||
475 | + if (viewOpts) { | ||
476 | + utils.shallowCopy(opts, viewOpts); | ||
477 | + } | ||
478 | + } | ||
479 | + // Express 2 and lower, values set in app.locals, or people who just | ||
480 | + // want to pass options in their data. NOTE: These values will override | ||
481 | + // anything previously set in settings or settings['view options'] | ||
482 | + utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS); | ||
483 | + } | ||
484 | + opts.filename = filename; | ||
485 | + } | ||
486 | + else { | ||
487 | + data = {}; | ||
488 | + } | ||
489 | + | ||
490 | + return tryHandleCache(opts, data, cb); | ||
491 | +}; | ||
492 | + | ||
493 | +/** | ||
494 | + * Clear intermediate JavaScript cache. Calls {@link Cache#reset}. | ||
495 | + * @public | ||
496 | + */ | ||
497 | + | ||
498 | +/** | ||
499 | + * EJS template class | ||
500 | + * @public | ||
501 | + */ | ||
502 | +exports.Template = Template; | ||
503 | + | ||
504 | +exports.clearCache = function () { | ||
505 | + exports.cache.reset(); | ||
506 | +}; | ||
507 | + | ||
508 | +function Template(text, opts) { | ||
509 | + opts = opts || {}; | ||
510 | + var options = {}; | ||
511 | + this.templateText = text; | ||
512 | + /** @type {string | null} */ | ||
513 | + this.mode = null; | ||
514 | + this.truncate = false; | ||
515 | + this.currentLine = 1; | ||
516 | + this.source = ''; | ||
517 | + options.client = opts.client || false; | ||
518 | + options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML; | ||
519 | + options.compileDebug = opts.compileDebug !== false; | ||
520 | + options.debug = !!opts.debug; | ||
521 | + options.filename = opts.filename; | ||
522 | + options.openDelimiter = opts.openDelimiter || exports.openDelimiter || _DEFAULT_OPEN_DELIMITER; | ||
523 | + options.closeDelimiter = opts.closeDelimiter || exports.closeDelimiter || _DEFAULT_CLOSE_DELIMITER; | ||
524 | + options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER; | ||
525 | + options.strict = opts.strict || false; | ||
526 | + options.context = opts.context; | ||
527 | + options.cache = opts.cache || false; | ||
528 | + options.rmWhitespace = opts.rmWhitespace; | ||
529 | + options.root = opts.root; | ||
530 | + options.includer = opts.includer; | ||
531 | + options.outputFunctionName = opts.outputFunctionName; | ||
532 | + options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME; | ||
533 | + options.views = opts.views; | ||
534 | + options.async = opts.async; | ||
535 | + options.destructuredLocals = opts.destructuredLocals; | ||
536 | + options.legacyInclude = typeof opts.legacyInclude != 'undefined' ? !!opts.legacyInclude : true; | ||
537 | + | ||
538 | + if (options.strict) { | ||
539 | + options._with = false; | ||
540 | + } | ||
541 | + else { | ||
542 | + options._with = typeof opts._with != 'undefined' ? opts._with : true; | ||
543 | + } | ||
544 | + | ||
545 | + this.opts = options; | ||
546 | + | ||
547 | + this.regex = this.createRegex(); | ||
548 | +} | ||
549 | + | ||
550 | +Template.modes = { | ||
551 | + EVAL: 'eval', | ||
552 | + ESCAPED: 'escaped', | ||
553 | + RAW: 'raw', | ||
554 | + COMMENT: 'comment', | ||
555 | + LITERAL: 'literal' | ||
556 | +}; | ||
557 | + | ||
558 | +Template.prototype = { | ||
559 | + createRegex: function () { | ||
560 | + var str = _REGEX_STRING; | ||
561 | + var delim = utils.escapeRegExpChars(this.opts.delimiter); | ||
562 | + var open = utils.escapeRegExpChars(this.opts.openDelimiter); | ||
563 | + var close = utils.escapeRegExpChars(this.opts.closeDelimiter); | ||
564 | + str = str.replace(/%/g, delim) | ||
565 | + .replace(/</g, open) | ||
566 | + .replace(/>/g, close); | ||
567 | + return new RegExp(str); | ||
568 | + }, | ||
569 | + | ||
570 | + compile: function () { | ||
571 | + /** @type {string} */ | ||
572 | + var src; | ||
573 | + /** @type {ClientFunction} */ | ||
574 | + var fn; | ||
575 | + var opts = this.opts; | ||
576 | + var prepended = ''; | ||
577 | + var appended = ''; | ||
578 | + /** @type {EscapeCallback} */ | ||
579 | + var escapeFn = opts.escapeFunction; | ||
580 | + /** @type {FunctionConstructor} */ | ||
581 | + var ctor; | ||
582 | + /** @type {string} */ | ||
583 | + var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : 'undefined'; | ||
584 | + | ||
585 | + if (!this.source) { | ||
586 | + this.generateSource(); | ||
587 | + prepended += | ||
588 | + ' var __output = "";\n' + | ||
589 | + ' function __append(s) { if (s !== undefined && s !== null) __output += s }\n'; | ||
590 | + if (opts.outputFunctionName) { | ||
591 | + prepended += ' var ' + opts.outputFunctionName + ' = __append;' + '\n'; | ||
592 | + } | ||
593 | + if (opts.destructuredLocals && opts.destructuredLocals.length) { | ||
594 | + var destructuring = ' var __locals = (' + opts.localsName + ' || {}),\n'; | ||
595 | + for (var i = 0; i < opts.destructuredLocals.length; i++) { | ||
596 | + var name = opts.destructuredLocals[i]; | ||
597 | + if (i > 0) { | ||
598 | + destructuring += ',\n '; | ||
599 | + } | ||
600 | + destructuring += name + ' = __locals.' + name; | ||
601 | + } | ||
602 | + prepended += destructuring + ';\n'; | ||
603 | + } | ||
604 | + if (opts._with !== false) { | ||
605 | + prepended += ' with (' + opts.localsName + ' || {}) {' + '\n'; | ||
606 | + appended += ' }' + '\n'; | ||
607 | + } | ||
608 | + appended += ' return __output;' + '\n'; | ||
609 | + this.source = prepended + this.source + appended; | ||
610 | + } | ||
611 | + | ||
612 | + if (opts.compileDebug) { | ||
613 | + src = 'var __line = 1' + '\n' | ||
614 | + + ' , __lines = ' + JSON.stringify(this.templateText) + '\n' | ||
615 | + + ' , __filename = ' + sanitizedFilename + ';' + '\n' | ||
616 | + + 'try {' + '\n' | ||
617 | + + this.source | ||
618 | + + '} catch (e) {' + '\n' | ||
619 | + + ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n' | ||
620 | + + '}' + '\n'; | ||
621 | + } | ||
622 | + else { | ||
623 | + src = this.source; | ||
624 | + } | ||
625 | + | ||
626 | + if (opts.client) { | ||
627 | + src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src; | ||
628 | + if (opts.compileDebug) { | ||
629 | + src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src; | ||
630 | + } | ||
631 | + } | ||
632 | + | ||
633 | + if (opts.strict) { | ||
634 | + src = '"use strict";\n' + src; | ||
635 | + } | ||
636 | + if (opts.debug) { | ||
637 | + console.log(src); | ||
638 | + } | ||
639 | + if (opts.compileDebug && opts.filename) { | ||
640 | + src = src + '\n' | ||
641 | + + '//# sourceURL=' + sanitizedFilename + '\n'; | ||
642 | + } | ||
643 | + | ||
644 | + try { | ||
645 | + if (opts.async) { | ||
646 | + // Have to use generated function for this, since in envs without support, | ||
647 | + // it breaks in parsing | ||
648 | + try { | ||
649 | + ctor = (new Function('return (async function(){}).constructor;'))(); | ||
650 | + } | ||
651 | + catch(e) { | ||
652 | + if (e instanceof SyntaxError) { | ||
653 | + throw new Error('This environment does not support async/await'); | ||
654 | + } | ||
655 | + else { | ||
656 | + throw e; | ||
657 | + } | ||
658 | + } | ||
659 | + } | ||
660 | + else { | ||
661 | + ctor = Function; | ||
662 | + } | ||
663 | + fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src); | ||
664 | + } | ||
665 | + catch(e) { | ||
666 | + // istanbul ignore else | ||
667 | + if (e instanceof SyntaxError) { | ||
668 | + if (opts.filename) { | ||
669 | + e.message += ' in ' + opts.filename; | ||
670 | + } | ||
671 | + e.message += ' while compiling ejs\n\n'; | ||
672 | + e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n'; | ||
673 | + e.message += 'https://github.com/RyanZim/EJS-Lint'; | ||
674 | + if (!opts.async) { | ||
675 | + e.message += '\n'; | ||
676 | + e.message += 'Or, if you meant to create an async function, pass `async: true` as an option.'; | ||
677 | + } | ||
678 | + } | ||
679 | + throw e; | ||
680 | + } | ||
681 | + | ||
682 | + // Return a callable function which will execute the function | ||
683 | + // created by the source-code, with the passed data as locals | ||
684 | + // Adds a local `include` function which allows full recursive include | ||
685 | + var returnedFn = opts.client ? fn : function anonymous(data) { | ||
686 | + var include = function (path, includeData) { | ||
687 | + var d = utils.shallowCopy({}, data); | ||
688 | + if (includeData) { | ||
689 | + d = utils.shallowCopy(d, includeData); | ||
690 | + } | ||
691 | + return includeFile(path, opts)(d); | ||
692 | + }; | ||
693 | + return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]); | ||
694 | + }; | ||
695 | + if (opts.filename && typeof Object.defineProperty === 'function') { | ||
696 | + var filename = opts.filename; | ||
697 | + var basename = path.basename(filename, path.extname(filename)); | ||
698 | + try { | ||
699 | + Object.defineProperty(returnedFn, 'name', { | ||
700 | + value: basename, | ||
701 | + writable: false, | ||
702 | + enumerable: false, | ||
703 | + configurable: true | ||
704 | + }); | ||
705 | + } catch (e) {/* ignore */} | ||
706 | + } | ||
707 | + return returnedFn; | ||
708 | + }, | ||
709 | + | ||
710 | + generateSource: function () { | ||
711 | + var opts = this.opts; | ||
712 | + | ||
713 | + if (opts.rmWhitespace) { | ||
714 | + // Have to use two separate replace here as `^` and `$` operators don't | ||
715 | + // work well with `\r` and empty lines don't work well with the `m` flag. | ||
716 | + this.templateText = | ||
717 | + this.templateText.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, ''); | ||
718 | + } | ||
719 | + | ||
720 | + // Slurp spaces and tabs before <%_ and after _%> | ||
721 | + this.templateText = | ||
722 | + this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>'); | ||
723 | + | ||
724 | + var self = this; | ||
725 | + var matches = this.parseTemplateText(); | ||
726 | + var d = this.opts.delimiter; | ||
727 | + var o = this.opts.openDelimiter; | ||
728 | + var c = this.opts.closeDelimiter; | ||
729 | + | ||
730 | + if (matches && matches.length) { | ||
731 | + matches.forEach(function (line, index) { | ||
732 | + var closing; | ||
733 | + // If this is an opening tag, check for closing tags | ||
734 | + // FIXME: May end up with some false positives here | ||
735 | + // Better to store modes as k/v with openDelimiter + delimiter as key | ||
736 | + // Then this can simply check against the map | ||
737 | + if ( line.indexOf(o + d) === 0 // If it is a tag | ||
738 | + && line.indexOf(o + d + d) !== 0) { // and is not escaped | ||
739 | + closing = matches[index + 2]; | ||
740 | + if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) { | ||
741 | + throw new Error('Could not find matching close tag for "' + line + '".'); | ||
742 | + } | ||
743 | + } | ||
744 | + self.scanLine(line); | ||
745 | + }); | ||
746 | + } | ||
747 | + | ||
748 | + }, | ||
749 | + | ||
750 | + parseTemplateText: function () { | ||
751 | + var str = this.templateText; | ||
752 | + var pat = this.regex; | ||
753 | + var result = pat.exec(str); | ||
754 | + var arr = []; | ||
755 | + var firstPos; | ||
756 | + | ||
757 | + while (result) { | ||
758 | + firstPos = result.index; | ||
759 | + | ||
760 | + if (firstPos !== 0) { | ||
761 | + arr.push(str.substring(0, firstPos)); | ||
762 | + str = str.slice(firstPos); | ||
763 | + } | ||
764 | + | ||
765 | + arr.push(result[0]); | ||
766 | + str = str.slice(result[0].length); | ||
767 | + result = pat.exec(str); | ||
768 | + } | ||
769 | + | ||
770 | + if (str) { | ||
771 | + arr.push(str); | ||
772 | + } | ||
773 | + | ||
774 | + return arr; | ||
775 | + }, | ||
776 | + | ||
777 | + _addOutput: function (line) { | ||
778 | + if (this.truncate) { | ||
779 | + // Only replace single leading linebreak in the line after | ||
780 | + // -%> tag -- this is the single, trailing linebreak | ||
781 | + // after the tag that the truncation mode replaces | ||
782 | + // Handle Win / Unix / old Mac linebreaks -- do the \r\n | ||
783 | + // combo first in the regex-or | ||
784 | + line = line.replace(/^(?:\r\n|\r|\n)/, ''); | ||
785 | + this.truncate = false; | ||
786 | + } | ||
787 | + if (!line) { | ||
788 | + return line; | ||
789 | + } | ||
790 | + | ||
791 | + // Preserve literal slashes | ||
792 | + line = line.replace(/\\/g, '\\\\'); | ||
793 | + | ||
794 | + // Convert linebreaks | ||
795 | + line = line.replace(/\n/g, '\\n'); | ||
796 | + line = line.replace(/\r/g, '\\r'); | ||
797 | + | ||
798 | + // Escape double-quotes | ||
799 | + // - this will be the delimiter during execution | ||
800 | + line = line.replace(/"/g, '\\"'); | ||
801 | + this.source += ' ; __append("' + line + '")' + '\n'; | ||
802 | + }, | ||
803 | + | ||
804 | + scanLine: function (line) { | ||
805 | + var self = this; | ||
806 | + var d = this.opts.delimiter; | ||
807 | + var o = this.opts.openDelimiter; | ||
808 | + var c = this.opts.closeDelimiter; | ||
809 | + var newLineCount = 0; | ||
810 | + | ||
811 | + newLineCount = (line.split('\n').length - 1); | ||
812 | + | ||
813 | + switch (line) { | ||
814 | + case o + d: | ||
815 | + case o + d + '_': | ||
816 | + this.mode = Template.modes.EVAL; | ||
817 | + break; | ||
818 | + case o + d + '=': | ||
819 | + this.mode = Template.modes.ESCAPED; | ||
820 | + break; | ||
821 | + case o + d + '-': | ||
822 | + this.mode = Template.modes.RAW; | ||
823 | + break; | ||
824 | + case o + d + '#': | ||
825 | + this.mode = Template.modes.COMMENT; | ||
826 | + break; | ||
827 | + case o + d + d: | ||
828 | + this.mode = Template.modes.LITERAL; | ||
829 | + this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n'; | ||
830 | + break; | ||
831 | + case d + d + c: | ||
832 | + this.mode = Template.modes.LITERAL; | ||
833 | + this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n'; | ||
834 | + break; | ||
835 | + case d + c: | ||
836 | + case '-' + d + c: | ||
837 | + case '_' + d + c: | ||
838 | + if (this.mode == Template.modes.LITERAL) { | ||
839 | + this._addOutput(line); | ||
840 | + } | ||
841 | + | ||
842 | + this.mode = null; | ||
843 | + this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0; | ||
844 | + break; | ||
845 | + default: | ||
846 | + // In script mode, depends on type of tag | ||
847 | + if (this.mode) { | ||
848 | + // If '//' is found without a line break, add a line break. | ||
849 | + switch (this.mode) { | ||
850 | + case Template.modes.EVAL: | ||
851 | + case Template.modes.ESCAPED: | ||
852 | + case Template.modes.RAW: | ||
853 | + if (line.lastIndexOf('//') > line.lastIndexOf('\n')) { | ||
854 | + line += '\n'; | ||
855 | + } | ||
856 | + } | ||
857 | + switch (this.mode) { | ||
858 | + // Just executing code | ||
859 | + case Template.modes.EVAL: | ||
860 | + this.source += ' ; ' + line + '\n'; | ||
861 | + break; | ||
862 | + // Exec, esc, and output | ||
863 | + case Template.modes.ESCAPED: | ||
864 | + this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n'; | ||
865 | + break; | ||
866 | + // Exec and output | ||
867 | + case Template.modes.RAW: | ||
868 | + this.source += ' ; __append(' + stripSemi(line) + ')' + '\n'; | ||
869 | + break; | ||
870 | + case Template.modes.COMMENT: | ||
871 | + // Do nothing | ||
872 | + break; | ||
873 | + // Literal <%% mode, append as raw output | ||
874 | + case Template.modes.LITERAL: | ||
875 | + this._addOutput(line); | ||
876 | + break; | ||
877 | + } | ||
878 | + } | ||
879 | + // In string mode, just add the output | ||
880 | + else { | ||
881 | + this._addOutput(line); | ||
882 | + } | ||
883 | + } | ||
884 | + | ||
885 | + if (self.opts.compileDebug && newLineCount) { | ||
886 | + this.currentLine += newLineCount; | ||
887 | + this.source += ' ; __line = ' + this.currentLine + '\n'; | ||
888 | + } | ||
889 | + } | ||
890 | +}; | ||
891 | + | ||
892 | +/** | ||
893 | + * Escape characters reserved in XML. | ||
894 | + * | ||
895 | + * This is simply an export of {@link module:utils.escapeXML}. | ||
896 | + * | ||
897 | + * If `markup` is `undefined` or `null`, the empty string is returned. | ||
898 | + * | ||
899 | + * @param {String} markup Input string | ||
900 | + * @return {String} Escaped string | ||
901 | + * @public | ||
902 | + * @func | ||
903 | + * */ | ||
904 | +exports.escapeXML = utils.escapeXML; | ||
905 | + | ||
906 | +/** | ||
907 | + * Express.js support. | ||
908 | + * | ||
909 | + * This is an alias for {@link module:ejs.renderFile}, in order to support | ||
910 | + * Express.js out-of-the-box. | ||
911 | + * | ||
912 | + * @func | ||
913 | + */ | ||
914 | + | ||
915 | +exports.__express = exports.renderFile; | ||
916 | + | ||
917 | +/** | ||
918 | + * Version of EJS. | ||
919 | + * | ||
920 | + * @readonly | ||
921 | + * @type {String} | ||
922 | + * @public | ||
923 | + */ | ||
924 | + | ||
925 | +exports.VERSION = _VERSION_STRING; | ||
926 | + | ||
927 | +/** | ||
928 | + * Name for detection of EJS. | ||
929 | + * | ||
930 | + * @readonly | ||
931 | + * @type {String} | ||
932 | + * @public | ||
933 | + */ | ||
934 | + | ||
935 | +exports.name = _NAME; | ||
936 | + | ||
937 | +/* istanbul ignore if */ | ||
938 | +if (typeof window != 'undefined') { | ||
939 | + window.ejs = exports; | ||
940 | +} | ||
941 | + | ||
942 | +},{"../package.json":6,"./utils":2,"fs":3,"path":4}],2:[function(require,module,exports){ | ||
943 | +/* | ||
944 | + * EJS Embedded JavaScript templates | ||
945 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
946 | + * | ||
947 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
948 | + * you may not use this file except in compliance with the License. | ||
949 | + * You may obtain a copy of the License at | ||
950 | + * | ||
951 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
952 | + * | ||
953 | + * Unless required by applicable law or agreed to in writing, software | ||
954 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
955 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
956 | + * See the License for the specific language governing permissions and | ||
957 | + * limitations under the License. | ||
958 | + * | ||
959 | +*/ | ||
960 | + | ||
961 | +/** | ||
962 | + * Private utility functions | ||
963 | + * @module utils | ||
964 | + * @private | ||
965 | + */ | ||
966 | + | ||
967 | +'use strict'; | ||
968 | + | ||
969 | +var regExpChars = /[|\\{}()[\]^$+*?.]/g; | ||
970 | + | ||
971 | +/** | ||
972 | + * Escape characters reserved in regular expressions. | ||
973 | + * | ||
974 | + * If `string` is `undefined` or `null`, the empty string is returned. | ||
975 | + * | ||
976 | + * @param {String} string Input string | ||
977 | + * @return {String} Escaped string | ||
978 | + * @static | ||
979 | + * @private | ||
980 | + */ | ||
981 | +exports.escapeRegExpChars = function (string) { | ||
982 | + // istanbul ignore if | ||
983 | + if (!string) { | ||
984 | + return ''; | ||
985 | + } | ||
986 | + return String(string).replace(regExpChars, '\\$&'); | ||
987 | +}; | ||
988 | + | ||
989 | +var _ENCODE_HTML_RULES = { | ||
990 | + '&': '&', | ||
991 | + '<': '<', | ||
992 | + '>': '>', | ||
993 | + '"': '"', | ||
994 | + "'": ''' | ||
995 | +}; | ||
996 | +var _MATCH_HTML = /[&<>'"]/g; | ||
997 | + | ||
998 | +function encode_char(c) { | ||
999 | + return _ENCODE_HTML_RULES[c] || c; | ||
1000 | +} | ||
1001 | + | ||
1002 | +/** | ||
1003 | + * Stringified version of constants used by {@link module:utils.escapeXML}. | ||
1004 | + * | ||
1005 | + * It is used in the process of generating {@link ClientFunction}s. | ||
1006 | + * | ||
1007 | + * @readonly | ||
1008 | + * @type {String} | ||
1009 | + */ | ||
1010 | + | ||
1011 | +var escapeFuncStr = | ||
1012 | + 'var _ENCODE_HTML_RULES = {\n' | ||
1013 | ++ ' "&": "&"\n' | ||
1014 | ++ ' , "<": "<"\n' | ||
1015 | ++ ' , ">": ">"\n' | ||
1016 | ++ ' , \'"\': """\n' | ||
1017 | ++ ' , "\'": "'"\n' | ||
1018 | ++ ' }\n' | ||
1019 | ++ ' , _MATCH_HTML = /[&<>\'"]/g;\n' | ||
1020 | ++ 'function encode_char(c) {\n' | ||
1021 | ++ ' return _ENCODE_HTML_RULES[c] || c;\n' | ||
1022 | ++ '};\n'; | ||
1023 | + | ||
1024 | +/** | ||
1025 | + * Escape characters reserved in XML. | ||
1026 | + * | ||
1027 | + * If `markup` is `undefined` or `null`, the empty string is returned. | ||
1028 | + * | ||
1029 | + * @implements {EscapeCallback} | ||
1030 | + * @param {String} markup Input string | ||
1031 | + * @return {String} Escaped string | ||
1032 | + * @static | ||
1033 | + * @private | ||
1034 | + */ | ||
1035 | + | ||
1036 | +exports.escapeXML = function (markup) { | ||
1037 | + return markup == undefined | ||
1038 | + ? '' | ||
1039 | + : String(markup) | ||
1040 | + .replace(_MATCH_HTML, encode_char); | ||
1041 | +}; | ||
1042 | +exports.escapeXML.toString = function () { | ||
1043 | + return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr; | ||
1044 | +}; | ||
1045 | + | ||
1046 | +/** | ||
1047 | + * Naive copy of properties from one object to another. | ||
1048 | + * Does not recurse into non-scalar properties | ||
1049 | + * Does not check to see if the property has a value before copying | ||
1050 | + * | ||
1051 | + * @param {Object} to Destination object | ||
1052 | + * @param {Object} from Source object | ||
1053 | + * @return {Object} Destination object | ||
1054 | + * @static | ||
1055 | + * @private | ||
1056 | + */ | ||
1057 | +exports.shallowCopy = function (to, from) { | ||
1058 | + from = from || {}; | ||
1059 | + for (var p in from) { | ||
1060 | + to[p] = from[p]; | ||
1061 | + } | ||
1062 | + return to; | ||
1063 | +}; | ||
1064 | + | ||
1065 | +/** | ||
1066 | + * Naive copy of a list of key names, from one object to another. | ||
1067 | + * Only copies property if it is actually defined | ||
1068 | + * Does not recurse into non-scalar properties | ||
1069 | + * | ||
1070 | + * @param {Object} to Destination object | ||
1071 | + * @param {Object} from Source object | ||
1072 | + * @param {Array} list List of properties to copy | ||
1073 | + * @return {Object} Destination object | ||
1074 | + * @static | ||
1075 | + * @private | ||
1076 | + */ | ||
1077 | +exports.shallowCopyFromList = function (to, from, list) { | ||
1078 | + for (var i = 0; i < list.length; i++) { | ||
1079 | + var p = list[i]; | ||
1080 | + if (typeof from[p] != 'undefined') { | ||
1081 | + to[p] = from[p]; | ||
1082 | + } | ||
1083 | + } | ||
1084 | + return to; | ||
1085 | +}; | ||
1086 | + | ||
1087 | +/** | ||
1088 | + * Simple in-process cache implementation. Does not implement limits of any | ||
1089 | + * sort. | ||
1090 | + * | ||
1091 | + * @implements {Cache} | ||
1092 | + * @static | ||
1093 | + * @private | ||
1094 | + */ | ||
1095 | +exports.cache = { | ||
1096 | + _data: {}, | ||
1097 | + set: function (key, val) { | ||
1098 | + this._data[key] = val; | ||
1099 | + }, | ||
1100 | + get: function (key) { | ||
1101 | + return this._data[key]; | ||
1102 | + }, | ||
1103 | + remove: function (key) { | ||
1104 | + delete this._data[key]; | ||
1105 | + }, | ||
1106 | + reset: function () { | ||
1107 | + this._data = {}; | ||
1108 | + } | ||
1109 | +}; | ||
1110 | + | ||
1111 | +/** | ||
1112 | + * Transforms hyphen case variable into camel case. | ||
1113 | + * | ||
1114 | + * @param {String} string Hyphen case string | ||
1115 | + * @return {String} Camel case string | ||
1116 | + * @static | ||
1117 | + * @private | ||
1118 | + */ | ||
1119 | +exports.hyphenToCamel = function (str) { | ||
1120 | + return str.replace(/-[a-z]/g, function (match) { return match[1].toUpperCase(); }); | ||
1121 | +}; | ||
1122 | + | ||
1123 | +},{}],3:[function(require,module,exports){ | ||
1124 | + | ||
1125 | +},{}],4:[function(require,module,exports){ | ||
1126 | +(function (process){ | ||
1127 | +// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1, | ||
1128 | +// backported and transplited with Babel, with backwards-compat fixes | ||
1129 | + | ||
1130 | +// Copyright Joyent, Inc. and other Node contributors. | ||
1131 | +// | ||
1132 | +// Permission is hereby granted, free of charge, to any person obtaining a | ||
1133 | +// copy of this software and associated documentation files (the | ||
1134 | +// "Software"), to deal in the Software without restriction, including | ||
1135 | +// without limitation the rights to use, copy, modify, merge, publish, | ||
1136 | +// distribute, sublicense, and/or sell copies of the Software, and to permit | ||
1137 | +// persons to whom the Software is furnished to do so, subject to the | ||
1138 | +// following conditions: | ||
1139 | +// | ||
1140 | +// The above copyright notice and this permission notice shall be included | ||
1141 | +// in all copies or substantial portions of the Software. | ||
1142 | +// | ||
1143 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
1144 | +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
1145 | +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
1146 | +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
1147 | +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
1148 | +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
1149 | +// USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
1150 | + | ||
1151 | +// resolves . and .. elements in a path array with directory names there | ||
1152 | +// must be no slashes, empty elements, or device names (c:\) in the array | ||
1153 | +// (so also no leading and trailing slashes - it does not distinguish | ||
1154 | +// relative and absolute paths) | ||
1155 | +function normalizeArray(parts, allowAboveRoot) { | ||
1156 | + // if the path tries to go above the root, `up` ends up > 0 | ||
1157 | + var up = 0; | ||
1158 | + for (var i = parts.length - 1; i >= 0; i--) { | ||
1159 | + var last = parts[i]; | ||
1160 | + if (last === '.') { | ||
1161 | + parts.splice(i, 1); | ||
1162 | + } else if (last === '..') { | ||
1163 | + parts.splice(i, 1); | ||
1164 | + up++; | ||
1165 | + } else if (up) { | ||
1166 | + parts.splice(i, 1); | ||
1167 | + up--; | ||
1168 | + } | ||
1169 | + } | ||
1170 | + | ||
1171 | + // if the path is allowed to go above the root, restore leading ..s | ||
1172 | + if (allowAboveRoot) { | ||
1173 | + for (; up--; up) { | ||
1174 | + parts.unshift('..'); | ||
1175 | + } | ||
1176 | + } | ||
1177 | + | ||
1178 | + return parts; | ||
1179 | +} | ||
1180 | + | ||
1181 | +// path.resolve([from ...], to) | ||
1182 | +// posix version | ||
1183 | +exports.resolve = function() { | ||
1184 | + var resolvedPath = '', | ||
1185 | + resolvedAbsolute = false; | ||
1186 | + | ||
1187 | + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | ||
1188 | + var path = (i >= 0) ? arguments[i] : process.cwd(); | ||
1189 | + | ||
1190 | + // Skip empty and invalid entries | ||
1191 | + if (typeof path !== 'string') { | ||
1192 | + throw new TypeError('Arguments to path.resolve must be strings'); | ||
1193 | + } else if (!path) { | ||
1194 | + continue; | ||
1195 | + } | ||
1196 | + | ||
1197 | + resolvedPath = path + '/' + resolvedPath; | ||
1198 | + resolvedAbsolute = path.charAt(0) === '/'; | ||
1199 | + } | ||
1200 | + | ||
1201 | + // At this point the path should be resolved to a full absolute path, but | ||
1202 | + // handle relative paths to be safe (might happen when process.cwd() fails) | ||
1203 | + | ||
1204 | + // Normalize the path | ||
1205 | + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { | ||
1206 | + return !!p; | ||
1207 | + }), !resolvedAbsolute).join('/'); | ||
1208 | + | ||
1209 | + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | ||
1210 | +}; | ||
1211 | + | ||
1212 | +// path.normalize(path) | ||
1213 | +// posix version | ||
1214 | +exports.normalize = function(path) { | ||
1215 | + var isAbsolute = exports.isAbsolute(path), | ||
1216 | + trailingSlash = substr(path, -1) === '/'; | ||
1217 | + | ||
1218 | + // Normalize the path | ||
1219 | + path = normalizeArray(filter(path.split('/'), function(p) { | ||
1220 | + return !!p; | ||
1221 | + }), !isAbsolute).join('/'); | ||
1222 | + | ||
1223 | + if (!path && !isAbsolute) { | ||
1224 | + path = '.'; | ||
1225 | + } | ||
1226 | + if (path && trailingSlash) { | ||
1227 | + path += '/'; | ||
1228 | + } | ||
1229 | + | ||
1230 | + return (isAbsolute ? '/' : '') + path; | ||
1231 | +}; | ||
1232 | + | ||
1233 | +// posix version | ||
1234 | +exports.isAbsolute = function(path) { | ||
1235 | + return path.charAt(0) === '/'; | ||
1236 | +}; | ||
1237 | + | ||
1238 | +// posix version | ||
1239 | +exports.join = function() { | ||
1240 | + var paths = Array.prototype.slice.call(arguments, 0); | ||
1241 | + return exports.normalize(filter(paths, function(p, index) { | ||
1242 | + if (typeof p !== 'string') { | ||
1243 | + throw new TypeError('Arguments to path.join must be strings'); | ||
1244 | + } | ||
1245 | + return p; | ||
1246 | + }).join('/')); | ||
1247 | +}; | ||
1248 | + | ||
1249 | + | ||
1250 | +// path.relative(from, to) | ||
1251 | +// posix version | ||
1252 | +exports.relative = function(from, to) { | ||
1253 | + from = exports.resolve(from).substr(1); | ||
1254 | + to = exports.resolve(to).substr(1); | ||
1255 | + | ||
1256 | + function trim(arr) { | ||
1257 | + var start = 0; | ||
1258 | + for (; start < arr.length; start++) { | ||
1259 | + if (arr[start] !== '') break; | ||
1260 | + } | ||
1261 | + | ||
1262 | + var end = arr.length - 1; | ||
1263 | + for (; end >= 0; end--) { | ||
1264 | + if (arr[end] !== '') break; | ||
1265 | + } | ||
1266 | + | ||
1267 | + if (start > end) return []; | ||
1268 | + return arr.slice(start, end - start + 1); | ||
1269 | + } | ||
1270 | + | ||
1271 | + var fromParts = trim(from.split('/')); | ||
1272 | + var toParts = trim(to.split('/')); | ||
1273 | + | ||
1274 | + var length = Math.min(fromParts.length, toParts.length); | ||
1275 | + var samePartsLength = length; | ||
1276 | + for (var i = 0; i < length; i++) { | ||
1277 | + if (fromParts[i] !== toParts[i]) { | ||
1278 | + samePartsLength = i; | ||
1279 | + break; | ||
1280 | + } | ||
1281 | + } | ||
1282 | + | ||
1283 | + var outputParts = []; | ||
1284 | + for (var i = samePartsLength; i < fromParts.length; i++) { | ||
1285 | + outputParts.push('..'); | ||
1286 | + } | ||
1287 | + | ||
1288 | + outputParts = outputParts.concat(toParts.slice(samePartsLength)); | ||
1289 | + | ||
1290 | + return outputParts.join('/'); | ||
1291 | +}; | ||
1292 | + | ||
1293 | +exports.sep = '/'; | ||
1294 | +exports.delimiter = ':'; | ||
1295 | + | ||
1296 | +exports.dirname = function (path) { | ||
1297 | + if (typeof path !== 'string') path = path + ''; | ||
1298 | + if (path.length === 0) return '.'; | ||
1299 | + var code = path.charCodeAt(0); | ||
1300 | + var hasRoot = code === 47 /*/*/; | ||
1301 | + var end = -1; | ||
1302 | + var matchedSlash = true; | ||
1303 | + for (var i = path.length - 1; i >= 1; --i) { | ||
1304 | + code = path.charCodeAt(i); | ||
1305 | + if (code === 47 /*/*/) { | ||
1306 | + if (!matchedSlash) { | ||
1307 | + end = i; | ||
1308 | + break; | ||
1309 | + } | ||
1310 | + } else { | ||
1311 | + // We saw the first non-path separator | ||
1312 | + matchedSlash = false; | ||
1313 | + } | ||
1314 | + } | ||
1315 | + | ||
1316 | + if (end === -1) return hasRoot ? '/' : '.'; | ||
1317 | + if (hasRoot && end === 1) { | ||
1318 | + // return '//'; | ||
1319 | + // Backwards-compat fix: | ||
1320 | + return '/'; | ||
1321 | + } | ||
1322 | + return path.slice(0, end); | ||
1323 | +}; | ||
1324 | + | ||
1325 | +function basename(path) { | ||
1326 | + if (typeof path !== 'string') path = path + ''; | ||
1327 | + | ||
1328 | + var start = 0; | ||
1329 | + var end = -1; | ||
1330 | + var matchedSlash = true; | ||
1331 | + var i; | ||
1332 | + | ||
1333 | + for (i = path.length - 1; i >= 0; --i) { | ||
1334 | + if (path.charCodeAt(i) === 47 /*/*/) { | ||
1335 | + // If we reached a path separator that was not part of a set of path | ||
1336 | + // separators at the end of the string, stop now | ||
1337 | + if (!matchedSlash) { | ||
1338 | + start = i + 1; | ||
1339 | + break; | ||
1340 | + } | ||
1341 | + } else if (end === -1) { | ||
1342 | + // We saw the first non-path separator, mark this as the end of our | ||
1343 | + // path component | ||
1344 | + matchedSlash = false; | ||
1345 | + end = i + 1; | ||
1346 | + } | ||
1347 | + } | ||
1348 | + | ||
1349 | + if (end === -1) return ''; | ||
1350 | + return path.slice(start, end); | ||
1351 | +} | ||
1352 | + | ||
1353 | +// Uses a mixed approach for backwards-compatibility, as ext behavior changed | ||
1354 | +// in new Node.js versions, so only basename() above is backported here | ||
1355 | +exports.basename = function (path, ext) { | ||
1356 | + var f = basename(path); | ||
1357 | + if (ext && f.substr(-1 * ext.length) === ext) { | ||
1358 | + f = f.substr(0, f.length - ext.length); | ||
1359 | + } | ||
1360 | + return f; | ||
1361 | +}; | ||
1362 | + | ||
1363 | +exports.extname = function (path) { | ||
1364 | + if (typeof path !== 'string') path = path + ''; | ||
1365 | + var startDot = -1; | ||
1366 | + var startPart = 0; | ||
1367 | + var end = -1; | ||
1368 | + var matchedSlash = true; | ||
1369 | + // Track the state of characters (if any) we see before our first dot and | ||
1370 | + // after any path separator we find | ||
1371 | + var preDotState = 0; | ||
1372 | + for (var i = path.length - 1; i >= 0; --i) { | ||
1373 | + var code = path.charCodeAt(i); | ||
1374 | + if (code === 47 /*/*/) { | ||
1375 | + // If we reached a path separator that was not part of a set of path | ||
1376 | + // separators at the end of the string, stop now | ||
1377 | + if (!matchedSlash) { | ||
1378 | + startPart = i + 1; | ||
1379 | + break; | ||
1380 | + } | ||
1381 | + continue; | ||
1382 | + } | ||
1383 | + if (end === -1) { | ||
1384 | + // We saw the first non-path separator, mark this as the end of our | ||
1385 | + // extension | ||
1386 | + matchedSlash = false; | ||
1387 | + end = i + 1; | ||
1388 | + } | ||
1389 | + if (code === 46 /*.*/) { | ||
1390 | + // If this is our first dot, mark it as the start of our extension | ||
1391 | + if (startDot === -1) | ||
1392 | + startDot = i; | ||
1393 | + else if (preDotState !== 1) | ||
1394 | + preDotState = 1; | ||
1395 | + } else if (startDot !== -1) { | ||
1396 | + // We saw a non-dot and non-path separator before our dot, so we should | ||
1397 | + // have a good chance at having a non-empty extension | ||
1398 | + preDotState = -1; | ||
1399 | + } | ||
1400 | + } | ||
1401 | + | ||
1402 | + if (startDot === -1 || end === -1 || | ||
1403 | + // We saw a non-dot character immediately before the dot | ||
1404 | + preDotState === 0 || | ||
1405 | + // The (right-most) trimmed path component is exactly '..' | ||
1406 | + preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { | ||
1407 | + return ''; | ||
1408 | + } | ||
1409 | + return path.slice(startDot, end); | ||
1410 | +}; | ||
1411 | + | ||
1412 | +function filter (xs, f) { | ||
1413 | + if (xs.filter) return xs.filter(f); | ||
1414 | + var res = []; | ||
1415 | + for (var i = 0; i < xs.length; i++) { | ||
1416 | + if (f(xs[i], i, xs)) res.push(xs[i]); | ||
1417 | + } | ||
1418 | + return res; | ||
1419 | +} | ||
1420 | + | ||
1421 | +// String.prototype.substr - negative index don't work in IE8 | ||
1422 | +var substr = 'ab'.substr(-1) === 'b' | ||
1423 | + ? function (str, start, len) { return str.substr(start, len) } | ||
1424 | + : function (str, start, len) { | ||
1425 | + if (start < 0) start = str.length + start; | ||
1426 | + return str.substr(start, len); | ||
1427 | + } | ||
1428 | +; | ||
1429 | + | ||
1430 | +}).call(this,require('_process')) | ||
1431 | +},{"_process":5}],5:[function(require,module,exports){ | ||
1432 | +// shim for using process in browser | ||
1433 | +var process = module.exports = {}; | ||
1434 | + | ||
1435 | +// cached from whatever global is present so that test runners that stub it | ||
1436 | +// don't break things. But we need to wrap it in a try catch in case it is | ||
1437 | +// wrapped in strict mode code which doesn't define any globals. It's inside a | ||
1438 | +// function because try/catches deoptimize in certain engines. | ||
1439 | + | ||
1440 | +var cachedSetTimeout; | ||
1441 | +var cachedClearTimeout; | ||
1442 | + | ||
1443 | +function defaultSetTimout() { | ||
1444 | + throw new Error('setTimeout has not been defined'); | ||
1445 | +} | ||
1446 | +function defaultClearTimeout () { | ||
1447 | + throw new Error('clearTimeout has not been defined'); | ||
1448 | +} | ||
1449 | +(function () { | ||
1450 | + try { | ||
1451 | + if (typeof setTimeout === 'function') { | ||
1452 | + cachedSetTimeout = setTimeout; | ||
1453 | + } else { | ||
1454 | + cachedSetTimeout = defaultSetTimout; | ||
1455 | + } | ||
1456 | + } catch (e) { | ||
1457 | + cachedSetTimeout = defaultSetTimout; | ||
1458 | + } | ||
1459 | + try { | ||
1460 | + if (typeof clearTimeout === 'function') { | ||
1461 | + cachedClearTimeout = clearTimeout; | ||
1462 | + } else { | ||
1463 | + cachedClearTimeout = defaultClearTimeout; | ||
1464 | + } | ||
1465 | + } catch (e) { | ||
1466 | + cachedClearTimeout = defaultClearTimeout; | ||
1467 | + } | ||
1468 | +} ()) | ||
1469 | +function runTimeout(fun) { | ||
1470 | + if (cachedSetTimeout === setTimeout) { | ||
1471 | + //normal enviroments in sane situations | ||
1472 | + return setTimeout(fun, 0); | ||
1473 | + } | ||
1474 | + // if setTimeout wasn't available but was latter defined | ||
1475 | + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { | ||
1476 | + cachedSetTimeout = setTimeout; | ||
1477 | + return setTimeout(fun, 0); | ||
1478 | + } | ||
1479 | + try { | ||
1480 | + // when when somebody has screwed with setTimeout but no I.E. maddness | ||
1481 | + return cachedSetTimeout(fun, 0); | ||
1482 | + } catch(e){ | ||
1483 | + try { | ||
1484 | + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | ||
1485 | + return cachedSetTimeout.call(null, fun, 0); | ||
1486 | + } catch(e){ | ||
1487 | + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error | ||
1488 | + return cachedSetTimeout.call(this, fun, 0); | ||
1489 | + } | ||
1490 | + } | ||
1491 | + | ||
1492 | + | ||
1493 | +} | ||
1494 | +function runClearTimeout(marker) { | ||
1495 | + if (cachedClearTimeout === clearTimeout) { | ||
1496 | + //normal enviroments in sane situations | ||
1497 | + return clearTimeout(marker); | ||
1498 | + } | ||
1499 | + // if clearTimeout wasn't available but was latter defined | ||
1500 | + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { | ||
1501 | + cachedClearTimeout = clearTimeout; | ||
1502 | + return clearTimeout(marker); | ||
1503 | + } | ||
1504 | + try { | ||
1505 | + // when when somebody has screwed with setTimeout but no I.E. maddness | ||
1506 | + return cachedClearTimeout(marker); | ||
1507 | + } catch (e){ | ||
1508 | + try { | ||
1509 | + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | ||
1510 | + return cachedClearTimeout.call(null, marker); | ||
1511 | + } catch (e){ | ||
1512 | + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. | ||
1513 | + // Some versions of I.E. have different rules for clearTimeout vs setTimeout | ||
1514 | + return cachedClearTimeout.call(this, marker); | ||
1515 | + } | ||
1516 | + } | ||
1517 | + | ||
1518 | + | ||
1519 | + | ||
1520 | +} | ||
1521 | +var queue = []; | ||
1522 | +var draining = false; | ||
1523 | +var currentQueue; | ||
1524 | +var queueIndex = -1; | ||
1525 | + | ||
1526 | +function cleanUpNextTick() { | ||
1527 | + if (!draining || !currentQueue) { | ||
1528 | + return; | ||
1529 | + } | ||
1530 | + draining = false; | ||
1531 | + if (currentQueue.length) { | ||
1532 | + queue = currentQueue.concat(queue); | ||
1533 | + } else { | ||
1534 | + queueIndex = -1; | ||
1535 | + } | ||
1536 | + if (queue.length) { | ||
1537 | + drainQueue(); | ||
1538 | + } | ||
1539 | +} | ||
1540 | + | ||
1541 | +function drainQueue() { | ||
1542 | + if (draining) { | ||
1543 | + return; | ||
1544 | + } | ||
1545 | + var timeout = runTimeout(cleanUpNextTick); | ||
1546 | + draining = true; | ||
1547 | + | ||
1548 | + var len = queue.length; | ||
1549 | + while(len) { | ||
1550 | + currentQueue = queue; | ||
1551 | + queue = []; | ||
1552 | + while (++queueIndex < len) { | ||
1553 | + if (currentQueue) { | ||
1554 | + currentQueue[queueIndex].run(); | ||
1555 | + } | ||
1556 | + } | ||
1557 | + queueIndex = -1; | ||
1558 | + len = queue.length; | ||
1559 | + } | ||
1560 | + currentQueue = null; | ||
1561 | + draining = false; | ||
1562 | + runClearTimeout(timeout); | ||
1563 | +} | ||
1564 | + | ||
1565 | +process.nextTick = function (fun) { | ||
1566 | + var args = new Array(arguments.length - 1); | ||
1567 | + if (arguments.length > 1) { | ||
1568 | + for (var i = 1; i < arguments.length; i++) { | ||
1569 | + args[i - 1] = arguments[i]; | ||
1570 | + } | ||
1571 | + } | ||
1572 | + queue.push(new Item(fun, args)); | ||
1573 | + if (queue.length === 1 && !draining) { | ||
1574 | + runTimeout(drainQueue); | ||
1575 | + } | ||
1576 | +}; | ||
1577 | + | ||
1578 | +// v8 likes predictible objects | ||
1579 | +function Item(fun, array) { | ||
1580 | + this.fun = fun; | ||
1581 | + this.array = array; | ||
1582 | +} | ||
1583 | +Item.prototype.run = function () { | ||
1584 | + this.fun.apply(null, this.array); | ||
1585 | +}; | ||
1586 | +process.title = 'browser'; | ||
1587 | +process.browser = true; | ||
1588 | +process.env = {}; | ||
1589 | +process.argv = []; | ||
1590 | +process.version = ''; // empty string to avoid regexp issues | ||
1591 | +process.versions = {}; | ||
1592 | + | ||
1593 | +function noop() {} | ||
1594 | + | ||
1595 | +process.on = noop; | ||
1596 | +process.addListener = noop; | ||
1597 | +process.once = noop; | ||
1598 | +process.off = noop; | ||
1599 | +process.removeListener = noop; | ||
1600 | +process.removeAllListeners = noop; | ||
1601 | +process.emit = noop; | ||
1602 | +process.prependListener = noop; | ||
1603 | +process.prependOnceListener = noop; | ||
1604 | + | ||
1605 | +process.listeners = function (name) { return [] } | ||
1606 | + | ||
1607 | +process.binding = function (name) { | ||
1608 | + throw new Error('process.binding is not supported'); | ||
1609 | +}; | ||
1610 | + | ||
1611 | +process.cwd = function () { return '/' }; | ||
1612 | +process.chdir = function (dir) { | ||
1613 | + throw new Error('process.chdir is not supported'); | ||
1614 | +}; | ||
1615 | +process.umask = function() { return 0; }; | ||
1616 | + | ||
1617 | +},{}],6:[function(require,module,exports){ | ||
1618 | +module.exports={ | ||
1619 | + "name": "ejs", | ||
1620 | + "description": "Embedded JavaScript templates", | ||
1621 | + "keywords": [ | ||
1622 | + "template", | ||
1623 | + "engine", | ||
1624 | + "ejs" | ||
1625 | + ], | ||
1626 | + "version": "3.1.6", | ||
1627 | + "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)", | ||
1628 | + "license": "Apache-2.0", | ||
1629 | + "bin": { | ||
1630 | + "ejs": "./bin/cli.js" | ||
1631 | + }, | ||
1632 | + "main": "./lib/ejs.js", | ||
1633 | + "jsdelivr": "ejs.min.js", | ||
1634 | + "unpkg": "ejs.min.js", | ||
1635 | + "repository": { | ||
1636 | + "type": "git", | ||
1637 | + "url": "git://github.com/mde/ejs.git" | ||
1638 | + }, | ||
1639 | + "bugs": "https://github.com/mde/ejs/issues", | ||
1640 | + "homepage": "https://github.com/mde/ejs", | ||
1641 | + "dependencies": { | ||
1642 | + "jake": "^10.6.1" | ||
1643 | + }, | ||
1644 | + "devDependencies": { | ||
1645 | + "browserify": "^16.5.1", | ||
1646 | + "eslint": "^6.8.0", | ||
1647 | + "git-directory-deploy": "^1.5.1", | ||
1648 | + "jsdoc": "^3.6.4", | ||
1649 | + "lru-cache": "^4.0.1", | ||
1650 | + "mocha": "^7.1.1", | ||
1651 | + "uglify-js": "^3.3.16" | ||
1652 | + }, | ||
1653 | + "engines": { | ||
1654 | + "node": ">=0.10.0" | ||
1655 | + }, | ||
1656 | + "scripts": { | ||
1657 | + "test": "mocha" | ||
1658 | + } | ||
1659 | +} | ||
1660 | + | ||
1661 | +},{}]},{},[1])(1) | ||
1662 | +}); |
node_modules/ejs/ejs.min.js
0 → 100644
1 | +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ejs=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){"use strict";var fs=require("fs");var path=require("path");var utils=require("./utils");var scopeOptionWarned=false;var _VERSION_STRING=require("../package.json").version;var _DEFAULT_OPEN_DELIMITER="<";var _DEFAULT_CLOSE_DELIMITER=">";var _DEFAULT_DELIMITER="%";var _DEFAULT_LOCALS_NAME="locals";var _NAME="ejs";var _REGEX_STRING="(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)";var _OPTS_PASSABLE_WITH_DATA=["delimiter","scope","context","debug","compileDebug","client","_with","rmWhitespace","strict","filename","async"];var _OPTS_PASSABLE_WITH_DATA_EXPRESS=_OPTS_PASSABLE_WITH_DATA.concat("cache");var _BOM=/^\uFEFF/;exports.cache=utils.cache;exports.fileLoader=fs.readFileSync;exports.localsName=_DEFAULT_LOCALS_NAME;exports.promiseImpl=new Function("return this;")().Promise;exports.resolveInclude=function(name,filename,isDir){var dirname=path.dirname;var extname=path.extname;var resolve=path.resolve;var includePath=resolve(isDir?filename:dirname(filename),name);var ext=extname(name);if(!ext){includePath+=".ejs"}return includePath};function resolvePaths(name,paths){var filePath;if(paths.some(function(v){filePath=exports.resolveInclude(name,v,true);return fs.existsSync(filePath)})){return filePath}}function getIncludePath(path,options){var includePath;var filePath;var views=options.views;var match=/^[A-Za-z]+:\\|^\//.exec(path);if(match&&match.length){path=path.replace(/^\/*/,"");if(Array.isArray(options.root)){includePath=resolvePaths(path,options.root)}else{includePath=exports.resolveInclude(path,options.root||"/",true)}}else{if(options.filename){filePath=exports.resolveInclude(path,options.filename);if(fs.existsSync(filePath)){includePath=filePath}}if(!includePath&&Array.isArray(views)){includePath=resolvePaths(path,views)}if(!includePath&&typeof options.includer!=="function"){throw new Error('Could not find the include file "'+options.escapeFunction(path)+'"')}}return includePath}function handleCache(options,template){var func;var filename=options.filename;var hasTemplate=arguments.length>1;if(options.cache){if(!filename){throw new Error("cache option requires a filename")}func=exports.cache.get(filename);if(func){return func}if(!hasTemplate){template=fileLoader(filename).toString().replace(_BOM,"")}}else if(!hasTemplate){if(!filename){throw new Error("Internal EJS error: no file name or template "+"provided")}template=fileLoader(filename).toString().replace(_BOM,"")}func=exports.compile(template,options);if(options.cache){exports.cache.set(filename,func)}return func}function tryHandleCache(options,data,cb){var result;if(!cb){if(typeof exports.promiseImpl=="function"){return new exports.promiseImpl(function(resolve,reject){try{result=handleCache(options)(data);resolve(result)}catch(err){reject(err)}})}else{throw new Error("Please provide a callback function")}}else{try{result=handleCache(options)(data)}catch(err){return cb(err)}cb(null,result)}}function fileLoader(filePath){return exports.fileLoader(filePath)}function includeFile(path,options){var opts=utils.shallowCopy({},options);opts.filename=getIncludePath(path,opts);if(typeof options.includer==="function"){var includerResult=options.includer(path,opts.filename);if(includerResult){if(includerResult.filename){opts.filename=includerResult.filename}if(includerResult.template){return handleCache(opts,includerResult.template)}}}return handleCache(opts)}function rethrow(err,str,flnm,lineno,esc){var lines=str.split("\n");var start=Math.max(lineno-3,0);var end=Math.min(lines.length,lineno+3);var filename=esc(flnm);var context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" >> ":" ")+curr+"| "+line}).join("\n");err.path=filename;err.message=(filename||"ejs")+":"+lineno+"\n"+context+"\n\n"+err.message;throw err}function stripSemi(str){return str.replace(/;(\s*$)/,"$1")}exports.compile=function compile(template,opts){var templ;if(opts&&opts.scope){if(!scopeOptionWarned){console.warn("`scope` option is deprecated and will be removed in EJS 3");scopeOptionWarned=true}if(!opts.context){opts.context=opts.scope}delete opts.scope}templ=new Template(template,opts);return templ.compile()};exports.render=function(template,d,o){var data=d||{};var opts=o||{};if(arguments.length==2){utils.shallowCopyFromList(opts,data,_OPTS_PASSABLE_WITH_DATA)}return handleCache(opts,template)(data)};exports.renderFile=function(){var args=Array.prototype.slice.call(arguments);var filename=args.shift();var cb;var opts={filename:filename};var data;var viewOpts;if(typeof arguments[arguments.length-1]=="function"){cb=args.pop()}if(args.length){data=args.shift();if(args.length){utils.shallowCopy(opts,args.pop())}else{if(data.settings){if(data.settings.views){opts.views=data.settings.views}if(data.settings["view cache"]){opts.cache=true}viewOpts=data.settings["view options"];if(viewOpts){utils.shallowCopy(opts,viewOpts)}}utils.shallowCopyFromList(opts,data,_OPTS_PASSABLE_WITH_DATA_EXPRESS)}opts.filename=filename}else{data={}}return tryHandleCache(opts,data,cb)};exports.Template=Template;exports.clearCache=function(){exports.cache.reset()};function Template(text,opts){opts=opts||{};var options={};this.templateText=text;this.mode=null;this.truncate=false;this.currentLine=1;this.source="";options.client=opts.client||false;options.escapeFunction=opts.escape||opts.escapeFunction||utils.escapeXML;options.compileDebug=opts.compileDebug!==false;options.debug=!!opts.debug;options.filename=opts.filename;options.openDelimiter=opts.openDelimiter||exports.openDelimiter||_DEFAULT_OPEN_DELIMITER;options.closeDelimiter=opts.closeDelimiter||exports.closeDelimiter||_DEFAULT_CLOSE_DELIMITER;options.delimiter=opts.delimiter||exports.delimiter||_DEFAULT_DELIMITER;options.strict=opts.strict||false;options.context=opts.context;options.cache=opts.cache||false;options.rmWhitespace=opts.rmWhitespace;options.root=opts.root;options.includer=opts.includer;options.outputFunctionName=opts.outputFunctionName;options.localsName=opts.localsName||exports.localsName||_DEFAULT_LOCALS_NAME;options.views=opts.views;options.async=opts.async;options.destructuredLocals=opts.destructuredLocals;options.legacyInclude=typeof opts.legacyInclude!="undefined"?!!opts.legacyInclude:true;if(options.strict){options._with=false}else{options._with=typeof opts._with!="undefined"?opts._with:true}this.opts=options;this.regex=this.createRegex()}Template.modes={EVAL:"eval",ESCAPED:"escaped",RAW:"raw",COMMENT:"comment",LITERAL:"literal"};Template.prototype={createRegex:function(){var str=_REGEX_STRING;var delim=utils.escapeRegExpChars(this.opts.delimiter);var open=utils.escapeRegExpChars(this.opts.openDelimiter);var close=utils.escapeRegExpChars(this.opts.closeDelimiter);str=str.replace(/%/g,delim).replace(/</g,open).replace(/>/g,close);return new RegExp(str)},compile:function(){var src;var fn;var opts=this.opts;var prepended="";var appended="";var escapeFn=opts.escapeFunction;var ctor;var sanitizedFilename=opts.filename?JSON.stringify(opts.filename):"undefined";if(!this.source){this.generateSource();prepended+=' var __output = "";\n'+" function __append(s) { if (s !== undefined && s !== null) __output += s }\n";if(opts.outputFunctionName){prepended+=" var "+opts.outputFunctionName+" = __append;"+"\n"}if(opts.destructuredLocals&&opts.destructuredLocals.length){var destructuring=" var __locals = ("+opts.localsName+" || {}),\n";for(var i=0;i<opts.destructuredLocals.length;i++){var name=opts.destructuredLocals[i];if(i>0){destructuring+=",\n "}destructuring+=name+" = __locals."+name}prepended+=destructuring+";\n"}if(opts._with!==false){prepended+=" with ("+opts.localsName+" || {}) {"+"\n";appended+=" }"+"\n"}appended+=" return __output;"+"\n";this.source=prepended+this.source+appended}if(opts.compileDebug){src="var __line = 1"+"\n"+" , __lines = "+JSON.stringify(this.templateText)+"\n"+" , __filename = "+sanitizedFilename+";"+"\n"+"try {"+"\n"+this.source+"} catch (e) {"+"\n"+" rethrow(e, __lines, __filename, __line, escapeFn);"+"\n"+"}"+"\n"}else{src=this.source}if(opts.client){src="escapeFn = escapeFn || "+escapeFn.toString()+";"+"\n"+src;if(opts.compileDebug){src="rethrow = rethrow || "+rethrow.toString()+";"+"\n"+src}}if(opts.strict){src='"use strict";\n'+src}if(opts.debug){console.log(src)}if(opts.compileDebug&&opts.filename){src=src+"\n"+"//# sourceURL="+sanitizedFilename+"\n"}try{if(opts.async){try{ctor=new Function("return (async function(){}).constructor;")()}catch(e){if(e instanceof SyntaxError){throw new Error("This environment does not support async/await")}else{throw e}}}else{ctor=Function}fn=new ctor(opts.localsName+", escapeFn, include, rethrow",src)}catch(e){if(e instanceof SyntaxError){if(opts.filename){e.message+=" in "+opts.filename}e.message+=" while compiling ejs\n\n";e.message+="If the above error is not helpful, you may want to try EJS-Lint:\n";e.message+="https://github.com/RyanZim/EJS-Lint";if(!opts.async){e.message+="\n";e.message+="Or, if you meant to create an async function, pass `async: true` as an option."}}throw e}var returnedFn=opts.client?fn:function anonymous(data){var include=function(path,includeData){var d=utils.shallowCopy({},data);if(includeData){d=utils.shallowCopy(d,includeData)}return includeFile(path,opts)(d)};return fn.apply(opts.context,[data||{},escapeFn,include,rethrow])};if(opts.filename&&typeof Object.defineProperty==="function"){var filename=opts.filename;var basename=path.basename(filename,path.extname(filename));try{Object.defineProperty(returnedFn,"name",{value:basename,writable:false,enumerable:false,configurable:true})}catch(e){}}return returnedFn},generateSource:function(){var opts=this.opts;if(opts.rmWhitespace){this.templateText=this.templateText.replace(/[\r\n]+/g,"\n").replace(/^\s+|\s+$/gm,"")}this.templateText=this.templateText.replace(/[ \t]*<%_/gm,"<%_").replace(/_%>[ \t]*/gm,"_%>");var self=this;var matches=this.parseTemplateText();var d=this.opts.delimiter;var o=this.opts.openDelimiter;var c=this.opts.closeDelimiter;if(matches&&matches.length){matches.forEach(function(line,index){var closing;if(line.indexOf(o+d)===0&&line.indexOf(o+d+d)!==0){closing=matches[index+2];if(!(closing==d+c||closing=="-"+d+c||closing=="_"+d+c)){throw new Error('Could not find matching close tag for "'+line+'".')}}self.scanLine(line)})}},parseTemplateText:function(){var str=this.templateText;var pat=this.regex;var result=pat.exec(str);var arr=[];var firstPos;while(result){firstPos=result.index;if(firstPos!==0){arr.push(str.substring(0,firstPos));str=str.slice(firstPos)}arr.push(result[0]);str=str.slice(result[0].length);result=pat.exec(str)}if(str){arr.push(str)}return arr},_addOutput:function(line){if(this.truncate){line=line.replace(/^(?:\r\n|\r|\n)/,"");this.truncate=false}if(!line){return line}line=line.replace(/\\/g,"\\\\");line=line.replace(/\n/g,"\\n");line=line.replace(/\r/g,"\\r");line=line.replace(/"/g,'\\"');this.source+=' ; __append("'+line+'")'+"\n"},scanLine:function(line){var self=this;var d=this.opts.delimiter;var o=this.opts.openDelimiter;var c=this.opts.closeDelimiter;var newLineCount=0;newLineCount=line.split("\n").length-1;switch(line){case o+d:case o+d+"_":this.mode=Template.modes.EVAL;break;case o+d+"=":this.mode=Template.modes.ESCAPED;break;case o+d+"-":this.mode=Template.modes.RAW;break;case o+d+"#":this.mode=Template.modes.COMMENT;break;case o+d+d:this.mode=Template.modes.LITERAL;this.source+=' ; __append("'+line.replace(o+d+d,o+d)+'")'+"\n";break;case d+d+c:this.mode=Template.modes.LITERAL;this.source+=' ; __append("'+line.replace(d+d+c,d+c)+'")'+"\n";break;case d+c:case"-"+d+c:case"_"+d+c:if(this.mode==Template.modes.LITERAL){this._addOutput(line)}this.mode=null;this.truncate=line.indexOf("-")===0||line.indexOf("_")===0;break;default:if(this.mode){switch(this.mode){case Template.modes.EVAL:case Template.modes.ESCAPED:case Template.modes.RAW:if(line.lastIndexOf("//")>line.lastIndexOf("\n")){line+="\n"}}switch(this.mode){case Template.modes.EVAL:this.source+=" ; "+line+"\n";break;case Template.modes.ESCAPED:this.source+=" ; __append(escapeFn("+stripSemi(line)+"))"+"\n";break;case Template.modes.RAW:this.source+=" ; __append("+stripSemi(line)+")"+"\n";break;case Template.modes.COMMENT:break;case Template.modes.LITERAL:this._addOutput(line);break}}else{this._addOutput(line)}}if(self.opts.compileDebug&&newLineCount){this.currentLine+=newLineCount;this.source+=" ; __line = "+this.currentLine+"\n"}}};exports.escapeXML=utils.escapeXML;exports.__express=exports.renderFile;exports.VERSION=_VERSION_STRING;exports.name=_NAME;if(typeof window!="undefined"){window.ejs=exports}},{"../package.json":6,"./utils":2,fs:3,path:4}],2:[function(require,module,exports){"use strict";var regExpChars=/[|\\{}()[\]^$+*?.]/g;exports.escapeRegExpChars=function(string){if(!string){return""}return String(string).replace(regExpChars,"\\$&")};var _ENCODE_HTML_RULES={"&":"&","<":"<",">":">",'"':""","'":"'"};var _MATCH_HTML=/[&<>'"]/g;function encode_char(c){return _ENCODE_HTML_RULES[c]||c}var escapeFuncStr="var _ENCODE_HTML_RULES = {\n"+' "&": "&"\n'+' , "<": "<"\n'+' , ">": ">"\n'+' , \'"\': """\n'+' , "\'": "'"\n'+" }\n"+" , _MATCH_HTML = /[&<>'\"]/g;\n"+"function encode_char(c) {\n"+" return _ENCODE_HTML_RULES[c] || c;\n"+"};\n";exports.escapeXML=function(markup){return markup==undefined?"":String(markup).replace(_MATCH_HTML,encode_char)};exports.escapeXML.toString=function(){return Function.prototype.toString.call(this)+";\n"+escapeFuncStr};exports.shallowCopy=function(to,from){from=from||{};for(var p in from){to[p]=from[p]}return to};exports.shallowCopyFromList=function(to,from,list){for(var i=0;i<list.length;i++){var p=list[i];if(typeof from[p]!="undefined"){to[p]=from[p]}}return to};exports.cache={_data:{},set:function(key,val){this._data[key]=val},get:function(key){return this._data[key]},remove:function(key){delete this._data[key]},reset:function(){this._data={}}};exports.hyphenToCamel=function(str){return str.replace(/-[a-z]/g,function(match){return match[1].toUpperCase()})}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(process){function normalizeArray(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up--;up){parts.unshift("..")}}return parts}exports.resolve=function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:process.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){continue}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=normalizeArray(filter(resolvedPath.split("/"),function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."};exports.normalize=function(path){var isAbsolute=exports.isAbsolute(path),trailingSlash=substr(path,-1)==="/";path=normalizeArray(filter(path.split("/"),function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path};exports.isAbsolute=function(path){return path.charAt(0)==="/"};exports.join=function(){var paths=Array.prototype.slice.call(arguments,0);return exports.normalize(filter(paths,function(p,index){if(typeof p!=="string"){throw new TypeError("Arguments to path.join must be strings")}return p}).join("/"))};exports.relative=function(from,to){from=exports.resolve(from).substr(1);to=exports.resolve(to).substr(1);function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[start]!=="")break}var end=arr.length-1;for(;end>=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i<length;i++){if(fromParts[i]!==toParts[i]){samePartsLength=i;break}}var outputParts=[];for(var i=samePartsLength;i<fromParts.length;i++){outputParts.push("..")}outputParts=outputParts.concat(toParts.slice(samePartsLength));return outputParts.join("/")};exports.sep="/";exports.delimiter=":";exports.dirname=function(path){if(typeof path!=="string")path=path+"";if(path.length===0)return".";var code=path.charCodeAt(0);var hasRoot=code===47;var end=-1;var matchedSlash=true;for(var i=path.length-1;i>=1;--i){code=path.charCodeAt(i);if(code===47){if(!matchedSlash){end=i;break}}else{matchedSlash=false}}if(end===-1)return hasRoot?"/":".";if(hasRoot&&end===1){return"/"}return path.slice(0,end)};function basename(path){if(typeof path!=="string")path=path+"";var start=0;var end=-1;var matchedSlash=true;var i;for(i=path.length-1;i>=0;--i){if(path.charCodeAt(i)===47){if(!matchedSlash){start=i+1;break}}else if(end===-1){matchedSlash=false;end=i+1}}if(end===-1)return"";return path.slice(start,end)}exports.basename=function(path,ext){var f=basename(path);if(ext&&f.substr(-1*ext.length)===ext){f=f.substr(0,f.length-ext.length)}return f};exports.extname=function(path){if(typeof path!=="string")path=path+"";var startDot=-1;var startPart=0;var end=-1;var matchedSlash=true;var preDotState=0;for(var i=path.length-1;i>=0;--i){var code=path.charCodeAt(i);if(code===47){if(!matchedSlash){startPart=i+1;break}continue}if(end===-1){matchedSlash=false;end=i+1}if(code===46){if(startDot===-1)startDot=i;else if(preDotState!==1)preDotState=1}else if(startDot!==-1){preDotState=-1}}if(startDot===-1||end===-1||preDotState===0||preDotState===1&&startDot===end-1&&startDot===startPart+1){return""}return path.slice(startDot,end)};function filter(xs,f){if(xs.filter)return xs.filter(f);var res=[];for(var i=0;i<xs.length;i++){if(f(xs[i],i,xs))res.push(xs[i])}return res}var substr="ab".substr(-1)==="b"?function(str,start,len){return str.substr(start,len)}:function(str,start,len){if(start<0)start=str.length+start;return str.substr(start,len)}}).call(this,require("_process"))},{_process:5}],5:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.prependListener=noop;process.prependOnceListener=noop;process.listeners=function(name){return[]};process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],6:[function(require,module,exports){module.exports={name:"ejs",description:"Embedded JavaScript templates",keywords:["template","engine","ejs"],version:"3.1.6",author:"Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",license:"Apache-2.0",bin:{ejs:"./bin/cli.js"},main:"./lib/ejs.js",jsdelivr:"ejs.min.js",unpkg:"ejs.min.js",repository:{type:"git",url:"git://github.com/mde/ejs.git"},bugs:"https://github.com/mde/ejs/issues",homepage:"https://github.com/mde/ejs",dependencies:{jake:"^10.6.1"},devDependencies:{browserify:"^16.5.1",eslint:"^6.8.0","git-directory-deploy":"^1.5.1",jsdoc:"^3.6.4","lru-cache":"^4.0.1",mocha:"^7.1.1","uglify-js":"^3.3.16"},engines:{node:">=0.10.0"},scripts:{test:"mocha"}}},{}]},{},[1])(1)}); |
node_modules/ejs/jakefile.js
0 → 100644
1 | +var fs = require('fs'); | ||
2 | +var execSync = require('child_process').execSync; | ||
3 | +var exec = function (cmd) { | ||
4 | + execSync(cmd, {stdio: 'inherit'}); | ||
5 | +}; | ||
6 | + | ||
7 | +/* global jake, task, desc, publishTask */ | ||
8 | + | ||
9 | +task('build', ['lint', 'clean', 'browserify', 'minify'], function () { | ||
10 | + console.log('Build completed.'); | ||
11 | +}); | ||
12 | + | ||
13 | +desc('Cleans browerified/minified files and package files'); | ||
14 | +task('clean', ['clobber'], function () { | ||
15 | + jake.rmRf('./ejs.js'); | ||
16 | + jake.rmRf('./ejs.min.js'); | ||
17 | + console.log('Cleaned up compiled files.'); | ||
18 | +}); | ||
19 | + | ||
20 | +desc('Lints the source code'); | ||
21 | +task('lint', ['clean'], function () { | ||
22 | + exec('./node_modules/.bin/eslint "**/*.js"'); | ||
23 | + console.log('Linting completed.'); | ||
24 | +}); | ||
25 | + | ||
26 | +task('browserify', function () { | ||
27 | + exec('./node_modules/browserify/bin/cmd.js --standalone ejs lib/ejs.js > ejs.js'); | ||
28 | + console.log('Browserification completed.'); | ||
29 | +}); | ||
30 | + | ||
31 | +task('minify', function () { | ||
32 | + exec('./node_modules/uglify-js/bin/uglifyjs ejs.js > ejs.min.js'); | ||
33 | + console.log('Minification completed.'); | ||
34 | +}); | ||
35 | + | ||
36 | +desc('Generates the EJS API docs for the public API'); | ||
37 | +task('doc', function () { | ||
38 | + jake.rmRf('out'); | ||
39 | + exec('./node_modules/.bin/jsdoc --verbose -c jsdoc.json lib/* docs/jsdoc/*'); | ||
40 | + console.log('Documentation generated in ./out.'); | ||
41 | +}); | ||
42 | + | ||
43 | +desc('Generates the EJS API docs for the public and private API'); | ||
44 | +task('devdoc', function () { | ||
45 | + jake.rmRf('out'); | ||
46 | + exec('./node_modules/.bin/jsdoc --verbose -p -c jsdoc.json lib/* docs/jsdoc/*'); | ||
47 | + console.log('Documentation generated in ./out.'); | ||
48 | +}); | ||
49 | + | ||
50 | +desc('Publishes the EJS API docs'); | ||
51 | +task('docPublish', ['doc'], function () { | ||
52 | + fs.writeFileSync('out/CNAME', 'api.ejs.co'); | ||
53 | + console.log('Pushing docs to gh-pages...'); | ||
54 | + exec('./node_modules/.bin/git-directory-deploy --directory out/'); | ||
55 | + console.log('Docs published to gh-pages.'); | ||
56 | +}); | ||
57 | + | ||
58 | +desc('Runs the EJS test suite'); | ||
59 | +task('test', ['lint'], function () { | ||
60 | + exec('./node_modules/.bin/mocha'); | ||
61 | +}); | ||
62 | + | ||
63 | +publishTask('ejs', ['build'], function () { | ||
64 | + this.packageFiles.include([ | ||
65 | + 'jakefile.js', | ||
66 | + 'README.md', | ||
67 | + 'LICENSE', | ||
68 | + 'package.json', | ||
69 | + 'ejs.js', | ||
70 | + 'ejs.min.js', | ||
71 | + 'lib/**', | ||
72 | + 'bin/**', | ||
73 | + 'usage.txt' | ||
74 | + ]); | ||
75 | +}); | ||
76 | + | ||
77 | +jake.Task.publish.on('complete', function () { | ||
78 | + console.log('Updating hosted docs...'); | ||
79 | + console.log('If this fails, run jake docPublish to re-try.'); | ||
80 | + jake.Task.docPublish.invoke(); | ||
81 | +}); |
node_modules/ejs/lib/ejs.js
0 → 100644
1 | +/* | ||
2 | + * EJS Embedded JavaScript templates | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +'use strict'; | ||
20 | + | ||
21 | +/** | ||
22 | + * @file Embedded JavaScript templating engine. {@link http://ejs.co} | ||
23 | + * @author Matthew Eernisse <mde@fleegix.org> | ||
24 | + * @author Tiancheng "Timothy" Gu <timothygu99@gmail.com> | ||
25 | + * @project EJS | ||
26 | + * @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0} | ||
27 | + */ | ||
28 | + | ||
29 | +/** | ||
30 | + * EJS internal functions. | ||
31 | + * | ||
32 | + * Technically this "module" lies in the same file as {@link module:ejs}, for | ||
33 | + * the sake of organization all the private functions re grouped into this | ||
34 | + * module. | ||
35 | + * | ||
36 | + * @module ejs-internal | ||
37 | + * @private | ||
38 | + */ | ||
39 | + | ||
40 | +/** | ||
41 | + * Embedded JavaScript templating engine. | ||
42 | + * | ||
43 | + * @module ejs | ||
44 | + * @public | ||
45 | + */ | ||
46 | + | ||
47 | +var fs = require('fs'); | ||
48 | +var path = require('path'); | ||
49 | +var utils = require('./utils'); | ||
50 | + | ||
51 | +var scopeOptionWarned = false; | ||
52 | +/** @type {string} */ | ||
53 | +var _VERSION_STRING = require('../package.json').version; | ||
54 | +var _DEFAULT_OPEN_DELIMITER = '<'; | ||
55 | +var _DEFAULT_CLOSE_DELIMITER = '>'; | ||
56 | +var _DEFAULT_DELIMITER = '%'; | ||
57 | +var _DEFAULT_LOCALS_NAME = 'locals'; | ||
58 | +var _NAME = 'ejs'; | ||
59 | +var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'; | ||
60 | +var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug', | ||
61 | + 'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async']; | ||
62 | +// We don't allow 'cache' option to be passed in the data obj for | ||
63 | +// the normal `render` call, but this is where Express 2 & 3 put it | ||
64 | +// so we make an exception for `renderFile` | ||
65 | +var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache'); | ||
66 | +var _BOM = /^\uFEFF/; | ||
67 | + | ||
68 | +/** | ||
69 | + * EJS template function cache. This can be a LRU object from lru-cache NPM | ||
70 | + * module. By default, it is {@link module:utils.cache}, a simple in-process | ||
71 | + * cache that grows continuously. | ||
72 | + * | ||
73 | + * @type {Cache} | ||
74 | + */ | ||
75 | + | ||
76 | +exports.cache = utils.cache; | ||
77 | + | ||
78 | +/** | ||
79 | + * Custom file loader. Useful for template preprocessing or restricting access | ||
80 | + * to a certain part of the filesystem. | ||
81 | + * | ||
82 | + * @type {fileLoader} | ||
83 | + */ | ||
84 | + | ||
85 | +exports.fileLoader = fs.readFileSync; | ||
86 | + | ||
87 | +/** | ||
88 | + * Name of the object containing the locals. | ||
89 | + * | ||
90 | + * This variable is overridden by {@link Options}`.localsName` if it is not | ||
91 | + * `undefined`. | ||
92 | + * | ||
93 | + * @type {String} | ||
94 | + * @public | ||
95 | + */ | ||
96 | + | ||
97 | +exports.localsName = _DEFAULT_LOCALS_NAME; | ||
98 | + | ||
99 | +/** | ||
100 | + * Promise implementation -- defaults to the native implementation if available | ||
101 | + * This is mostly just for testability | ||
102 | + * | ||
103 | + * @type {PromiseConstructorLike} | ||
104 | + * @public | ||
105 | + */ | ||
106 | + | ||
107 | +exports.promiseImpl = (new Function('return this;'))().Promise; | ||
108 | + | ||
109 | +/** | ||
110 | + * Get the path to the included file from the parent file path and the | ||
111 | + * specified path. | ||
112 | + * | ||
113 | + * @param {String} name specified path | ||
114 | + * @param {String} filename parent file path | ||
115 | + * @param {Boolean} [isDir=false] whether the parent file path is a directory | ||
116 | + * @return {String} | ||
117 | + */ | ||
118 | +exports.resolveInclude = function(name, filename, isDir) { | ||
119 | + var dirname = path.dirname; | ||
120 | + var extname = path.extname; | ||
121 | + var resolve = path.resolve; | ||
122 | + var includePath = resolve(isDir ? filename : dirname(filename), name); | ||
123 | + var ext = extname(name); | ||
124 | + if (!ext) { | ||
125 | + includePath += '.ejs'; | ||
126 | + } | ||
127 | + return includePath; | ||
128 | +}; | ||
129 | + | ||
130 | +/** | ||
131 | + * Try to resolve file path on multiple directories | ||
132 | + * | ||
133 | + * @param {String} name specified path | ||
134 | + * @param {Array<String>} paths list of possible parent directory paths | ||
135 | + * @return {String} | ||
136 | + */ | ||
137 | +function resolvePaths(name, paths) { | ||
138 | + var filePath; | ||
139 | + if (paths.some(function (v) { | ||
140 | + filePath = exports.resolveInclude(name, v, true); | ||
141 | + return fs.existsSync(filePath); | ||
142 | + })) { | ||
143 | + return filePath; | ||
144 | + } | ||
145 | +} | ||
146 | + | ||
147 | +/** | ||
148 | + * Get the path to the included file by Options | ||
149 | + * | ||
150 | + * @param {String} path specified path | ||
151 | + * @param {Options} options compilation options | ||
152 | + * @return {String} | ||
153 | + */ | ||
154 | +function getIncludePath(path, options) { | ||
155 | + var includePath; | ||
156 | + var filePath; | ||
157 | + var views = options.views; | ||
158 | + var match = /^[A-Za-z]+:\\|^\//.exec(path); | ||
159 | + | ||
160 | + // Abs path | ||
161 | + if (match && match.length) { | ||
162 | + path = path.replace(/^\/*/, ''); | ||
163 | + if (Array.isArray(options.root)) { | ||
164 | + includePath = resolvePaths(path, options.root); | ||
165 | + } else { | ||
166 | + includePath = exports.resolveInclude(path, options.root || '/', true); | ||
167 | + } | ||
168 | + } | ||
169 | + // Relative paths | ||
170 | + else { | ||
171 | + // Look relative to a passed filename first | ||
172 | + if (options.filename) { | ||
173 | + filePath = exports.resolveInclude(path, options.filename); | ||
174 | + if (fs.existsSync(filePath)) { | ||
175 | + includePath = filePath; | ||
176 | + } | ||
177 | + } | ||
178 | + // Then look in any views directories | ||
179 | + if (!includePath && Array.isArray(views)) { | ||
180 | + includePath = resolvePaths(path, views); | ||
181 | + } | ||
182 | + if (!includePath && typeof options.includer !== 'function') { | ||
183 | + throw new Error('Could not find the include file "' + | ||
184 | + options.escapeFunction(path) + '"'); | ||
185 | + } | ||
186 | + } | ||
187 | + return includePath; | ||
188 | +} | ||
189 | + | ||
190 | +/** | ||
191 | + * Get the template from a string or a file, either compiled on-the-fly or | ||
192 | + * read from cache (if enabled), and cache the template if needed. | ||
193 | + * | ||
194 | + * If `template` is not set, the file specified in `options.filename` will be | ||
195 | + * read. | ||
196 | + * | ||
197 | + * If `options.cache` is true, this function reads the file from | ||
198 | + * `options.filename` so it must be set prior to calling this function. | ||
199 | + * | ||
200 | + * @memberof module:ejs-internal | ||
201 | + * @param {Options} options compilation options | ||
202 | + * @param {String} [template] template source | ||
203 | + * @return {(TemplateFunction|ClientFunction)} | ||
204 | + * Depending on the value of `options.client`, either type might be returned. | ||
205 | + * @static | ||
206 | + */ | ||
207 | + | ||
208 | +function handleCache(options, template) { | ||
209 | + var func; | ||
210 | + var filename = options.filename; | ||
211 | + var hasTemplate = arguments.length > 1; | ||
212 | + | ||
213 | + if (options.cache) { | ||
214 | + if (!filename) { | ||
215 | + throw new Error('cache option requires a filename'); | ||
216 | + } | ||
217 | + func = exports.cache.get(filename); | ||
218 | + if (func) { | ||
219 | + return func; | ||
220 | + } | ||
221 | + if (!hasTemplate) { | ||
222 | + template = fileLoader(filename).toString().replace(_BOM, ''); | ||
223 | + } | ||
224 | + } | ||
225 | + else if (!hasTemplate) { | ||
226 | + // istanbul ignore if: should not happen at all | ||
227 | + if (!filename) { | ||
228 | + throw new Error('Internal EJS error: no file name or template ' | ||
229 | + + 'provided'); | ||
230 | + } | ||
231 | + template = fileLoader(filename).toString().replace(_BOM, ''); | ||
232 | + } | ||
233 | + func = exports.compile(template, options); | ||
234 | + if (options.cache) { | ||
235 | + exports.cache.set(filename, func); | ||
236 | + } | ||
237 | + return func; | ||
238 | +} | ||
239 | + | ||
240 | +/** | ||
241 | + * Try calling handleCache with the given options and data and call the | ||
242 | + * callback with the result. If an error occurs, call the callback with | ||
243 | + * the error. Used by renderFile(). | ||
244 | + * | ||
245 | + * @memberof module:ejs-internal | ||
246 | + * @param {Options} options compilation options | ||
247 | + * @param {Object} data template data | ||
248 | + * @param {RenderFileCallback} cb callback | ||
249 | + * @static | ||
250 | + */ | ||
251 | + | ||
252 | +function tryHandleCache(options, data, cb) { | ||
253 | + var result; | ||
254 | + if (!cb) { | ||
255 | + if (typeof exports.promiseImpl == 'function') { | ||
256 | + return new exports.promiseImpl(function (resolve, reject) { | ||
257 | + try { | ||
258 | + result = handleCache(options)(data); | ||
259 | + resolve(result); | ||
260 | + } | ||
261 | + catch (err) { | ||
262 | + reject(err); | ||
263 | + } | ||
264 | + }); | ||
265 | + } | ||
266 | + else { | ||
267 | + throw new Error('Please provide a callback function'); | ||
268 | + } | ||
269 | + } | ||
270 | + else { | ||
271 | + try { | ||
272 | + result = handleCache(options)(data); | ||
273 | + } | ||
274 | + catch (err) { | ||
275 | + return cb(err); | ||
276 | + } | ||
277 | + | ||
278 | + cb(null, result); | ||
279 | + } | ||
280 | +} | ||
281 | + | ||
282 | +/** | ||
283 | + * fileLoader is independent | ||
284 | + * | ||
285 | + * @param {String} filePath ejs file path. | ||
286 | + * @return {String} The contents of the specified file. | ||
287 | + * @static | ||
288 | + */ | ||
289 | + | ||
290 | +function fileLoader(filePath){ | ||
291 | + return exports.fileLoader(filePath); | ||
292 | +} | ||
293 | + | ||
294 | +/** | ||
295 | + * Get the template function. | ||
296 | + * | ||
297 | + * If `options.cache` is `true`, then the template is cached. | ||
298 | + * | ||
299 | + * @memberof module:ejs-internal | ||
300 | + * @param {String} path path for the specified file | ||
301 | + * @param {Options} options compilation options | ||
302 | + * @return {(TemplateFunction|ClientFunction)} | ||
303 | + * Depending on the value of `options.client`, either type might be returned | ||
304 | + * @static | ||
305 | + */ | ||
306 | + | ||
307 | +function includeFile(path, options) { | ||
308 | + var opts = utils.shallowCopy({}, options); | ||
309 | + opts.filename = getIncludePath(path, opts); | ||
310 | + if (typeof options.includer === 'function') { | ||
311 | + var includerResult = options.includer(path, opts.filename); | ||
312 | + if (includerResult) { | ||
313 | + if (includerResult.filename) { | ||
314 | + opts.filename = includerResult.filename; | ||
315 | + } | ||
316 | + if (includerResult.template) { | ||
317 | + return handleCache(opts, includerResult.template); | ||
318 | + } | ||
319 | + } | ||
320 | + } | ||
321 | + return handleCache(opts); | ||
322 | +} | ||
323 | + | ||
324 | +/** | ||
325 | + * Re-throw the given `err` in context to the `str` of ejs, `filename`, and | ||
326 | + * `lineno`. | ||
327 | + * | ||
328 | + * @implements {RethrowCallback} | ||
329 | + * @memberof module:ejs-internal | ||
330 | + * @param {Error} err Error object | ||
331 | + * @param {String} str EJS source | ||
332 | + * @param {String} flnm file name of the EJS file | ||
333 | + * @param {Number} lineno line number of the error | ||
334 | + * @param {EscapeCallback} esc | ||
335 | + * @static | ||
336 | + */ | ||
337 | + | ||
338 | +function rethrow(err, str, flnm, lineno, esc) { | ||
339 | + var lines = str.split('\n'); | ||
340 | + var start = Math.max(lineno - 3, 0); | ||
341 | + var end = Math.min(lines.length, lineno + 3); | ||
342 | + var filename = esc(flnm); | ||
343 | + // Error context | ||
344 | + var context = lines.slice(start, end).map(function (line, i){ | ||
345 | + var curr = i + start + 1; | ||
346 | + return (curr == lineno ? ' >> ' : ' ') | ||
347 | + + curr | ||
348 | + + '| ' | ||
349 | + + line; | ||
350 | + }).join('\n'); | ||
351 | + | ||
352 | + // Alter exception message | ||
353 | + err.path = filename; | ||
354 | + err.message = (filename || 'ejs') + ':' | ||
355 | + + lineno + '\n' | ||
356 | + + context + '\n\n' | ||
357 | + + err.message; | ||
358 | + | ||
359 | + throw err; | ||
360 | +} | ||
361 | + | ||
362 | +function stripSemi(str){ | ||
363 | + return str.replace(/;(\s*$)/, '$1'); | ||
364 | +} | ||
365 | + | ||
366 | +/** | ||
367 | + * Compile the given `str` of ejs into a template function. | ||
368 | + * | ||
369 | + * @param {String} template EJS template | ||
370 | + * | ||
371 | + * @param {Options} [opts] compilation options | ||
372 | + * | ||
373 | + * @return {(TemplateFunction|ClientFunction)} | ||
374 | + * Depending on the value of `opts.client`, either type might be returned. | ||
375 | + * Note that the return type of the function also depends on the value of `opts.async`. | ||
376 | + * @public | ||
377 | + */ | ||
378 | + | ||
379 | +exports.compile = function compile(template, opts) { | ||
380 | + var templ; | ||
381 | + | ||
382 | + // v1 compat | ||
383 | + // 'scope' is 'context' | ||
384 | + // FIXME: Remove this in a future version | ||
385 | + if (opts && opts.scope) { | ||
386 | + if (!scopeOptionWarned){ | ||
387 | + console.warn('`scope` option is deprecated and will be removed in EJS 3'); | ||
388 | + scopeOptionWarned = true; | ||
389 | + } | ||
390 | + if (!opts.context) { | ||
391 | + opts.context = opts.scope; | ||
392 | + } | ||
393 | + delete opts.scope; | ||
394 | + } | ||
395 | + templ = new Template(template, opts); | ||
396 | + return templ.compile(); | ||
397 | +}; | ||
398 | + | ||
399 | +/** | ||
400 | + * Render the given `template` of ejs. | ||
401 | + * | ||
402 | + * If you would like to include options but not data, you need to explicitly | ||
403 | + * call this function with `data` being an empty object or `null`. | ||
404 | + * | ||
405 | + * @param {String} template EJS template | ||
406 | + * @param {Object} [data={}] template data | ||
407 | + * @param {Options} [opts={}] compilation and rendering options | ||
408 | + * @return {(String|Promise<String>)} | ||
409 | + * Return value type depends on `opts.async`. | ||
410 | + * @public | ||
411 | + */ | ||
412 | + | ||
413 | +exports.render = function (template, d, o) { | ||
414 | + var data = d || {}; | ||
415 | + var opts = o || {}; | ||
416 | + | ||
417 | + // No options object -- if there are optiony names | ||
418 | + // in the data, copy them to options | ||
419 | + if (arguments.length == 2) { | ||
420 | + utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA); | ||
421 | + } | ||
422 | + | ||
423 | + return handleCache(opts, template)(data); | ||
424 | +}; | ||
425 | + | ||
426 | +/** | ||
427 | + * Render an EJS file at the given `path` and callback `cb(err, str)`. | ||
428 | + * | ||
429 | + * If you would like to include options but not data, you need to explicitly | ||
430 | + * call this function with `data` being an empty object or `null`. | ||
431 | + * | ||
432 | + * @param {String} path path to the EJS file | ||
433 | + * @param {Object} [data={}] template data | ||
434 | + * @param {Options} [opts={}] compilation and rendering options | ||
435 | + * @param {RenderFileCallback} cb callback | ||
436 | + * @public | ||
437 | + */ | ||
438 | + | ||
439 | +exports.renderFile = function () { | ||
440 | + var args = Array.prototype.slice.call(arguments); | ||
441 | + var filename = args.shift(); | ||
442 | + var cb; | ||
443 | + var opts = {filename: filename}; | ||
444 | + var data; | ||
445 | + var viewOpts; | ||
446 | + | ||
447 | + // Do we have a callback? | ||
448 | + if (typeof arguments[arguments.length - 1] == 'function') { | ||
449 | + cb = args.pop(); | ||
450 | + } | ||
451 | + // Do we have data/opts? | ||
452 | + if (args.length) { | ||
453 | + // Should always have data obj | ||
454 | + data = args.shift(); | ||
455 | + // Normal passed opts (data obj + opts obj) | ||
456 | + if (args.length) { | ||
457 | + // Use shallowCopy so we don't pollute passed in opts obj with new vals | ||
458 | + utils.shallowCopy(opts, args.pop()); | ||
459 | + } | ||
460 | + // Special casing for Express (settings + opts-in-data) | ||
461 | + else { | ||
462 | + // Express 3 and 4 | ||
463 | + if (data.settings) { | ||
464 | + // Pull a few things from known locations | ||
465 | + if (data.settings.views) { | ||
466 | + opts.views = data.settings.views; | ||
467 | + } | ||
468 | + if (data.settings['view cache']) { | ||
469 | + opts.cache = true; | ||
470 | + } | ||
471 | + // Undocumented after Express 2, but still usable, esp. for | ||
472 | + // items that are unsafe to be passed along with data, like `root` | ||
473 | + viewOpts = data.settings['view options']; | ||
474 | + if (viewOpts) { | ||
475 | + utils.shallowCopy(opts, viewOpts); | ||
476 | + } | ||
477 | + } | ||
478 | + // Express 2 and lower, values set in app.locals, or people who just | ||
479 | + // want to pass options in their data. NOTE: These values will override | ||
480 | + // anything previously set in settings or settings['view options'] | ||
481 | + utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS); | ||
482 | + } | ||
483 | + opts.filename = filename; | ||
484 | + } | ||
485 | + else { | ||
486 | + data = {}; | ||
487 | + } | ||
488 | + | ||
489 | + return tryHandleCache(opts, data, cb); | ||
490 | +}; | ||
491 | + | ||
492 | +/** | ||
493 | + * Clear intermediate JavaScript cache. Calls {@link Cache#reset}. | ||
494 | + * @public | ||
495 | + */ | ||
496 | + | ||
497 | +/** | ||
498 | + * EJS template class | ||
499 | + * @public | ||
500 | + */ | ||
501 | +exports.Template = Template; | ||
502 | + | ||
503 | +exports.clearCache = function () { | ||
504 | + exports.cache.reset(); | ||
505 | +}; | ||
506 | + | ||
507 | +function Template(text, opts) { | ||
508 | + opts = opts || {}; | ||
509 | + var options = {}; | ||
510 | + this.templateText = text; | ||
511 | + /** @type {string | null} */ | ||
512 | + this.mode = null; | ||
513 | + this.truncate = false; | ||
514 | + this.currentLine = 1; | ||
515 | + this.source = ''; | ||
516 | + options.client = opts.client || false; | ||
517 | + options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML; | ||
518 | + options.compileDebug = opts.compileDebug !== false; | ||
519 | + options.debug = !!opts.debug; | ||
520 | + options.filename = opts.filename; | ||
521 | + options.openDelimiter = opts.openDelimiter || exports.openDelimiter || _DEFAULT_OPEN_DELIMITER; | ||
522 | + options.closeDelimiter = opts.closeDelimiter || exports.closeDelimiter || _DEFAULT_CLOSE_DELIMITER; | ||
523 | + options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER; | ||
524 | + options.strict = opts.strict || false; | ||
525 | + options.context = opts.context; | ||
526 | + options.cache = opts.cache || false; | ||
527 | + options.rmWhitespace = opts.rmWhitespace; | ||
528 | + options.root = opts.root; | ||
529 | + options.includer = opts.includer; | ||
530 | + options.outputFunctionName = opts.outputFunctionName; | ||
531 | + options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME; | ||
532 | + options.views = opts.views; | ||
533 | + options.async = opts.async; | ||
534 | + options.destructuredLocals = opts.destructuredLocals; | ||
535 | + options.legacyInclude = typeof opts.legacyInclude != 'undefined' ? !!opts.legacyInclude : true; | ||
536 | + | ||
537 | + if (options.strict) { | ||
538 | + options._with = false; | ||
539 | + } | ||
540 | + else { | ||
541 | + options._with = typeof opts._with != 'undefined' ? opts._with : true; | ||
542 | + } | ||
543 | + | ||
544 | + this.opts = options; | ||
545 | + | ||
546 | + this.regex = this.createRegex(); | ||
547 | +} | ||
548 | + | ||
549 | +Template.modes = { | ||
550 | + EVAL: 'eval', | ||
551 | + ESCAPED: 'escaped', | ||
552 | + RAW: 'raw', | ||
553 | + COMMENT: 'comment', | ||
554 | + LITERAL: 'literal' | ||
555 | +}; | ||
556 | + | ||
557 | +Template.prototype = { | ||
558 | + createRegex: function () { | ||
559 | + var str = _REGEX_STRING; | ||
560 | + var delim = utils.escapeRegExpChars(this.opts.delimiter); | ||
561 | + var open = utils.escapeRegExpChars(this.opts.openDelimiter); | ||
562 | + var close = utils.escapeRegExpChars(this.opts.closeDelimiter); | ||
563 | + str = str.replace(/%/g, delim) | ||
564 | + .replace(/</g, open) | ||
565 | + .replace(/>/g, close); | ||
566 | + return new RegExp(str); | ||
567 | + }, | ||
568 | + | ||
569 | + compile: function () { | ||
570 | + /** @type {string} */ | ||
571 | + var src; | ||
572 | + /** @type {ClientFunction} */ | ||
573 | + var fn; | ||
574 | + var opts = this.opts; | ||
575 | + var prepended = ''; | ||
576 | + var appended = ''; | ||
577 | + /** @type {EscapeCallback} */ | ||
578 | + var escapeFn = opts.escapeFunction; | ||
579 | + /** @type {FunctionConstructor} */ | ||
580 | + var ctor; | ||
581 | + /** @type {string} */ | ||
582 | + var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : 'undefined'; | ||
583 | + | ||
584 | + if (!this.source) { | ||
585 | + this.generateSource(); | ||
586 | + prepended += | ||
587 | + ' var __output = "";\n' + | ||
588 | + ' function __append(s) { if (s !== undefined && s !== null) __output += s }\n'; | ||
589 | + if (opts.outputFunctionName) { | ||
590 | + prepended += ' var ' + opts.outputFunctionName + ' = __append;' + '\n'; | ||
591 | + } | ||
592 | + if (opts.destructuredLocals && opts.destructuredLocals.length) { | ||
593 | + var destructuring = ' var __locals = (' + opts.localsName + ' || {}),\n'; | ||
594 | + for (var i = 0; i < opts.destructuredLocals.length; i++) { | ||
595 | + var name = opts.destructuredLocals[i]; | ||
596 | + if (i > 0) { | ||
597 | + destructuring += ',\n '; | ||
598 | + } | ||
599 | + destructuring += name + ' = __locals.' + name; | ||
600 | + } | ||
601 | + prepended += destructuring + ';\n'; | ||
602 | + } | ||
603 | + if (opts._with !== false) { | ||
604 | + prepended += ' with (' + opts.localsName + ' || {}) {' + '\n'; | ||
605 | + appended += ' }' + '\n'; | ||
606 | + } | ||
607 | + appended += ' return __output;' + '\n'; | ||
608 | + this.source = prepended + this.source + appended; | ||
609 | + } | ||
610 | + | ||
611 | + if (opts.compileDebug) { | ||
612 | + src = 'var __line = 1' + '\n' | ||
613 | + + ' , __lines = ' + JSON.stringify(this.templateText) + '\n' | ||
614 | + + ' , __filename = ' + sanitizedFilename + ';' + '\n' | ||
615 | + + 'try {' + '\n' | ||
616 | + + this.source | ||
617 | + + '} catch (e) {' + '\n' | ||
618 | + + ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n' | ||
619 | + + '}' + '\n'; | ||
620 | + } | ||
621 | + else { | ||
622 | + src = this.source; | ||
623 | + } | ||
624 | + | ||
625 | + if (opts.client) { | ||
626 | + src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src; | ||
627 | + if (opts.compileDebug) { | ||
628 | + src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src; | ||
629 | + } | ||
630 | + } | ||
631 | + | ||
632 | + if (opts.strict) { | ||
633 | + src = '"use strict";\n' + src; | ||
634 | + } | ||
635 | + if (opts.debug) { | ||
636 | + console.log(src); | ||
637 | + } | ||
638 | + if (opts.compileDebug && opts.filename) { | ||
639 | + src = src + '\n' | ||
640 | + + '//# sourceURL=' + sanitizedFilename + '\n'; | ||
641 | + } | ||
642 | + | ||
643 | + try { | ||
644 | + if (opts.async) { | ||
645 | + // Have to use generated function for this, since in envs without support, | ||
646 | + // it breaks in parsing | ||
647 | + try { | ||
648 | + ctor = (new Function('return (async function(){}).constructor;'))(); | ||
649 | + } | ||
650 | + catch(e) { | ||
651 | + if (e instanceof SyntaxError) { | ||
652 | + throw new Error('This environment does not support async/await'); | ||
653 | + } | ||
654 | + else { | ||
655 | + throw e; | ||
656 | + } | ||
657 | + } | ||
658 | + } | ||
659 | + else { | ||
660 | + ctor = Function; | ||
661 | + } | ||
662 | + fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src); | ||
663 | + } | ||
664 | + catch(e) { | ||
665 | + // istanbul ignore else | ||
666 | + if (e instanceof SyntaxError) { | ||
667 | + if (opts.filename) { | ||
668 | + e.message += ' in ' + opts.filename; | ||
669 | + } | ||
670 | + e.message += ' while compiling ejs\n\n'; | ||
671 | + e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n'; | ||
672 | + e.message += 'https://github.com/RyanZim/EJS-Lint'; | ||
673 | + if (!opts.async) { | ||
674 | + e.message += '\n'; | ||
675 | + e.message += 'Or, if you meant to create an async function, pass `async: true` as an option.'; | ||
676 | + } | ||
677 | + } | ||
678 | + throw e; | ||
679 | + } | ||
680 | + | ||
681 | + // Return a callable function which will execute the function | ||
682 | + // created by the source-code, with the passed data as locals | ||
683 | + // Adds a local `include` function which allows full recursive include | ||
684 | + var returnedFn = opts.client ? fn : function anonymous(data) { | ||
685 | + var include = function (path, includeData) { | ||
686 | + var d = utils.shallowCopy({}, data); | ||
687 | + if (includeData) { | ||
688 | + d = utils.shallowCopy(d, includeData); | ||
689 | + } | ||
690 | + return includeFile(path, opts)(d); | ||
691 | + }; | ||
692 | + return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]); | ||
693 | + }; | ||
694 | + if (opts.filename && typeof Object.defineProperty === 'function') { | ||
695 | + var filename = opts.filename; | ||
696 | + var basename = path.basename(filename, path.extname(filename)); | ||
697 | + try { | ||
698 | + Object.defineProperty(returnedFn, 'name', { | ||
699 | + value: basename, | ||
700 | + writable: false, | ||
701 | + enumerable: false, | ||
702 | + configurable: true | ||
703 | + }); | ||
704 | + } catch (e) {/* ignore */} | ||
705 | + } | ||
706 | + return returnedFn; | ||
707 | + }, | ||
708 | + | ||
709 | + generateSource: function () { | ||
710 | + var opts = this.opts; | ||
711 | + | ||
712 | + if (opts.rmWhitespace) { | ||
713 | + // Have to use two separate replace here as `^` and `$` operators don't | ||
714 | + // work well with `\r` and empty lines don't work well with the `m` flag. | ||
715 | + this.templateText = | ||
716 | + this.templateText.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, ''); | ||
717 | + } | ||
718 | + | ||
719 | + // Slurp spaces and tabs before <%_ and after _%> | ||
720 | + this.templateText = | ||
721 | + this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>'); | ||
722 | + | ||
723 | + var self = this; | ||
724 | + var matches = this.parseTemplateText(); | ||
725 | + var d = this.opts.delimiter; | ||
726 | + var o = this.opts.openDelimiter; | ||
727 | + var c = this.opts.closeDelimiter; | ||
728 | + | ||
729 | + if (matches && matches.length) { | ||
730 | + matches.forEach(function (line, index) { | ||
731 | + var closing; | ||
732 | + // If this is an opening tag, check for closing tags | ||
733 | + // FIXME: May end up with some false positives here | ||
734 | + // Better to store modes as k/v with openDelimiter + delimiter as key | ||
735 | + // Then this can simply check against the map | ||
736 | + if ( line.indexOf(o + d) === 0 // If it is a tag | ||
737 | + && line.indexOf(o + d + d) !== 0) { // and is not escaped | ||
738 | + closing = matches[index + 2]; | ||
739 | + if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) { | ||
740 | + throw new Error('Could not find matching close tag for "' + line + '".'); | ||
741 | + } | ||
742 | + } | ||
743 | + self.scanLine(line); | ||
744 | + }); | ||
745 | + } | ||
746 | + | ||
747 | + }, | ||
748 | + | ||
749 | + parseTemplateText: function () { | ||
750 | + var str = this.templateText; | ||
751 | + var pat = this.regex; | ||
752 | + var result = pat.exec(str); | ||
753 | + var arr = []; | ||
754 | + var firstPos; | ||
755 | + | ||
756 | + while (result) { | ||
757 | + firstPos = result.index; | ||
758 | + | ||
759 | + if (firstPos !== 0) { | ||
760 | + arr.push(str.substring(0, firstPos)); | ||
761 | + str = str.slice(firstPos); | ||
762 | + } | ||
763 | + | ||
764 | + arr.push(result[0]); | ||
765 | + str = str.slice(result[0].length); | ||
766 | + result = pat.exec(str); | ||
767 | + } | ||
768 | + | ||
769 | + if (str) { | ||
770 | + arr.push(str); | ||
771 | + } | ||
772 | + | ||
773 | + return arr; | ||
774 | + }, | ||
775 | + | ||
776 | + _addOutput: function (line) { | ||
777 | + if (this.truncate) { | ||
778 | + // Only replace single leading linebreak in the line after | ||
779 | + // -%> tag -- this is the single, trailing linebreak | ||
780 | + // after the tag that the truncation mode replaces | ||
781 | + // Handle Win / Unix / old Mac linebreaks -- do the \r\n | ||
782 | + // combo first in the regex-or | ||
783 | + line = line.replace(/^(?:\r\n|\r|\n)/, ''); | ||
784 | + this.truncate = false; | ||
785 | + } | ||
786 | + if (!line) { | ||
787 | + return line; | ||
788 | + } | ||
789 | + | ||
790 | + // Preserve literal slashes | ||
791 | + line = line.replace(/\\/g, '\\\\'); | ||
792 | + | ||
793 | + // Convert linebreaks | ||
794 | + line = line.replace(/\n/g, '\\n'); | ||
795 | + line = line.replace(/\r/g, '\\r'); | ||
796 | + | ||
797 | + // Escape double-quotes | ||
798 | + // - this will be the delimiter during execution | ||
799 | + line = line.replace(/"/g, '\\"'); | ||
800 | + this.source += ' ; __append("' + line + '")' + '\n'; | ||
801 | + }, | ||
802 | + | ||
803 | + scanLine: function (line) { | ||
804 | + var self = this; | ||
805 | + var d = this.opts.delimiter; | ||
806 | + var o = this.opts.openDelimiter; | ||
807 | + var c = this.opts.closeDelimiter; | ||
808 | + var newLineCount = 0; | ||
809 | + | ||
810 | + newLineCount = (line.split('\n').length - 1); | ||
811 | + | ||
812 | + switch (line) { | ||
813 | + case o + d: | ||
814 | + case o + d + '_': | ||
815 | + this.mode = Template.modes.EVAL; | ||
816 | + break; | ||
817 | + case o + d + '=': | ||
818 | + this.mode = Template.modes.ESCAPED; | ||
819 | + break; | ||
820 | + case o + d + '-': | ||
821 | + this.mode = Template.modes.RAW; | ||
822 | + break; | ||
823 | + case o + d + '#': | ||
824 | + this.mode = Template.modes.COMMENT; | ||
825 | + break; | ||
826 | + case o + d + d: | ||
827 | + this.mode = Template.modes.LITERAL; | ||
828 | + this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n'; | ||
829 | + break; | ||
830 | + case d + d + c: | ||
831 | + this.mode = Template.modes.LITERAL; | ||
832 | + this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n'; | ||
833 | + break; | ||
834 | + case d + c: | ||
835 | + case '-' + d + c: | ||
836 | + case '_' + d + c: | ||
837 | + if (this.mode == Template.modes.LITERAL) { | ||
838 | + this._addOutput(line); | ||
839 | + } | ||
840 | + | ||
841 | + this.mode = null; | ||
842 | + this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0; | ||
843 | + break; | ||
844 | + default: | ||
845 | + // In script mode, depends on type of tag | ||
846 | + if (this.mode) { | ||
847 | + // If '//' is found without a line break, add a line break. | ||
848 | + switch (this.mode) { | ||
849 | + case Template.modes.EVAL: | ||
850 | + case Template.modes.ESCAPED: | ||
851 | + case Template.modes.RAW: | ||
852 | + if (line.lastIndexOf('//') > line.lastIndexOf('\n')) { | ||
853 | + line += '\n'; | ||
854 | + } | ||
855 | + } | ||
856 | + switch (this.mode) { | ||
857 | + // Just executing code | ||
858 | + case Template.modes.EVAL: | ||
859 | + this.source += ' ; ' + line + '\n'; | ||
860 | + break; | ||
861 | + // Exec, esc, and output | ||
862 | + case Template.modes.ESCAPED: | ||
863 | + this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n'; | ||
864 | + break; | ||
865 | + // Exec and output | ||
866 | + case Template.modes.RAW: | ||
867 | + this.source += ' ; __append(' + stripSemi(line) + ')' + '\n'; | ||
868 | + break; | ||
869 | + case Template.modes.COMMENT: | ||
870 | + // Do nothing | ||
871 | + break; | ||
872 | + // Literal <%% mode, append as raw output | ||
873 | + case Template.modes.LITERAL: | ||
874 | + this._addOutput(line); | ||
875 | + break; | ||
876 | + } | ||
877 | + } | ||
878 | + // In string mode, just add the output | ||
879 | + else { | ||
880 | + this._addOutput(line); | ||
881 | + } | ||
882 | + } | ||
883 | + | ||
884 | + if (self.opts.compileDebug && newLineCount) { | ||
885 | + this.currentLine += newLineCount; | ||
886 | + this.source += ' ; __line = ' + this.currentLine + '\n'; | ||
887 | + } | ||
888 | + } | ||
889 | +}; | ||
890 | + | ||
891 | +/** | ||
892 | + * Escape characters reserved in XML. | ||
893 | + * | ||
894 | + * This is simply an export of {@link module:utils.escapeXML}. | ||
895 | + * | ||
896 | + * If `markup` is `undefined` or `null`, the empty string is returned. | ||
897 | + * | ||
898 | + * @param {String} markup Input string | ||
899 | + * @return {String} Escaped string | ||
900 | + * @public | ||
901 | + * @func | ||
902 | + * */ | ||
903 | +exports.escapeXML = utils.escapeXML; | ||
904 | + | ||
905 | +/** | ||
906 | + * Express.js support. | ||
907 | + * | ||
908 | + * This is an alias for {@link module:ejs.renderFile}, in order to support | ||
909 | + * Express.js out-of-the-box. | ||
910 | + * | ||
911 | + * @func | ||
912 | + */ | ||
913 | + | ||
914 | +exports.__express = exports.renderFile; | ||
915 | + | ||
916 | +/** | ||
917 | + * Version of EJS. | ||
918 | + * | ||
919 | + * @readonly | ||
920 | + * @type {String} | ||
921 | + * @public | ||
922 | + */ | ||
923 | + | ||
924 | +exports.VERSION = _VERSION_STRING; | ||
925 | + | ||
926 | +/** | ||
927 | + * Name for detection of EJS. | ||
928 | + * | ||
929 | + * @readonly | ||
930 | + * @type {String} | ||
931 | + * @public | ||
932 | + */ | ||
933 | + | ||
934 | +exports.name = _NAME; | ||
935 | + | ||
936 | +/* istanbul ignore if */ | ||
937 | +if (typeof window != 'undefined') { | ||
938 | + window.ejs = exports; | ||
939 | +} |
node_modules/ejs/lib/utils.js
0 → 100644
1 | +/* | ||
2 | + * EJS Embedded JavaScript templates | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +/** | ||
20 | + * Private utility functions | ||
21 | + * @module utils | ||
22 | + * @private | ||
23 | + */ | ||
24 | + | ||
25 | +'use strict'; | ||
26 | + | ||
27 | +var regExpChars = /[|\\{}()[\]^$+*?.]/g; | ||
28 | + | ||
29 | +/** | ||
30 | + * Escape characters reserved in regular expressions. | ||
31 | + * | ||
32 | + * If `string` is `undefined` or `null`, the empty string is returned. | ||
33 | + * | ||
34 | + * @param {String} string Input string | ||
35 | + * @return {String} Escaped string | ||
36 | + * @static | ||
37 | + * @private | ||
38 | + */ | ||
39 | +exports.escapeRegExpChars = function (string) { | ||
40 | + // istanbul ignore if | ||
41 | + if (!string) { | ||
42 | + return ''; | ||
43 | + } | ||
44 | + return String(string).replace(regExpChars, '\\$&'); | ||
45 | +}; | ||
46 | + | ||
47 | +var _ENCODE_HTML_RULES = { | ||
48 | + '&': '&', | ||
49 | + '<': '<', | ||
50 | + '>': '>', | ||
51 | + '"': '"', | ||
52 | + "'": ''' | ||
53 | +}; | ||
54 | +var _MATCH_HTML = /[&<>'"]/g; | ||
55 | + | ||
56 | +function encode_char(c) { | ||
57 | + return _ENCODE_HTML_RULES[c] || c; | ||
58 | +} | ||
59 | + | ||
60 | +/** | ||
61 | + * Stringified version of constants used by {@link module:utils.escapeXML}. | ||
62 | + * | ||
63 | + * It is used in the process of generating {@link ClientFunction}s. | ||
64 | + * | ||
65 | + * @readonly | ||
66 | + * @type {String} | ||
67 | + */ | ||
68 | + | ||
69 | +var escapeFuncStr = | ||
70 | + 'var _ENCODE_HTML_RULES = {\n' | ||
71 | ++ ' "&": "&"\n' | ||
72 | ++ ' , "<": "<"\n' | ||
73 | ++ ' , ">": ">"\n' | ||
74 | ++ ' , \'"\': """\n' | ||
75 | ++ ' , "\'": "'"\n' | ||
76 | ++ ' }\n' | ||
77 | ++ ' , _MATCH_HTML = /[&<>\'"]/g;\n' | ||
78 | ++ 'function encode_char(c) {\n' | ||
79 | ++ ' return _ENCODE_HTML_RULES[c] || c;\n' | ||
80 | ++ '};\n'; | ||
81 | + | ||
82 | +/** | ||
83 | + * Escape characters reserved in XML. | ||
84 | + * | ||
85 | + * If `markup` is `undefined` or `null`, the empty string is returned. | ||
86 | + * | ||
87 | + * @implements {EscapeCallback} | ||
88 | + * @param {String} markup Input string | ||
89 | + * @return {String} Escaped string | ||
90 | + * @static | ||
91 | + * @private | ||
92 | + */ | ||
93 | + | ||
94 | +exports.escapeXML = function (markup) { | ||
95 | + return markup == undefined | ||
96 | + ? '' | ||
97 | + : String(markup) | ||
98 | + .replace(_MATCH_HTML, encode_char); | ||
99 | +}; | ||
100 | +exports.escapeXML.toString = function () { | ||
101 | + return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr; | ||
102 | +}; | ||
103 | + | ||
104 | +/** | ||
105 | + * Naive copy of properties from one object to another. | ||
106 | + * Does not recurse into non-scalar properties | ||
107 | + * Does not check to see if the property has a value before copying | ||
108 | + * | ||
109 | + * @param {Object} to Destination object | ||
110 | + * @param {Object} from Source object | ||
111 | + * @return {Object} Destination object | ||
112 | + * @static | ||
113 | + * @private | ||
114 | + */ | ||
115 | +exports.shallowCopy = function (to, from) { | ||
116 | + from = from || {}; | ||
117 | + for (var p in from) { | ||
118 | + to[p] = from[p]; | ||
119 | + } | ||
120 | + return to; | ||
121 | +}; | ||
122 | + | ||
123 | +/** | ||
124 | + * Naive copy of a list of key names, from one object to another. | ||
125 | + * Only copies property if it is actually defined | ||
126 | + * Does not recurse into non-scalar properties | ||
127 | + * | ||
128 | + * @param {Object} to Destination object | ||
129 | + * @param {Object} from Source object | ||
130 | + * @param {Array} list List of properties to copy | ||
131 | + * @return {Object} Destination object | ||
132 | + * @static | ||
133 | + * @private | ||
134 | + */ | ||
135 | +exports.shallowCopyFromList = function (to, from, list) { | ||
136 | + for (var i = 0; i < list.length; i++) { | ||
137 | + var p = list[i]; | ||
138 | + if (typeof from[p] != 'undefined') { | ||
139 | + to[p] = from[p]; | ||
140 | + } | ||
141 | + } | ||
142 | + return to; | ||
143 | +}; | ||
144 | + | ||
145 | +/** | ||
146 | + * Simple in-process cache implementation. Does not implement limits of any | ||
147 | + * sort. | ||
148 | + * | ||
149 | + * @implements {Cache} | ||
150 | + * @static | ||
151 | + * @private | ||
152 | + */ | ||
153 | +exports.cache = { | ||
154 | + _data: {}, | ||
155 | + set: function (key, val) { | ||
156 | + this._data[key] = val; | ||
157 | + }, | ||
158 | + get: function (key) { | ||
159 | + return this._data[key]; | ||
160 | + }, | ||
161 | + remove: function (key) { | ||
162 | + delete this._data[key]; | ||
163 | + }, | ||
164 | + reset: function () { | ||
165 | + this._data = {}; | ||
166 | + } | ||
167 | +}; | ||
168 | + | ||
169 | +/** | ||
170 | + * Transforms hyphen case variable into camel case. | ||
171 | + * | ||
172 | + * @param {String} string Hyphen case string | ||
173 | + * @return {String} Camel case string | ||
174 | + * @static | ||
175 | + * @private | ||
176 | + */ | ||
177 | +exports.hyphenToCamel = function (str) { | ||
178 | + return str.replace(/-[a-z]/g, function (match) { return match[1].toUpperCase(); }); | ||
179 | +}; |
node_modules/ejs/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "ejs", | ||
3 | + "description": "Embedded JavaScript templates", | ||
4 | + "keywords": [ | ||
5 | + "template", | ||
6 | + "engine", | ||
7 | + "ejs" | ||
8 | + ], | ||
9 | + "version": "3.1.6", | ||
10 | + "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)", | ||
11 | + "license": "Apache-2.0", | ||
12 | + "bin": { | ||
13 | + "ejs": "./bin/cli.js" | ||
14 | + }, | ||
15 | + "main": "./lib/ejs.js", | ||
16 | + "jsdelivr": "ejs.min.js", | ||
17 | + "unpkg": "ejs.min.js", | ||
18 | + "repository": { | ||
19 | + "type": "git", | ||
20 | + "url": "git://github.com/mde/ejs.git" | ||
21 | + }, | ||
22 | + "bugs": "https://github.com/mde/ejs/issues", | ||
23 | + "homepage": "https://github.com/mde/ejs", | ||
24 | + "dependencies": { | ||
25 | + "jake": "^10.6.1" | ||
26 | + }, | ||
27 | + "devDependencies": { | ||
28 | + "browserify": "^16.5.1", | ||
29 | + "eslint": "^6.8.0", | ||
30 | + "git-directory-deploy": "^1.5.1", | ||
31 | + "jsdoc": "^3.6.4", | ||
32 | + "lru-cache": "^4.0.1", | ||
33 | + "mocha": "^7.1.1", | ||
34 | + "uglify-js": "^3.3.16" | ||
35 | + }, | ||
36 | + "engines": { | ||
37 | + "node": ">=0.10.0" | ||
38 | + }, | ||
39 | + "scripts": { | ||
40 | + "test": "mocha" | ||
41 | + } | ||
42 | +} |
node_modules/ejs/usage.txt
0 → 100644
1 | +EJS Embedded JavaScript templates | ||
2 | +{Usage}: ejs [options ...] template-file [data variables ...] | ||
3 | + | ||
4 | +{Options}: | ||
5 | + -o, --output-file FILE Write the rendered output to FILE rather than stdout. | ||
6 | + -f, --data-file FILE Must be JSON-formatted. Use parsed input from FILE as data for rendering. | ||
7 | + -i, --data-input STRING Must be JSON-formatted and URI-encoded. Use parsed input from STRING as data for rendering. | ||
8 | + -m, --delimiter CHARACTER Use CHARACTER with angle brackets for open/close (defaults to %). | ||
9 | + -p, --open-delimiter CHARACTER Use CHARACTER instead of left angle bracket to open. | ||
10 | + -c, --close-delimiter CHARACTER Use CHARACTER instead of right angle bracket to close. | ||
11 | + -s, --strict When set to `true`, generated function is in strict mode | ||
12 | + -n --no-with Use 'locals' object for vars rather than using `with` (implies --strict). | ||
13 | + -l --locals-name Name to use for the object storing local variables when not using `with`. | ||
14 | + -w --rm-whitespace Remove all safe-to-remove whitespace, including leading and trailing whitespace. | ||
15 | + -d --debug Outputs generated function body | ||
16 | + -h, --help Display this help message. | ||
17 | + -V/v, --version Display the EJS version. | ||
18 | + | ||
19 | +{Examples}: | ||
20 | + ejs -m $ ./test/fixtures/user.ejs -f ./user_data.json | ||
21 | + ejs -m $ ./test/fixtures/user.ejs name=Lerxst | ||
22 | + ejs -p [ -c ] ./template_file.ejs -o ./output.html | ||
23 | + ejs -n -l _ ./some_template.ejs -f ./data_file.json | ||
24 | + ejs -w ./template_with_whitspace.ejs -o ./output_file.html |
node_modules/escape-string-regexp/index.js
0 → 100644
node_modules/escape-string-regexp/license
0 → 100644
1 | +The MIT License (MIT) | ||
2 | + | ||
3 | +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | +of this software and associated documentation files (the "Software"), to deal | ||
7 | +in the Software without restriction, including without limitation the rights | ||
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | +copies of the Software, and to permit persons to whom the Software is | ||
10 | +furnished to do so, subject to the following conditions: | ||
11 | + | ||
12 | +The above copyright notice and this permission notice shall be included in | ||
13 | +all copies or substantial portions of the Software. | ||
14 | + | ||
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | +THE SOFTWARE. |
1 | +{ | ||
2 | + "name": "escape-string-regexp", | ||
3 | + "version": "1.0.5", | ||
4 | + "description": "Escape RegExp special characters", | ||
5 | + "license": "MIT", | ||
6 | + "repository": "sindresorhus/escape-string-regexp", | ||
7 | + "author": { | ||
8 | + "name": "Sindre Sorhus", | ||
9 | + "email": "sindresorhus@gmail.com", | ||
10 | + "url": "sindresorhus.com" | ||
11 | + }, | ||
12 | + "maintainers": [ | ||
13 | + "Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)", | ||
14 | + "Joshua Boy Nicolai Appelman <joshua@jbna.nl> (jbna.nl)" | ||
15 | + ], | ||
16 | + "engines": { | ||
17 | + "node": ">=0.8.0" | ||
18 | + }, | ||
19 | + "scripts": { | ||
20 | + "test": "xo && ava" | ||
21 | + }, | ||
22 | + "files": [ | ||
23 | + "index.js" | ||
24 | + ], | ||
25 | + "keywords": [ | ||
26 | + "escape", | ||
27 | + "regex", | ||
28 | + "regexp", | ||
29 | + "re", | ||
30 | + "regular", | ||
31 | + "expression", | ||
32 | + "string", | ||
33 | + "str", | ||
34 | + "special", | ||
35 | + "characters" | ||
36 | + ], | ||
37 | + "devDependencies": { | ||
38 | + "ava": "*", | ||
39 | + "xo": "*" | ||
40 | + } | ||
41 | +} |
node_modules/escape-string-regexp/readme.md
0 → 100644
1 | +# escape-string-regexp [![Build Status](https://travis-ci.org/sindresorhus/escape-string-regexp.svg?branch=master)](https://travis-ci.org/sindresorhus/escape-string-regexp) | ||
2 | + | ||
3 | +> Escape RegExp special characters | ||
4 | + | ||
5 | + | ||
6 | +## Install | ||
7 | + | ||
8 | +``` | ||
9 | +$ npm install --save escape-string-regexp | ||
10 | +``` | ||
11 | + | ||
12 | + | ||
13 | +## Usage | ||
14 | + | ||
15 | +```js | ||
16 | +const escapeStringRegexp = require('escape-string-regexp'); | ||
17 | + | ||
18 | +const escapedString = escapeStringRegexp('how much $ for a unicorn?'); | ||
19 | +//=> 'how much \$ for a unicorn\?' | ||
20 | + | ||
21 | +new RegExp(escapedString); | ||
22 | +``` | ||
23 | + | ||
24 | + | ||
25 | +## License | ||
26 | + | ||
27 | +MIT © [Sindre Sorhus](http://sindresorhus.com) |
node_modules/filelist/README.md
0 → 100644
1 | +## FileList | ||
2 | + | ||
3 | +A FileList is a lazy-evaluated list of files. When given a list | ||
4 | +of glob patterns for possible files to be included in the file | ||
5 | +list, instead of searching the file structures to find the files, | ||
6 | +a FileList holds the pattern for latter use. | ||
7 | + | ||
8 | +This allows you to define a FileList to match any number of | ||
9 | +files, but only search out the actual files when then FileList | ||
10 | +itself is actually used. The key is that the first time an | ||
11 | +element of the FileList/Array is requested, the pending patterns | ||
12 | +are resolved into a real list of file names. | ||
13 | + | ||
14 | +### Usage | ||
15 | + | ||
16 | +Add files to the list with the `include` method. You can add glob | ||
17 | +patterns, individual files, or RegExp objects. When the Array | ||
18 | +methods are invoked on the FileList, these items are resolved to | ||
19 | +an actual list of files. | ||
20 | + | ||
21 | +```javascript | ||
22 | +var fl = new FileList(); | ||
23 | +fl.include('test/*.js'); | ||
24 | +fl.exclude('test/helpers.js'); | ||
25 | +``` | ||
26 | + | ||
27 | +Use the `exclude` method to override inclusions. You can use this | ||
28 | +when your inclusions are too broad. | ||
29 | + | ||
30 | +### Array methods | ||
31 | + | ||
32 | +FileList has lazy-evaluated versions of most of the array | ||
33 | +methods, including the following: | ||
34 | + | ||
35 | +* join | ||
36 | +* pop | ||
37 | +* push | ||
38 | +* concat | ||
39 | +* reverse | ||
40 | +* shift | ||
41 | +* unshift | ||
42 | +* slice | ||
43 | +* splice | ||
44 | +* sort | ||
45 | +* filter | ||
46 | +* forEach | ||
47 | +* some | ||
48 | +* every | ||
49 | +* map | ||
50 | +* indexOf | ||
51 | +* lastIndexOf | ||
52 | +* reduce | ||
53 | +* reduceRight | ||
54 | + | ||
55 | +When you call one of these methods, the items in the FileList | ||
56 | +will be resolved to the full list of files, and the method will | ||
57 | +be invoked on that result. | ||
58 | + | ||
59 | +### Special `length` method | ||
60 | + | ||
61 | +`length`: FileList includes a length *method* (instead of a | ||
62 | +property) which returns the number of actual files in the list | ||
63 | +once it's been resolved. | ||
64 | + | ||
65 | +### FileList-specific methods | ||
66 | + | ||
67 | +`include`: Add a filename/glob/regex to the list | ||
68 | + | ||
69 | +`exclude`: Override inclusions by excluding a filename/glob/regex | ||
70 | + | ||
71 | +`resolve`: Resolve the items in the FileList to the full list of | ||
72 | +files. This method is invoked automatically when one of the array | ||
73 | +methods is called. | ||
74 | + | ||
75 | +`toArray`: Immediately resolves the list of items, and returns an | ||
76 | +actual array of filepaths. | ||
77 | + | ||
78 | +`clearInclusions`: Clears any pending items -- must be used | ||
79 | +before resolving the list. | ||
80 | + | ||
81 | +`clearExclusions`: Clears the list of exclusions rules. | ||
82 | + | ||
83 | + | ||
84 | + |
node_modules/filelist/index.d.ts
0 → 100644
1 | +// Type definitions for filelist v0.0.6 | ||
2 | +// Project: https://github.com/mde/filelist | ||
3 | +// Definitions by: Christophe MASSOLIN <https://github.com/FuriouZz> | ||
4 | +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped | ||
5 | + | ||
6 | +declare module "filelist" { | ||
7 | + export class FileList { | ||
8 | + pendingAdd: string[] | ||
9 | + pending: boolean | ||
10 | + excludes: { | ||
11 | + pats: RegExp[], | ||
12 | + funcs: Function[], | ||
13 | + regex: null | RegExp | ||
14 | + } | ||
15 | + items: string[] | ||
16 | + static clone(): FileList | ||
17 | + static verbose: boolean | ||
18 | + toArray(): string[] | ||
19 | + include(options: any, ...items: string[]): void | ||
20 | + exclude(...items: string[]): void | ||
21 | + resolve(): void | ||
22 | + clearInclusions(): void | ||
23 | + clearExclusions(): void | ||
24 | + length(): number | ||
25 | + toString(): string; | ||
26 | + toLocaleString(): string; | ||
27 | + push(...items: string[]): number; | ||
28 | + pop(): string | undefined; | ||
29 | + concat(...items: ReadonlyArray<string>[]): string[]; | ||
30 | + concat(...items: (string | ReadonlyArray<string>)[]): string[]; | ||
31 | + join(separator?: string): string; | ||
32 | + reverse(): string[]; | ||
33 | + shift(): string | undefined; | ||
34 | + slice(start?: number, end?: number): string[]; | ||
35 | + sort(compareFn?: (a: string, b: string) => number): this; | ||
36 | + splice(start: number, deleteCount?: number): string[]; | ||
37 | + splice(start: number, deleteCount: number, ...items: string[]): string[]; | ||
38 | + unshift(...items: string[]): number; | ||
39 | + indexOf(searchElement: string, fromIndex?: number): number; | ||
40 | + lastIndexOf(searchElement: string, fromIndex?: number): number; | ||
41 | + every(callbackfn: (value: string, index: number, array: string[]) => boolean, thisArg?: any): boolean; | ||
42 | + some(callbackfn: (value: string, index: number, array: string[]) => boolean, thisArg?: any): boolean; | ||
43 | + forEach(callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any): void; | ||
44 | + map<U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any): U[]; | ||
45 | + filter<S extends string>(callbackfn: (value: string, index: number, array: string[]) => value is S, thisArg?: any): S[]; | ||
46 | + filter(callbackfn: (value: string, index: number, array: string[]) => any, thisArg?: any): string[]; | ||
47 | + reduce(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; | ||
48 | + reduce(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; | ||
49 | + reduce<U>(callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; | ||
50 | + reduceRight(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; | ||
51 | + reduceRight(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; | ||
52 | + reduceRight<U>(callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; | ||
53 | + } | ||
54 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/filelist/index.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | +var fs = require('fs') | ||
19 | +, path = require('path') | ||
20 | +, minimatch = require('minimatch') | ||
21 | +, escapeRegExpChars | ||
22 | +, merge | ||
23 | +, basedir | ||
24 | +, _readDir | ||
25 | +, readdirR | ||
26 | +, globSync; | ||
27 | + | ||
28 | + /** | ||
29 | + @name escapeRegExpChars | ||
30 | + @function | ||
31 | + @return {String} A string of escaped characters | ||
32 | + @description Escapes regex control-characters in strings | ||
33 | + used to build regexes dynamically | ||
34 | + @param {String} string The string of chars to escape | ||
35 | + */ | ||
36 | + escapeRegExpChars = (function () { | ||
37 | + var specials = [ '^', '$', '/', '.', '*', '+', '?', '|', '(', ')', | ||
38 | + '[', ']', '{', '}', '\\' ]; | ||
39 | + var sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g'); | ||
40 | + return function (string) { | ||
41 | + var str = string || ''; | ||
42 | + str = String(str); | ||
43 | + return str.replace(sRE, '\\$1'); | ||
44 | + }; | ||
45 | + })(); | ||
46 | + | ||
47 | + /** | ||
48 | + @name merge | ||
49 | + @function | ||
50 | + @return {Object} Returns the merged object | ||
51 | + @description Merge merges `otherObject` into `object` and takes care of deep | ||
52 | + merging of objects | ||
53 | + @param {Object} object Object to merge into | ||
54 | + @param {Object} otherObject Object to read from | ||
55 | + */ | ||
56 | + merge = function (object, otherObject) { | ||
57 | + var obj = object || {} | ||
58 | + , otherObj = otherObject || {} | ||
59 | + , key, value; | ||
60 | + | ||
61 | + for (key in otherObj) { | ||
62 | + value = otherObj[key]; | ||
63 | + | ||
64 | + // Check if a value is an Object, if so recursively add it's key/values | ||
65 | + if (typeof value === 'object' && !(value instanceof Array)) { | ||
66 | + // Update value of object to the one from otherObj | ||
67 | + obj[key] = merge(obj[key], value); | ||
68 | + } | ||
69 | + // Value is anything other than an Object, so just add it | ||
70 | + else { | ||
71 | + obj[key] = value; | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
75 | + return obj; | ||
76 | + }; | ||
77 | + /** | ||
78 | + Given a patern, return the base directory of it (ie. the folder | ||
79 | + that will contain all the files matching the path). | ||
80 | + eg. file.basedir('/test/**') => '/test/' | ||
81 | + Path ending by '/' are considerd as folder while other are considerd | ||
82 | + as files, eg.: | ||
83 | + file.basedir('/test/a/') => '/test/a' | ||
84 | + file.basedir('/test/a') => '/test' | ||
85 | + The returned path always end with a '/' so we have: | ||
86 | + file.basedir(file.basedir(x)) == file.basedir(x) | ||
87 | + */ | ||
88 | + basedir = function (pathParam) { | ||
89 | + var bd = '' | ||
90 | + , parts | ||
91 | + , part | ||
92 | + , pos = 0 | ||
93 | + , p = pathParam || ''; | ||
94 | + | ||
95 | + // If the path has a leading asterisk, basedir is the current dir | ||
96 | + if (p.indexOf('*') == 0 || p.indexOf('**') == 0) { | ||
97 | + return '.'; | ||
98 | + } | ||
99 | + | ||
100 | + // always consider .. at the end as a folder and not a filename | ||
101 | + if (/(?:^|\/|\\)\.\.$/.test(p.slice(-3))) { | ||
102 | + p += '/'; | ||
103 | + } | ||
104 | + | ||
105 | + parts = p.split(/\\|\//); | ||
106 | + for (var i = 0, l = parts.length - 1; i < l; i++) { | ||
107 | + part = parts[i]; | ||
108 | + if (part.indexOf('*') > -1 || part.indexOf('**') > -1) { | ||
109 | + break; | ||
110 | + } | ||
111 | + pos += part.length + 1; | ||
112 | + bd += part + p[pos - 1]; | ||
113 | + } | ||
114 | + if (!bd) { | ||
115 | + bd = '.'; | ||
116 | + } | ||
117 | + // Strip trailing slashes | ||
118 | + if (!(bd == '\\' || bd == '/')) { | ||
119 | + bd = bd.replace(/\\$|\/$/, ''); | ||
120 | + } | ||
121 | + return bd; | ||
122 | + | ||
123 | + }; | ||
124 | + | ||
125 | + // Return the contents of a given directory | ||
126 | + _readDir = function (dirPath) { | ||
127 | + var dir = path.normalize(dirPath) | ||
128 | + , paths = [] | ||
129 | + , ret = [dir] | ||
130 | + , msg; | ||
131 | + | ||
132 | + try { | ||
133 | + paths = fs.readdirSync(dir); | ||
134 | + } | ||
135 | + catch (e) { | ||
136 | + msg = 'Could not read path ' + dir + '\n'; | ||
137 | + if (e.stack) { | ||
138 | + msg += e.stack; | ||
139 | + } | ||
140 | + throw new Error(msg); | ||
141 | + } | ||
142 | + | ||
143 | + paths.forEach(function (p) { | ||
144 | + var curr = path.join(dir, p); | ||
145 | + var stat = fs.statSync(curr); | ||
146 | + if (stat.isDirectory()) { | ||
147 | + ret = ret.concat(_readDir(curr)); | ||
148 | + } | ||
149 | + else { | ||
150 | + ret.push(curr); | ||
151 | + } | ||
152 | + }); | ||
153 | + | ||
154 | + return ret; | ||
155 | + }; | ||
156 | + | ||
157 | + /** | ||
158 | + @name file#readdirR | ||
159 | + @function | ||
160 | + @return {Array} Returns the contents as an Array, can be configured via opts.format | ||
161 | + @description Reads the given directory returning it's contents | ||
162 | + @param {String} dir The directory to read | ||
163 | + @param {Object} opts Options to use | ||
164 | + @param {String} [opts.format] Set the format to return(Default: Array) | ||
165 | + */ | ||
166 | + readdirR = function (dir, opts) { | ||
167 | + var options = opts || {} | ||
168 | + , format = options.format || 'array' | ||
169 | + , ret; | ||
170 | + ret = _readDir(dir); | ||
171 | + return format == 'string' ? ret.join('\n') : ret; | ||
172 | + }; | ||
173 | + | ||
174 | + | ||
175 | +globSync = function (pat, opts) { | ||
176 | + var dirname = basedir(pat) | ||
177 | + , files | ||
178 | + , matches; | ||
179 | + | ||
180 | + try { | ||
181 | + files = readdirR(dirname).map(function(file){ | ||
182 | + return file.replace(/\\/g, '/'); | ||
183 | + }); | ||
184 | + } | ||
185 | + // Bail if path doesn't exist -- assume no files | ||
186 | + catch(e) { | ||
187 | + if (FileList.verbose) console.error(e.message); | ||
188 | + } | ||
189 | + | ||
190 | + if (files) { | ||
191 | + pat = path.normalize(pat); | ||
192 | + matches = minimatch.match(files, pat, opts || {}); | ||
193 | + } | ||
194 | + return matches || []; | ||
195 | +}; | ||
196 | + | ||
197 | +// Constants | ||
198 | +// --------------- | ||
199 | +// List of all the builtin Array methods we want to override | ||
200 | +var ARRAY_METHODS = Object.getOwnPropertyNames(Array.prototype) | ||
201 | +// Array methods that return a copy instead of affecting the original | ||
202 | + , SPECIAL_RETURN = { | ||
203 | + 'concat': true | ||
204 | + , 'slice': true | ||
205 | + , 'filter': true | ||
206 | + , 'map': true | ||
207 | + } | ||
208 | +// Default file-patterns we want to ignore | ||
209 | + , DEFAULT_IGNORE_PATTERNS = [ | ||
210 | + /(^|[\/\\])CVS([\/\\]|$)/ | ||
211 | + , /(^|[\/\\])\.svn([\/\\]|$)/ | ||
212 | + , /(^|[\/\\])\.git([\/\\]|$)/ | ||
213 | + , /\.bak$/ | ||
214 | + , /~$/ | ||
215 | + ] | ||
216 | +// Ignore core files | ||
217 | + , DEFAULT_IGNORE_FUNCS = [ | ||
218 | + function (name) { | ||
219 | + var isDir = false | ||
220 | + , stats; | ||
221 | + try { | ||
222 | + stats = fs.statSync(name); | ||
223 | + isDir = stats.isDirectory(); | ||
224 | + } | ||
225 | + catch(e) {} | ||
226 | + return (/(^|[\/\\])core$/).test(name) && !isDir; | ||
227 | + } | ||
228 | + ]; | ||
229 | + | ||
230 | +var FileList = function () { | ||
231 | + var self = this | ||
232 | + , wrap; | ||
233 | + | ||
234 | + // List of glob-patterns or specific filenames | ||
235 | + this.pendingAdd = []; | ||
236 | + // Switched to false after lazy-eval of files | ||
237 | + this.pending = true; | ||
238 | + // Used to calculate exclusions from the list of files | ||
239 | + this.excludes = { | ||
240 | + pats: DEFAULT_IGNORE_PATTERNS.slice() | ||
241 | + , funcs: DEFAULT_IGNORE_FUNCS.slice() | ||
242 | + , regex: null | ||
243 | + }; | ||
244 | + this.items = []; | ||
245 | + | ||
246 | + // Wrap the array methods with the delegates | ||
247 | + wrap = function (prop) { | ||
248 | + var arr; | ||
249 | + self[prop] = function () { | ||
250 | + if (self.pending) { | ||
251 | + self.resolve(); | ||
252 | + } | ||
253 | + if (typeof self.items[prop] == 'function') { | ||
254 | + // Special method that return a copy | ||
255 | + if (SPECIAL_RETURN[prop]) { | ||
256 | + arr = self.items[prop].apply(self.items, arguments); | ||
257 | + return FileList.clone(self, arr); | ||
258 | + } | ||
259 | + else { | ||
260 | + return self.items[prop].apply(self.items, arguments); | ||
261 | + } | ||
262 | + } | ||
263 | + else { | ||
264 | + return self.items[prop]; | ||
265 | + } | ||
266 | + }; | ||
267 | + }; | ||
268 | + for (var i = 0, ii = ARRAY_METHODS.length; i < ii; i++) { | ||
269 | + wrap(ARRAY_METHODS[i]); | ||
270 | + } | ||
271 | + | ||
272 | + // Include whatever files got passed to the constructor | ||
273 | + this.include.apply(this, arguments); | ||
274 | + | ||
275 | + // Fix constructor linkage | ||
276 | + this.constructor = FileList; | ||
277 | +}; | ||
278 | + | ||
279 | +FileList.prototype = new (function () { | ||
280 | + var globPattern = /[*?\[\{]/; | ||
281 | + | ||
282 | + var _addMatching = function (item) { | ||
283 | + var matches = globSync(item.path, item.options); | ||
284 | + this.items = this.items.concat(matches); | ||
285 | + } | ||
286 | + | ||
287 | + , _resolveAdd = function (item) { | ||
288 | + if (globPattern.test(item.path)) { | ||
289 | + _addMatching.call(this, item); | ||
290 | + } | ||
291 | + else { | ||
292 | + this.push(item.path); | ||
293 | + } | ||
294 | + } | ||
295 | + | ||
296 | + , _calculateExcludeRe = function () { | ||
297 | + var pats = this.excludes.pats | ||
298 | + , pat | ||
299 | + , excl = [] | ||
300 | + , matches = []; | ||
301 | + | ||
302 | + for (var i = 0, ii = pats.length; i < ii; i++) { | ||
303 | + pat = pats[i]; | ||
304 | + if (typeof pat == 'string') { | ||
305 | + // Glob, look up files | ||
306 | + if (/[*?]/.test(pat)) { | ||
307 | + matches = globSync(pat); | ||
308 | + matches = matches.map(function (m) { | ||
309 | + return escapeRegExpChars(m); | ||
310 | + }); | ||
311 | + excl = excl.concat(matches); | ||
312 | + } | ||
313 | + // String for regex | ||
314 | + else { | ||
315 | + excl.push(escapeRegExpChars(pat)); | ||
316 | + } | ||
317 | + } | ||
318 | + // Regex, grab the string-representation | ||
319 | + else if (pat instanceof RegExp) { | ||
320 | + excl.push(pat.toString().replace(/^\/|\/$/g, '')); | ||
321 | + } | ||
322 | + } | ||
323 | + if (excl.length) { | ||
324 | + this.excludes.regex = new RegExp('(' + excl.join(')|(') + ')'); | ||
325 | + } | ||
326 | + else { | ||
327 | + this.excludes.regex = /^$/; | ||
328 | + } | ||
329 | + } | ||
330 | + | ||
331 | + , _resolveExclude = function () { | ||
332 | + var self = this; | ||
333 | + _calculateExcludeRe.call(this); | ||
334 | + // No `reject` method, so use reverse-filter | ||
335 | + this.items = this.items.filter(function (name) { | ||
336 | + return !self.shouldExclude(name); | ||
337 | + }); | ||
338 | + }; | ||
339 | + | ||
340 | + /** | ||
341 | + * Includes file-patterns in the FileList. Should be called with one or more | ||
342 | + * pattern for finding file to include in the list. Arguments should be strings | ||
343 | + * for either a glob-pattern or a specific file-name, or an array of them | ||
344 | + */ | ||
345 | + this.include = function () { | ||
346 | + var args = Array.prototype.slice.call(arguments) | ||
347 | + , arg | ||
348 | + , includes = { items: [], options: {} }; | ||
349 | + | ||
350 | + for (var i = 0, ilen = args.length; i < ilen; i++) { | ||
351 | + arg = args[i]; | ||
352 | + | ||
353 | + if (typeof arg === 'object' && !Array.isArray(arg)) { | ||
354 | + merge(includes.options, arg); | ||
355 | + } else { | ||
356 | + includes.items = includes.items.concat(arg).filter(function (item) { | ||
357 | + return !!item; | ||
358 | + }); | ||
359 | + } | ||
360 | + } | ||
361 | + | ||
362 | + var items = includes.items.map(function(item) { | ||
363 | + return { path: item, options: includes.options }; | ||
364 | + }); | ||
365 | + | ||
366 | + this.pendingAdd = this.pendingAdd.concat(items); | ||
367 | + | ||
368 | + return this; | ||
369 | + }; | ||
370 | + | ||
371 | + /** | ||
372 | + * Indicates whether a particular file would be filtered out by the current | ||
373 | + * exclusion rules for this FileList. | ||
374 | + * @param {String} name The filename to check | ||
375 | + * @return {Boolean} Whether or not the file should be excluded | ||
376 | + */ | ||
377 | + this.shouldExclude = function (name) { | ||
378 | + if (!this.excludes.regex) { | ||
379 | + _calculateExcludeRe.call(this); | ||
380 | + } | ||
381 | + var excl = this.excludes; | ||
382 | + return excl.regex.test(name) || excl.funcs.some(function (f) { | ||
383 | + return !!f(name); | ||
384 | + }); | ||
385 | + }; | ||
386 | + | ||
387 | + /** | ||
388 | + * Excludes file-patterns from the FileList. Should be called with one or more | ||
389 | + * pattern for finding file to include in the list. Arguments can be: | ||
390 | + * 1. Strings for either a glob-pattern or a specific file-name | ||
391 | + * 2. Regular expression literals | ||
392 | + * 3. Functions to be run on the filename that return a true/false | ||
393 | + */ | ||
394 | + this.exclude = function () { | ||
395 | + var args = Array.isArray(arguments[0]) ? arguments[0] : arguments | ||
396 | + , arg; | ||
397 | + for (var i = 0, ii = args.length; i < ii; i++) { | ||
398 | + arg = args[i]; | ||
399 | + if (typeof arg == 'function' && !(arg instanceof RegExp)) { | ||
400 | + this.excludes.funcs.push(arg); | ||
401 | + } | ||
402 | + else { | ||
403 | + this.excludes.pats.push(arg); | ||
404 | + } | ||
405 | + } | ||
406 | + if (!this.pending) { | ||
407 | + _resolveExclude.call(this); | ||
408 | + } | ||
409 | + return this; | ||
410 | + }; | ||
411 | + | ||
412 | + /** | ||
413 | + * Populates the FileList from the include/exclude rules with a list of | ||
414 | + * actual files | ||
415 | + */ | ||
416 | + this.resolve = function () { | ||
417 | + var item | ||
418 | + , uniqueFunc = function (p, c) { | ||
419 | + if (p.indexOf(c) < 0) { | ||
420 | + p.push(c); | ||
421 | + } | ||
422 | + return p; | ||
423 | + }; | ||
424 | + if (this.pending) { | ||
425 | + this.pending = false; | ||
426 | + while ((item = this.pendingAdd.shift())) { | ||
427 | + _resolveAdd.call(this, item); | ||
428 | + } | ||
429 | + // Reduce to a unique list | ||
430 | + this.items = this.items.reduce(uniqueFunc, []); | ||
431 | + // Remove exclusions | ||
432 | + _resolveExclude.call(this); | ||
433 | + } | ||
434 | + return this; | ||
435 | + }; | ||
436 | + | ||
437 | + /** | ||
438 | + * Convert to a plain-jane array | ||
439 | + */ | ||
440 | + this.toArray = function () { | ||
441 | + // Call slice to ensure lazy-resolution before slicing items | ||
442 | + var ret = this.slice().items.slice(); | ||
443 | + return ret; | ||
444 | + }; | ||
445 | + | ||
446 | + /** | ||
447 | + * Clear any pending items -- only useful before | ||
448 | + * calling `resolve` | ||
449 | + */ | ||
450 | + this.clearInclusions = function () { | ||
451 | + this.pendingAdd = []; | ||
452 | + return this; | ||
453 | + }; | ||
454 | + | ||
455 | + /** | ||
456 | + * Clear any current exclusion rules | ||
457 | + */ | ||
458 | + this.clearExclusions = function () { | ||
459 | + this.excludes = { | ||
460 | + pats: [] | ||
461 | + , funcs: [] | ||
462 | + , regex: null | ||
463 | + }; | ||
464 | + return this; | ||
465 | + }; | ||
466 | + | ||
467 | +})(); | ||
468 | + | ||
469 | +// Static method, used to create copy returned by special | ||
470 | +// array methods | ||
471 | +FileList.clone = function (list, items) { | ||
472 | + var clone = new FileList(); | ||
473 | + if (items) { | ||
474 | + clone.items = items; | ||
475 | + } | ||
476 | + clone.pendingAdd = list.pendingAdd; | ||
477 | + clone.pending = list.pending; | ||
478 | + for (var p in list.excludes) { | ||
479 | + clone.excludes[p] = list.excludes[p]; | ||
480 | + } | ||
481 | + return clone; | ||
482 | +}; | ||
483 | + | ||
484 | +FileList.verbose = true | ||
485 | + | ||
486 | +exports.FileList = FileList; |
node_modules/filelist/jakefile.js
0 → 100644
node_modules/filelist/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "filelist", | ||
3 | + "version": "1.0.2", | ||
4 | + "description": "Lazy-evaluating list of files, based on globs or regex patterns", | ||
5 | + "main": "index.js", | ||
6 | + "types": "index.d.ts", | ||
7 | + "scripts": { | ||
8 | + "test": "jake test" | ||
9 | + }, | ||
10 | + "repository": { | ||
11 | + "type": "git", | ||
12 | + "url": "git://github.com/mde/filelist.git" | ||
13 | + }, | ||
14 | + "keywords": [ | ||
15 | + "file", | ||
16 | + "utility", | ||
17 | + "glob" | ||
18 | + ], | ||
19 | + "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)", | ||
20 | + "license": "Apache-2.0", | ||
21 | + "bugs": { | ||
22 | + "url": "https://github.com/mde/filelist/issues" | ||
23 | + }, | ||
24 | + "homepage": "https://github.com/mde/filelist", | ||
25 | + "dependencies": { | ||
26 | + "minimatch": "^3.0.4" | ||
27 | + } | ||
28 | +} |
node_modules/has-flag/index.js
0 → 100644
1 | +'use strict'; | ||
2 | +module.exports = (flag, argv) => { | ||
3 | + argv = argv || process.argv; | ||
4 | + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); | ||
5 | + const pos = argv.indexOf(prefix + flag); | ||
6 | + const terminatorPos = argv.indexOf('--'); | ||
7 | + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); | ||
8 | +}; |
node_modules/has-flag/license
0 → 100644
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
6 | + | ||
7 | +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
8 | + | ||
9 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
node_modules/has-flag/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "has-flag", | ||
3 | + "version": "3.0.0", | ||
4 | + "description": "Check if argv has a specific flag", | ||
5 | + "license": "MIT", | ||
6 | + "repository": "sindresorhus/has-flag", | ||
7 | + "author": { | ||
8 | + "name": "Sindre Sorhus", | ||
9 | + "email": "sindresorhus@gmail.com", | ||
10 | + "url": "sindresorhus.com" | ||
11 | + }, | ||
12 | + "engines": { | ||
13 | + "node": ">=4" | ||
14 | + }, | ||
15 | + "scripts": { | ||
16 | + "test": "xo && ava" | ||
17 | + }, | ||
18 | + "files": [ | ||
19 | + "index.js" | ||
20 | + ], | ||
21 | + "keywords": [ | ||
22 | + "has", | ||
23 | + "check", | ||
24 | + "detect", | ||
25 | + "contains", | ||
26 | + "find", | ||
27 | + "flag", | ||
28 | + "cli", | ||
29 | + "command-line", | ||
30 | + "argv", | ||
31 | + "process", | ||
32 | + "arg", | ||
33 | + "args", | ||
34 | + "argument", | ||
35 | + "arguments", | ||
36 | + "getopt", | ||
37 | + "minimist", | ||
38 | + "optimist" | ||
39 | + ], | ||
40 | + "devDependencies": { | ||
41 | + "ava": "*", | ||
42 | + "xo": "*" | ||
43 | + } | ||
44 | +} |
node_modules/has-flag/readme.md
0 → 100644
1 | +# has-flag [![Build Status](https://travis-ci.org/sindresorhus/has-flag.svg?branch=master)](https://travis-ci.org/sindresorhus/has-flag) | ||
2 | + | ||
3 | +> Check if [`argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv) has a specific flag | ||
4 | + | ||
5 | +Correctly stops looking after an `--` argument terminator. | ||
6 | + | ||
7 | + | ||
8 | +## Install | ||
9 | + | ||
10 | +``` | ||
11 | +$ npm install has-flag | ||
12 | +``` | ||
13 | + | ||
14 | + | ||
15 | +## Usage | ||
16 | + | ||
17 | +```js | ||
18 | +// foo.js | ||
19 | +const hasFlag = require('has-flag'); | ||
20 | + | ||
21 | +hasFlag('unicorn'); | ||
22 | +//=> true | ||
23 | + | ||
24 | +hasFlag('--unicorn'); | ||
25 | +//=> true | ||
26 | + | ||
27 | +hasFlag('f'); | ||
28 | +//=> true | ||
29 | + | ||
30 | +hasFlag('-f'); | ||
31 | +//=> true | ||
32 | + | ||
33 | +hasFlag('foo=bar'); | ||
34 | +//=> true | ||
35 | + | ||
36 | +hasFlag('foo'); | ||
37 | +//=> false | ||
38 | + | ||
39 | +hasFlag('rainbow'); | ||
40 | +//=> false | ||
41 | +``` | ||
42 | + | ||
43 | +``` | ||
44 | +$ node foo.js -f --unicorn --foo=bar -- --rainbow | ||
45 | +``` | ||
46 | + | ||
47 | + | ||
48 | +## API | ||
49 | + | ||
50 | +### hasFlag(flag, [argv]) | ||
51 | + | ||
52 | +Returns a boolean for whether the flag exists. | ||
53 | + | ||
54 | +#### flag | ||
55 | + | ||
56 | +Type: `string` | ||
57 | + | ||
58 | +CLI flag to look for. The `--` prefix is optional. | ||
59 | + | ||
60 | +#### argv | ||
61 | + | ||
62 | +Type: `string[]`<br> | ||
63 | +Default: `process.argv` | ||
64 | + | ||
65 | +CLI arguments. | ||
66 | + | ||
67 | + | ||
68 | +## License | ||
69 | + | ||
70 | +MIT © [Sindre Sorhus](https://sindresorhus.com) |
node_modules/jake/Makefile
0 → 100644
1 | +# | ||
2 | +# Jake JavaScript build tool | ||
3 | +# Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | +# | ||
5 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | +# you may not use this file except in compliance with the License. | ||
7 | +# You may obtain a copy of the License at | ||
8 | +# | ||
9 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | +# | ||
11 | +# Unless required by applicable law or agreed to in writing, software | ||
12 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | +# See the License for the specific language governing permissions and | ||
15 | +# limitations under the License. | ||
16 | +# | ||
17 | + | ||
18 | +.PHONY: all build install clean uninstall | ||
19 | + | ||
20 | +PREFIX=/usr/local | ||
21 | +DESTDIR= | ||
22 | + | ||
23 | +all: build | ||
24 | + | ||
25 | +build: | ||
26 | + @echo 'Jake built.' | ||
27 | + | ||
28 | +install: | ||
29 | + @mkdir -p $(DESTDIR)$(PREFIX)/bin && \ | ||
30 | + mkdir -p $(DESTDIR)$(PREFIX)/lib/node_modules/jake && \ | ||
31 | + mkdir -p ./node_modules && \ | ||
32 | + npm install utilities minimatch && \ | ||
33 | + cp -R ./* $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \ | ||
34 | + ln -snf ../lib/node_modules/jake/bin/cli.js $(DESTDIR)$(PREFIX)/bin/jake && \ | ||
35 | + chmod 755 $(DESTDIR)$(PREFIX)/lib/node_modules/jake/bin/cli.js && \ | ||
36 | + echo 'Jake installed.' | ||
37 | + | ||
38 | +clean: | ||
39 | + @true | ||
40 | + | ||
41 | +uninstall: | ||
42 | + @rm -f $(DESTDIR)$(PREFIX)/bin/jake && \ | ||
43 | + rm -fr $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \ | ||
44 | + echo 'Jake uninstalled.' |
node_modules/jake/README.md
0 → 100644
1 | +### Jake -- the JavaScript build tool for Node.js | ||
2 | + | ||
3 | +[![Build Status](https://travis-ci.org/jakejs/jake.svg?branch=master)](https://travis-ci.org/jakejs/jake) | ||
4 | + | ||
5 | +Documentation site at [http://jakejs.com](http://jakejs.com/) | ||
6 | + | ||
7 | +### Contributing | ||
8 | +1. [Install node](http://nodejs.org/#download). | ||
9 | +2. Clone this repository `$ git clone git@github.com:jakejs/jake.git`. | ||
10 | +3. Install dependencies `$ npm install`. | ||
11 | +4. Run tests with `$ npm test`. | ||
12 | +5. Start Hacking! | ||
13 | + | ||
14 | +### License | ||
15 | + | ||
16 | +Licensed under the Apache License, Version 2.0 | ||
17 | +(<http://www.apache.org/licenses/LICENSE-2.0>) |
node_modules/jake/bin/bash_completion.sh
0 → 100644
1 | +#!/bin/bash | ||
2 | + | ||
3 | +# http://stackoverflow.com/a/246128 | ||
4 | +SOURCE="${BASH_SOURCE[0]}" | ||
5 | +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink | ||
6 | + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" | ||
7 | + SOURCE="$(readlink "$SOURCE")" | ||
8 | + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located | ||
9 | +done | ||
10 | +JAKE_BIN_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" | ||
11 | + | ||
12 | +# http://stackoverflow.com/a/12495480 | ||
13 | +# http://stackoverflow.com/a/28647824 | ||
14 | +_auto_jake() | ||
15 | +{ | ||
16 | + local cur | ||
17 | + local -a COMPGEN=() | ||
18 | + _get_comp_words_by_ref -n : -c cur | ||
19 | + | ||
20 | + # run auto-completions in jake via our auto_complete.js wrapper | ||
21 | + local -a auto_complete_info=( $(export COMP_LINE="${COMP_LINE}" && ${JAKE_BIN_DIR}/auto_complete.js "$cur" "${3}") ) | ||
22 | + # check reply flag | ||
23 | + local reply_flag="${auto_complete_info[0]}" | ||
24 | + if [[ "${reply_flag}" == "no-complete" ]]; then | ||
25 | + return 1 | ||
26 | + fi | ||
27 | + local auto_completions=("${auto_complete_info[@]:1}") | ||
28 | + COMPGEN=( $(compgen -W "${auto_completions[*]}" -- "$cur") ) | ||
29 | + COMPREPLY=( "${COMPGEN[@]}" ) | ||
30 | + | ||
31 | + __ltrim_colon_completions "$cur" | ||
32 | + | ||
33 | + # do we need another space?? | ||
34 | + if [[ "${reply_flag}" == "yes-space" ]]; then | ||
35 | + COMPREPLY=( "${COMPGEN[@]}" " " ) | ||
36 | + fi | ||
37 | + | ||
38 | + return 0 | ||
39 | +} | ||
40 | + | ||
41 | +complete -o default -F _auto_jake jake |
node_modules/jake/bin/cli.js
0 → 100644
1 | +#!/usr/bin/env node | ||
2 | +/* | ||
3 | + * Jake JavaScript build tool | ||
4 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
5 | + * | ||
6 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + * you may not use this file except in compliance with the License. | ||
8 | + * You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, software | ||
13 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + * See the License for the specific language governing permissions and | ||
16 | + * limitations under the License. | ||
17 | + * | ||
18 | +*/ | ||
19 | + | ||
20 | +// Try to load a local jake | ||
21 | +try { | ||
22 | + require(`${ process.cwd() }/node_modules/jake`); | ||
23 | +} | ||
24 | +// If that fails, likely running globally | ||
25 | +catch(e) { | ||
26 | + require('../lib/jake'); | ||
27 | +} | ||
28 | + | ||
29 | +var args = process.argv.slice(2); | ||
30 | + | ||
31 | +jake.run.apply(jake, args); |
node_modules/jake/jakefile.js
0 → 100644
1 | +let fs = require('fs') | ||
2 | +let path = require('path'); | ||
3 | +let proc = require('child_process'); | ||
4 | + | ||
5 | +const PROJECT_DIR = process.cwd(); | ||
6 | +process.env.PROJECT_DIR = PROJECT_DIR; | ||
7 | + | ||
8 | +namespace('doc', function () { | ||
9 | + task('generate', ['doc:clobber'], function () { | ||
10 | + var cmd = '../node-jsdoc-toolkit/app/run.js -n -r=100 ' + | ||
11 | + '-t=../node-jsdoc-toolkit/templates/codeview -d=./doc/ ./lib'; | ||
12 | + jake.logger.log('Generating docs ...'); | ||
13 | + jake.exec([cmd], function () { | ||
14 | + jake.logger.log('Done.'); | ||
15 | + complete(); | ||
16 | + }); | ||
17 | + }, {async: true}); | ||
18 | + | ||
19 | + task('clobber', function () { | ||
20 | + var cmd = 'rm -fr ./doc/*'; | ||
21 | + jake.exec([cmd], function () { | ||
22 | + jake.logger.log('Clobbered old docs.'); | ||
23 | + complete(); | ||
24 | + }); | ||
25 | + }, {async: true}); | ||
26 | + | ||
27 | +}); | ||
28 | + | ||
29 | +desc('Generate docs for Jake'); | ||
30 | +task('doc', ['doc:generate']); | ||
31 | + | ||
32 | +npmPublishTask('jake', function () { | ||
33 | + this.packageFiles.include([ | ||
34 | + 'Makefile', | ||
35 | + 'jakefile.js', | ||
36 | + 'README.md', | ||
37 | + 'package.json', | ||
38 | + 'usage.txt', | ||
39 | + 'lib/**', | ||
40 | + 'bin/**', | ||
41 | + 'test/**' | ||
42 | + ]); | ||
43 | + this.packageFiles.exclude([ | ||
44 | + 'test/tmp' | ||
45 | + ]); | ||
46 | +}); | ||
47 | + | ||
48 | +jake.Task['publish:package'].directory = PROJECT_DIR; | ||
49 | + | ||
50 | +namespace('test', function () { | ||
51 | + | ||
52 | + let integrationTest = task('integration', ['publish:package'], async function () { | ||
53 | + let pkg = JSON.parse(fs.readFileSync(`${PROJECT_DIR}/package.json`).toString()); | ||
54 | + let version = pkg.version; | ||
55 | + | ||
56 | + proc.execSync('rm -rf ./node_modules'); | ||
57 | + // Install from the actual package, run tests from the packaged binary | ||
58 | + proc.execSync(`mkdir -p node_modules/.bin && mv ${PROJECT_DIR}/pkg/jake-v` + | ||
59 | + `${version} node_modules/jake && ln -s ${process.cwd()}` + | ||
60 | + '/node_modules/jake/bin/cli.js ./node_modules/.bin/jake'); | ||
61 | + | ||
62 | + let testArgs = []; | ||
63 | + if (process.env.filter) { | ||
64 | + testArgs.push(process.env.filter); | ||
65 | + } | ||
66 | + else { | ||
67 | + testArgs.push('*.js'); | ||
68 | + } | ||
69 | + let spawned = proc.spawn(`${PROJECT_DIR}/node_modules/.bin/mocha`, testArgs, { | ||
70 | + stdio: 'inherit' | ||
71 | + }); | ||
72 | + return new Promise((resolve, reject) => { | ||
73 | + spawned.on('exit', () => { | ||
74 | + if (!(process.env.noclobber || process.env.noClobber)) { | ||
75 | + proc.execSync('rm -rf tmp_publish && rm -rf package.json' + | ||
76 | + ' && rm -rf package-lock.json && rm -rf node_modules'); | ||
77 | + // Rather than invoking 'clobber' task | ||
78 | + jake.rmRf(`${PROJECT_DIR}/pkg`); | ||
79 | + } | ||
80 | + resolve(); | ||
81 | + }); | ||
82 | + }); | ||
83 | + | ||
84 | + }); | ||
85 | + | ||
86 | + integrationTest.directory = `${PROJECT_DIR}/test/integration`; | ||
87 | + | ||
88 | + let unitTest = task('unit', async function () { | ||
89 | + let testArgs = []; | ||
90 | + if (process.env.filter) { | ||
91 | + testArgs.push(process.env.filter); | ||
92 | + } | ||
93 | + else { | ||
94 | + testArgs.push('*.js'); | ||
95 | + } | ||
96 | + let spawned = proc.spawn(`${PROJECT_DIR}/node_modules/.bin/mocha`, testArgs, { | ||
97 | + stdio: 'inherit' | ||
98 | + }); | ||
99 | + }); | ||
100 | + | ||
101 | + unitTest.directory = `${PROJECT_DIR}/test/unit`; | ||
102 | +}); | ||
103 | + | ||
104 | +desc('Runs all tests'); | ||
105 | +task('test', ['test:unit', 'test:integration']); |
node_modules/jake/lib/api.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | +let { uuid } = require('./utils'); | ||
19 | + | ||
20 | +let api = new (function () { | ||
21 | + /** | ||
22 | + @name task | ||
23 | + @static | ||
24 | + @function | ||
25 | + @description Creates a Jake Task | ||
26 | + ` | ||
27 | + @param {String} name The name of the Task | ||
28 | + @param {Array} [prereqs] Prerequisites to be run before this task | ||
29 | + @param {Function} [action] The action to perform for this task | ||
30 | + @param {Object} [opts] | ||
31 | + @param {Boolean} [opts.asyc=false] Perform this task asynchronously. | ||
32 | + If you flag a task with this option, you must call the global | ||
33 | + `complete` method inside the task's action, for execution to proceed | ||
34 | + to the next task. | ||
35 | + | ||
36 | + @example | ||
37 | + desc('This is the default task.'); | ||
38 | + task('default', function (params) { | ||
39 | + console.log('This is the default task.'); | ||
40 | + }); | ||
41 | + | ||
42 | + desc('This task has prerequisites.'); | ||
43 | + task('hasPrereqs', ['foo', 'bar', 'baz'], function (params) { | ||
44 | + console.log('Ran some prereqs first.'); | ||
45 | + }); | ||
46 | + | ||
47 | + desc('This is an asynchronous task.'); | ||
48 | + task('asyncTask', function () { | ||
49 | + setTimeout(complete, 1000); | ||
50 | + }, {async: true}); | ||
51 | + */ | ||
52 | + this.task = function (name, prereqs, action, opts) { | ||
53 | + let args = Array.prototype.slice.call(arguments); | ||
54 | + let createdTask; | ||
55 | + args.unshift('task'); | ||
56 | + createdTask = jake.createTask.apply(global, args); | ||
57 | + jake.currentTaskDescription = null; | ||
58 | + return createdTask; | ||
59 | + }; | ||
60 | + | ||
61 | + /** | ||
62 | + @name rule | ||
63 | + @static | ||
64 | + @function | ||
65 | + @description Creates a Jake Suffix Rule | ||
66 | + ` | ||
67 | + @param {String} pattern The suffix name of the objective | ||
68 | + @param {String} source The suffix name of the objective | ||
69 | + @param {Array} [prereqs] Prerequisites to be run before this task | ||
70 | + @param {Function} [action] The action to perform for this task | ||
71 | + @param {Object} [opts] | ||
72 | + @param {Boolean} [opts.asyc=false] Perform this task asynchronously. | ||
73 | + If you flag a task with this option, you must call the global | ||
74 | + `complete` method inside the task's action, for execution to proceed | ||
75 | + to the next task. | ||
76 | + @example | ||
77 | + desc('This is a rule, which does not support namespace or pattern.'); | ||
78 | + rule('.o', '.c', {async: true}, function () { | ||
79 | + let cmd = util.format('gcc -o %s %s', this.name, this.source); | ||
80 | + jake.exec([cmd], function () { | ||
81 | + complete(); | ||
82 | + }, {printStdout: true}); | ||
83 | + }); | ||
84 | + | ||
85 | + desc('This rule has prerequisites.'); | ||
86 | + rule('.o', '.c', ['util.h'], {async: true}, function () { | ||
87 | + let cmd = util.format('gcc -o %s %s', this.name, this.source); | ||
88 | + jake.exec([cmd], function () { | ||
89 | + complete(); | ||
90 | + }, {printStdout: true}); | ||
91 | + }); | ||
92 | + | ||
93 | + desc('This is a rule with patterns.'); | ||
94 | + rule('%.o', '%.c', {async: true}, function () { | ||
95 | + let cmd = util.format('gcc -o %s %s', this.name, this.source); | ||
96 | + jake.exec([cmd], function () { | ||
97 | + complete(); | ||
98 | + }, {printStdout: true}); | ||
99 | + }); | ||
100 | + | ||
101 | + desc('This is another rule with patterns.'); | ||
102 | + rule('obj/%.o', 'src/%.c', {async: true}, function () { | ||
103 | + let cmd = util.format('gcc -o %s %s', this.name, this.source); | ||
104 | + jake.exec([cmd], function () { | ||
105 | + complete(); | ||
106 | + }, {printStdout: true}); | ||
107 | + }); | ||
108 | + | ||
109 | + desc('This is an example with chain rules.'); | ||
110 | + rule('%.pdf', '%.dvi', {async: true}, function () { | ||
111 | + let cmd = util.format('dvipdfm %s',this.source); | ||
112 | + jake.exec([cmd], function () { | ||
113 | + complete(); | ||
114 | + }, {printStdout: true}); | ||
115 | + }); | ||
116 | + | ||
117 | + rule('%.dvi', '%.tex', {async: true}, function () { | ||
118 | + let cmd = util.format('latex %s',this.source); | ||
119 | + jake.exec([cmd], function () { | ||
120 | + complete(); | ||
121 | + }, {printStdout: true}); | ||
122 | + }); | ||
123 | + | ||
124 | + desc('This rule has a namespace.'); | ||
125 | + task('default', ['debug:obj/main.o]); | ||
126 | + | ||
127 | + namespace('debug', {async: true}, function() { | ||
128 | + rule('obj/%.o', 'src/%.c', function () { | ||
129 | + // ... | ||
130 | + }); | ||
131 | + } | ||
132 | + */ | ||
133 | + this.rule = function () { | ||
134 | + let args = Array.prototype.slice.call(arguments); | ||
135 | + let arg; | ||
136 | + let pattern = args.shift(); | ||
137 | + let source = args.shift(); | ||
138 | + let prereqs = []; | ||
139 | + let action = function () {}; | ||
140 | + let opts = {}; | ||
141 | + let key = pattern.toString(); // May be a RegExp | ||
142 | + | ||
143 | + while ((arg = args.shift())) { | ||
144 | + if (typeof arg == 'function') { | ||
145 | + action = arg; | ||
146 | + } | ||
147 | + else if (Array.isArray(arg)) { | ||
148 | + prereqs = arg; | ||
149 | + } | ||
150 | + else { | ||
151 | + opts = arg; | ||
152 | + } | ||
153 | + } | ||
154 | + | ||
155 | + jake.currentNamespace.rules[key] = new jake.Rule({ | ||
156 | + pattern: pattern, | ||
157 | + source: source, | ||
158 | + prereqs: prereqs, | ||
159 | + action: action, | ||
160 | + opts: opts, | ||
161 | + desc: jake.currentTaskDescription, | ||
162 | + ns: jake.currentNamespace | ||
163 | + }); | ||
164 | + jake.currentTaskDescription = null; | ||
165 | + }; | ||
166 | + | ||
167 | + /** | ||
168 | + @name directory | ||
169 | + @static | ||
170 | + @function | ||
171 | + @description Creates a Jake DirectoryTask. Can be used as a prerequisite | ||
172 | + for FileTasks, or for simply ensuring a directory exists for use with a | ||
173 | + Task's action. | ||
174 | + ` | ||
175 | + @param {String} name The name of the DiretoryTask | ||
176 | + | ||
177 | + @example | ||
178 | + | ||
179 | + // Creates the package directory for distribution | ||
180 | + directory('pkg'); | ||
181 | + */ | ||
182 | + this.directory = function (name) { | ||
183 | + let args = Array.prototype.slice.call(arguments); | ||
184 | + let createdTask; | ||
185 | + args.unshift('directory'); | ||
186 | + createdTask = jake.createTask.apply(global, args); | ||
187 | + jake.currentTaskDescription = null; | ||
188 | + return createdTask; | ||
189 | + }; | ||
190 | + | ||
191 | + /** | ||
192 | + @name file | ||
193 | + @static | ||
194 | + @function | ||
195 | + @description Creates a Jake FileTask. | ||
196 | + ` | ||
197 | + @param {String} name The name of the FileTask | ||
198 | + @param {Array} [prereqs] Prerequisites to be run before this task | ||
199 | + @param {Function} [action] The action to create this file, if it doesn't | ||
200 | + exist already. | ||
201 | + @param {Object} [opts] | ||
202 | + @param {Array} [opts.asyc=false] Perform this task asynchronously. | ||
203 | + If you flag a task with this option, you must call the global | ||
204 | + `complete` method inside the task's action, for execution to proceed | ||
205 | + to the next task. | ||
206 | + | ||
207 | + */ | ||
208 | + this.file = function (name, prereqs, action, opts) { | ||
209 | + let args = Array.prototype.slice.call(arguments); | ||
210 | + let createdTask; | ||
211 | + args.unshift('file'); | ||
212 | + createdTask = jake.createTask.apply(global, args); | ||
213 | + jake.currentTaskDescription = null; | ||
214 | + return createdTask; | ||
215 | + }; | ||
216 | + | ||
217 | + /** | ||
218 | + @name desc | ||
219 | + @static | ||
220 | + @function | ||
221 | + @description Creates a description for a Jake Task (or FileTask, | ||
222 | + DirectoryTask). When invoked, the description that iscreated will | ||
223 | + be associated with whatever Task is created next. | ||
224 | + ` | ||
225 | + @param {String} description The description for the Task | ||
226 | + */ | ||
227 | + this.desc = function (description) { | ||
228 | + jake.currentTaskDescription = description; | ||
229 | + }; | ||
230 | + | ||
231 | + /** | ||
232 | + @name namespace | ||
233 | + @static | ||
234 | + @function | ||
235 | + @description Creates a namespace which allows logical grouping | ||
236 | + of tasks, and prevents name-collisions with task-names. Namespaces | ||
237 | + can be nested inside of other namespaces. | ||
238 | + ` | ||
239 | + @param {String} name The name of the namespace | ||
240 | + @param {Function} scope The enclosing scope for the namespaced tasks | ||
241 | + | ||
242 | + @example | ||
243 | + namespace('doc', function () { | ||
244 | + task('generate', ['doc:clobber'], function () { | ||
245 | + // Generate some docs | ||
246 | + }); | ||
247 | + | ||
248 | + task('clobber', function () { | ||
249 | + // Clobber the doc directory first | ||
250 | + }); | ||
251 | + }); | ||
252 | + */ | ||
253 | + this.namespace = function (name, closure) { | ||
254 | + let curr = jake.currentNamespace; | ||
255 | + let ns = curr.childNamespaces[name] || new jake.Namespace(name, curr); | ||
256 | + let fn = closure || function () {}; | ||
257 | + curr.childNamespaces[name] = ns; | ||
258 | + jake.currentNamespace = ns; | ||
259 | + fn(); | ||
260 | + jake.currentNamespace = curr; | ||
261 | + jake.currentTaskDescription = null; | ||
262 | + return ns; | ||
263 | + }; | ||
264 | + | ||
265 | + /** | ||
266 | + @name complete | ||
267 | + @static | ||
268 | + @function | ||
269 | + @description Completes an asynchronous task, allowing Jake's | ||
270 | + execution to proceed to the next task. Calling complete globally or without | ||
271 | + arguments completes the last task on the invocationChain. If you use parallel | ||
272 | + execution of prereqs this will probably complete a wrong task. You should call this | ||
273 | + function with this task as the first argument, before the optional return value. | ||
274 | + Alternatively you can call task.complete() | ||
275 | + ` | ||
276 | + @example | ||
277 | + task('generate', ['doc:clobber'], function () { | ||
278 | + exec('./generate_docs.sh', function (err, stdout, stderr) { | ||
279 | + if (err || stderr) { | ||
280 | + fail(err || stderr); | ||
281 | + } | ||
282 | + else { | ||
283 | + console.log(stdout); | ||
284 | + complete(); | ||
285 | + } | ||
286 | + }); | ||
287 | + }, {async: true}); | ||
288 | + */ | ||
289 | + this.complete = function (task, val) { | ||
290 | + //this should detect if the first arg is a task, but I guess it should be more thorough | ||
291 | + if(task && task. _currentPrereqIndex >=0 ) { | ||
292 | + task.complete(val); | ||
293 | + } | ||
294 | + else { | ||
295 | + val = task; | ||
296 | + if(jake._invocationChain.length > 0) { | ||
297 | + jake._invocationChain[jake._invocationChain.length-1].complete(val); | ||
298 | + } | ||
299 | + } | ||
300 | + }; | ||
301 | + | ||
302 | + /** | ||
303 | + @name fail | ||
304 | + @static | ||
305 | + @function | ||
306 | + @description Causes Jake execution to abort with an error. | ||
307 | + Allows passing an optional error code, which will be used to | ||
308 | + set the exit-code of exiting process. | ||
309 | + ` | ||
310 | + @param {Error|String} err The error to thow when aborting execution. | ||
311 | + If this argument is an Error object, it will simply be thrown. If | ||
312 | + a String, it will be used as the error-message. (If it is a multi-line | ||
313 | + String, the first line will be used as the Error message, and the | ||
314 | + remaining lines will be used as the error-stack.) | ||
315 | + | ||
316 | + @example | ||
317 | + task('createTests, function () { | ||
318 | + if (!fs.existsSync('./tests')) { | ||
319 | + fail('Test directory does not exist.'); | ||
320 | + } | ||
321 | + else { | ||
322 | + // Do some testing stuff ... | ||
323 | + } | ||
324 | + }); | ||
325 | + */ | ||
326 | + this.fail = function (err, code) { | ||
327 | + let msg; | ||
328 | + let errObj; | ||
329 | + if (code) { | ||
330 | + jake.errorCode = code; | ||
331 | + } | ||
332 | + if (err) { | ||
333 | + if (typeof err == 'string') { | ||
334 | + // Use the initial or only line of the error as the error-message | ||
335 | + // If there was a multi-line error, use the rest as the stack | ||
336 | + msg = err.split('\n'); | ||
337 | + errObj = new Error(msg.shift()); | ||
338 | + if (msg.length) { | ||
339 | + errObj.stack = msg.join('\n'); | ||
340 | + } | ||
341 | + throw errObj; | ||
342 | + } | ||
343 | + else if (err instanceof Error) { | ||
344 | + throw err; | ||
345 | + } | ||
346 | + else { | ||
347 | + throw new Error(err.toString()); | ||
348 | + } | ||
349 | + } | ||
350 | + else { | ||
351 | + throw new Error(); | ||
352 | + } | ||
353 | + }; | ||
354 | + | ||
355 | + this.packageTask = function (name, version, prereqs, definition) { | ||
356 | + return new jake.PackageTask(name, version, prereqs, definition); | ||
357 | + }; | ||
358 | + | ||
359 | + this.publishTask = function (name, prereqs, opts, definition) { | ||
360 | + return new jake.PublishTask(name, prereqs, opts, definition); | ||
361 | + }; | ||
362 | + | ||
363 | + // Backward-compat | ||
364 | + this.npmPublishTask = function (name, prereqs, opts, definition) { | ||
365 | + return new jake.PublishTask(name, prereqs, opts, definition); | ||
366 | + }; | ||
367 | + | ||
368 | + this.testTask = function () { | ||
369 | + let ctor = function () {}; | ||
370 | + let t; | ||
371 | + ctor.prototype = jake.TestTask.prototype; | ||
372 | + t = new ctor(); | ||
373 | + jake.TestTask.apply(t, arguments); | ||
374 | + return t; | ||
375 | + }; | ||
376 | + | ||
377 | + this.setTaskTimeout = function (t) { | ||
378 | + this._taskTimeout = t; | ||
379 | + }; | ||
380 | + | ||
381 | + this.setSeriesAutoPrefix = function (prefix) { | ||
382 | + this._seriesAutoPrefix = prefix; | ||
383 | + }; | ||
384 | + | ||
385 | + this.series = function (...args) { | ||
386 | + let prereqs = args.map((arg) => { | ||
387 | + let name = (this._seriesAutoPrefix || '') + arg.name; | ||
388 | + jake.task(name, arg); | ||
389 | + return name; | ||
390 | + }); | ||
391 | + let seriesName = uuid(); | ||
392 | + let seriesTask = jake.task(seriesName, prereqs); | ||
393 | + seriesTask._internal = true; | ||
394 | + let res = function () { | ||
395 | + return new Promise((resolve) => { | ||
396 | + seriesTask.invoke(); | ||
397 | + seriesTask.on('complete', (val) => { | ||
398 | + resolve(val); | ||
399 | + }); | ||
400 | + }); | ||
401 | + }; | ||
402 | + Object.defineProperty(res, 'name', {value: uuid(), | ||
403 | + writable: false}); | ||
404 | + return res; | ||
405 | + }; | ||
406 | + | ||
407 | +})(); | ||
408 | + | ||
409 | +module.exports = api; |
node_modules/jake/lib/jake.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +if (!global.jake) { | ||
20 | + | ||
21 | + let EventEmitter = require('events').EventEmitter; | ||
22 | + // And so it begins | ||
23 | + global.jake = new EventEmitter(); | ||
24 | + | ||
25 | + let fs = require('fs'); | ||
26 | + let chalk = require('chalk'); | ||
27 | + let taskNs = require('./task'); | ||
28 | + let Task = taskNs.Task; | ||
29 | + let FileTask = taskNs.FileTask; | ||
30 | + let DirectoryTask = taskNs.DirectoryTask; | ||
31 | + let Rule = require('./rule').Rule; | ||
32 | + let Namespace = require('./namespace').Namespace; | ||
33 | + let RootNamespace = require('./namespace').RootNamespace; | ||
34 | + let api = require('./api'); | ||
35 | + let utils = require('./utils'); | ||
36 | + let Program = require('./program').Program; | ||
37 | + let loader = require('./loader')(); | ||
38 | + let pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString()); | ||
39 | + | ||
40 | + const MAX_RULE_RECURSION_LEVEL = 16; | ||
41 | + | ||
42 | + // Globalize jake and top-level API methods (e.g., `task`, `desc`) | ||
43 | + Object.assign(global, api); | ||
44 | + | ||
45 | + // Copy utils onto base jake | ||
46 | + jake.logger = utils.logger; | ||
47 | + jake.exec = utils.exec; | ||
48 | + | ||
49 | + // File utils should be aliased directly on base jake as well | ||
50 | + Object.assign(jake, utils.file); | ||
51 | + | ||
52 | + // Also add top-level API methods to exported object for those who don't want to | ||
53 | + // use the globals (`file` here will overwrite the 'file' utils namespace) | ||
54 | + Object.assign(jake, api); | ||
55 | + | ||
56 | + Object.assign(jake, new (function () { | ||
57 | + | ||
58 | + this._invocationChain = []; | ||
59 | + this._taskTimeout = 30000; | ||
60 | + | ||
61 | + // Public properties | ||
62 | + // ================= | ||
63 | + this.version = pkg.version; | ||
64 | + // Used when Jake exits with a specific error-code | ||
65 | + this.errorCode = null; | ||
66 | + // Loads Jakefiles/jakelibdirs | ||
67 | + this.loader = loader; | ||
68 | + // The root of all ... namespaces | ||
69 | + this.rootNamespace = new RootNamespace(); | ||
70 | + // Non-namespaced tasks are placed into the default | ||
71 | + this.defaultNamespace = this.rootNamespace; | ||
72 | + // Start in the default | ||
73 | + this.currentNamespace = this.defaultNamespace; | ||
74 | + // Saves the description created by a 'desc' call that prefaces a | ||
75 | + // 'task' call that defines a task. | ||
76 | + this.currentTaskDescription = null; | ||
77 | + this.program = new Program(); | ||
78 | + this.FileList = require('filelist').FileList; | ||
79 | + this.PackageTask = require('./package_task').PackageTask; | ||
80 | + this.PublishTask = require('./publish_task').PublishTask; | ||
81 | + this.TestTask = require('./test_task').TestTask; | ||
82 | + this.Task = Task; | ||
83 | + this.FileTask = FileTask; | ||
84 | + this.DirectoryTask = DirectoryTask; | ||
85 | + this.Namespace = Namespace; | ||
86 | + this.Rule = Rule; | ||
87 | + | ||
88 | + this.parseAllTasks = function () { | ||
89 | + let _parseNs = function (ns) { | ||
90 | + let nsTasks = ns.tasks; | ||
91 | + let nsNamespaces = ns.childNamespaces; | ||
92 | + for (let q in nsTasks) { | ||
93 | + let nsTask = nsTasks[q]; | ||
94 | + jake.Task[nsTask.fullName] = nsTask; | ||
95 | + } | ||
96 | + for (let p in nsNamespaces) { | ||
97 | + let nsNamespace = nsNamespaces[p]; | ||
98 | + _parseNs(nsNamespace); | ||
99 | + } | ||
100 | + }; | ||
101 | + _parseNs(jake.defaultNamespace); | ||
102 | + }; | ||
103 | + | ||
104 | + /** | ||
105 | + * Displays the list of descriptions avaliable for tasks defined in | ||
106 | + * a Jakefile | ||
107 | + */ | ||
108 | + this.showAllTaskDescriptions = function (f) { | ||
109 | + let p; | ||
110 | + let maxTaskNameLength = 0; | ||
111 | + let task; | ||
112 | + let padding; | ||
113 | + let name; | ||
114 | + let descr; | ||
115 | + let filter = typeof f == 'string' ? f : null; | ||
116 | + | ||
117 | + for (p in jake.Task) { | ||
118 | + if (!Object.prototype.hasOwnProperty.call(jake.Task, p)) { | ||
119 | + continue; | ||
120 | + } | ||
121 | + if (filter && p.indexOf(filter) == -1) { | ||
122 | + continue; | ||
123 | + } | ||
124 | + task = jake.Task[p]; | ||
125 | + // Record the length of the longest task name -- used for | ||
126 | + // pretty alignment of the task descriptions | ||
127 | + if (task.description) { | ||
128 | + maxTaskNameLength = p.length > maxTaskNameLength ? | ||
129 | + p.length : maxTaskNameLength; | ||
130 | + } | ||
131 | + } | ||
132 | + // Print out each entry with descriptions neatly aligned | ||
133 | + for (p in jake.Task) { | ||
134 | + if (!Object.prototype.hasOwnProperty.call(jake.Task, p)) { | ||
135 | + continue; | ||
136 | + } | ||
137 | + if (filter && p.indexOf(filter) == -1) { | ||
138 | + continue; | ||
139 | + } | ||
140 | + task = jake.Task[p]; | ||
141 | + | ||
142 | + //name = '\033[32m' + p + '\033[39m '; | ||
143 | + name = chalk.green(p); | ||
144 | + | ||
145 | + descr = task.description; | ||
146 | + if (descr) { | ||
147 | + descr = chalk.gray('# ' + descr); | ||
148 | + | ||
149 | + // Create padding-string with calculated length | ||
150 | + padding = (new Array(maxTaskNameLength - p.length + 2)).join(' '); | ||
151 | + | ||
152 | + console.log('jake ' + name + padding + descr); | ||
153 | + } | ||
154 | + } | ||
155 | + }; | ||
156 | + | ||
157 | + this.createTask = function () { | ||
158 | + let args = Array.prototype.slice.call(arguments); | ||
159 | + let arg; | ||
160 | + let obj; | ||
161 | + let task; | ||
162 | + let type; | ||
163 | + let name; | ||
164 | + let action; | ||
165 | + let opts = {}; | ||
166 | + let prereqs = []; | ||
167 | + | ||
168 | + type = args.shift(); | ||
169 | + | ||
170 | + // name, [deps], [action] | ||
171 | + // Name (string) + deps (array) format | ||
172 | + if (typeof args[0] == 'string') { | ||
173 | + name = args.shift(); | ||
174 | + if (Array.isArray(args[0])) { | ||
175 | + prereqs = args.shift(); | ||
176 | + } | ||
177 | + } | ||
178 | + // name:deps, [action] | ||
179 | + // Legacy object-literal syntax, e.g.: {'name': ['depA', 'depB']} | ||
180 | + else { | ||
181 | + obj = args.shift(); | ||
182 | + for (let p in obj) { | ||
183 | + prereqs = prereqs.concat(obj[p]); | ||
184 | + name = p; | ||
185 | + } | ||
186 | + } | ||
187 | + | ||
188 | + // Optional opts/callback or callback/opts | ||
189 | + while ((arg = args.shift())) { | ||
190 | + if (typeof arg == 'function') { | ||
191 | + action = arg; | ||
192 | + } | ||
193 | + else { | ||
194 | + opts = Object.assign(Object.create(null), arg); | ||
195 | + } | ||
196 | + } | ||
197 | + | ||
198 | + task = jake.currentNamespace.resolveTask(name); | ||
199 | + if (task && !action) { | ||
200 | + // Task already exists and no action, just update prereqs, and return it. | ||
201 | + task.prereqs = task.prereqs.concat(prereqs); | ||
202 | + return task; | ||
203 | + } | ||
204 | + | ||
205 | + switch (type) { | ||
206 | + case 'directory': | ||
207 | + action = function () { | ||
208 | + jake.mkdirP(name); | ||
209 | + }; | ||
210 | + task = new DirectoryTask(name, prereqs, action, opts); | ||
211 | + break; | ||
212 | + case 'file': | ||
213 | + task = new FileTask(name, prereqs, action, opts); | ||
214 | + break; | ||
215 | + default: | ||
216 | + task = new Task(name, prereqs, action, opts); | ||
217 | + } | ||
218 | + | ||
219 | + jake.currentNamespace.addTask(task); | ||
220 | + | ||
221 | + if (jake.currentTaskDescription) { | ||
222 | + task.description = jake.currentTaskDescription; | ||
223 | + jake.currentTaskDescription = null; | ||
224 | + } | ||
225 | + | ||
226 | + // FIXME: Should only need to add a new entry for the current | ||
227 | + // task-definition, not reparse the entire structure | ||
228 | + jake.parseAllTasks(); | ||
229 | + | ||
230 | + return task; | ||
231 | + }; | ||
232 | + | ||
233 | + this.attemptRule = function (name, ns, level) { | ||
234 | + let prereqRule; | ||
235 | + let prereq; | ||
236 | + if (level > MAX_RULE_RECURSION_LEVEL) { | ||
237 | + return null; | ||
238 | + } | ||
239 | + // Check Rule | ||
240 | + prereqRule = ns.matchRule(name); | ||
241 | + if (prereqRule) { | ||
242 | + prereq = prereqRule.createTask(name, level); | ||
243 | + } | ||
244 | + return prereq || null; | ||
245 | + }; | ||
246 | + | ||
247 | + this.createPlaceholderFileTask = function (name, namespace) { | ||
248 | + let parsed = name.split(':'); | ||
249 | + let filePath = parsed.pop(); // Strip any namespace | ||
250 | + let task; | ||
251 | + | ||
252 | + task = namespace.resolveTask(name); | ||
253 | + | ||
254 | + // If there's not already an existing dummy FileTask for it, | ||
255 | + // create one | ||
256 | + if (!task) { | ||
257 | + // Create a dummy FileTask only if file actually exists | ||
258 | + if (fs.existsSync(filePath)) { | ||
259 | + task = new jake.FileTask(filePath); | ||
260 | + task.dummy = true; | ||
261 | + let ns; | ||
262 | + if (parsed.length) { | ||
263 | + ns = namespace.resolveNamespace(parsed.join(':')); | ||
264 | + } | ||
265 | + else { | ||
266 | + ns = namespace; | ||
267 | + } | ||
268 | + if (!namespace) { | ||
269 | + throw new Error('Invalid namespace, cannot add FileTask'); | ||
270 | + } | ||
271 | + ns.addTask(task); | ||
272 | + // Put this dummy Task in the global Tasks list so | ||
273 | + // modTime will be eval'd correctly | ||
274 | + jake.Task[`${ns.path}:${filePath}`] = task; | ||
275 | + } | ||
276 | + } | ||
277 | + | ||
278 | + return task || null; | ||
279 | + }; | ||
280 | + | ||
281 | + | ||
282 | + this.run = function () { | ||
283 | + let args = Array.prototype.slice.call(arguments); | ||
284 | + let program = this.program; | ||
285 | + let loader = this.loader; | ||
286 | + let preempt; | ||
287 | + let opts; | ||
288 | + | ||
289 | + program.parseArgs(args); | ||
290 | + program.init(); | ||
291 | + | ||
292 | + preempt = program.firstPreemptiveOption(); | ||
293 | + if (preempt) { | ||
294 | + preempt(); | ||
295 | + } | ||
296 | + else { | ||
297 | + opts = program.opts; | ||
298 | + // jakefile flag set but no jakefile yet | ||
299 | + if (opts.autocomplete && opts.jakefile === true) { | ||
300 | + process.stdout.write('no-complete'); | ||
301 | + return; | ||
302 | + } | ||
303 | + // Load Jakefile and jakelibdir files | ||
304 | + let jakefileLoaded = loader.loadFile(opts.jakefile); | ||
305 | + let jakelibdirLoaded = loader.loadDirectory(opts.jakelibdir); | ||
306 | + | ||
307 | + if(!jakefileLoaded && !jakelibdirLoaded && !opts.autocomplete) { | ||
308 | + fail('No Jakefile. Specify a valid path with -f/--jakefile, ' + | ||
309 | + 'or place one in the current directory.'); | ||
310 | + } | ||
311 | + | ||
312 | + program.run(); | ||
313 | + } | ||
314 | + }; | ||
315 | + | ||
316 | + })()); | ||
317 | +} | ||
318 | + | ||
319 | +module.exports = jake; |
node_modules/jake/lib/loader.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let path = require('path'); | ||
20 | +let fs = require('fs'); | ||
21 | +let existsSync = fs.existsSync; | ||
22 | +let utils = require('./utils'); | ||
23 | + | ||
24 | +// Files like jakelib/foobar.jake.js | ||
25 | +const JAKELIB_FILE_PAT = /\.jake$|\.js$/; | ||
26 | +const SUPPORTED_EXTENSIONS = { | ||
27 | + 'js': null, | ||
28 | + 'coffee': function () { | ||
29 | + try { | ||
30 | + let cs = require('coffeescript'); | ||
31 | + if (typeof cs.register == 'function') { | ||
32 | + cs.register(); | ||
33 | + } | ||
34 | + } | ||
35 | + catch(e) { | ||
36 | + throw new Error('You have a CoffeeScript Jakefile, but have not installed CoffeeScript'); | ||
37 | + } | ||
38 | + }, | ||
39 | + 'ls': function () { | ||
40 | + try { | ||
41 | + require('livescript'); | ||
42 | + } | ||
43 | + catch (e) { | ||
44 | + throw new Error('You have a LiveScript Jakefile, but have not installed LiveScript'); | ||
45 | + } | ||
46 | + } | ||
47 | +}; | ||
48 | +const IMPLICIT_JAKEFILE_NAMES = [ | ||
49 | + 'Jakefile', | ||
50 | + 'Gulpfile' | ||
51 | +]; | ||
52 | + | ||
53 | +let Loader = function () { | ||
54 | + // Load a Jakefile, running the code inside -- this may result in | ||
55 | + // tasks getting defined using the original Jake API, e.g., | ||
56 | + // `task('foo' ['bar', 'baz']);`, or can also auto-create tasks | ||
57 | + // from any functions exported from the file | ||
58 | + function loadFile(filePath) { | ||
59 | + let exported = require(filePath); | ||
60 | + for (let [key, value] of Object.entries(exported)) { | ||
61 | + let t; | ||
62 | + if (typeof value == 'function') { | ||
63 | + t = jake.task(key, value); | ||
64 | + t.description = '(Exported function)'; | ||
65 | + } | ||
66 | + } | ||
67 | + } | ||
68 | + | ||
69 | + function fileExists(name) { | ||
70 | + let nameWithExt = null; | ||
71 | + // Support no file extension as well | ||
72 | + let exts = Object.keys(SUPPORTED_EXTENSIONS).concat(['']); | ||
73 | + exts.some((ext) => { | ||
74 | + let fname = ext ? `${name}.${ext}` : name; | ||
75 | + if (existsSync(fname)) { | ||
76 | + nameWithExt = fname; | ||
77 | + return true; | ||
78 | + } | ||
79 | + }); | ||
80 | + return nameWithExt; | ||
81 | + } | ||
82 | + | ||
83 | + // Recursive | ||
84 | + function findImplicitJakefile() { | ||
85 | + let cwd = process.cwd(); | ||
86 | + let names = IMPLICIT_JAKEFILE_NAMES; | ||
87 | + let found = null; | ||
88 | + names.some((name) => { | ||
89 | + let n; | ||
90 | + // Prefer all-lowercase | ||
91 | + n = name.toLowerCase(); | ||
92 | + if ((found = fileExists(n))) { | ||
93 | + return found; | ||
94 | + } | ||
95 | + // Check mixed-case as well | ||
96 | + n = name; | ||
97 | + if ((found = fileExists(n))) { | ||
98 | + return found; | ||
99 | + } | ||
100 | + }); | ||
101 | + if (found) { | ||
102 | + return found; | ||
103 | + } | ||
104 | + else { | ||
105 | + process.chdir(".."); | ||
106 | + // If we've walked all the way up the directory tree, | ||
107 | + // bail out with no result | ||
108 | + if (cwd === process.cwd()) { | ||
109 | + return null; | ||
110 | + } | ||
111 | + return findImplicitJakefile(); | ||
112 | + } | ||
113 | + } | ||
114 | + | ||
115 | + this.loadFile = function (fileSpecified) { | ||
116 | + let jakefile; | ||
117 | + let origCwd = process.cwd(); | ||
118 | + | ||
119 | + if (fileSpecified) { | ||
120 | + if (existsSync(fileSpecified)) { | ||
121 | + jakefile = fileSpecified; | ||
122 | + } | ||
123 | + } | ||
124 | + else { | ||
125 | + jakefile = findImplicitJakefile(); | ||
126 | + } | ||
127 | + | ||
128 | + if (jakefile) { | ||
129 | + let ext = jakefile.split('.')[1]; | ||
130 | + let loaderFunc = SUPPORTED_EXTENSIONS[ext]; | ||
131 | + loaderFunc && loaderFunc(); | ||
132 | + | ||
133 | + loadFile(utils.file.absolutize(jakefile)); | ||
134 | + return true; | ||
135 | + } | ||
136 | + else { | ||
137 | + if (!fileSpecified) { | ||
138 | + // Restore the working directory on failure | ||
139 | + process.chdir(origCwd); | ||
140 | + } | ||
141 | + return false; | ||
142 | + } | ||
143 | + }; | ||
144 | + | ||
145 | + this.loadDirectory = function (d) { | ||
146 | + let dirname = d || 'jakelib'; | ||
147 | + let dirlist; | ||
148 | + dirname = utils.file.absolutize(dirname); | ||
149 | + if (existsSync(dirname)) { | ||
150 | + dirlist = fs.readdirSync(dirname); | ||
151 | + dirlist.forEach(function (filePath) { | ||
152 | + if (JAKELIB_FILE_PAT.test(filePath)) { | ||
153 | + loadFile(path.join(dirname, filePath)); | ||
154 | + } | ||
155 | + }); | ||
156 | + return true; | ||
157 | + } | ||
158 | + return false; | ||
159 | + }; | ||
160 | + | ||
161 | +}; | ||
162 | + | ||
163 | +module.exports = function () { | ||
164 | + return new Loader(); | ||
165 | +}; |
node_modules/jake/lib/namespace.js
0 → 100644
1 | +const ROOT_NAMESPACE_NAME = '__rootNamespace__'; | ||
2 | + | ||
3 | +class Namespace { | ||
4 | + constructor(name, parentNamespace) { | ||
5 | + this.name = name; | ||
6 | + this.parentNamespace = parentNamespace; | ||
7 | + this.childNamespaces = {}; | ||
8 | + this.tasks = {}; | ||
9 | + this.rules = {}; | ||
10 | + this.path = this.getPath(); | ||
11 | + } | ||
12 | + | ||
13 | + get fullName() { | ||
14 | + return this._getFullName(); | ||
15 | + } | ||
16 | + | ||
17 | + addTask(task) { | ||
18 | + this.tasks[task.name] = task; | ||
19 | + task.namespace = this; | ||
20 | + } | ||
21 | + | ||
22 | + resolveTask(name) { | ||
23 | + if (!name) { | ||
24 | + return; | ||
25 | + } | ||
26 | + | ||
27 | + let taskPath = name.split(':'); | ||
28 | + let taskName = taskPath.pop(); | ||
29 | + let task; | ||
30 | + let ns; | ||
31 | + | ||
32 | + // Namespaced, return either relative to current, or from root | ||
33 | + if (taskPath.length) { | ||
34 | + taskPath = taskPath.join(':'); | ||
35 | + ns = this.resolveNamespace(taskPath) || | ||
36 | + Namespace.ROOT_NAMESPACE.resolveNamespace(taskPath); | ||
37 | + task = (ns && ns.resolveTask(taskName)); | ||
38 | + } | ||
39 | + // Bare task, return either local, or top-level | ||
40 | + else { | ||
41 | + task = this.tasks[name] || Namespace.ROOT_NAMESPACE.tasks[name]; | ||
42 | + } | ||
43 | + | ||
44 | + return task || null; | ||
45 | + } | ||
46 | + | ||
47 | + | ||
48 | + resolveNamespace(relativeName) { | ||
49 | + if (!relativeName) { | ||
50 | + return this; | ||
51 | + } | ||
52 | + | ||
53 | + let parts = relativeName.split(':'); | ||
54 | + let ns = this; | ||
55 | + | ||
56 | + for (let i = 0, ii = parts.length; (ns && i < ii); i++) { | ||
57 | + ns = ns.childNamespaces[parts[i]]; | ||
58 | + } | ||
59 | + | ||
60 | + return ns || null; | ||
61 | + } | ||
62 | + | ||
63 | + matchRule(relativeName) { | ||
64 | + let parts = relativeName.split(':'); | ||
65 | + parts.pop(); | ||
66 | + let ns = this.resolveNamespace(parts.join(':')); | ||
67 | + let rules = ns ? ns.rules : []; | ||
68 | + let r; | ||
69 | + let match; | ||
70 | + | ||
71 | + for (let p in rules) { | ||
72 | + r = rules[p]; | ||
73 | + if (r.match(relativeName)) { | ||
74 | + match = r; | ||
75 | + } | ||
76 | + } | ||
77 | + | ||
78 | + return (ns && match) || | ||
79 | + (this.parentNamespace && | ||
80 | + this.parentNamespace.matchRule(relativeName)); | ||
81 | + } | ||
82 | + | ||
83 | + getPath() { | ||
84 | + let parts = []; | ||
85 | + let next = this.parentNamespace; | ||
86 | + while (next) { | ||
87 | + parts.push(next.name); | ||
88 | + next = next.parentNamespace; | ||
89 | + } | ||
90 | + parts.pop(); // Remove '__rootNamespace__' | ||
91 | + return parts.reverse().join(':'); | ||
92 | + } | ||
93 | + | ||
94 | + _getFullName() { | ||
95 | + let path = this.path; | ||
96 | + path = (path && path.split(':')) || []; | ||
97 | + path.push(this.name); | ||
98 | + return path.join(':'); | ||
99 | + } | ||
100 | + | ||
101 | + isRootNamespace() { | ||
102 | + return !this.parentNamespace; | ||
103 | + } | ||
104 | +} | ||
105 | + | ||
106 | +class RootNamespace extends Namespace { | ||
107 | + constructor() { | ||
108 | + super(ROOT_NAMESPACE_NAME, null); | ||
109 | + Namespace.ROOT_NAMESPACE = this; | ||
110 | + } | ||
111 | +} | ||
112 | + | ||
113 | +module.exports.Namespace = Namespace; | ||
114 | +module.exports.RootNamespace = RootNamespace; | ||
115 | + |
node_modules/jake/lib/package_task.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let path = require('path'); | ||
20 | +let fs = require('fs'); | ||
21 | +let exec = require('child_process').exec; | ||
22 | +let FileList = require('filelist').FileList; | ||
23 | + | ||
24 | +/** | ||
25 | + @name jake | ||
26 | + @namespace jake | ||
27 | +*/ | ||
28 | +/** | ||
29 | + @name jake.PackageTask | ||
30 | + @constructor | ||
31 | + @description Instantiating a PackageTask creates a number of Jake | ||
32 | + Tasks that make packaging and distributing your software easy. | ||
33 | + | ||
34 | + @param {String} name The name of the project | ||
35 | + @param {String} version The current project version (will be | ||
36 | + appended to the project-name in the package-archive | ||
37 | + @param {Function} definition Defines the contents of the package, | ||
38 | + and format of the package-archive. Will be executed on the instantiated | ||
39 | + PackageTask (i.e., 'this', will be the PackageTask instance), | ||
40 | + to set the various instance-propertiess. | ||
41 | + | ||
42 | + @example | ||
43 | + let t = new jake.PackageTask('rous', 'v' + version, function () { | ||
44 | + let files = [ | ||
45 | + 'Capfile' | ||
46 | + , 'Jakefile' | ||
47 | + , 'README.md' | ||
48 | + , 'package.json' | ||
49 | + , 'app/*' | ||
50 | + , 'bin/*' | ||
51 | + , 'config/*' | ||
52 | + , 'lib/*' | ||
53 | + , 'node_modules/*' | ||
54 | + ]; | ||
55 | + this.packageFiles.include(files); | ||
56 | + this.packageFiles.exclude('node_modules/foobar'); | ||
57 | + this.needTarGz = true; | ||
58 | + }); | ||
59 | + | ||
60 | + */ | ||
61 | +let PackageTask = function () { | ||
62 | + let args = Array.prototype.slice.call(arguments); | ||
63 | + let name = args.shift(); | ||
64 | + let version = args.shift(); | ||
65 | + let definition = args.pop(); | ||
66 | + let prereqs = args.pop() || []; // Optional | ||
67 | + | ||
68 | + prereqs = [].concat(prereqs); // Accept string or list | ||
69 | + | ||
70 | + /** | ||
71 | + @name jake.PackageTask#name | ||
72 | + @public | ||
73 | + @type {String} | ||
74 | + @description The name of the project | ||
75 | + */ | ||
76 | + this.name = name; | ||
77 | + /** | ||
78 | + @name jake.PackageTask#version | ||
79 | + @public | ||
80 | + @type {String} | ||
81 | + @description The project version-string | ||
82 | + */ | ||
83 | + this.version = version; | ||
84 | + /** | ||
85 | + @name jake.PackageTask#prereqs | ||
86 | + @public | ||
87 | + @type {Array} | ||
88 | + @description Tasks to run before packaging | ||
89 | + */ | ||
90 | + this.prereqs = prereqs; | ||
91 | + /** | ||
92 | + @name jake.PackageTask#packageDir | ||
93 | + @public | ||
94 | + @type {String='pkg'} | ||
95 | + @description The directory-name to use for packaging the software | ||
96 | + */ | ||
97 | + this.packageDir = 'pkg'; | ||
98 | + /** | ||
99 | + @name jake.PackageTask#packageFiles | ||
100 | + @public | ||
101 | + @type {jake.FileList} | ||
102 | + @description The list of files and directories to include in the | ||
103 | + package-archive | ||
104 | + */ | ||
105 | + this.packageFiles = new FileList(); | ||
106 | + /** | ||
107 | + @name jake.PackageTask#needTar | ||
108 | + @public | ||
109 | + @type {Boolean=false} | ||
110 | + @description If set to true, uses the `tar` utility to create | ||
111 | + a gzip .tgz archive of the package | ||
112 | + */ | ||
113 | + this.needTar = false; | ||
114 | + /** | ||
115 | + @name jake.PackageTask#needTarGz | ||
116 | + @public | ||
117 | + @type {Boolean=false} | ||
118 | + @description If set to true, uses the `tar` utility to create | ||
119 | + a gzip .tar.gz archive of the package | ||
120 | + */ | ||
121 | + this.needTarGz = false; | ||
122 | + /** | ||
123 | + @name jake.PackageTask#needTarBz2 | ||
124 | + @public | ||
125 | + @type {Boolean=false} | ||
126 | + @description If set to true, uses the `tar` utility to create | ||
127 | + a bzip2 .bz2 archive of the package | ||
128 | + */ | ||
129 | + this.needTarBz2 = false; | ||
130 | + /** | ||
131 | + @name jake.PackageTask#needJar | ||
132 | + @public | ||
133 | + @type {Boolean=false} | ||
134 | + @description If set to true, uses the `jar` utility to create | ||
135 | + a .jar archive of the package | ||
136 | + */ | ||
137 | + this.needJar = false; | ||
138 | + /** | ||
139 | + @name jake.PackageTask#needZip | ||
140 | + @public | ||
141 | + @type {Boolean=false} | ||
142 | + @description If set to true, uses the `zip` utility to create | ||
143 | + a .zip archive of the package | ||
144 | + */ | ||
145 | + this.needZip = false; | ||
146 | + /** | ||
147 | + @name jake.PackageTask#manifestFile | ||
148 | + @public | ||
149 | + @type {String=null} | ||
150 | + @description Can be set to point the `jar` utility at a manifest | ||
151 | + file to use in a .jar archive. If unset, one will be automatically | ||
152 | + created by the `jar` utility. This path should be relative to the | ||
153 | + root of the package directory (this.packageDir above, likely 'pkg') | ||
154 | + */ | ||
155 | + this.manifestFile = null; | ||
156 | + /** | ||
157 | + @name jake.PackageTask#tarCommand | ||
158 | + @public | ||
159 | + @type {String='tar'} | ||
160 | + @description The shell-command to use for creating tar archives. | ||
161 | + */ | ||
162 | + this.tarCommand = 'tar'; | ||
163 | + /** | ||
164 | + @name jake.PackageTask#jarCommand | ||
165 | + @public | ||
166 | + @type {String='jar'} | ||
167 | + @description The shell-command to use for creating jar archives. | ||
168 | + */ | ||
169 | + this.jarCommand = 'jar'; | ||
170 | + /** | ||
171 | + @name jake.PackageTask#zipCommand | ||
172 | + @public | ||
173 | + @type {String='zip'} | ||
174 | + @description The shell-command to use for creating zip archives. | ||
175 | + */ | ||
176 | + this.zipCommand = 'zip'; | ||
177 | + /** | ||
178 | + @name jake.PackageTask#archiveNoBaseDir | ||
179 | + @public | ||
180 | + @type {Boolean=false} | ||
181 | + @description Simple option for performing the archive on the | ||
182 | + contents of the directory instead of the directory itself | ||
183 | + */ | ||
184 | + this.archiveNoBaseDir = false; | ||
185 | + /** | ||
186 | + @name jake.PackageTask#archiveChangeDir | ||
187 | + @public | ||
188 | + @type {String=null} | ||
189 | + @description Equivalent to the '-C' command for the `tar` and `jar` | ||
190 | + commands. ("Change to this directory before adding files.") | ||
191 | + */ | ||
192 | + this.archiveChangeDir = null; | ||
193 | + /** | ||
194 | + @name jake.PackageTask#archiveContentDir | ||
195 | + @public | ||
196 | + @type {String=null} | ||
197 | + @description Specifies the files and directories to include in the | ||
198 | + package-archive. If unset, this will default to the main package | ||
199 | + directory -- i.e., name + version. | ||
200 | + */ | ||
201 | + this.archiveContentDir = null; | ||
202 | + | ||
203 | + if (typeof definition == 'function') { | ||
204 | + definition.call(this); | ||
205 | + } | ||
206 | + this.define(); | ||
207 | +}; | ||
208 | + | ||
209 | +PackageTask.prototype = new (function () { | ||
210 | + | ||
211 | + let _compressOpts = { | ||
212 | + Tar: { | ||
213 | + ext: '.tgz', | ||
214 | + flags: 'czf', | ||
215 | + cmd: 'tar' | ||
216 | + }, | ||
217 | + TarGz: { | ||
218 | + ext: '.tar.gz', | ||
219 | + flags: 'czf', | ||
220 | + cmd: 'tar' | ||
221 | + }, | ||
222 | + TarBz2: { | ||
223 | + ext: '.tar.bz2', | ||
224 | + flags: 'cjf', | ||
225 | + cmd: 'tar' | ||
226 | + }, | ||
227 | + Jar: { | ||
228 | + ext: '.jar', | ||
229 | + flags: 'cf', | ||
230 | + cmd: 'jar' | ||
231 | + }, | ||
232 | + Zip: { | ||
233 | + ext: '.zip', | ||
234 | + flags: 'qr', | ||
235 | + cmd: 'zip' | ||
236 | + } | ||
237 | + }; | ||
238 | + | ||
239 | + this.define = function () { | ||
240 | + let self = this; | ||
241 | + let packageDirPath = this.packageDirPath(); | ||
242 | + let compressTaskArr = []; | ||
243 | + | ||
244 | + desc('Build the package for distribution'); | ||
245 | + task('package', self.prereqs.concat(['clobberPackage', 'buildPackage'])); | ||
246 | + // Backward-compat alias | ||
247 | + task('repackage', ['package']); | ||
248 | + | ||
249 | + task('clobberPackage', function () { | ||
250 | + jake.rmRf(self.packageDir, {silent: true}); | ||
251 | + }); | ||
252 | + | ||
253 | + desc('Remove the package'); | ||
254 | + task('clobber', ['clobberPackage']); | ||
255 | + | ||
256 | + let doCommand = function (p) { | ||
257 | + let filename = path.resolve(self.packageDir + '/' + self.packageName() + | ||
258 | + _compressOpts[p].ext); | ||
259 | + if (process.platform == 'win32') { | ||
260 | + // Windows full path may have drive letter, which is going to cause | ||
261 | + // namespace problems, so strip it. | ||
262 | + if (filename.length > 2 && filename[1] == ':') { | ||
263 | + filename = filename.substr(2); | ||
264 | + } | ||
265 | + } | ||
266 | + compressTaskArr.push(filename); | ||
267 | + | ||
268 | + file(filename, [packageDirPath], function () { | ||
269 | + let cmd; | ||
270 | + let opts = _compressOpts[p]; | ||
271 | + // Directory to move to when doing the compression-task | ||
272 | + // Changes in the case of zip for emulating -C option | ||
273 | + let chdir = self.packageDir; | ||
274 | + // Save the current dir so it's possible to pop back up | ||
275 | + // after compressing | ||
276 | + let currDir = process.cwd(); | ||
277 | + let archiveChangeDir; | ||
278 | + let archiveContentDir; | ||
279 | + | ||
280 | + if (self.archiveNoBaseDir) { | ||
281 | + archiveChangeDir = self.packageName(); | ||
282 | + archiveContentDir = '.'; | ||
283 | + } | ||
284 | + else { | ||
285 | + archiveChangeDir = self.archiveChangeDir; | ||
286 | + archiveContentDir = self.archiveContentDir; | ||
287 | + } | ||
288 | + | ||
289 | + cmd = self[opts.cmd + 'Command']; | ||
290 | + cmd += ' -' + opts.flags; | ||
291 | + if (opts.cmd == 'jar' && self.manifestFile) { | ||
292 | + cmd += 'm'; | ||
293 | + } | ||
294 | + | ||
295 | + // The name of the archive to create -- use full path | ||
296 | + // so compression can be performed from a different dir | ||
297 | + // if needed | ||
298 | + cmd += ' ' + filename; | ||
299 | + | ||
300 | + if (opts.cmd == 'jar' && self.manifestFile) { | ||
301 | + cmd += ' ' + self.manifestFile; | ||
302 | + } | ||
303 | + | ||
304 | + // Where to perform the compression -- -C option isn't | ||
305 | + // supported in zip, so actually do process.chdir for this | ||
306 | + if (archiveChangeDir) { | ||
307 | + if (opts.cmd == 'zip') { | ||
308 | + chdir = path.join(chdir, archiveChangeDir); | ||
309 | + } | ||
310 | + else { | ||
311 | + cmd += ' -C ' + archiveChangeDir; | ||
312 | + } | ||
313 | + } | ||
314 | + | ||
315 | + // Where to get the archive content | ||
316 | + if (archiveContentDir) { | ||
317 | + cmd += ' ' + archiveContentDir; | ||
318 | + } | ||
319 | + else { | ||
320 | + cmd += ' ' + self.packageName(); | ||
321 | + } | ||
322 | + | ||
323 | + // Move into the desired dir (usually packageDir) to compress | ||
324 | + // Return back up to the current dir after the exec | ||
325 | + process.chdir(chdir); | ||
326 | + | ||
327 | + exec(cmd, function (err, stdout, stderr) { | ||
328 | + if (err) { throw err; } | ||
329 | + | ||
330 | + // Return back up to the starting directory (see above, | ||
331 | + // before exec) | ||
332 | + process.chdir(currDir); | ||
333 | + | ||
334 | + complete(); | ||
335 | + }); | ||
336 | + }, {async: true}); | ||
337 | + }; | ||
338 | + | ||
339 | + for (let p in _compressOpts) { | ||
340 | + if (this['need' + p]) { | ||
341 | + doCommand(p); | ||
342 | + } | ||
343 | + } | ||
344 | + | ||
345 | + task('buildPackage', compressTaskArr, function () {}); | ||
346 | + | ||
347 | + directory(this.packageDir); | ||
348 | + | ||
349 | + file(packageDirPath, this.packageFiles, function () { | ||
350 | + jake.mkdirP(packageDirPath); | ||
351 | + let fileList = []; | ||
352 | + self.packageFiles.forEach(function (name) { | ||
353 | + let f = path.join(self.packageDirPath(), name); | ||
354 | + let fDir = path.dirname(f); | ||
355 | + jake.mkdirP(fDir, {silent: true}); | ||
356 | + | ||
357 | + // Add both files and directories | ||
358 | + fileList.push({ | ||
359 | + from: name, | ||
360 | + to: f | ||
361 | + }); | ||
362 | + }); | ||
363 | + let _copyFile = function () { | ||
364 | + let file = fileList.pop(); | ||
365 | + let stat; | ||
366 | + if (file) { | ||
367 | + stat = fs.statSync(file.from); | ||
368 | + // Target is a directory, just create it | ||
369 | + if (stat.isDirectory()) { | ||
370 | + jake.mkdirP(file.to, {silent: true}); | ||
371 | + _copyFile(); | ||
372 | + } | ||
373 | + // Otherwise copy the file | ||
374 | + else { | ||
375 | + jake.cpR(file.from, file.to, {silent: true}); | ||
376 | + _copyFile(); | ||
377 | + } | ||
378 | + } | ||
379 | + else { | ||
380 | + complete(); | ||
381 | + } | ||
382 | + }; | ||
383 | + _copyFile(); | ||
384 | + }, {async: true}); | ||
385 | + | ||
386 | + | ||
387 | + }; | ||
388 | + | ||
389 | + this.packageName = function () { | ||
390 | + if (this.version) { | ||
391 | + return this.name + '-' + this.version; | ||
392 | + } | ||
393 | + else { | ||
394 | + return this.name; | ||
395 | + } | ||
396 | + }; | ||
397 | + | ||
398 | + this.packageDirPath = function () { | ||
399 | + return this.packageDir + '/' + this.packageName(); | ||
400 | + }; | ||
401 | + | ||
402 | +})(); | ||
403 | + | ||
404 | +jake.PackageTask = PackageTask; | ||
405 | +exports.PackageTask = PackageTask; | ||
406 | + |
node_modules/jake/lib/parseargs.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let parseargs = {}; | ||
20 | +let isOpt = function (arg) { return arg.indexOf('-') === 0 }; | ||
21 | +let removeOptPrefix = function (opt) { return opt.replace(/^--/, '').replace(/^-/, '') }; | ||
22 | + | ||
23 | +/** | ||
24 | + * @constructor | ||
25 | + * Parses a list of command-line args into a key/value object of | ||
26 | + * options and an array of positional commands. | ||
27 | + * @ param {Array} opts A list of options in the following format: | ||
28 | + * [{full: 'foo', abbr: 'f'}, {full: 'bar', abbr: 'b'}]] | ||
29 | + */ | ||
30 | +parseargs.Parser = function (opts) { | ||
31 | + // A key/value object of matching options parsed out of the args | ||
32 | + this.opts = {}; | ||
33 | + this.taskNames = null; | ||
34 | + this.envVars = null; | ||
35 | + | ||
36 | + // Data structures used for parsing | ||
37 | + this.reg = opts; | ||
38 | + this.shortOpts = {}; | ||
39 | + this.longOpts = {}; | ||
40 | + | ||
41 | + let self = this; | ||
42 | + [].forEach.call(opts, function (item) { | ||
43 | + self.shortOpts[item.abbr] = item; | ||
44 | + self.longOpts[item.full] = item; | ||
45 | + }); | ||
46 | +}; | ||
47 | + | ||
48 | +parseargs.Parser.prototype = new function () { | ||
49 | + | ||
50 | + let _trueOrNextVal = function (argParts, args) { | ||
51 | + if (argParts[1]) { | ||
52 | + return argParts[1]; | ||
53 | + } | ||
54 | + else { | ||
55 | + return (!args[0] || isOpt(args[0])) ? | ||
56 | + true : args.shift(); | ||
57 | + } | ||
58 | + }; | ||
59 | + | ||
60 | + /** | ||
61 | + * Parses an array of arguments into options and positional commands | ||
62 | + * @param {Array} args The command-line args to parse | ||
63 | + */ | ||
64 | + this.parse = function (args) { | ||
65 | + let cmds = []; | ||
66 | + let cmd; | ||
67 | + let envVars = {}; | ||
68 | + let opts = {}; | ||
69 | + let arg; | ||
70 | + let argItem; | ||
71 | + let argParts; | ||
72 | + let cmdItems; | ||
73 | + let taskNames = []; | ||
74 | + let preempt; | ||
75 | + | ||
76 | + while (args.length) { | ||
77 | + arg = args.shift(); | ||
78 | + | ||
79 | + if (isOpt(arg)) { | ||
80 | + arg = removeOptPrefix(arg); | ||
81 | + argParts = arg.split('='); | ||
82 | + argItem = this.longOpts[argParts[0]] || this.shortOpts[argParts[0]]; | ||
83 | + if (argItem) { | ||
84 | + // First-encountered preemptive opt takes precedence -- no further opts | ||
85 | + // or possibility of ambiguity, so just look for a value, or set to | ||
86 | + // true and then bail | ||
87 | + if (argItem.preempts) { | ||
88 | + opts[argItem.full] = _trueOrNextVal(argParts, args); | ||
89 | + preempt = true; | ||
90 | + break; | ||
91 | + } | ||
92 | + // If the opt requires a value, see if we can get a value from the | ||
93 | + // next arg, or infer true from no-arg -- if it's followed by another | ||
94 | + // opt, throw an error | ||
95 | + if (argItem.expectValue || argItem.allowValue) { | ||
96 | + opts[argItem.full] = _trueOrNextVal(argParts, args); | ||
97 | + if (argItem.expectValue && !opts[argItem.full]) { | ||
98 | + throw new Error(argItem.full + ' option expects a value.'); | ||
99 | + } | ||
100 | + } | ||
101 | + else { | ||
102 | + opts[argItem.full] = true; | ||
103 | + } | ||
104 | + } | ||
105 | + } | ||
106 | + else { | ||
107 | + cmds.unshift(arg); | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + if (!preempt) { | ||
112 | + // Parse out any env-vars and task-name | ||
113 | + while ((cmd = cmds.pop())) { | ||
114 | + cmdItems = cmd.split('='); | ||
115 | + if (cmdItems.length > 1) { | ||
116 | + envVars[cmdItems[0]] = cmdItems[1]; | ||
117 | + } | ||
118 | + else { | ||
119 | + taskNames.push(cmd); | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + } | ||
124 | + | ||
125 | + return { | ||
126 | + opts: opts, | ||
127 | + envVars: envVars, | ||
128 | + taskNames: taskNames | ||
129 | + }; | ||
130 | + }; | ||
131 | + | ||
132 | +}; | ||
133 | + | ||
134 | +module.exports = parseargs; |
node_modules/jake/lib/program.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let fs = require('fs'); | ||
20 | +let parseargs = require('./parseargs'); | ||
21 | +let utils = require('./utils'); | ||
22 | +let Program; | ||
23 | +let usage = require('fs').readFileSync(`${__dirname}/../usage.txt`).toString(); | ||
24 | +let { Task } = require('./task/task'); | ||
25 | + | ||
26 | +function die(msg) { | ||
27 | + console.log(msg); | ||
28 | + process.stdout.write('', function () { | ||
29 | + process.stderr.write('', function () { | ||
30 | + process.exit(); | ||
31 | + }); | ||
32 | + }); | ||
33 | +} | ||
34 | + | ||
35 | +let preempts = { | ||
36 | + version: function () { | ||
37 | + die(jake.version); | ||
38 | + }, | ||
39 | + help: function () { | ||
40 | + die(usage); | ||
41 | + } | ||
42 | +}; | ||
43 | + | ||
44 | +let AVAILABLE_OPTS = [ | ||
45 | + { full: 'jakefile', | ||
46 | + abbr: 'f', | ||
47 | + expectValue: true | ||
48 | + }, | ||
49 | + { full: 'quiet', | ||
50 | + abbr: 'q', | ||
51 | + expectValue: false | ||
52 | + }, | ||
53 | + { full: 'directory', | ||
54 | + abbr: 'C', | ||
55 | + expectValue: true | ||
56 | + }, | ||
57 | + { full: 'always-make', | ||
58 | + abbr: 'B', | ||
59 | + expectValue: false | ||
60 | + }, | ||
61 | + { full: 'tasks', | ||
62 | + abbr: 'T', | ||
63 | + expectValue: false, | ||
64 | + allowValue: true | ||
65 | + }, | ||
66 | + // Alias t | ||
67 | + { full: 'tasks', | ||
68 | + abbr: 't', | ||
69 | + expectValue: false, | ||
70 | + allowValue: true | ||
71 | + }, | ||
72 | + // Alias ls | ||
73 | + { full: 'tasks', | ||
74 | + abbr: 'ls', | ||
75 | + expectValue: false, | ||
76 | + allowValue: true | ||
77 | + }, | ||
78 | + { full: 'help', | ||
79 | + abbr: 'h', | ||
80 | + }, | ||
81 | + { full: 'version', | ||
82 | + abbr: 'V', | ||
83 | + }, | ||
84 | + // Alias lowercase v | ||
85 | + { full: 'version', | ||
86 | + abbr: 'v', | ||
87 | + }, | ||
88 | + { full: 'jakelibdir', | ||
89 | + abbr: 'J', | ||
90 | + expectValue: true | ||
91 | + }, | ||
92 | + { full: 'allow-rejection', | ||
93 | + abbr: 'ar', | ||
94 | + expectValue: false | ||
95 | + } | ||
96 | +]; | ||
97 | + | ||
98 | +Program = function () { | ||
99 | + this.availableOpts = AVAILABLE_OPTS; | ||
100 | + this.opts = {}; | ||
101 | + this.taskNames = null; | ||
102 | + this.taskArgs = null; | ||
103 | + this.envVars = null; | ||
104 | + this.die = die; | ||
105 | +}; | ||
106 | + | ||
107 | +Program.prototype = new (function () { | ||
108 | + | ||
109 | + this.handleErr = function (err) { | ||
110 | + if (jake.listeners('error').length !== 0) { | ||
111 | + jake.emit('error', err); | ||
112 | + return; | ||
113 | + } | ||
114 | + | ||
115 | + if (jake.listeners('error').length) { | ||
116 | + jake.emit('error', err); | ||
117 | + return; | ||
118 | + } | ||
119 | + | ||
120 | + utils.logger.error('jake aborted.'); | ||
121 | + if (err.stack) { | ||
122 | + utils.logger.error(err.stack); | ||
123 | + } | ||
124 | + else { | ||
125 | + utils.logger.error(err.message); | ||
126 | + } | ||
127 | + | ||
128 | + process.stdout.write('', function () { | ||
129 | + process.stderr.write('', function () { | ||
130 | + jake.errorCode = jake.errorCode || 1; | ||
131 | + process.exit(jake.errorCode); | ||
132 | + }); | ||
133 | + }); | ||
134 | + }; | ||
135 | + | ||
136 | + this.parseArgs = function (args) { | ||
137 | + let result = (new parseargs.Parser(this.availableOpts)).parse(args); | ||
138 | + this.setOpts(result.opts); | ||
139 | + this.setTaskNames(result.taskNames); | ||
140 | + this.setEnvVars(result.envVars); | ||
141 | + }; | ||
142 | + | ||
143 | + this.setOpts = function (options) { | ||
144 | + let opts = options || {}; | ||
145 | + Object.assign(this.opts, opts); | ||
146 | + }; | ||
147 | + | ||
148 | + this.internalOpts = function (options) { | ||
149 | + this.availableOpts = this.availableOpts.concat(options); | ||
150 | + }; | ||
151 | + | ||
152 | + this.autocompletions = function (cur) { | ||
153 | + let p; let i; let task; | ||
154 | + let commonPrefix = ''; | ||
155 | + let matches = []; | ||
156 | + | ||
157 | + for (p in jake.Task) { | ||
158 | + task = jake.Task[p]; | ||
159 | + if ( | ||
160 | + 'fullName' in task | ||
161 | + && ( | ||
162 | + // if empty string, program converts to true | ||
163 | + cur === true || | ||
164 | + task.fullName.indexOf(cur) === 0 | ||
165 | + ) | ||
166 | + ) { | ||
167 | + if (matches.length === 0) { | ||
168 | + commonPrefix = task.fullName; | ||
169 | + } | ||
170 | + else { | ||
171 | + for (i = commonPrefix.length; i > -1; --i) { | ||
172 | + commonPrefix = commonPrefix.substr(0, i); | ||
173 | + if (task.fullName.indexOf(commonPrefix) === 0) { | ||
174 | + break; | ||
175 | + } | ||
176 | + } | ||
177 | + } | ||
178 | + matches.push(task.fullName); | ||
179 | + } | ||
180 | + } | ||
181 | + | ||
182 | + if (matches.length > 1 && commonPrefix === cur) { | ||
183 | + matches.unshift('yes-space'); | ||
184 | + } | ||
185 | + else { | ||
186 | + matches.unshift('no-space'); | ||
187 | + } | ||
188 | + | ||
189 | + process.stdout.write(matches.join(' ')); | ||
190 | + }; | ||
191 | + | ||
192 | + this.setTaskNames = function (names) { | ||
193 | + if (names && !Array.isArray(names)) { | ||
194 | + throw new Error('Task names must be an array'); | ||
195 | + } | ||
196 | + this.taskNames = (names && names.length) ? names : ['default']; | ||
197 | + }; | ||
198 | + | ||
199 | + this.setEnvVars = function (vars) { | ||
200 | + this.envVars = vars || null; | ||
201 | + }; | ||
202 | + | ||
203 | + this.firstPreemptiveOption = function () { | ||
204 | + let opts = this.opts; | ||
205 | + for (let p in opts) { | ||
206 | + if (preempts[p]) { | ||
207 | + return preempts[p]; | ||
208 | + } | ||
209 | + } | ||
210 | + return false; | ||
211 | + }; | ||
212 | + | ||
213 | + this.init = function (configuration) { | ||
214 | + let self = this; | ||
215 | + let config = configuration || {}; | ||
216 | + if (config.options) { | ||
217 | + this.setOpts(config.options); | ||
218 | + } | ||
219 | + if (config.taskNames) { | ||
220 | + this.setTaskNames(config.taskNames); | ||
221 | + } | ||
222 | + if (config.envVars) { | ||
223 | + this.setEnvVars(config.envVars); | ||
224 | + } | ||
225 | + process.addListener('uncaughtException', function (err) { | ||
226 | + self.handleErr(err); | ||
227 | + }); | ||
228 | + if (!this.opts['allow-rejection']) { | ||
229 | + process.addListener('unhandledRejection', (reason, promise) => { | ||
230 | + utils.logger.error('Unhandled rejection at:', promise, 'reason:', reason); | ||
231 | + self.handleErr(reason); | ||
232 | + }); | ||
233 | + } | ||
234 | + if (this.envVars) { | ||
235 | + Object.assign(process.env, this.envVars); | ||
236 | + } | ||
237 | + }; | ||
238 | + | ||
239 | + this.run = function () { | ||
240 | + let rootTask; | ||
241 | + let taskNames; | ||
242 | + let dirname; | ||
243 | + let opts = this.opts; | ||
244 | + | ||
245 | + if (opts.autocomplete) { | ||
246 | + return this.autocompletions(opts['autocomplete-cur'], opts['autocomplete-prev']); | ||
247 | + } | ||
248 | + // Run with `jake -T`, just show descriptions | ||
249 | + if (opts.tasks) { | ||
250 | + return jake.showAllTaskDescriptions(opts.tasks); | ||
251 | + } | ||
252 | + | ||
253 | + taskNames = this.taskNames; | ||
254 | + if (!(Array.isArray(taskNames) && taskNames.length)) { | ||
255 | + throw new Error('Please pass jake.runTasks an array of task-names'); | ||
256 | + } | ||
257 | + | ||
258 | + // Set working dir | ||
259 | + dirname = opts.directory; | ||
260 | + if (dirname) { | ||
261 | + if (fs.existsSync(dirname) && | ||
262 | + fs.statSync(dirname).isDirectory()) { | ||
263 | + process.chdir(dirname); | ||
264 | + } | ||
265 | + else { | ||
266 | + throw new Error(dirname + ' is not a valid directory path'); | ||
267 | + } | ||
268 | + } | ||
269 | + | ||
270 | + rootTask = task(Task.ROOT_TASK_NAME, taskNames, function () {}); | ||
271 | + rootTask._internal = true; | ||
272 | + | ||
273 | + rootTask.once('complete', function () { | ||
274 | + jake.emit('complete'); | ||
275 | + }); | ||
276 | + jake.emit('start'); | ||
277 | + rootTask.invoke(); | ||
278 | + }; | ||
279 | + | ||
280 | +})(); | ||
281 | + | ||
282 | +module.exports.Program = Program; |
node_modules/jake/lib/publish_task.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let fs = require('fs'); | ||
20 | +let path = require('path'); | ||
21 | +let exec = require('child_process').execSync; | ||
22 | +let FileList = require('filelist').FileList; | ||
23 | + | ||
24 | +let PublishTask = function () { | ||
25 | + let args = Array.prototype.slice.call(arguments).filter(function (item) { | ||
26 | + return typeof item != 'undefined'; | ||
27 | + }); | ||
28 | + let arg; | ||
29 | + let opts = {}; | ||
30 | + let definition; | ||
31 | + let prereqs = []; | ||
32 | + let createDef = function (arg) { | ||
33 | + return function () { | ||
34 | + this.packageFiles.include(arg); | ||
35 | + }; | ||
36 | + }; | ||
37 | + | ||
38 | + this.name = args.shift(); | ||
39 | + | ||
40 | + // Old API, just name + list of files | ||
41 | + if (args.length == 1 && (Array.isArray(args[0]) || typeof args[0] == 'string')) { | ||
42 | + definition = createDef(args.pop()); | ||
43 | + } | ||
44 | + // Current API, name + [prereqs] + [opts] + definition | ||
45 | + else { | ||
46 | + while ((arg = args.pop())) { | ||
47 | + // Definition func | ||
48 | + if (typeof arg == 'function') { | ||
49 | + definition = arg; | ||
50 | + } | ||
51 | + // Prereqs | ||
52 | + else if (Array.isArray(arg) || typeof arg == 'string') { | ||
53 | + prereqs = arg; | ||
54 | + } | ||
55 | + // Opts | ||
56 | + else { | ||
57 | + opts = arg; | ||
58 | + } | ||
59 | + } | ||
60 | + } | ||
61 | + | ||
62 | + this.prereqs = prereqs; | ||
63 | + this.packageFiles = new FileList(); | ||
64 | + this.publishCmd = opts.publishCmd || 'npm publish %filename'; | ||
65 | + this.publishMessage = opts.publishMessage || 'BOOM! Published.'; | ||
66 | + this.gitCmd = opts.gitCmd || 'git'; | ||
67 | + this.versionFiles = opts.versionFiles || ['package.json']; | ||
68 | + this.scheduleDelay = 5000; | ||
69 | + | ||
70 | + // Override utility funcs for testing | ||
71 | + this._ensureRepoClean = function (stdout) { | ||
72 | + if (stdout.length) { | ||
73 | + fail(new Error('Git repository is not clean.')); | ||
74 | + } | ||
75 | + }; | ||
76 | + this._getCurrentBranch = function (stdout) { | ||
77 | + return String(stdout).trim(); | ||
78 | + }; | ||
79 | + | ||
80 | + if (typeof definition == 'function') { | ||
81 | + definition.call(this); | ||
82 | + } | ||
83 | + this.define(); | ||
84 | +}; | ||
85 | + | ||
86 | + | ||
87 | +PublishTask.prototype = new (function () { | ||
88 | + | ||
89 | + let _currentBranch = null; | ||
90 | + | ||
91 | + let getPackage = function () { | ||
92 | + let pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), | ||
93 | + '/package.json')).toString()); | ||
94 | + return pkg; | ||
95 | + }; | ||
96 | + let getPackageVersionNumber = function () { | ||
97 | + return getPackage().version; | ||
98 | + }; | ||
99 | + | ||
100 | + this.define = function () { | ||
101 | + let self = this; | ||
102 | + | ||
103 | + namespace('publish', function () { | ||
104 | + task('fetchTags', function () { | ||
105 | + // Make sure local tags are up to date | ||
106 | + exec(self.gitCmd + ' fetch --tags'); | ||
107 | + console.log('Fetched remote tags.'); | ||
108 | + }); | ||
109 | + | ||
110 | + task('getCurrentBranch', function () { | ||
111 | + // Figure out what branch to push to | ||
112 | + let stdout = exec(self.gitCmd + ' symbolic-ref --short HEAD').toString(); | ||
113 | + if (!stdout) { | ||
114 | + throw new Error('No current Git branch found'); | ||
115 | + } | ||
116 | + _currentBranch = self._getCurrentBranch(stdout); | ||
117 | + console.log('On branch ' + _currentBranch); | ||
118 | + }); | ||
119 | + | ||
120 | + task('ensureClean', function () { | ||
121 | + // Only bump, push, and tag if the Git repo is clean | ||
122 | + let stdout = exec(self.gitCmd + ' status --porcelain --untracked-files=no').toString(); | ||
123 | + // Throw if there's output | ||
124 | + self._ensureRepoClean(stdout); | ||
125 | + }); | ||
126 | + | ||
127 | + task('updateVersionFiles', function () { | ||
128 | + let pkg; | ||
129 | + let version; | ||
130 | + let arr; | ||
131 | + let patch; | ||
132 | + | ||
133 | + // Grab the current version-string | ||
134 | + pkg = getPackage(); | ||
135 | + version = pkg.version; | ||
136 | + // Increment the patch-number for the version | ||
137 | + arr = version.split('.'); | ||
138 | + patch = parseInt(arr.pop(), 10) + 1; | ||
139 | + arr.push(patch); | ||
140 | + version = arr.join('.'); | ||
141 | + | ||
142 | + // Update package.json or other files with the new version-info | ||
143 | + self.versionFiles.forEach(function (file) { | ||
144 | + let p = path.join(process.cwd(), file); | ||
145 | + let data = JSON.parse(fs.readFileSync(p).toString()); | ||
146 | + data.version = version; | ||
147 | + fs.writeFileSync(p, JSON.stringify(data, true, 2) + '\n'); | ||
148 | + }); | ||
149 | + // Return the version string so that listeners for the 'complete' event | ||
150 | + // for this task can use it (e.g., to update other files before pushing | ||
151 | + // to Git) | ||
152 | + return version; | ||
153 | + }); | ||
154 | + | ||
155 | + task('pushVersion', ['ensureClean', 'updateVersionFiles'], function () { | ||
156 | + let version = getPackageVersionNumber(); | ||
157 | + let message = 'Version ' + version; | ||
158 | + let cmds = [ | ||
159 | + self.gitCmd + ' commit -a -m "' + message + '"', | ||
160 | + self.gitCmd + ' push origin ' + _currentBranch, | ||
161 | + self.gitCmd + ' tag -a v' + version + ' -m "' + message + '"', | ||
162 | + self.gitCmd + ' push --tags' | ||
163 | + ]; | ||
164 | + cmds.forEach((cmd) => { | ||
165 | + exec(cmd); | ||
166 | + }); | ||
167 | + version = getPackageVersionNumber(); | ||
168 | + console.log('Bumped version number to v' + version + '.'); | ||
169 | + }); | ||
170 | + | ||
171 | + let defineTask = task('definePackage', function () { | ||
172 | + let version = getPackageVersionNumber(); | ||
173 | + new jake.PackageTask(self.name, 'v' + version, self.prereqs, function () { | ||
174 | + // Replace the PackageTask's FileList with the PublishTask's FileList | ||
175 | + this.packageFiles = self.packageFiles; | ||
176 | + this.needTarGz = true; // Default to tar.gz | ||
177 | + // If any of the need<CompressionFormat> or archive opts are set | ||
178 | + // proxy them to the PackageTask | ||
179 | + for (let p in this) { | ||
180 | + if (p.indexOf('need') === 0 || p.indexOf('archive') === 0) { | ||
181 | + if (typeof self[p] != 'undefined') { | ||
182 | + this[p] = self[p]; | ||
183 | + } | ||
184 | + } | ||
185 | + } | ||
186 | + }); | ||
187 | + }); | ||
188 | + defineTask._internal = true; | ||
189 | + | ||
190 | + task('package', function () { | ||
191 | + let definePack = jake.Task['publish:definePackage']; | ||
192 | + let pack = jake.Task['package']; | ||
193 | + let version = getPackageVersionNumber(); | ||
194 | + | ||
195 | + // May have already been run | ||
196 | + if (definePack.taskStatus == jake.Task.runStatuses.DONE) { | ||
197 | + definePack.reenable(true); | ||
198 | + } | ||
199 | + definePack.invoke(); | ||
200 | + // Set manually, completion happens in next tick, creating deadlock | ||
201 | + definePack.taskStatus = jake.Task.runStatuses.DONE; | ||
202 | + pack.invoke(); | ||
203 | + console.log('Created package for ' + self.name + ' v' + version); | ||
204 | + }); | ||
205 | + | ||
206 | + task('publish', function () { | ||
207 | + return new Promise((resolve) => { | ||
208 | + let version = getPackageVersionNumber(); | ||
209 | + let filename; | ||
210 | + let cmd; | ||
211 | + | ||
212 | + console.log('Publishing ' + self.name + ' v' + version); | ||
213 | + | ||
214 | + if (typeof self.createPublishCommand == 'function') { | ||
215 | + cmd = self.createPublishCommand(version); | ||
216 | + } | ||
217 | + else { | ||
218 | + filename = './pkg/' + self.name + '-v' + version + '.tar.gz'; | ||
219 | + cmd = self.publishCmd.replace(/%filename/gi, filename); | ||
220 | + } | ||
221 | + | ||
222 | + if (typeof cmd == 'function') { | ||
223 | + cmd(function (err) { | ||
224 | + if (err) { | ||
225 | + throw err; | ||
226 | + } | ||
227 | + console.log(self.publishMessage); | ||
228 | + resolve(); | ||
229 | + }); | ||
230 | + } | ||
231 | + else { | ||
232 | + // Hackity hack -- NPM publish sometimes returns errror like: | ||
233 | + // Error sending version data\nnpm ERR! | ||
234 | + // Error: forbidden 0.2.4 is modified, should match modified time | ||
235 | + setTimeout(function () { | ||
236 | + let stdout = exec(cmd).toString() || ''; | ||
237 | + stdout = stdout.trim(); | ||
238 | + if (stdout) { | ||
239 | + console.log(stdout); | ||
240 | + } | ||
241 | + console.log(self.publishMessage); | ||
242 | + resolve(); | ||
243 | + }, self.scheduleDelay); | ||
244 | + } | ||
245 | + }); | ||
246 | + }); | ||
247 | + | ||
248 | + task('cleanup', function () { | ||
249 | + return new Promise((resolve) => { | ||
250 | + let clobber = jake.Task.clobber; | ||
251 | + clobber.reenable(true); | ||
252 | + clobber.on('complete', function () { | ||
253 | + console.log('Cleaned up package'); | ||
254 | + resolve(); | ||
255 | + }); | ||
256 | + clobber.invoke(); | ||
257 | + }); | ||
258 | + }); | ||
259 | + | ||
260 | + }); | ||
261 | + | ||
262 | + let prefixNs = function (item) { | ||
263 | + return 'publish:' + item; | ||
264 | + }; | ||
265 | + | ||
266 | + // Create aliases in the default namespace | ||
267 | + desc('Create a new version and release.'); | ||
268 | + task('publish', self.prereqs.concat(['version', 'release'] | ||
269 | + .map(prefixNs))); | ||
270 | + | ||
271 | + desc('Release the existing version.'); | ||
272 | + task('publishExisting', self.prereqs.concat(['release'] | ||
273 | + .map(prefixNs))); | ||
274 | + | ||
275 | + task('version', ['fetchTags', 'getCurrentBranch', 'pushVersion'] | ||
276 | + .map(prefixNs)); | ||
277 | + | ||
278 | + task('release', ['package', 'publish', 'cleanup'] | ||
279 | + .map(prefixNs)); | ||
280 | + | ||
281 | + // Invoke proactively so there will be a callable 'package' task | ||
282 | + // which can be used apart from 'publish' | ||
283 | + jake.Task['publish:definePackage'].invoke(); | ||
284 | + }; | ||
285 | + | ||
286 | +})(); | ||
287 | + | ||
288 | +jake.PublishTask = PublishTask; | ||
289 | +exports.PublishTask = PublishTask; | ||
290 | + |
node_modules/jake/lib/rule.js
0 → 100644
1 | +let path = require('path'); | ||
2 | +let fs = require('fs'); | ||
3 | +let Task = require('./task/task').Task; | ||
4 | + | ||
5 | +// Split a task to two parts, name space and task name. | ||
6 | +// For example, given 'foo:bin/a%.c', return an object with | ||
7 | +// - 'ns' : foo | ||
8 | +// - 'name' : bin/a%.c | ||
9 | +function splitNs(task) { | ||
10 | + let parts = task.split(':'); | ||
11 | + let name = parts.pop(); | ||
12 | + let ns = resolveNs(parts); | ||
13 | + return { | ||
14 | + 'name' : name, | ||
15 | + 'ns' : ns | ||
16 | + }; | ||
17 | +} | ||
18 | + | ||
19 | +// Return the namespace based on an array of names. | ||
20 | +// For example, given ['foo', 'baz' ], return the namespace | ||
21 | +// | ||
22 | +// default -> foo -> baz | ||
23 | +// | ||
24 | +// where default is the global root namespace | ||
25 | +// and -> means child namespace. | ||
26 | +function resolveNs(parts) { | ||
27 | + let ns = jake.defaultNamespace; | ||
28 | + for(let i = 0, l = parts.length; ns && i < l; i++) { | ||
29 | + ns = ns.childNamespaces[parts[i]]; | ||
30 | + } | ||
31 | + return ns; | ||
32 | +} | ||
33 | + | ||
34 | +// Given a pattern p, say 'foo:bin/a%.c' | ||
35 | +// Return an object with | ||
36 | +// - 'ns' : foo | ||
37 | +// - 'dir' : bin | ||
38 | +// - 'prefix' : a | ||
39 | +// - 'suffix' : .c | ||
40 | +function resolve(p) { | ||
41 | + let task = splitNs(p); | ||
42 | + let name = task.name; | ||
43 | + let ns = task.ns; | ||
44 | + let split = path.basename(name).split('%'); | ||
45 | + return { | ||
46 | + ns: ns, | ||
47 | + dir: path.dirname(name), | ||
48 | + prefix: split[0], | ||
49 | + suffix: split[1] | ||
50 | + }; | ||
51 | +} | ||
52 | + | ||
53 | +// Test whether string a is a suffix of string b | ||
54 | +function stringEndWith(a, b) { | ||
55 | + let l; | ||
56 | + return (l = b.lastIndexOf(a)) == -1 ? false : l + a.length == b.length; | ||
57 | +} | ||
58 | + | ||
59 | +// Replace the suffix a of the string s with b. | ||
60 | +// Note that, it is assumed a is a suffix of s. | ||
61 | +function stringReplaceSuffix(s, a, b) { | ||
62 | + return s.slice(0, s.lastIndexOf(a)) + b; | ||
63 | +} | ||
64 | + | ||
65 | +class Rule { | ||
66 | + constructor(opts) { | ||
67 | + this.pattern = opts.pattern; | ||
68 | + this.source = opts.source; | ||
69 | + this.prereqs = opts.prereqs; | ||
70 | + this.action = opts.action; | ||
71 | + this.opts = opts.opts; | ||
72 | + this.desc = opts.desc; | ||
73 | + this.ns = opts.ns; | ||
74 | + } | ||
75 | + | ||
76 | + // Create a file task based on this rule for the specified | ||
77 | + // task-name | ||
78 | + // ====== | ||
79 | + // FIXME: Right now this just throws away any passed-in args | ||
80 | + // for the synthsized task (taskArgs param) | ||
81 | + // ====== | ||
82 | + createTask(fullName, level) { | ||
83 | + let self = this; | ||
84 | + let pattern; | ||
85 | + let source; | ||
86 | + let action; | ||
87 | + let opts; | ||
88 | + let prereqs; | ||
89 | + let valid; | ||
90 | + let src; | ||
91 | + let tNs; | ||
92 | + let createdTask; | ||
93 | + let name = Task.getBaseTaskName(fullName); | ||
94 | + let nsPath = Task.getBaseNamespacePath(fullName); | ||
95 | + let ns = this.ns.resolveNamespace(nsPath); | ||
96 | + | ||
97 | + pattern = this.pattern; | ||
98 | + source = this.source; | ||
99 | + | ||
100 | + if (typeof source == 'string') { | ||
101 | + src = Rule.getSource(name, pattern, source); | ||
102 | + } | ||
103 | + else { | ||
104 | + src = source(name); | ||
105 | + } | ||
106 | + | ||
107 | + // TODO: Write a utility function that appends a | ||
108 | + // taskname to a namespace path | ||
109 | + src = nsPath.split(':').filter(function (item) { | ||
110 | + return !!item; | ||
111 | + }).concat(src).join(':'); | ||
112 | + | ||
113 | + // Generate the prerequisite for the matching task. | ||
114 | + // It is the original prerequisites plus the prerequisite | ||
115 | + // representing source file, i.e., | ||
116 | + // | ||
117 | + // rule( '%.o', '%.c', ['some.h'] ... | ||
118 | + // | ||
119 | + // If the objective is main.o, then new task should be | ||
120 | + // | ||
121 | + // file( 'main.o', ['main.c', 'some.h' ] ... | ||
122 | + prereqs = this.prereqs.slice(); // Get a copy to work with | ||
123 | + prereqs.unshift(src); | ||
124 | + | ||
125 | + // Prereq should be: | ||
126 | + // 1. an existing task | ||
127 | + // 2. an existing file on disk | ||
128 | + // 3. a valid rule (i.e., not at too deep a level) | ||
129 | + valid = prereqs.some(function (p) { | ||
130 | + let ns = self.ns; | ||
131 | + return ns.resolveTask(p) || | ||
132 | + fs.existsSync(Task.getBaseTaskName(p)) || | ||
133 | + jake.attemptRule(p, ns, level + 1); | ||
134 | + }); | ||
135 | + | ||
136 | + // If any of the prereqs aren't valid, the rule isn't valid | ||
137 | + if (!valid) { | ||
138 | + return null; | ||
139 | + } | ||
140 | + // Otherwise, hunky-dory, finish creating the task for the rule | ||
141 | + else { | ||
142 | + // Create the action for the task | ||
143 | + action = function () { | ||
144 | + let task = this; | ||
145 | + self.action.apply(task); | ||
146 | + }; | ||
147 | + | ||
148 | + opts = this.opts; | ||
149 | + | ||
150 | + // Insert the file task into Jake | ||
151 | + // | ||
152 | + // Since createTask function stores the task as a child task | ||
153 | + // of currentNamespace. Here we temporariliy switch the namespace. | ||
154 | + // FIXME: Should allow optional ns passed in instead of this hack | ||
155 | + tNs = jake.currentNamespace; | ||
156 | + jake.currentNamespace = ns; | ||
157 | + createdTask = jake.createTask('file', name, prereqs, action, opts); | ||
158 | + createdTask.source = src.split(':').pop(); | ||
159 | + jake.currentNamespace = tNs; | ||
160 | + | ||
161 | + return createdTask; | ||
162 | + } | ||
163 | + } | ||
164 | + | ||
165 | + match(name) { | ||
166 | + return Rule.match(this.pattern, name); | ||
167 | + } | ||
168 | + | ||
169 | + // Test wether the a prerequisite matchs the pattern. | ||
170 | + // The arg 'pattern' does not have namespace as prefix. | ||
171 | + // For example, the following tests are true | ||
172 | + // | ||
173 | + // pattern | name | ||
174 | + // bin/%.o | bin/main.o | ||
175 | + // bin/%.o | foo:bin/main.o | ||
176 | + // | ||
177 | + // The following tests are false (trivally) | ||
178 | + // | ||
179 | + // pattern | name | ||
180 | + // bin/%.o | foobin/main.o | ||
181 | + // bin/%.o | bin/main.oo | ||
182 | + static match(pattern, name) { | ||
183 | + let p; | ||
184 | + let task; | ||
185 | + let obj; | ||
186 | + let filename; | ||
187 | + | ||
188 | + if (pattern instanceof RegExp) { | ||
189 | + return pattern.test(name); | ||
190 | + } | ||
191 | + else if (pattern.indexOf('%') == -1) { | ||
192 | + // No Pattern. No Folder. No Namespace. | ||
193 | + // A Simple Suffix Rule. Just test suffix | ||
194 | + return stringEndWith(pattern, name); | ||
195 | + } | ||
196 | + else { | ||
197 | + // Resolve the dir, prefix and suffix of pattern | ||
198 | + p = resolve(pattern); | ||
199 | + | ||
200 | + // Resolve the namespace and task-name | ||
201 | + task = splitNs(name); | ||
202 | + name = task.name; | ||
203 | + | ||
204 | + // Set the objective as the task-name | ||
205 | + obj = name; | ||
206 | + | ||
207 | + // Namespace is already matched. | ||
208 | + | ||
209 | + // Check dir | ||
210 | + if (path.dirname(obj) != p.dir) { | ||
211 | + return false; | ||
212 | + } | ||
213 | + | ||
214 | + filename = path.basename(obj); | ||
215 | + | ||
216 | + // Check file name length | ||
217 | + if ((p.prefix.length + p.suffix.length + 1) > filename.length) { | ||
218 | + // Length does not match. | ||
219 | + return false; | ||
220 | + } | ||
221 | + | ||
222 | + // Check prefix | ||
223 | + if (filename.indexOf(p.prefix) !== 0) { | ||
224 | + return false; | ||
225 | + } | ||
226 | + | ||
227 | + // Check suffix | ||
228 | + if (!stringEndWith(p.suffix, filename)) { | ||
229 | + return false; | ||
230 | + } | ||
231 | + | ||
232 | + // OK. Find a match. | ||
233 | + return true; | ||
234 | + } | ||
235 | + } | ||
236 | + | ||
237 | + // Generate the source based on | ||
238 | + // - name name for the synthesized task | ||
239 | + // - pattern pattern for the objective | ||
240 | + // - source pattern for the source | ||
241 | + // | ||
242 | + // Return the source with properties | ||
243 | + // - dep the prerequisite of source | ||
244 | + // (with the namespace) | ||
245 | + // | ||
246 | + // - file the file name of source | ||
247 | + // (without the namespace) | ||
248 | + // | ||
249 | + // For example, given | ||
250 | + // | ||
251 | + // - name foo:bin/main.o | ||
252 | + // - pattern bin/%.o | ||
253 | + // - source src/%.c | ||
254 | + // | ||
255 | + // return 'foo:src/main.c', | ||
256 | + // | ||
257 | + static getSource(name, pattern, source) { | ||
258 | + let dep; | ||
259 | + let pat; | ||
260 | + let match; | ||
261 | + let file; | ||
262 | + let src; | ||
263 | + | ||
264 | + // Regex pattern -- use to look up the extension | ||
265 | + if (pattern instanceof RegExp) { | ||
266 | + match = pattern.exec(name); | ||
267 | + if (match) { | ||
268 | + if (typeof source == 'function') { | ||
269 | + src = source(name); | ||
270 | + } | ||
271 | + else { | ||
272 | + src = stringReplaceSuffix(name, match[0], source); | ||
273 | + } | ||
274 | + } | ||
275 | + } | ||
276 | + // Assume string | ||
277 | + else { | ||
278 | + // Simple string suffix replacement | ||
279 | + if (pattern.indexOf('%') == -1) { | ||
280 | + if (typeof source == 'function') { | ||
281 | + src = source(name); | ||
282 | + } | ||
283 | + else { | ||
284 | + src = stringReplaceSuffix(name, pattern, source); | ||
285 | + } | ||
286 | + } | ||
287 | + // Percent-based substitution | ||
288 | + else { | ||
289 | + pat = pattern.replace('%', '(.*?)'); | ||
290 | + pat = new RegExp(pat); | ||
291 | + match = pat.exec(name); | ||
292 | + if (match) { | ||
293 | + if (typeof source == 'function') { | ||
294 | + src = source(name); | ||
295 | + } | ||
296 | + else { | ||
297 | + file = match[1]; | ||
298 | + file = source.replace('%', file); | ||
299 | + dep = match[0]; | ||
300 | + src = name.replace(dep, file); | ||
301 | + } | ||
302 | + } | ||
303 | + } | ||
304 | + } | ||
305 | + | ||
306 | + return src; | ||
307 | + } | ||
308 | +} | ||
309 | + | ||
310 | + | ||
311 | +exports.Rule = Rule; |
node_modules/jake/lib/task/directory_task.js
0 → 100644
1 | +let fs = require('fs'); | ||
2 | +let FileTask = require('./file_task').FileTask; | ||
3 | + | ||
4 | +/** | ||
5 | + @name jake | ||
6 | + @namespace jake | ||
7 | +*/ | ||
8 | +/** | ||
9 | + @name jake.DirectoryTask | ||
10 | + @constructor | ||
11 | + @augments EventEmitter | ||
12 | + @augments jake.Task | ||
13 | + @augments jake.FileTask | ||
14 | + @description A Jake DirectoryTask | ||
15 | + | ||
16 | + @param {String} name The name of the directory to create. | ||
17 | + */ | ||
18 | +class DirectoryTask extends FileTask { | ||
19 | + constructor(...args) { | ||
20 | + super(...args); | ||
21 | + if (fs.existsSync(this.name)) { | ||
22 | + this.updateModTime(); | ||
23 | + } | ||
24 | + else { | ||
25 | + this.modTime = null; | ||
26 | + } | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +exports.DirectoryTask = DirectoryTask; |
node_modules/jake/lib/task/file_task.js
0 → 100644
1 | +let fs = require('fs'); | ||
2 | +let Task = require('./task').Task; | ||
3 | + | ||
4 | +function isFileOrDirectory(t) { | ||
5 | + return (t instanceof FileTask || | ||
6 | + t instanceof DirectoryTask); | ||
7 | +} | ||
8 | + | ||
9 | +function isFile(t) { | ||
10 | + return (t instanceof FileTask && !(t instanceof DirectoryTask)); | ||
11 | +} | ||
12 | + | ||
13 | +/** | ||
14 | + @name jake | ||
15 | + @namespace jake | ||
16 | +*/ | ||
17 | +/** | ||
18 | + @name jake.FileTask | ||
19 | + @class` | ||
20 | + @extentds Task | ||
21 | + @description A Jake FileTask | ||
22 | + | ||
23 | + @param {String} name The name of the Task | ||
24 | + @param {Array} [prereqs] Prerequisites to be run before this task | ||
25 | + @param {Function} [action] The action to perform to create this file | ||
26 | + @param {Object} [opts] | ||
27 | + @param {Array} [opts.asyc=false] Perform this task asynchronously. | ||
28 | + If you flag a task with this option, you must call the global | ||
29 | + `complete` method inside the task's action, for execution to proceed | ||
30 | + to the next task. | ||
31 | + */ | ||
32 | +class FileTask extends Task { | ||
33 | + constructor(...args) { | ||
34 | + super(...args); | ||
35 | + this.dummy = false; | ||
36 | + if (fs.existsSync(this.name)) { | ||
37 | + this.updateModTime(); | ||
38 | + } | ||
39 | + else { | ||
40 | + this.modTime = null; | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
44 | + isNeeded() { | ||
45 | + let prereqs = this.prereqs; | ||
46 | + let prereqName; | ||
47 | + let prereqTask; | ||
48 | + | ||
49 | + // No repeatsies | ||
50 | + if (this.taskStatus == Task.runStatuses.DONE) { | ||
51 | + return false; | ||
52 | + } | ||
53 | + // The always-make override | ||
54 | + else if (jake.program.opts['always-make']) { | ||
55 | + return true; | ||
56 | + } | ||
57 | + // Default case | ||
58 | + else { | ||
59 | + | ||
60 | + // We need either an existing file, or an action to create one. | ||
61 | + // First try grabbing the actual mod-time of the file | ||
62 | + try { | ||
63 | + this.updateModTime(); | ||
64 | + } | ||
65 | + // Then fall back to looking for an action | ||
66 | + catch(e) { | ||
67 | + if (typeof this.action == 'function') { | ||
68 | + return true; | ||
69 | + } | ||
70 | + else { | ||
71 | + throw new Error('File-task ' + this.fullName + ' has no ' + | ||
72 | + 'existing file, and no action to create one.'); | ||
73 | + } | ||
74 | + } | ||
75 | + | ||
76 | + // Compare mod-time of all the prereqs with its mod-time | ||
77 | + // If any prereqs are newer, need to run the action to update | ||
78 | + if (prereqs && prereqs.length) { | ||
79 | + for (let i = 0, ii = prereqs.length; i < ii; i++) { | ||
80 | + prereqName = prereqs[i]; | ||
81 | + prereqTask = this.namespace.resolveTask(prereqName) || | ||
82 | + jake.createPlaceholderFileTask(prereqName, this.namespace); | ||
83 | + // Run the action if: | ||
84 | + // 1. The prereq is a normal task (not file/dir) | ||
85 | + // 2. The prereq is a file-task with a mod-date more recent than | ||
86 | + // the one for this file/dir | ||
87 | + if (prereqTask) { | ||
88 | + if (!isFileOrDirectory(prereqTask) || | ||
89 | + (isFile(prereqTask) && prereqTask.modTime > this.modTime)) { | ||
90 | + return true; | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + } | ||
95 | + // File/dir has no prereqs, and exists -- no need to run | ||
96 | + else { | ||
97 | + // Effectively done | ||
98 | + this.taskStatus = Task.runStatuses.DONE; | ||
99 | + return false; | ||
100 | + } | ||
101 | + } | ||
102 | + } | ||
103 | + | ||
104 | + updateModTime() { | ||
105 | + let stats = fs.statSync(this.name); | ||
106 | + this.modTime = stats.mtime; | ||
107 | + } | ||
108 | + | ||
109 | + complete() { | ||
110 | + if (!this.dummy) { | ||
111 | + this.updateModTime(); | ||
112 | + } | ||
113 | + // Hackity hack | ||
114 | + Task.prototype.complete.apply(this, arguments); | ||
115 | + } | ||
116 | + | ||
117 | +} | ||
118 | + | ||
119 | +exports.FileTask = FileTask; | ||
120 | + | ||
121 | +// DirectoryTask is a subclass of FileTask, depends on it | ||
122 | +// being defined | ||
123 | +let DirectoryTask = require('./directory_task').DirectoryTask; | ||
124 | + |
node_modules/jake/lib/task/index.js
0 → 100644
node_modules/jake/lib/task/task.js
0 → 100644
1 | +let EventEmitter = require('events').EventEmitter; | ||
2 | +let async = require('async'); | ||
3 | +let chalk = require('chalk'); | ||
4 | +// 'rule' module is required at the bottom because circular deps | ||
5 | + | ||
6 | +// Used for task value, so better not to use | ||
7 | +// null, since value should be unset/uninitialized | ||
8 | +let UNDEFINED_VALUE; | ||
9 | + | ||
10 | +const ROOT_TASK_NAME = '__rootTask__'; | ||
11 | +const POLLING_INTERVAL = 100; | ||
12 | + | ||
13 | +// Parse any positional args attached to the task-name | ||
14 | +function parsePrereqName(name) { | ||
15 | + let taskArr = name.split('['); | ||
16 | + let taskName = taskArr[0]; | ||
17 | + let taskArgs = []; | ||
18 | + if (taskArr[1]) { | ||
19 | + taskArgs = taskArr[1].replace(/\]$/, ''); | ||
20 | + taskArgs = taskArgs.split(','); | ||
21 | + } | ||
22 | + return { | ||
23 | + name: taskName, | ||
24 | + args: taskArgs | ||
25 | + }; | ||
26 | +} | ||
27 | + | ||
28 | +/** | ||
29 | + @name jake.Task | ||
30 | + @class | ||
31 | + @extends EventEmitter | ||
32 | + @description A Jake Task | ||
33 | + | ||
34 | + @param {String} name The name of the Task | ||
35 | + @param {Array} [prereqs] Prerequisites to be run before this task | ||
36 | + @param {Function} [action] The action to perform for this task | ||
37 | + @param {Object} [opts] | ||
38 | + @param {Array} [opts.asyc=false] Perform this task asynchronously. | ||
39 | + If you flag a task with this option, you must call the global | ||
40 | + `complete` method inside the task's action, for execution to proceed | ||
41 | + to the next task. | ||
42 | + */ | ||
43 | +class Task extends EventEmitter { | ||
44 | + | ||
45 | + constructor(name, prereqs, action, options) { | ||
46 | + // EventEmitter ctor takes no args | ||
47 | + super(); | ||
48 | + | ||
49 | + if (name.indexOf(':') > -1) { | ||
50 | + throw new Error('Task name cannot include a colon. It is used internally as namespace delimiter.'); | ||
51 | + } | ||
52 | + let opts = options || {}; | ||
53 | + | ||
54 | + this._currentPrereqIndex = 0; | ||
55 | + this._internal = false; | ||
56 | + this._skipped = false; | ||
57 | + | ||
58 | + this.name = name; | ||
59 | + this.prereqs = prereqs; | ||
60 | + this.action = action; | ||
61 | + this.async = false; | ||
62 | + this.taskStatus = Task.runStatuses.UNSTARTED; | ||
63 | + this.description = null; | ||
64 | + this.args = []; | ||
65 | + this.value = UNDEFINED_VALUE; | ||
66 | + this.concurrency = 1; | ||
67 | + this.startTime = null; | ||
68 | + this.endTime = null; | ||
69 | + this.directory = null; | ||
70 | + this.namespace = null; | ||
71 | + | ||
72 | + // Support legacy async-flag -- if not explicitly passed or falsy, will | ||
73 | + // be set to empty-object | ||
74 | + if (typeof opts == 'boolean' && opts === true) { | ||
75 | + this.async = true; | ||
76 | + } | ||
77 | + else { | ||
78 | + if (opts.async) { | ||
79 | + this.async = true; | ||
80 | + } | ||
81 | + if (opts.concurrency) { | ||
82 | + this.concurrency = opts.concurrency; | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + //Do a test on self dependencies for this task | ||
87 | + if(Array.isArray(this.prereqs) && this.prereqs.indexOf(this.name) !== -1) { | ||
88 | + throw new Error("Cannot use prereq " + this.name + " as a dependency of itself"); | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | + get fullName() { | ||
93 | + return this._getFullName(); | ||
94 | + } | ||
95 | + | ||
96 | + _initInvocationChain() { | ||
97 | + // Legacy global invocation chain | ||
98 | + jake._invocationChain.push(this); | ||
99 | + | ||
100 | + // New root chain | ||
101 | + if (!this._invocationChain) { | ||
102 | + this._invocationChainRoot = true; | ||
103 | + this._invocationChain = []; | ||
104 | + if (jake.currentRunningTask) { | ||
105 | + jake.currentRunningTask._waitForChains = jake.currentRunningTask._waitForChains || []; | ||
106 | + jake.currentRunningTask._waitForChains.push(this._invocationChain); | ||
107 | + } | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + /** | ||
112 | + @name jake.Task#invoke | ||
113 | + @function | ||
114 | + @description Runs prerequisites, then this task. If the task has already | ||
115 | + been run, will not run the task again. | ||
116 | + */ | ||
117 | + invoke() { | ||
118 | + this._initInvocationChain(); | ||
119 | + | ||
120 | + this.args = Array.prototype.slice.call(arguments); | ||
121 | + this.reenabled = false | ||
122 | + this.runPrereqs(); | ||
123 | + } | ||
124 | + | ||
125 | + /** | ||
126 | + @name jake.Task#execute | ||
127 | + @function | ||
128 | + @description Run only this task, without prereqs. If the task has already | ||
129 | + been run, *will* run the task again. | ||
130 | + */ | ||
131 | + execute() { | ||
132 | + this._initInvocationChain(); | ||
133 | + | ||
134 | + this.args = Array.prototype.slice.call(arguments); | ||
135 | + this.reenable(); | ||
136 | + this.reenabled = true | ||
137 | + this.run(); | ||
138 | + } | ||
139 | + | ||
140 | + runPrereqs() { | ||
141 | + if (this.prereqs && this.prereqs.length) { | ||
142 | + | ||
143 | + if (this.concurrency > 1) { | ||
144 | + async.eachLimit(this.prereqs, this.concurrency, | ||
145 | + | ||
146 | + (name, cb) => { | ||
147 | + let parsed = parsePrereqName(name); | ||
148 | + | ||
149 | + let prereq = this.namespace.resolveTask(parsed.name) || | ||
150 | + jake.attemptRule(name, this.namespace, 0) || | ||
151 | + jake.createPlaceholderFileTask(name, this.namespace); | ||
152 | + | ||
153 | + if (!prereq) { | ||
154 | + throw new Error('Unknown task "' + name + '"'); | ||
155 | + } | ||
156 | + | ||
157 | + //Test for circular invocation | ||
158 | + if(prereq === this) { | ||
159 | + setImmediate(function () { | ||
160 | + cb(new Error("Cannot use prereq " + prereq.name + " as a dependency of itself")); | ||
161 | + }); | ||
162 | + } | ||
163 | + | ||
164 | + if (prereq.taskStatus == Task.runStatuses.DONE) { | ||
165 | + //prereq already done, return | ||
166 | + setImmediate(cb); | ||
167 | + } | ||
168 | + else { | ||
169 | + //wait for complete before calling cb | ||
170 | + prereq.once('_done', () => { | ||
171 | + prereq.removeAllListeners('_done'); | ||
172 | + setImmediate(cb); | ||
173 | + }); | ||
174 | + // Start the prereq if we are the first to encounter it | ||
175 | + if (prereq.taskStatus === Task.runStatuses.UNSTARTED) { | ||
176 | + prereq.taskStatus = Task.runStatuses.STARTED; | ||
177 | + prereq.invoke.apply(prereq, parsed.args); | ||
178 | + } | ||
179 | + } | ||
180 | + }, | ||
181 | + | ||
182 | + (err) => { | ||
183 | + //async callback is called after all prereqs have run. | ||
184 | + if (err) { | ||
185 | + throw err; | ||
186 | + } | ||
187 | + else { | ||
188 | + setImmediate(this.run.bind(this)); | ||
189 | + } | ||
190 | + } | ||
191 | + ); | ||
192 | + } | ||
193 | + else { | ||
194 | + setImmediate(this.nextPrereq.bind(this)); | ||
195 | + } | ||
196 | + } | ||
197 | + else { | ||
198 | + setImmediate(this.run.bind(this)); | ||
199 | + } | ||
200 | + } | ||
201 | + | ||
202 | + nextPrereq() { | ||
203 | + let self = this; | ||
204 | + let index = this._currentPrereqIndex; | ||
205 | + let name = this.prereqs[index]; | ||
206 | + let prereq; | ||
207 | + let parsed; | ||
208 | + | ||
209 | + if (name) { | ||
210 | + | ||
211 | + parsed = parsePrereqName(name); | ||
212 | + | ||
213 | + prereq = this.namespace.resolveTask(parsed.name) || | ||
214 | + jake.attemptRule(name, this.namespace, 0) || | ||
215 | + jake.createPlaceholderFileTask(name, this.namespace); | ||
216 | + | ||
217 | + if (!prereq) { | ||
218 | + throw new Error('Unknown task "' + name + '"'); | ||
219 | + } | ||
220 | + | ||
221 | + // Do when done | ||
222 | + if (prereq.taskStatus == Task.runStatuses.DONE) { | ||
223 | + self.handlePrereqDone(prereq); | ||
224 | + } | ||
225 | + else { | ||
226 | + prereq.once('_done', () => { | ||
227 | + this.handlePrereqDone(prereq); | ||
228 | + prereq.removeAllListeners('_done'); | ||
229 | + }); | ||
230 | + if (prereq.taskStatus == Task.runStatuses.UNSTARTED) { | ||
231 | + prereq.taskStatus = Task.runStatuses.STARTED; | ||
232 | + prereq._invocationChain = this._invocationChain; | ||
233 | + prereq.invoke.apply(prereq, parsed.args); | ||
234 | + } | ||
235 | + } | ||
236 | + } | ||
237 | + } | ||
238 | + | ||
239 | + /** | ||
240 | + @name jake.Task#reenable | ||
241 | + @function | ||
242 | + @description Reenables a task so that it can be run again. | ||
243 | + */ | ||
244 | + reenable(deep) { | ||
245 | + let prereqs; | ||
246 | + let prereq; | ||
247 | + this._skipped = false; | ||
248 | + this.taskStatus = Task.runStatuses.UNSTARTED; | ||
249 | + this.value = UNDEFINED_VALUE; | ||
250 | + if (deep && this.prereqs) { | ||
251 | + prereqs = this.prereqs; | ||
252 | + for (let i = 0, ii = prereqs.length; i < ii; i++) { | ||
253 | + prereq = jake.Task[prereqs[i]]; | ||
254 | + if (prereq) { | ||
255 | + prereq.reenable(deep); | ||
256 | + } | ||
257 | + } | ||
258 | + } | ||
259 | + } | ||
260 | + | ||
261 | + handlePrereqDone(prereq) { | ||
262 | + this._currentPrereqIndex++; | ||
263 | + if (this._currentPrereqIndex < this.prereqs.length) { | ||
264 | + setImmediate(this.nextPrereq.bind(this)); | ||
265 | + } | ||
266 | + else { | ||
267 | + setImmediate(this.run.bind(this)); | ||
268 | + } | ||
269 | + } | ||
270 | + | ||
271 | + isNeeded() { | ||
272 | + let needed = true; | ||
273 | + if (this.taskStatus == Task.runStatuses.DONE) { | ||
274 | + needed = false; | ||
275 | + } | ||
276 | + return needed; | ||
277 | + } | ||
278 | + | ||
279 | + run() { | ||
280 | + let val, previous; | ||
281 | + let hasAction = typeof this.action == 'function'; | ||
282 | + | ||
283 | + if (!this.isNeeded()) { | ||
284 | + this.emit('skip'); | ||
285 | + this.emit('_done'); | ||
286 | + } | ||
287 | + else { | ||
288 | + if (this._invocationChain.length) { | ||
289 | + previous = this._invocationChain[this._invocationChain.length - 1]; | ||
290 | + // If this task is repeating and its previous is equal to this, don't check its status because it was set to UNSTARTED by the reenable() method | ||
291 | + if (!(this.reenabled && previous == this)) { | ||
292 | + if (previous.taskStatus != Task.runStatuses.DONE) { | ||
293 | + let now = (new Date()).getTime(); | ||
294 | + if (now - this.startTime > jake._taskTimeout) { | ||
295 | + return jake.fail(`Timed out waiting for task: ${previous.name} with status of ${previous.taskStatus}`); | ||
296 | + } | ||
297 | + setTimeout(this.run.bind(this), POLLING_INTERVAL); | ||
298 | + return; | ||
299 | + } | ||
300 | + } | ||
301 | + } | ||
302 | + if (!(this.reenabled && previous == this)) { | ||
303 | + this._invocationChain.push(this); | ||
304 | + } | ||
305 | + | ||
306 | + if (!(this._internal || jake.program.opts.quiet)) { | ||
307 | + console.log("Starting '" + chalk.green(this.fullName) + "'..."); | ||
308 | + } | ||
309 | + | ||
310 | + this.startTime = (new Date()).getTime(); | ||
311 | + this.emit('start'); | ||
312 | + | ||
313 | + jake.currentRunningTask = this; | ||
314 | + | ||
315 | + if (hasAction) { | ||
316 | + try { | ||
317 | + if (this.directory) { | ||
318 | + process.chdir(this.directory); | ||
319 | + } | ||
320 | + | ||
321 | + val = this.action.apply(this, this.args); | ||
322 | + | ||
323 | + if (typeof val == 'object' && typeof val.then == 'function') { | ||
324 | + this.async = true; | ||
325 | + | ||
326 | + val.then( | ||
327 | + (result) => { | ||
328 | + setImmediate(() => { | ||
329 | + this.complete(result); | ||
330 | + }); | ||
331 | + }, | ||
332 | + (err) => { | ||
333 | + setImmediate(() => { | ||
334 | + this.errorOut(err); | ||
335 | + }); | ||
336 | + }); | ||
337 | + } | ||
338 | + } | ||
339 | + catch (err) { | ||
340 | + this.errorOut(err); | ||
341 | + return; // Bail out, not complete | ||
342 | + } | ||
343 | + } | ||
344 | + | ||
345 | + if (!(hasAction && this.async)) { | ||
346 | + setImmediate(() => { | ||
347 | + this.complete(val); | ||
348 | + }); | ||
349 | + } | ||
350 | + } | ||
351 | + } | ||
352 | + | ||
353 | + errorOut(err) { | ||
354 | + this.taskStatus = Task.runStatuses.ERROR; | ||
355 | + this._invocationChain.chainStatus = Task.runStatuses.ERROR; | ||
356 | + this.emit('error', err); | ||
357 | + } | ||
358 | + | ||
359 | + complete(val) { | ||
360 | + | ||
361 | + if (Array.isArray(this._waitForChains)) { | ||
362 | + let stillWaiting = this._waitForChains.some((chain) => { | ||
363 | + return !(chain.chainStatus == Task.runStatuses.DONE || | ||
364 | + chain.chainStatus == Task.runStatuses.ERROR); | ||
365 | + }); | ||
366 | + if (stillWaiting) { | ||
367 | + let now = (new Date()).getTime(); | ||
368 | + let elapsed = now - this.startTime; | ||
369 | + if (elapsed > jake._taskTimeout) { | ||
370 | + return jake.fail(`Timed out waiting for task: ${this.name} with status of ${this.taskStatus}. Elapsed: ${elapsed}`); | ||
371 | + } | ||
372 | + setTimeout(() => { | ||
373 | + this.complete(val); | ||
374 | + }, POLLING_INTERVAL); | ||
375 | + return; | ||
376 | + } | ||
377 | + } | ||
378 | + | ||
379 | + jake._invocationChain.splice(jake._invocationChain.indexOf(this), 1); | ||
380 | + | ||
381 | + if (this._invocationChainRoot) { | ||
382 | + this._invocationChain.chainStatus = Task.runStatuses.DONE; | ||
383 | + } | ||
384 | + | ||
385 | + this._currentPrereqIndex = 0; | ||
386 | + | ||
387 | + // If 'complete' getting called because task has been | ||
388 | + // run already, value will not be passed -- leave in place | ||
389 | + if (!this._skipped) { | ||
390 | + this.taskStatus = Task.runStatuses.DONE; | ||
391 | + this.value = val; | ||
392 | + | ||
393 | + this.emit('complete', this.value); | ||
394 | + this.emit('_done'); | ||
395 | + | ||
396 | + this.endTime = (new Date()).getTime(); | ||
397 | + let taskTime = this.endTime - this.startTime; | ||
398 | + | ||
399 | + if (!(this._internal || jake.program.opts.quiet)) { | ||
400 | + console.log("Finished '" + chalk.green(this.fullName) + "' after " + chalk.magenta(taskTime + ' ms')); | ||
401 | + } | ||
402 | + | ||
403 | + } | ||
404 | + } | ||
405 | + | ||
406 | + _getFullName() { | ||
407 | + let ns = this.namespace; | ||
408 | + let path = (ns && ns.path) || ''; | ||
409 | + path = (path && path.split(':')) || []; | ||
410 | + if (this.namespace !== jake.defaultNamespace) { | ||
411 | + path.push(this.namespace.name); | ||
412 | + } | ||
413 | + path.push(this.name); | ||
414 | + return path.join(':'); | ||
415 | + } | ||
416 | + | ||
417 | + static getBaseNamespacePath(fullName) { | ||
418 | + return fullName.split(':').slice(0, -1).join(':'); | ||
419 | + } | ||
420 | + | ||
421 | + static getBaseTaskName(fullName) { | ||
422 | + return fullName.split(':').pop(); | ||
423 | + } | ||
424 | +} | ||
425 | + | ||
426 | +Task.runStatuses = { | ||
427 | + UNSTARTED: 'unstarted', | ||
428 | + DONE: 'done', | ||
429 | + STARTED: 'started', | ||
430 | + ERROR: 'error' | ||
431 | +}; | ||
432 | + | ||
433 | +Task.ROOT_TASK_NAME = ROOT_TASK_NAME; | ||
434 | + | ||
435 | +exports.Task = Task; | ||
436 | + | ||
437 | +// Required here because circular deps | ||
438 | +require('../rule'); | ||
439 | + |
node_modules/jake/lib/test_task.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let path = require('path'); | ||
20 | +let currDir = process.cwd(); | ||
21 | + | ||
22 | +/** | ||
23 | + @name jake | ||
24 | + @namespace jake | ||
25 | +*/ | ||
26 | +/** | ||
27 | + @name jake.TestTask | ||
28 | + @constructor | ||
29 | + @description Instantiating a TestTask creates a number of Jake | ||
30 | + Tasks that make running tests for your software easy. | ||
31 | + | ||
32 | + @param {String} name The name of the project | ||
33 | + @param {Function} definition Defines the list of files containing the tests, | ||
34 | + and the name of the namespace/task for running them. Will be executed on the | ||
35 | + instantiated TestTask (i.e., 'this', will be the TestTask instance), to set | ||
36 | + the various instance-propertiess. | ||
37 | + | ||
38 | + @example | ||
39 | + let t = new jake.TestTask('bij-js', function () { | ||
40 | + this.testName = 'testSpecial'; | ||
41 | + this.testFiles.include('test/**'); | ||
42 | + }); | ||
43 | + | ||
44 | + */ | ||
45 | +let TestTask = function () { | ||
46 | + let self = this; | ||
47 | + let args = Array.prototype.slice.call(arguments); | ||
48 | + let name = args.shift(); | ||
49 | + let definition = args.pop(); | ||
50 | + let prereqs = args.pop() || []; | ||
51 | + | ||
52 | + /** | ||
53 | + @name jake.TestTask#testNam | ||
54 | + @public | ||
55 | + @type {String} | ||
56 | + @description The name of the namespace to place the tests in, and | ||
57 | + the top-level task for running tests. Defaults to "test" | ||
58 | + */ | ||
59 | + this.testName = 'test'; | ||
60 | + | ||
61 | + /** | ||
62 | + @name jake.TestTask#testFiles | ||
63 | + @public | ||
64 | + @type {jake.FileList} | ||
65 | + @description The list of files containing tests to load | ||
66 | + */ | ||
67 | + this.testFiles = new jake.FileList(); | ||
68 | + | ||
69 | + /** | ||
70 | + @name jake.TestTask#showDescription | ||
71 | + @public | ||
72 | + @type {Boolean} | ||
73 | + @description Show the created task when doing Jake -T | ||
74 | + */ | ||
75 | + this.showDescription = true; | ||
76 | + | ||
77 | + /* | ||
78 | + @name jake.TestTask#totalTests | ||
79 | + @public | ||
80 | + @type {Number} | ||
81 | + @description The total number of tests to run | ||
82 | + */ | ||
83 | + this.totalTests = 0; | ||
84 | + | ||
85 | + /* | ||
86 | + @name jake.TestTask#executedTests | ||
87 | + @public | ||
88 | + @type {Number} | ||
89 | + @description The number of tests successfully run | ||
90 | + */ | ||
91 | + this.executedTests = 0; | ||
92 | + | ||
93 | + if (typeof definition == 'function') { | ||
94 | + definition.call(this); | ||
95 | + } | ||
96 | + | ||
97 | + if (this.showDescription) { | ||
98 | + desc('Run the tests for ' + name); | ||
99 | + } | ||
100 | + | ||
101 | + task(this.testName, prereqs, {async: true}, function () { | ||
102 | + let t = jake.Task[this.fullName + ':run']; | ||
103 | + t.on('complete', function () { | ||
104 | + complete(); | ||
105 | + }); | ||
106 | + // Pass args to the namespaced test | ||
107 | + t.invoke.apply(t, arguments); | ||
108 | + }); | ||
109 | + | ||
110 | + namespace(self.testName, function () { | ||
111 | + | ||
112 | + let runTask = task('run', {async: true}, function (pat) { | ||
113 | + let re; | ||
114 | + let testFiles; | ||
115 | + | ||
116 | + // Don't nest; make a top-level namespace. Don't want | ||
117 | + // re-calling from inside to nest infinitely | ||
118 | + jake.currentNamespace = jake.defaultNamespace; | ||
119 | + | ||
120 | + re = new RegExp(pat); | ||
121 | + // Get test files that match the passed-in pattern | ||
122 | + testFiles = self.testFiles.toArray() | ||
123 | + .filter(function (f) { | ||
124 | + return (re).test(f); | ||
125 | + }) // Don't load the same file multiple times -- should this be in FileList? | ||
126 | + .reduce(function (p, c) { | ||
127 | + if (p.indexOf(c) < 0) { | ||
128 | + p.push(c); | ||
129 | + } | ||
130 | + return p; | ||
131 | + }, []); | ||
132 | + | ||
133 | + // Create a namespace for all the testing tasks to live in | ||
134 | + namespace(self.testName + 'Exec', function () { | ||
135 | + // Each test will be a prereq for the dummy top-level task | ||
136 | + let prereqs = []; | ||
137 | + // Continuation to pass to the async tests, wrapping `continune` | ||
138 | + let next = function () { | ||
139 | + complete(); | ||
140 | + }; | ||
141 | + // Create the task for this test-function | ||
142 | + let createTask = function (name, action) { | ||
143 | + // If the test-function is defined with a continuation | ||
144 | + // param, flag the task as async | ||
145 | + let t; | ||
146 | + let isAsync = !!action.length; | ||
147 | + | ||
148 | + // Define the actual namespaced task with the name, the | ||
149 | + // wrapped action, and the correc async-flag | ||
150 | + t = task(name, createAction(name, action), { | ||
151 | + async: isAsync | ||
152 | + }); | ||
153 | + t.once('complete', function () { | ||
154 | + self.executedTests++; | ||
155 | + }); | ||
156 | + t._internal = true; | ||
157 | + return t; | ||
158 | + }; | ||
159 | + // Used as the action for the defined task for each test. | ||
160 | + let createAction = function (n, a) { | ||
161 | + // A wrapped function that passes in the `next` function | ||
162 | + // for any tasks that run asynchronously | ||
163 | + return function () { | ||
164 | + let cb; | ||
165 | + if (a.length) { | ||
166 | + cb = next; | ||
167 | + } | ||
168 | + if (!(n == 'before' || n == 'after' || | ||
169 | + /_beforeEach$/.test(n) || /_afterEach$/.test(n))) { | ||
170 | + jake.logger.log(n); | ||
171 | + } | ||
172 | + // 'this' will be the task when action is run | ||
173 | + return a.call(this, cb); | ||
174 | + }; | ||
175 | + }; | ||
176 | + // Dummy top-level task for everything to be prereqs for | ||
177 | + let topLevel; | ||
178 | + | ||
179 | + // Pull in each test-file, and iterate over any exported | ||
180 | + // test-functions. Register each test-function as a prereq task | ||
181 | + testFiles.forEach(function (file) { | ||
182 | + let exp = require(path.join(currDir, file)); | ||
183 | + | ||
184 | + // Create a namespace for each filename, so test-name collisions | ||
185 | + // won't be a problem | ||
186 | + namespace(file, function () { | ||
187 | + let testPrefix = self.testName + 'Exec:' + file + ':'; | ||
188 | + let testName; | ||
189 | + // Dummy task for displaying file banner | ||
190 | + testName = '*** Running ' + file + ' ***'; | ||
191 | + prereqs.push(testPrefix + testName); | ||
192 | + createTask(testName, function () {}); | ||
193 | + | ||
194 | + // 'before' setup | ||
195 | + if (typeof exp.before == 'function') { | ||
196 | + prereqs.push(testPrefix + 'before'); | ||
197 | + // Create the task | ||
198 | + createTask('before', exp.before); | ||
199 | + } | ||
200 | + | ||
201 | + // Walk each exported function, and create a task for each | ||
202 | + for (let p in exp) { | ||
203 | + if (p == 'before' || p == 'after' || | ||
204 | + p == 'beforeEach' || p == 'afterEach') { | ||
205 | + continue; | ||
206 | + } | ||
207 | + | ||
208 | + if (typeof exp.beforeEach == 'function') { | ||
209 | + prereqs.push(testPrefix + p + '_beforeEach'); | ||
210 | + // Create the task | ||
211 | + createTask(p + '_beforeEach', exp.beforeEach); | ||
212 | + } | ||
213 | + | ||
214 | + // Add the namespace:name of this test to the list of prereqs | ||
215 | + // for the dummy top-level task | ||
216 | + prereqs.push(testPrefix + p); | ||
217 | + // Create the task | ||
218 | + createTask(p, exp[p]); | ||
219 | + | ||
220 | + if (typeof exp.afterEach == 'function') { | ||
221 | + prereqs.push(testPrefix + p + '_afterEach'); | ||
222 | + // Create the task | ||
223 | + createTask(p + '_afterEach', exp.afterEach); | ||
224 | + } | ||
225 | + } | ||
226 | + | ||
227 | + // 'after' teardown | ||
228 | + if (typeof exp.after == 'function') { | ||
229 | + prereqs.push(testPrefix + 'after'); | ||
230 | + // Create the task | ||
231 | + let afterTask = createTask('after', exp.after); | ||
232 | + afterTask._internal = true; | ||
233 | + } | ||
234 | + | ||
235 | + }); | ||
236 | + }); | ||
237 | + | ||
238 | + self.totalTests = prereqs.length; | ||
239 | + process.on('exit', function () { | ||
240 | + // Throw in the case where the process exits without | ||
241 | + // finishing tests, but no error was thrown | ||
242 | + if (!jake.errorCode && (self.totalTests > self.executedTests)) { | ||
243 | + throw new Error('Process exited without all tests completing.'); | ||
244 | + } | ||
245 | + }); | ||
246 | + | ||
247 | + // Create the dummy top-level task. When calling a task internally | ||
248 | + // with `invoke` that is async (or has async prereqs), have to listen | ||
249 | + // for the 'complete' event to know when it's done | ||
250 | + topLevel = task('__top__', prereqs); | ||
251 | + topLevel._internal = true; | ||
252 | + topLevel.addListener('complete', function () { | ||
253 | + jake.logger.log('All tests ran successfully'); | ||
254 | + complete(); | ||
255 | + }); | ||
256 | + | ||
257 | + topLevel.invoke(); // Do the thing! | ||
258 | + }); | ||
259 | + | ||
260 | + }); | ||
261 | + runTask._internal = true; | ||
262 | + | ||
263 | + }); | ||
264 | + | ||
265 | + | ||
266 | +}; | ||
267 | + | ||
268 | +jake.TestTask = TestTask; | ||
269 | +exports.TestTask = TestTask; | ||
270 | + |
node_modules/jake/lib/utils/file.js
0 → 100644
1 | +/* | ||
2 | + * Utilities: A classic collection of JavaScript utilities | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +let fs = require('fs'); | ||
20 | +let path = require('path'); | ||
21 | + | ||
22 | +/** | ||
23 | + @name file | ||
24 | + @namespace file | ||
25 | +*/ | ||
26 | + | ||
27 | +let fileUtils = new (function () { | ||
28 | + | ||
29 | + // Recursively copy files and directories | ||
30 | + let _copyFile = function (fromPath, toPath, opts) { | ||
31 | + let from = path.normalize(fromPath) | ||
32 | + let to = path.normalize(toPath) | ||
33 | + let options = opts || {} | ||
34 | + let fromStat; | ||
35 | + let toStat; | ||
36 | + let destExists; | ||
37 | + let destDoesNotExistErr; | ||
38 | + let content; | ||
39 | + let filename; | ||
40 | + let dirContents; | ||
41 | + let targetDir; | ||
42 | + | ||
43 | + fromStat = fs.statSync(from); | ||
44 | + | ||
45 | + try { | ||
46 | + //console.dir(to + ' destExists'); | ||
47 | + toStat = fs.statSync(to); | ||
48 | + destExists = true; | ||
49 | + } | ||
50 | + catch(e) { | ||
51 | + //console.dir(to + ' does not exist'); | ||
52 | + destDoesNotExistErr = e; | ||
53 | + destExists = false; | ||
54 | + } | ||
55 | + // Destination dir or file exists, copy into (directory) | ||
56 | + // or overwrite (file) | ||
57 | + if (destExists) { | ||
58 | + | ||
59 | + // If there's a rename-via-copy file/dir name passed, use it. | ||
60 | + // Otherwise use the actual file/dir name | ||
61 | + filename = options.rename || path.basename(from); | ||
62 | + | ||
63 | + // Copying a directory | ||
64 | + if (fromStat.isDirectory()) { | ||
65 | + dirContents = fs.readdirSync(from); | ||
66 | + targetDir = path.join(to, filename); | ||
67 | + // We don't care if the target dir already exists | ||
68 | + try { | ||
69 | + fs.mkdirSync(targetDir, {mode: fromStat.mode & 0o777}); | ||
70 | + } | ||
71 | + catch(e) { | ||
72 | + if (e.code !== 'EEXIST') { | ||
73 | + throw e; | ||
74 | + } | ||
75 | + } | ||
76 | + for (let i = 0, ii = dirContents.length; i < ii; i++) { | ||
77 | + _copyFile(path.join(from, dirContents[i]), targetDir, {preserveMode: options.preserveMode}); | ||
78 | + } | ||
79 | + } | ||
80 | + // Copying a file | ||
81 | + else { | ||
82 | + content = fs.readFileSync(from); | ||
83 | + let mode = fromStat.mode & 0o777; | ||
84 | + let targetFile = to; | ||
85 | + | ||
86 | + if (toStat.isDirectory()) { | ||
87 | + targetFile = path.join(to, filename); | ||
88 | + } | ||
89 | + | ||
90 | + let fileExists = fs.existsSync(targetFile); | ||
91 | + fs.writeFileSync(targetFile, content); | ||
92 | + | ||
93 | + // If the file didn't already exist, use the original file mode. | ||
94 | + // Otherwise, only update the mode if preserverMode is true. | ||
95 | + if(!fileExists || options.preserveMode) { | ||
96 | + fs.chmodSync(targetFile, mode); | ||
97 | + } | ||
98 | + } | ||
99 | + } | ||
100 | + // Dest doesn't exist, can't create it | ||
101 | + else { | ||
102 | + throw destDoesNotExistErr; | ||
103 | + } | ||
104 | + }; | ||
105 | + | ||
106 | + // Remove the given directory | ||
107 | + let _rmDir = function (dirPath) { | ||
108 | + let dir = path.normalize(dirPath); | ||
109 | + let paths = []; | ||
110 | + paths = fs.readdirSync(dir); | ||
111 | + paths.forEach(function (p) { | ||
112 | + let curr = path.join(dir, p); | ||
113 | + let stat = fs.lstatSync(curr); | ||
114 | + if (stat.isDirectory()) { | ||
115 | + _rmDir(curr); | ||
116 | + } | ||
117 | + else { | ||
118 | + try { | ||
119 | + fs.unlinkSync(curr); | ||
120 | + } catch(e) { | ||
121 | + if (e.code === 'EPERM') { | ||
122 | + fs.chmodSync(curr, parseInt(666, 8)); | ||
123 | + fs.unlinkSync(curr); | ||
124 | + } else { | ||
125 | + throw e; | ||
126 | + } | ||
127 | + } | ||
128 | + } | ||
129 | + }); | ||
130 | + fs.rmdirSync(dir); | ||
131 | + }; | ||
132 | + | ||
133 | + /** | ||
134 | + @name file#cpR | ||
135 | + @public | ||
136 | + @function | ||
137 | + @description Copies a directory/file to a destination | ||
138 | + @param {String} fromPath The source path to copy from | ||
139 | + @param {String} toPath The destination path to copy to | ||
140 | + @param {Object} opts Options to use | ||
141 | + @param {Boolean} [opts.preserveMode] If target file already exists, this | ||
142 | + determines whether the original file's mode is copied over. The default of | ||
143 | + false mimics the behavior of the `cp` command line tool. (Default: false) | ||
144 | + */ | ||
145 | + this.cpR = function (fromPath, toPath, options) { | ||
146 | + let from = path.normalize(fromPath); | ||
147 | + let to = path.normalize(toPath); | ||
148 | + let toStat; | ||
149 | + let doesNotExistErr; | ||
150 | + let filename; | ||
151 | + let opts = options || {}; | ||
152 | + | ||
153 | + if (from == to) { | ||
154 | + throw new Error('Cannot copy ' + from + ' to itself.'); | ||
155 | + } | ||
156 | + | ||
157 | + // Handle rename-via-copy | ||
158 | + try { | ||
159 | + toStat = fs.statSync(to); | ||
160 | + } | ||
161 | + catch(e) { | ||
162 | + doesNotExistErr = e; | ||
163 | + | ||
164 | + // Get abs path so it's possible to check parent dir | ||
165 | + if (!this.isAbsolute(to)) { | ||
166 | + to = path.join(process.cwd(), to); | ||
167 | + } | ||
168 | + | ||
169 | + // Save the file/dir name | ||
170 | + filename = path.basename(to); | ||
171 | + // See if a parent dir exists, so there's a place to put the | ||
172 | + /// renamed file/dir (resets the destination for the copy) | ||
173 | + to = path.dirname(to); | ||
174 | + try { | ||
175 | + toStat = fs.statSync(to); | ||
176 | + } | ||
177 | + catch(e) {} | ||
178 | + if (toStat && toStat.isDirectory()) { | ||
179 | + // Set the rename opt to pass to the copy func, will be used | ||
180 | + // as the new file/dir name | ||
181 | + opts.rename = filename; | ||
182 | + //console.log('filename ' + filename); | ||
183 | + } | ||
184 | + else { | ||
185 | + throw doesNotExistErr; | ||
186 | + } | ||
187 | + } | ||
188 | + | ||
189 | + _copyFile(from, to, opts); | ||
190 | + }; | ||
191 | + | ||
192 | + /** | ||
193 | + @name file#mkdirP | ||
194 | + @public | ||
195 | + @function | ||
196 | + @description Create the given directory(ies) using the given mode permissions | ||
197 | + @param {String} dir The directory to create | ||
198 | + @param {Number} mode The mode to give the created directory(ies)(Default: 0755) | ||
199 | + */ | ||
200 | + this.mkdirP = function (dir, mode) { | ||
201 | + let dirPath = path.normalize(dir); | ||
202 | + let paths = dirPath.split(/\/|\\/); | ||
203 | + let currPath = ''; | ||
204 | + let next; | ||
205 | + | ||
206 | + if (paths[0] == '' || /^[A-Za-z]+:/.test(paths[0])) { | ||
207 | + currPath = paths.shift() || '/'; | ||
208 | + currPath = path.join(currPath, paths.shift()); | ||
209 | + //console.log('basedir'); | ||
210 | + } | ||
211 | + while ((next = paths.shift())) { | ||
212 | + if (next == '..') { | ||
213 | + currPath = path.join(currPath, next); | ||
214 | + continue; | ||
215 | + } | ||
216 | + currPath = path.join(currPath, next); | ||
217 | + try { | ||
218 | + //console.log('making ' + currPath); | ||
219 | + fs.mkdirSync(currPath, mode || parseInt(755, 8)); | ||
220 | + } | ||
221 | + catch(e) { | ||
222 | + if (e.code != 'EEXIST') { | ||
223 | + throw e; | ||
224 | + } | ||
225 | + } | ||
226 | + } | ||
227 | + }; | ||
228 | + | ||
229 | + /** | ||
230 | + @name file#rmRf | ||
231 | + @public | ||
232 | + @function | ||
233 | + @description Deletes the given directory/file | ||
234 | + @param {String} p The path to delete, can be a directory or file | ||
235 | + */ | ||
236 | + this.rmRf = function (p, options) { | ||
237 | + let stat; | ||
238 | + try { | ||
239 | + stat = fs.lstatSync(p); | ||
240 | + if (stat.isDirectory()) { | ||
241 | + _rmDir(p); | ||
242 | + } | ||
243 | + else { | ||
244 | + fs.unlinkSync(p); | ||
245 | + } | ||
246 | + } | ||
247 | + catch (e) {} | ||
248 | + }; | ||
249 | + | ||
250 | + /** | ||
251 | + @name file#isAbsolute | ||
252 | + @public | ||
253 | + @function | ||
254 | + @return {Boolean/String} If it's absolute the first character is returned otherwise false | ||
255 | + @description Checks if a given path is absolute or relative | ||
256 | + @param {String} p Path to check | ||
257 | + */ | ||
258 | + this.isAbsolute = function (p) { | ||
259 | + let match = /^[A-Za-z]+:\\|^\//.exec(p); | ||
260 | + if (match && match.length) { | ||
261 | + return match[0]; | ||
262 | + } | ||
263 | + return false; | ||
264 | + }; | ||
265 | + | ||
266 | + /** | ||
267 | + @name file#absolutize | ||
268 | + @public | ||
269 | + @function | ||
270 | + @return {String} Returns the absolute path for the given path | ||
271 | + @description Returns the absolute path for the given path | ||
272 | + @param {String} p The path to get the absolute path for | ||
273 | + */ | ||
274 | + this.absolutize = function (p) { | ||
275 | + if (this.isAbsolute(p)) { | ||
276 | + return p; | ||
277 | + } | ||
278 | + else { | ||
279 | + return path.join(process.cwd(), p); | ||
280 | + } | ||
281 | + }; | ||
282 | + | ||
283 | +})(); | ||
284 | + | ||
285 | +module.exports = fileUtils; | ||
286 | + |
node_modules/jake/lib/utils/index.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | + | ||
20 | +let util = require('util'); // Native Node util module | ||
21 | +let spawn = require('child_process').spawn; | ||
22 | +let EventEmitter = require('events').EventEmitter; | ||
23 | +let logger = require('./logger'); | ||
24 | +let file = require('./file'); | ||
25 | +let Exec; | ||
26 | + | ||
27 | +const _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); | ||
28 | + | ||
29 | +let parseArgs = function (argumentsObj) { | ||
30 | + let args; | ||
31 | + let arg; | ||
32 | + let cmds; | ||
33 | + let callback; | ||
34 | + let opts = { | ||
35 | + interactive: false, | ||
36 | + printStdout: false, | ||
37 | + printStderr: false, | ||
38 | + breakOnError: true | ||
39 | + }; | ||
40 | + | ||
41 | + args = Array.prototype.slice.call(argumentsObj); | ||
42 | + | ||
43 | + cmds = args.shift(); | ||
44 | + // Arrayize if passed a single string command | ||
45 | + if (typeof cmds == 'string') { | ||
46 | + cmds = [cmds]; | ||
47 | + } | ||
48 | + // Make a copy if it's an actual list | ||
49 | + else { | ||
50 | + cmds = cmds.slice(); | ||
51 | + } | ||
52 | + | ||
53 | + // Get optional callback or opts | ||
54 | + while((arg = args.shift())) { | ||
55 | + if (typeof arg == 'function') { | ||
56 | + callback = arg; | ||
57 | + } | ||
58 | + else if (typeof arg == 'object') { | ||
59 | + opts = Object.assign(opts, arg); | ||
60 | + } | ||
61 | + } | ||
62 | + | ||
63 | + // Backward-compat shim | ||
64 | + if (typeof opts.stdout != 'undefined') { | ||
65 | + opts.printStdout = opts.stdout; | ||
66 | + delete opts.stdout; | ||
67 | + } | ||
68 | + if (typeof opts.stderr != 'undefined') { | ||
69 | + opts.printStderr = opts.stderr; | ||
70 | + delete opts.stderr; | ||
71 | + } | ||
72 | + | ||
73 | + return { | ||
74 | + cmds: cmds, | ||
75 | + opts: opts, | ||
76 | + callback: callback | ||
77 | + }; | ||
78 | +}; | ||
79 | + | ||
80 | +/** | ||
81 | + @name jake | ||
82 | + @namespace jake | ||
83 | +*/ | ||
84 | +let utils = new (function () { | ||
85 | + /** | ||
86 | + @name jake.exec | ||
87 | + @static | ||
88 | + @function | ||
89 | + @description Executes shell-commands asynchronously with an optional | ||
90 | + final callback. | ||
91 | + ` | ||
92 | + @param {String[]} cmds The list of shell-commands to execute | ||
93 | + @param {Object} [opts] | ||
94 | + @param {Boolean} [opts.printStdout=false] Print stdout from each command | ||
95 | + @param {Boolean} [opts.printStderr=false] Print stderr from each command | ||
96 | + @param {Boolean} [opts.breakOnError=true] Stop further execution on | ||
97 | + the first error. | ||
98 | + @param {Boolean} [opts.windowsVerbatimArguments=false] Don't translate | ||
99 | + arguments on Windows. | ||
100 | + @param {Function} [callback] Callback to run after executing the | ||
101 | + commands | ||
102 | + | ||
103 | + @example | ||
104 | + let cmds = [ | ||
105 | + 'echo "showing directories"' | ||
106 | + , 'ls -al | grep ^d' | ||
107 | + , 'echo "moving up a directory"' | ||
108 | + , 'cd ../' | ||
109 | + ] | ||
110 | + , callback = function () { | ||
111 | + console.log('Finished running commands.'); | ||
112 | + } | ||
113 | + jake.exec(cmds, {stdout: true}, callback); | ||
114 | + */ | ||
115 | + this.exec = function (a, b, c) { | ||
116 | + let parsed = parseArgs(arguments); | ||
117 | + let cmds = parsed.cmds; | ||
118 | + let opts = parsed.opts; | ||
119 | + let callback = parsed.callback; | ||
120 | + | ||
121 | + let ex = new Exec(cmds, opts, callback); | ||
122 | + | ||
123 | + ex.addListener('error', function (msg, code) { | ||
124 | + if (opts.breakOnError) { | ||
125 | + fail(msg, code); | ||
126 | + } | ||
127 | + }); | ||
128 | + ex.run(); | ||
129 | + | ||
130 | + return ex; | ||
131 | + }; | ||
132 | + | ||
133 | + this.createExec = function (a, b, c) { | ||
134 | + return new Exec(a, b, c); | ||
135 | + }; | ||
136 | + | ||
137 | + // From Math.uuid.js, https://github.com/broofa/node-uuid | ||
138 | + // Robert Kieffer (robert@broofa.com), MIT license | ||
139 | + this.uuid = function (length, radix) { | ||
140 | + var chars = _UUID_CHARS | ||
141 | + , uuid = [] | ||
142 | + , r | ||
143 | + , i; | ||
144 | + | ||
145 | + radix = radix || chars.length; | ||
146 | + | ||
147 | + if (length) { | ||
148 | + // Compact form | ||
149 | + i = -1; | ||
150 | + while (++i < length) { | ||
151 | + uuid[i] = chars[0 | Math.random()*radix]; | ||
152 | + } | ||
153 | + } else { | ||
154 | + // rfc4122, version 4 form | ||
155 | + | ||
156 | + // rfc4122 requires these characters | ||
157 | + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; | ||
158 | + uuid[14] = '4'; | ||
159 | + | ||
160 | + // Fill in random data. At i==19 set the high bits of clock sequence as | ||
161 | + // per rfc4122, sec. 4.1.5 | ||
162 | + i = -1; | ||
163 | + while (++i < 36) { | ||
164 | + if (!uuid[i]) { | ||
165 | + r = 0 | Math.random()*16; | ||
166 | + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; | ||
167 | + } | ||
168 | + } | ||
169 | + } | ||
170 | + | ||
171 | + return uuid.join(''); | ||
172 | + }; | ||
173 | + | ||
174 | +})(); | ||
175 | + | ||
176 | +Exec = function () { | ||
177 | + let parsed = parseArgs(arguments); | ||
178 | + let cmds = parsed.cmds; | ||
179 | + let opts = parsed.opts; | ||
180 | + let callback = parsed.callback; | ||
181 | + | ||
182 | + this._cmds = cmds; | ||
183 | + this._callback = callback; | ||
184 | + this._config = opts; | ||
185 | +}; | ||
186 | + | ||
187 | +util.inherits(Exec, EventEmitter); | ||
188 | + | ||
189 | +Object.assign(Exec.prototype, new (function () { | ||
190 | + | ||
191 | + let _run = function () { | ||
192 | + let self = this; | ||
193 | + let sh; | ||
194 | + let cmd; | ||
195 | + let args; | ||
196 | + let next = this._cmds.shift(); | ||
197 | + let config = this._config; | ||
198 | + let errData = ''; | ||
199 | + let shStdio; | ||
200 | + let handleStdoutData = function (data) { | ||
201 | + self.emit('stdout', data); | ||
202 | + }; | ||
203 | + let handleStderrData = function (data) { | ||
204 | + let d = data.toString(); | ||
205 | + self.emit('stderr', data); | ||
206 | + // Accumulate the error-data so we can use it as the | ||
207 | + // stack if the process exits with an error | ||
208 | + errData += d; | ||
209 | + }; | ||
210 | + | ||
211 | + // Keep running as long as there are commands in the array | ||
212 | + if (next) { | ||
213 | + let spawnOpts = {}; | ||
214 | + this.emit('cmdStart', next); | ||
215 | + | ||
216 | + // Ganking part of Node's child_process.exec to get cmdline args parsed | ||
217 | + if (process.platform == 'win32') { | ||
218 | + cmd = 'cmd'; | ||
219 | + args = ['/c', next]; | ||
220 | + if (config.windowsVerbatimArguments) { | ||
221 | + spawnOpts.windowsVerbatimArguments = true; | ||
222 | + } | ||
223 | + } | ||
224 | + else { | ||
225 | + cmd = '/bin/sh'; | ||
226 | + args = ['-c', next]; | ||
227 | + } | ||
228 | + | ||
229 | + if (config.interactive) { | ||
230 | + spawnOpts.stdio = 'inherit'; | ||
231 | + sh = spawn(cmd, args, spawnOpts); | ||
232 | + } | ||
233 | + else { | ||
234 | + shStdio = [ | ||
235 | + process.stdin | ||
236 | + ]; | ||
237 | + if (config.printStdout) { | ||
238 | + shStdio.push(process.stdout); | ||
239 | + } | ||
240 | + else { | ||
241 | + shStdio.push('pipe'); | ||
242 | + } | ||
243 | + if (config.printStderr) { | ||
244 | + shStdio.push(process.stderr); | ||
245 | + } | ||
246 | + else { | ||
247 | + shStdio.push('pipe'); | ||
248 | + } | ||
249 | + spawnOpts.stdio = shStdio; | ||
250 | + sh = spawn(cmd, args, spawnOpts); | ||
251 | + if (!config.printStdout) { | ||
252 | + sh.stdout.addListener('data', handleStdoutData); | ||
253 | + } | ||
254 | + if (!config.printStderr) { | ||
255 | + sh.stderr.addListener('data', handleStderrData); | ||
256 | + } | ||
257 | + } | ||
258 | + | ||
259 | + // Exit, handle err or run next | ||
260 | + sh.on('exit', function (code) { | ||
261 | + let msg; | ||
262 | + if (code !== 0) { | ||
263 | + msg = errData || 'Process exited with error.'; | ||
264 | + msg = msg.trim(); | ||
265 | + self.emit('error', msg, code); | ||
266 | + } | ||
267 | + if (code === 0 || !config.breakOnError) { | ||
268 | + self.emit('cmdEnd', next); | ||
269 | + setTimeout(function () { _run.call(self); }, 0); | ||
270 | + } | ||
271 | + }); | ||
272 | + | ||
273 | + } | ||
274 | + else { | ||
275 | + self.emit('end'); | ||
276 | + if (typeof self._callback == 'function') { | ||
277 | + self._callback(); | ||
278 | + } | ||
279 | + } | ||
280 | + }; | ||
281 | + | ||
282 | + this.append = function (cmd) { | ||
283 | + this._cmds.push(cmd); | ||
284 | + }; | ||
285 | + | ||
286 | + this.run = function () { | ||
287 | + _run.call(this); | ||
288 | + }; | ||
289 | + | ||
290 | +})()); | ||
291 | + | ||
292 | +utils.Exec = Exec; | ||
293 | +utils.file = file; | ||
294 | +utils.logger = logger; | ||
295 | + | ||
296 | +module.exports = utils; | ||
297 | + |
node_modules/jake/lib/utils/logger.js
0 → 100644
1 | +let util = require('util'); | ||
2 | + | ||
3 | +let logger = new (function () { | ||
4 | + let _output = function (type, out) { | ||
5 | + let quiet = typeof jake != 'undefined' && jake.program && | ||
6 | + jake.program.opts && jake.program.opts.quiet; | ||
7 | + let msg; | ||
8 | + if (!quiet) { | ||
9 | + msg = typeof out == 'string' ? out : util.inspect(out); | ||
10 | + console[type](msg); | ||
11 | + } | ||
12 | + }; | ||
13 | + | ||
14 | + this.log = function (out) { | ||
15 | + _output('log', out); | ||
16 | + }; | ||
17 | + | ||
18 | + this.error = function (out) { | ||
19 | + _output('error', out); | ||
20 | + }; | ||
21 | + | ||
22 | +})(); | ||
23 | + | ||
24 | +module.exports = logger; |
node_modules/jake/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "jake", | ||
3 | + "description": "JavaScript build tool, similar to Make or Rake", | ||
4 | + "keywords": [ | ||
5 | + "build", | ||
6 | + "cli", | ||
7 | + "make", | ||
8 | + "rake" | ||
9 | + ], | ||
10 | + "version": "10.8.2", | ||
11 | + "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)", | ||
12 | + "license": "Apache-2.0", | ||
13 | + "bin": { | ||
14 | + "jake": "./bin/cli.js" | ||
15 | + }, | ||
16 | + "main": "./lib/jake.js", | ||
17 | + "scripts": { | ||
18 | + "lint": "eslint --format codeframe \"lib/**/*.js\" \"test/**/*.js\"", | ||
19 | + "lint:fix": "eslint --fix \"lib/**/*.js\" \"test/**/*.js\"", | ||
20 | + "test": "./bin/cli.js test", | ||
21 | + "test:ci": "npm run lint && npm run test" | ||
22 | + }, | ||
23 | + "repository": { | ||
24 | + "type": "git", | ||
25 | + "url": "git://github.com/jakejs/jake.git" | ||
26 | + }, | ||
27 | + "preferGlobal": true, | ||
28 | + "dependencies": { | ||
29 | + "filelist": "^1.0.1", | ||
30 | + "minimatch": "^3.0.4", | ||
31 | + "chalk": "^2.4.2", | ||
32 | + "async": "0.9.x" | ||
33 | + }, | ||
34 | + "devDependencies": { | ||
35 | + "eslint": "^6.8.0", | ||
36 | + "mocha": "^7.1.1", | ||
37 | + "q": "^1.5.1" | ||
38 | + }, | ||
39 | + "engines": { | ||
40 | + "node": "*" | ||
41 | + } | ||
42 | +} |
1 | +let assert = require('assert'); | ||
2 | +let exec = require('child_process').execSync; | ||
3 | + | ||
4 | +suite('concurrent', function () { | ||
5 | + | ||
6 | + this.timeout(7000); | ||
7 | + | ||
8 | + test(' simple concurrent prerequisites 1', function () { | ||
9 | + let out = exec('./node_modules/.bin/jake -q concurrent:simple1').toString().trim() | ||
10 | + assert.equal('Started A\nStarted B\nFinished B\nFinished A', out); | ||
11 | + }); | ||
12 | + | ||
13 | + test(' simple concurrent prerequisites 2', function () { | ||
14 | + let out = exec('./node_modules/.bin/jake -q concurrent:simple2').toString().trim() | ||
15 | + assert.equal('Started C\nStarted D\nFinished C\nFinished D', out); | ||
16 | + }); | ||
17 | + | ||
18 | + test(' sequential concurrent prerequisites', function () { | ||
19 | + let out = exec('./node_modules/.bin/jake -q concurrent:seqconcurrent').toString().trim() | ||
20 | + assert.equal('Started A\nStarted B\nFinished B\nFinished A\nStarted C\nStarted D\nFinished C\nFinished D', out); | ||
21 | + }); | ||
22 | + | ||
23 | + test(' concurrent concurrent prerequisites', function () { | ||
24 | + let out = exec('./node_modules/.bin/jake -q concurrent:concurrentconcurrent').toString().trim() | ||
25 | + assert.equal('Started A\nStarted B\nStarted C\nStarted D\nFinished B\nFinished C\nFinished A\nFinished D', out); | ||
26 | + }); | ||
27 | + | ||
28 | + test(' concurrent prerequisites with subdependency', function () { | ||
29 | + let out = exec('./node_modules/.bin/jake -q concurrent:subdep').toString().trim() | ||
30 | + assert.equal('Started A\nFinished A\nStarted Ba\nFinished Ba', out); | ||
31 | + }); | ||
32 | + | ||
33 | + test(' failing in concurrent prerequisites', function () { | ||
34 | + try { | ||
35 | + exec('./node_modules/.bin/jake -q concurrent:Cfail'); | ||
36 | + } | ||
37 | + catch(err) { | ||
38 | + assert(err.message.indexOf('Command failed') > -1); | ||
39 | + } | ||
40 | + }); | ||
41 | + | ||
42 | +}); |
node_modules/jake/test/integration/file.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +let assert = require('assert'); | ||
22 | +let fs = require('fs'); | ||
23 | +let path = require('path'); | ||
24 | +let file = require(`${PROJECT_DIR}/lib/utils/file`); | ||
25 | +let existsSync = fs.existsSync || path.existsSync; | ||
26 | +let exec = require('child_process').execSync; | ||
27 | + | ||
28 | +suite('fileUtils', function () { | ||
29 | + | ||
30 | + test('mkdirP', function () { | ||
31 | + let expected = [ | ||
32 | + ['foo'], | ||
33 | + ['foo', 'bar'], | ||
34 | + ['foo', 'bar', 'baz'], | ||
35 | + ['foo', 'bar', 'baz', 'qux'] | ||
36 | + ]; | ||
37 | + file.mkdirP('foo/bar/baz/qux'); | ||
38 | + let res = exec('find foo').toString().trim().split('\n'); | ||
39 | + for (let i = 0, ii = res.length; i < ii; i++) { | ||
40 | + assert.equal(path.join.apply(path, expected[i]), res[i]); | ||
41 | + } | ||
42 | + file.rmRf('foo'); | ||
43 | + }); | ||
44 | + | ||
45 | + test('rmRf', function () { | ||
46 | + file.mkdirP('foo/bar/baz/qux'); | ||
47 | + file.rmRf('foo/bar'); | ||
48 | + let res = exec('find foo').toString().trim().split('\n'); | ||
49 | + assert.equal(1, res.length); | ||
50 | + assert.equal('foo', res[0]); | ||
51 | + fs.rmdirSync('foo'); | ||
52 | + }); | ||
53 | + | ||
54 | + test('rmRf with symlink subdir', function () { | ||
55 | + file.mkdirP('foo'); | ||
56 | + file.mkdirP('bar'); | ||
57 | + fs.writeFileSync('foo/hello.txt', 'hello, it\'s me'); | ||
58 | + fs.symlinkSync('../foo', 'bar/foo'); file.rmRf('bar'); | ||
59 | + | ||
60 | + // Make sure the bar directory was successfully deleted | ||
61 | + let barDeleted = false; | ||
62 | + try { | ||
63 | + fs.statSync('bar'); | ||
64 | + } catch(err) { | ||
65 | + if(err.code == 'ENOENT') { | ||
66 | + barDeleted = true; | ||
67 | + } | ||
68 | + } | ||
69 | + assert.equal(true, barDeleted); | ||
70 | + | ||
71 | + // Make sure that the file inside the linked folder wasn't deleted | ||
72 | + let res = fs.readdirSync('foo'); | ||
73 | + assert.equal(1, res.length); | ||
74 | + assert.equal('hello.txt', res[0]); | ||
75 | + | ||
76 | + // Cleanup | ||
77 | + fs.unlinkSync('foo/hello.txt'); | ||
78 | + fs.rmdirSync('foo'); | ||
79 | + }); | ||
80 | + | ||
81 | + test('rmRf with symlinked dir', function () { | ||
82 | + file.mkdirP('foo'); | ||
83 | + fs.writeFileSync('foo/hello.txt', 'hello!'); | ||
84 | + fs.symlinkSync('foo', 'bar'); | ||
85 | + file.rmRf('bar'); | ||
86 | + | ||
87 | + // Make sure the bar directory was successfully deleted | ||
88 | + let barDeleted = false; | ||
89 | + try { | ||
90 | + fs.statSync('bar'); | ||
91 | + } catch(err) { | ||
92 | + if(err.code == 'ENOENT') { | ||
93 | + barDeleted = true; | ||
94 | + } | ||
95 | + } | ||
96 | + assert.equal(true, barDeleted); | ||
97 | + | ||
98 | + // Make sure that the file inside the linked folder wasn't deleted | ||
99 | + let res = fs.readdirSync('foo'); | ||
100 | + assert.equal(1, res.length); | ||
101 | + assert.equal('hello.txt', res[0]); | ||
102 | + | ||
103 | + // Cleanup | ||
104 | + fs.unlinkSync('foo/hello.txt'); | ||
105 | + fs.rmdirSync('foo'); | ||
106 | + }); | ||
107 | + | ||
108 | + test('cpR with same name and different directory', function () { | ||
109 | + file.mkdirP('foo'); | ||
110 | + fs.writeFileSync('foo/bar.txt', 'w00t'); | ||
111 | + file.cpR('foo', 'bar'); | ||
112 | + assert.ok(existsSync('bar/bar.txt')); | ||
113 | + file.rmRf('foo'); | ||
114 | + file.rmRf('bar'); | ||
115 | + }); | ||
116 | + | ||
117 | + test('cpR with same to and from will throw', function () { | ||
118 | + assert.throws(function () { | ||
119 | + file.cpR('foo.txt', 'foo.txt'); | ||
120 | + }); | ||
121 | + }); | ||
122 | + | ||
123 | + test('cpR rename via copy in directory', function () { | ||
124 | + file.mkdirP('foo'); | ||
125 | + fs.writeFileSync('foo/bar.txt', 'w00t'); | ||
126 | + file.cpR('foo/bar.txt', 'foo/baz.txt'); | ||
127 | + assert.ok(existsSync('foo/baz.txt')); | ||
128 | + file.rmRf('foo'); | ||
129 | + }); | ||
130 | + | ||
131 | + test('cpR rename via copy in base', function () { | ||
132 | + fs.writeFileSync('bar.txt', 'w00t'); | ||
133 | + file.cpR('bar.txt', 'baz.txt'); | ||
134 | + assert.ok(existsSync('baz.txt')); | ||
135 | + file.rmRf('bar.txt'); | ||
136 | + file.rmRf('baz.txt'); | ||
137 | + }); | ||
138 | + | ||
139 | + test('cpR keeps file mode', function () { | ||
140 | + fs.writeFileSync('bar.txt', 'w00t', {mode: 0o750}); | ||
141 | + fs.writeFileSync('bar1.txt', 'w00t!', {mode: 0o744}); | ||
142 | + file.cpR('bar.txt', 'baz.txt'); | ||
143 | + file.cpR('bar1.txt', 'baz1.txt'); | ||
144 | + | ||
145 | + assert.ok(existsSync('baz.txt')); | ||
146 | + assert.ok(existsSync('baz1.txt')); | ||
147 | + let bazStat = fs.statSync('baz.txt'); | ||
148 | + let bazStat1 = fs.statSync('baz1.txt'); | ||
149 | + assert.equal(0o750, bazStat.mode & 0o7777); | ||
150 | + assert.equal(0o744, bazStat1.mode & 0o7777); | ||
151 | + | ||
152 | + file.rmRf('bar.txt'); | ||
153 | + file.rmRf('baz.txt'); | ||
154 | + file.rmRf('bar1.txt'); | ||
155 | + file.rmRf('baz1.txt'); | ||
156 | + }); | ||
157 | + | ||
158 | + test('cpR keeps file mode when overwriting with preserveMode', function () { | ||
159 | + fs.writeFileSync('bar.txt', 'w00t', {mode: 0o755}); | ||
160 | + fs.writeFileSync('baz.txt', 'w00t!', {mode: 0o744}); | ||
161 | + file.cpR('bar.txt', 'baz.txt', {silent: true, preserveMode: true}); | ||
162 | + | ||
163 | + assert.ok(existsSync('baz.txt')); | ||
164 | + let bazStat = fs.statSync('baz.txt'); | ||
165 | + assert.equal(0o755, bazStat.mode & 0o777); | ||
166 | + | ||
167 | + file.rmRf('bar.txt'); | ||
168 | + file.rmRf('baz.txt'); | ||
169 | + }); | ||
170 | + | ||
171 | + test('cpR does not keep file mode when overwriting', function () { | ||
172 | + fs.writeFileSync('bar.txt', 'w00t', {mode: 0o766}); | ||
173 | + fs.writeFileSync('baz.txt', 'w00t!', {mode: 0o744}); | ||
174 | + file.cpR('bar.txt', 'baz.txt'); | ||
175 | + | ||
176 | + assert.ok(existsSync('baz.txt')); | ||
177 | + let bazStat = fs.statSync('baz.txt'); | ||
178 | + assert.equal(0o744, bazStat.mode & 0o777); | ||
179 | + | ||
180 | + file.rmRf('bar.txt'); | ||
181 | + file.rmRf('baz.txt'); | ||
182 | + }); | ||
183 | + | ||
184 | + test('cpR copies file mode recursively', function () { | ||
185 | + fs.mkdirSync('foo'); | ||
186 | + fs.writeFileSync('foo/bar.txt', 'w00t', {mode: 0o740}); | ||
187 | + file.cpR('foo', 'baz'); | ||
188 | + | ||
189 | + assert.ok(existsSync('baz')); | ||
190 | + let barStat = fs.statSync('baz/bar.txt'); | ||
191 | + assert.equal(0o740, barStat.mode & 0o777); | ||
192 | + | ||
193 | + file.rmRf('foo'); | ||
194 | + file.rmRf('baz'); | ||
195 | + }); | ||
196 | + | ||
197 | + test('cpR keeps file mode recursively', function () { | ||
198 | + fs.mkdirSync('foo'); | ||
199 | + fs.writeFileSync('foo/bar.txt', 'w00t', {mode: 0o740}); | ||
200 | + fs.mkdirSync('baz'); | ||
201 | + fs.mkdirSync('baz/foo'); | ||
202 | + fs.writeFileSync('baz/foo/bar.txt', 'w00t!', {mode: 0o755}); | ||
203 | + file.cpR('foo', 'baz', {silent: true, preserveMode: true}); | ||
204 | + | ||
205 | + assert.ok(existsSync('baz')); | ||
206 | + let barStat = fs.statSync('baz/foo/bar.txt'); | ||
207 | + assert.equal(0o740, barStat.mode & 0o777); | ||
208 | + | ||
209 | + file.rmRf('foo'); | ||
210 | + file.rmRf('baz'); | ||
211 | + }); | ||
212 | + | ||
213 | + test('cpR copies directory mode recursively', function () { | ||
214 | + fs.mkdirSync('foo', 0o755); | ||
215 | + fs.mkdirSync('foo/bar', 0o700); | ||
216 | + file.cpR('foo', 'bar'); | ||
217 | + | ||
218 | + assert.ok(existsSync('foo')); | ||
219 | + let fooBarStat = fs.statSync('bar/bar'); | ||
220 | + assert.equal(0o700, fooBarStat.mode & 0o777); | ||
221 | + | ||
222 | + file.rmRf('foo'); | ||
223 | + file.rmRf('bar'); | ||
224 | + }); | ||
225 | + | ||
226 | +}); | ||
227 | + | ||
228 | + |
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +let assert = require('assert'); | ||
22 | +let fs = require('fs'); | ||
23 | +let exec = require('child_process').execSync; | ||
24 | +let { rmRf } = require(`${PROJECT_DIR}/lib/jake`); | ||
25 | + | ||
26 | +let cleanUpAndNext = function (callback) { | ||
27 | + rmRf('./foo', { | ||
28 | + silent: true | ||
29 | + }); | ||
30 | + callback && callback(); | ||
31 | +}; | ||
32 | + | ||
33 | +suite('fileTask', function () { | ||
34 | + this.timeout(7000); | ||
35 | + | ||
36 | + setup(function () { | ||
37 | + cleanUpAndNext(); | ||
38 | + }); | ||
39 | + | ||
40 | + test('where a file-task prereq does not change with --always-make', function () { | ||
41 | + let out; | ||
42 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim(); | ||
43 | + assert.equal('fileTest:foo/src1.txt task\nfileTest:foo/from-src1.txt task', | ||
44 | + out); | ||
45 | + out = exec('./node_modules/.bin/jake -q -B fileTest:foo/from-src1.txt').toString().trim(); | ||
46 | + assert.equal('fileTest:foo/src1.txt task\nfileTest:foo/from-src1.txt task', | ||
47 | + out); | ||
48 | + cleanUpAndNext(); | ||
49 | + }); | ||
50 | + | ||
51 | + test('concating two files', function () { | ||
52 | + let out; | ||
53 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/concat.txt').toString().trim(); | ||
54 | + assert.equal('fileTest:foo/src1.txt task\ndefault task\nfileTest:foo/src2.txt task\n' + | ||
55 | + 'fileTest:foo/concat.txt task', out); | ||
56 | + // Check to see the two files got concat'd | ||
57 | + let data = fs.readFileSync(process.cwd() + '/foo/concat.txt'); | ||
58 | + assert.equal('src1src2', data.toString()); | ||
59 | + cleanUpAndNext(); | ||
60 | + }); | ||
61 | + | ||
62 | + test('where a file-task prereq does not change', function () { | ||
63 | + let out; | ||
64 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim(); | ||
65 | + assert.equal('fileTest:foo/src1.txt task\nfileTest:foo/from-src1.txt task', out); | ||
66 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim(); | ||
67 | + // Second time should be a no-op | ||
68 | + assert.equal('', out); | ||
69 | + cleanUpAndNext(); | ||
70 | + }); | ||
71 | + | ||
72 | + test('where a file-task prereq does change, then does not', function (next) { | ||
73 | + exec('mkdir -p ./foo'); | ||
74 | + exec('touch ./foo/from-src1.txt'); | ||
75 | + setTimeout(() => { | ||
76 | + fs.writeFileSync('./foo/src1.txt', '-SRC'); | ||
77 | + // Task should run the first time | ||
78 | + let out; | ||
79 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim(); | ||
80 | + assert.equal('fileTest:foo/from-src1.txt task', out); | ||
81 | + // Task should not run on subsequent invocation | ||
82 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim(); | ||
83 | + assert.equal('', out); | ||
84 | + cleanUpAndNext(next); | ||
85 | + }, 1000); | ||
86 | + }); | ||
87 | + | ||
88 | + test('a preexisting file', function () { | ||
89 | + let prereqData = 'howdy'; | ||
90 | + exec('mkdir -p ./foo'); | ||
91 | + fs.writeFileSync('foo/prereq.txt', prereqData); | ||
92 | + let out; | ||
93 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-prereq.txt').toString().trim(); | ||
94 | + assert.equal('fileTest:foo/from-prereq.txt task', out); | ||
95 | + let data = fs.readFileSync(process.cwd() + '/foo/from-prereq.txt'); | ||
96 | + assert.equal(prereqData, data.toString()); | ||
97 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-prereq.txt').toString().trim(); | ||
98 | + // Second time should be a no-op | ||
99 | + assert.equal('', out); | ||
100 | + cleanUpAndNext(); | ||
101 | + }); | ||
102 | + | ||
103 | + test('a preexisting file with --always-make flag', function () { | ||
104 | + let prereqData = 'howdy'; | ||
105 | + exec('mkdir -p ./foo'); | ||
106 | + fs.writeFileSync('foo/prereq.txt', prereqData); | ||
107 | + let out; | ||
108 | + out = exec('./node_modules/.bin/jake -q fileTest:foo/from-prereq.txt').toString().trim(); | ||
109 | + assert.equal('fileTest:foo/from-prereq.txt task', out); | ||
110 | + let data = fs.readFileSync(process.cwd() + '/foo/from-prereq.txt'); | ||
111 | + assert.equal(prereqData, data.toString()); | ||
112 | + out = exec('./node_modules/.bin/jake -q -B fileTest:foo/from-prereq.txt').toString().trim(); | ||
113 | + assert.equal('fileTest:foo/from-prereq.txt task', out); | ||
114 | + cleanUpAndNext(); | ||
115 | + }); | ||
116 | + | ||
117 | + test('nested directory-task', function () { | ||
118 | + exec('./node_modules/.bin/jake -q fileTest:foo/bar/baz/bamf.txt'); | ||
119 | + let data = fs.readFileSync(process.cwd() + '/foo/bar/baz/bamf.txt'); | ||
120 | + assert.equal('w00t', data); | ||
121 | + cleanUpAndNext(); | ||
122 | + }); | ||
123 | + | ||
124 | +}); | ||
125 | + |
1 | +var exec = require('child_process').exec; | ||
2 | + | ||
3 | +var helpers = new (function () { | ||
4 | + var _tests; | ||
5 | + var _names = []; | ||
6 | + var _name; | ||
7 | + var _callback; | ||
8 | + var _runner = function () { | ||
9 | + if ((_name = _names.shift())) { | ||
10 | + console.log('Running ' + _name); | ||
11 | + _tests[_name](); | ||
12 | + } | ||
13 | + else { | ||
14 | + _callback(); | ||
15 | + } | ||
16 | + }; | ||
17 | + | ||
18 | + this.exec = function () { | ||
19 | + var args = Array.prototype.slice.call(arguments); | ||
20 | + var arg; | ||
21 | + var cmd = args.shift(); | ||
22 | + var opts = {}; | ||
23 | + var callback; | ||
24 | + // Optional opts/callback or callback/opts | ||
25 | + while ((arg = args.shift())) { | ||
26 | + if (typeof arg == 'function') { | ||
27 | + callback = arg; | ||
28 | + } | ||
29 | + else { | ||
30 | + opts = arg; | ||
31 | + } | ||
32 | + } | ||
33 | + | ||
34 | + cmd += ' --trace'; | ||
35 | + var execOpts = opts.execOpts ? opts.execOpts : {}; | ||
36 | + exec(cmd, execOpts, function (err, stdout, stderr) { | ||
37 | + var out = helpers.trim(stdout); | ||
38 | + if (err) { | ||
39 | + if (opts.breakOnError === false) { | ||
40 | + return callback(err); | ||
41 | + } | ||
42 | + else { | ||
43 | + throw err; | ||
44 | + } | ||
45 | + } | ||
46 | + if (stderr) { | ||
47 | + callback(stderr); | ||
48 | + } | ||
49 | + else { | ||
50 | + callback(out); | ||
51 | + } | ||
52 | + }); | ||
53 | + }; | ||
54 | + | ||
55 | + this.trim = function (s) { | ||
56 | + var str = s || ''; | ||
57 | + return str.replace(/^\s*|\s*$/g, ''); | ||
58 | + }; | ||
59 | + | ||
60 | + this.parse = function (s) { | ||
61 | + var str = s || ''; | ||
62 | + str = helpers.trim(str); | ||
63 | + str = str.replace(/'/g, '"'); | ||
64 | + return JSON.parse(str); | ||
65 | + }; | ||
66 | + | ||
67 | + this.run = function (tests, callback) { | ||
68 | + _tests = tests; | ||
69 | + _names = Object.keys(tests); | ||
70 | + _callback = callback; | ||
71 | + _runner(); | ||
72 | + }; | ||
73 | + | ||
74 | + this.next = function () { | ||
75 | + _runner(); | ||
76 | + }; | ||
77 | + | ||
78 | +})(); | ||
79 | + | ||
80 | +module.exports = helpers; |
1 | +let fs = require('fs'); | ||
2 | +let Q = require('q'); | ||
3 | + | ||
4 | +desc('The default t.'); | ||
5 | +task('default', function () { | ||
6 | + console.log('default task'); | ||
7 | +}); | ||
8 | + | ||
9 | +desc('No action.'); | ||
10 | +task({'noAction': ['default']}); | ||
11 | + | ||
12 | +desc('No action, no prereqs.'); | ||
13 | +task('noActionNoPrereqs'); | ||
14 | + | ||
15 | +desc('Top-level zerbofrangazoomy task'); | ||
16 | +task('zerbofrangazoomy', function () { | ||
17 | + console.log('Whaaaaaaaa? Ran the zerbofrangazoomy task!') | ||
18 | +}); | ||
19 | + | ||
20 | +desc('Task that throws'); | ||
21 | +task('throwy', function () { | ||
22 | + let errorListener = function (err) { | ||
23 | + console.log('Emitted'); | ||
24 | + console.log(err.toString()); | ||
25 | + | ||
26 | + jake.removeListener('error', errorListener); | ||
27 | + }; | ||
28 | + | ||
29 | + jake.on('error', errorListener); | ||
30 | + | ||
31 | + throw new Error('I am bad'); | ||
32 | +}); | ||
33 | + | ||
34 | +desc('Task that rejects a Promise'); | ||
35 | +task('promiseRejecter', function () { | ||
36 | + const originalOption = jake.program.opts['allow-rejection']; | ||
37 | + | ||
38 | + const errorListener = function (err) { | ||
39 | + console.log(err.toString()); | ||
40 | + jake.removeListener('error', errorListener); | ||
41 | + jake.program.opts['allow-rejection'] = originalOption; // Restore original 'allow-rejection' option | ||
42 | + }; | ||
43 | + jake.on('error', errorListener); | ||
44 | + | ||
45 | + jake.program.opts['allow-rejection'] = false; // Do not allow rejection so the rejection is passed to error handlers | ||
46 | + | ||
47 | + Promise.reject('<promise rejected on purpose>'); | ||
48 | +}); | ||
49 | + | ||
50 | +desc('Accepts args and env vars.'); | ||
51 | +task('argsEnvVars', function () { | ||
52 | + let res = { | ||
53 | + args: arguments | ||
54 | + , env: { | ||
55 | + foo: process.env.foo | ||
56 | + , baz: process.env.baz | ||
57 | + } | ||
58 | + }; | ||
59 | + console.log(JSON.stringify(res)); | ||
60 | +}); | ||
61 | + | ||
62 | +namespace('foo', function () { | ||
63 | + desc('The foo:bar t.'); | ||
64 | + task('bar', function () { | ||
65 | + if (arguments.length) { | ||
66 | + console.log('foo:bar[' + | ||
67 | + Array.prototype.join.call(arguments, ',') + | ||
68 | + '] task'); | ||
69 | + } | ||
70 | + else { | ||
71 | + console.log('foo:bar task'); | ||
72 | + } | ||
73 | + }); | ||
74 | + | ||
75 | + desc('The foo:baz task, calls foo:bar as a prerequisite.'); | ||
76 | + task('baz', ['foo:bar'], function () { | ||
77 | + console.log('foo:baz task'); | ||
78 | + }); | ||
79 | + | ||
80 | + desc('The foo:qux task, calls foo:bar with cmdline args as a prerequisite.'); | ||
81 | + task('qux', ['foo:bar[asdf,qwer]'], function () { | ||
82 | + console.log('foo:qux task'); | ||
83 | + }); | ||
84 | + | ||
85 | + desc('The foo:frang task,`invokes` foo:bar with passed args as a prerequisite.'); | ||
86 | + task('frang', function () { | ||
87 | + let t = jake.Task['foo:bar']; | ||
88 | + // Do args pass-through | ||
89 | + t.invoke.apply(t, arguments); | ||
90 | + t.on('complete', () => { | ||
91 | + console.log('foo:frang task'); | ||
92 | + }); | ||
93 | + }); | ||
94 | + | ||
95 | + desc('The foo:zerb task, `executes` foo:bar with passed args as a prerequisite.'); | ||
96 | + task('zerb', function () { | ||
97 | + let t = jake.Task['foo:bar']; | ||
98 | + // Do args pass-through | ||
99 | + t.execute.apply(t, arguments); | ||
100 | + t.on('complete', () => { | ||
101 | + console.log('foo:zerb task'); | ||
102 | + }); | ||
103 | + }); | ||
104 | + | ||
105 | + desc('The foo:zoobie task, has no prerequisites.'); | ||
106 | + task('zoobie', function () { | ||
107 | + console.log('foo:zoobie task'); | ||
108 | + }); | ||
109 | + | ||
110 | + desc('The foo:voom task, run the foo:zoobie task repeatedly.'); | ||
111 | + task('voom', function () { | ||
112 | + let t = jake.Task['foo:bar']; | ||
113 | + t.on('complete', function () { | ||
114 | + console.log('complete'); | ||
115 | + }); | ||
116 | + t.execute.apply(t); | ||
117 | + t.execute.apply(t); | ||
118 | + }); | ||
119 | + | ||
120 | + desc('The foo:asdf task, has the same prereq twice.'); | ||
121 | + task('asdf', ['foo:bar', 'foo:baz'], function () { | ||
122 | + console.log('foo:asdf task'); | ||
123 | + }); | ||
124 | + | ||
125 | +}); | ||
126 | + | ||
127 | +namespace('bar', function () { | ||
128 | + desc('The bar:foo task, has no prerequisites, is async, returns Promise which resolves.'); | ||
129 | + task('foo', async function () { | ||
130 | + return new Promise((resolve, reject) => { | ||
131 | + console.log('bar:foo task'); | ||
132 | + resolve(); | ||
133 | + }); | ||
134 | + }); | ||
135 | + | ||
136 | + desc('The bar:promise task has no prerequisites, is async, returns Q-based promise.'); | ||
137 | + task('promise', function () { | ||
138 | + return Q() | ||
139 | + .then(function () { | ||
140 | + console.log('bar:promise task'); | ||
141 | + return 123654; | ||
142 | + }); | ||
143 | + }); | ||
144 | + | ||
145 | + desc('The bar:dependOnpromise task waits for a promise based async test'); | ||
146 | + task('dependOnpromise', ['promise'], function () { | ||
147 | + console.log('bar:dependOnpromise task saw value', jake.Task["bar:promise"].value); | ||
148 | + }); | ||
149 | + | ||
150 | + desc('The bar:brokenPromise task is a failing Q-promise based async task.'); | ||
151 | + task('brokenPromise', function () { | ||
152 | + return Q() | ||
153 | + .then(function () { | ||
154 | + throw new Error("nom nom nom"); | ||
155 | + }); | ||
156 | + }); | ||
157 | + | ||
158 | + desc('The bar:bar task, has the async bar:foo task as a prerequisite.'); | ||
159 | + task('bar', ['bar:foo'], function () { | ||
160 | + console.log('bar:bar task'); | ||
161 | + }); | ||
162 | + | ||
163 | +}); | ||
164 | + | ||
165 | +namespace('hoge', function () { | ||
166 | + desc('The hoge:hoge task, has no prerequisites.'); | ||
167 | + task('hoge', function () { | ||
168 | + console.log('hoge:hoge task'); | ||
169 | + }); | ||
170 | + | ||
171 | + desc('The hoge:piyo task, has no prerequisites.'); | ||
172 | + task('piyo', function () { | ||
173 | + console.log('hoge:piyo task'); | ||
174 | + }); | ||
175 | + | ||
176 | + desc('The hoge:fuga task, has hoge:hoge and hoge:piyo as prerequisites.'); | ||
177 | + task('fuga', ['hoge:hoge', 'hoge:piyo'], function () { | ||
178 | + console.log('hoge:fuga task'); | ||
179 | + }); | ||
180 | + | ||
181 | + desc('The hoge:charan task, has hoge:fuga as a prerequisite.'); | ||
182 | + task('charan', ['hoge:fuga'], function () { | ||
183 | + console.log('hoge:charan task'); | ||
184 | + }); | ||
185 | + | ||
186 | + desc('The hoge:gero task, has hoge:fuga as a prerequisite.'); | ||
187 | + task('gero', ['hoge:fuga'], function () { | ||
188 | + console.log('hoge:gero task'); | ||
189 | + }); | ||
190 | + | ||
191 | + desc('The hoge:kira task, has hoge:charan and hoge:gero as prerequisites.'); | ||
192 | + task('kira', ['hoge:charan', 'hoge:gero'], function () { | ||
193 | + console.log('hoge:kira task'); | ||
194 | + }); | ||
195 | + | ||
196 | +}); | ||
197 | + | ||
198 | +namespace('fileTest', function () { | ||
199 | + directory('foo'); | ||
200 | + | ||
201 | + desc('File task, concatenating two files together'); | ||
202 | + file('foo/concat.txt', ['fileTest:foo', 'fileTest:foo/src1.txt', 'fileTest:foo/src2.txt'], function () { | ||
203 | + console.log('fileTest:foo/concat.txt task'); | ||
204 | + let data1 = fs.readFileSync('foo/src1.txt'); | ||
205 | + let data2 = fs.readFileSync('foo/src2.txt'); | ||
206 | + fs.writeFileSync('foo/concat.txt', data1 + data2); | ||
207 | + }); | ||
208 | + | ||
209 | + desc('File task, async creation with writeFile'); | ||
210 | + file('foo/src1.txt', function () { | ||
211 | + return new Promise(function (resolve, reject) { | ||
212 | + fs.writeFile('foo/src1.txt', 'src1', function (err) { | ||
213 | + if (err) { | ||
214 | + reject(err); | ||
215 | + } | ||
216 | + else { | ||
217 | + console.log('fileTest:foo/src1.txt task'); | ||
218 | + resolve(); | ||
219 | + } | ||
220 | + }); | ||
221 | + }); | ||
222 | + }); | ||
223 | + | ||
224 | + desc('File task, sync creation with writeFileSync'); | ||
225 | + file('foo/src2.txt', ['default'], function () { | ||
226 | + fs.writeFileSync('foo/src2.txt', 'src2'); | ||
227 | + console.log('fileTest:foo/src2.txt task'); | ||
228 | + }); | ||
229 | + | ||
230 | + desc('File task, do not run unless the prereq file changes'); | ||
231 | + file('foo/from-src1.txt', ['fileTest:foo', 'fileTest:foo/src1.txt'], function () { | ||
232 | + let data = fs.readFileSync('foo/src1.txt').toString(); | ||
233 | + fs.writeFileSync('foo/from-src1.txt', data); | ||
234 | + console.log('fileTest:foo/from-src1.txt task'); | ||
235 | + }); | ||
236 | + | ||
237 | + desc('File task, run if the prereq file changes'); | ||
238 | + task('touch-prereq', function () { | ||
239 | + fs.writeFileSync('foo/prereq.txt', 'UPDATED'); | ||
240 | + }) | ||
241 | + | ||
242 | + desc('File task, has a preexisting file (with no associated task) as a prereq'); | ||
243 | + file('foo/from-prereq.txt', ['fileTest:foo', 'foo/prereq.txt'], function () { | ||
244 | + let data = fs.readFileSync('foo/prereq.txt'); | ||
245 | + fs.writeFileSync('foo/from-prereq.txt', data); | ||
246 | + console.log('fileTest:foo/from-prereq.txt task'); | ||
247 | + }); | ||
248 | + | ||
249 | + directory('foo/bar/baz'); | ||
250 | + | ||
251 | + desc('Write a file in a nested subdirectory'); | ||
252 | + file('foo/bar/baz/bamf.txt', ['foo/bar/baz'], function () { | ||
253 | + fs.writeFileSync('foo/bar/baz/bamf.txt', 'w00t'); | ||
254 | + }); | ||
255 | + | ||
256 | +}); | ||
257 | + | ||
258 | +task('blammo'); | ||
259 | +// Define task | ||
260 | +task('voom', ['blammo'], function () { | ||
261 | + console.log(this.prereqs.length); | ||
262 | +}); | ||
263 | + | ||
264 | +// Modify, add a prereq | ||
265 | +task('voom', ['noActionNoPrereqs']); | ||
266 | + | ||
267 | +namespace('vronk', function () { | ||
268 | + task('groo', function () { | ||
269 | + let t = jake.Task['vronk:zong']; | ||
270 | + t.addListener('error', function (e) { | ||
271 | + console.log(e.message); | ||
272 | + }); | ||
273 | + t.invoke(); | ||
274 | + }); | ||
275 | + task('zong', function () { | ||
276 | + throw new Error('OMFGZONG'); | ||
277 | + }); | ||
278 | +}); | ||
279 | + | ||
280 | +// define namespace | ||
281 | +namespace('one', function () { | ||
282 | + task('one', function () { | ||
283 | + console.log('one:one'); | ||
284 | + }); | ||
285 | +}); | ||
286 | + | ||
287 | +// modify namespace (add task) | ||
288 | +namespace('one', function () { | ||
289 | + task('two', ['one:one'], function () { | ||
290 | + console.log('one:two'); | ||
291 | + }); | ||
292 | +}); | ||
293 | + | ||
294 | +task('selfdepconst', [], function () { | ||
295 | + task('selfdep', ['selfdep'], function () { | ||
296 | + console.log("I made a task that depends on itself"); | ||
297 | + }); | ||
298 | +}); | ||
299 | +task('selfdepdyn', function () { | ||
300 | + task('selfdeppar', [], {concurrency: 2}, function () { | ||
301 | + console.log("I will depend on myself and will fail at runtime"); | ||
302 | + }); | ||
303 | + task('selfdeppar', ['selfdeppar']); | ||
304 | + jake.Task['selfdeppar'].invoke(); | ||
305 | +}); | ||
306 | + | ||
307 | +namespace("large", function () { | ||
308 | + task("leaf", function () { | ||
309 | + console.log("large:leaf"); | ||
310 | + }); | ||
311 | + | ||
312 | + const same = []; | ||
313 | + for (let i = 0; i < 2000; i++) { | ||
314 | + same.push("leaf"); | ||
315 | + } | ||
316 | + | ||
317 | + desc("Task with a large number of same prereqs"); | ||
318 | + task("same", same, { concurrency: 2 }, function () { | ||
319 | + console.log("large:same"); | ||
320 | + }); | ||
321 | + | ||
322 | + const different = []; | ||
323 | + for (let i = 0; i < 2000; i++) { | ||
324 | + const name = "leaf-" + i; | ||
325 | + task(name, function () { | ||
326 | + if (name === "leaf-12" || name === "leaf-123") { | ||
327 | + console.log(name); | ||
328 | + } | ||
329 | + }); | ||
330 | + different.push(name); | ||
331 | + } | ||
332 | + | ||
333 | + desc("Task with a large number of different prereqs"); | ||
334 | + task("different", different, { concurrency: 2 } , function () { | ||
335 | + console.log("large:different") | ||
336 | + }) | ||
337 | +}); |
1 | + | ||
2 | +namespace('concurrent', function () { | ||
3 | + task('A', function () { | ||
4 | + console.log('Started A'); | ||
5 | + return new Promise((resolve, reject) => { | ||
6 | + setTimeout(() => { | ||
7 | + console.log('Finished A'); | ||
8 | + resolve(); | ||
9 | + }, 200); | ||
10 | + }); | ||
11 | + }); | ||
12 | + | ||
13 | + task('B', function () { | ||
14 | + console.log('Started B'); | ||
15 | + return new Promise((resolve, reject) => { | ||
16 | + setTimeout(() => { | ||
17 | + console.log('Finished B'); | ||
18 | + resolve(); | ||
19 | + }, 50); | ||
20 | + }); | ||
21 | + }); | ||
22 | + | ||
23 | + task('C', function () { | ||
24 | + console.log('Started C'); | ||
25 | + return new Promise((resolve, reject) => { | ||
26 | + setTimeout(() => { | ||
27 | + console.log('Finished C'); | ||
28 | + resolve(); | ||
29 | + }, 100); | ||
30 | + }); | ||
31 | + }); | ||
32 | + | ||
33 | + task('D', function () { | ||
34 | + console.log('Started D'); | ||
35 | + return new Promise((resolve, reject) => { | ||
36 | + setTimeout(() => { | ||
37 | + console.log('Finished D'); | ||
38 | + resolve(); | ||
39 | + }, 300); | ||
40 | + }); | ||
41 | + }); | ||
42 | + | ||
43 | + task('Ba', ['A'], function () { | ||
44 | + console.log('Started Ba'); | ||
45 | + return new Promise((resolve, reject) => { | ||
46 | + setTimeout(() => { | ||
47 | + console.log('Finished Ba'); | ||
48 | + resolve(); | ||
49 | + }, 50); | ||
50 | + }); | ||
51 | + }); | ||
52 | + | ||
53 | + task('Afail', function () { | ||
54 | + console.log('Started failing task'); | ||
55 | + return new Promise((resolve, reject) => { | ||
56 | + setTimeout(() => { | ||
57 | + console.log('Failing B with error'); | ||
58 | + throw new Error('I failed'); | ||
59 | + }, 50); | ||
60 | + }); | ||
61 | + }); | ||
62 | + | ||
63 | + task('simple1', ['A','B'], {concurrency: 2}, function () { | ||
64 | + return new Promise((resolve, reject) => { | ||
65 | + setTimeout(() => { | ||
66 | + resolve(); | ||
67 | + }, 50); | ||
68 | + }); | ||
69 | + }); | ||
70 | + | ||
71 | + task('simple2', ['C','D'], {concurrency: 2}, function () { | ||
72 | + return new Promise((resolve, reject) => { | ||
73 | + setTimeout(() => { | ||
74 | + resolve(); | ||
75 | + }, 50); | ||
76 | + }); | ||
77 | + }); | ||
78 | + | ||
79 | + task('seqconcurrent', ['simple1','simple2'], function () { | ||
80 | + return new Promise((resolve, reject) => { | ||
81 | + setTimeout(() => { | ||
82 | + resolve(); | ||
83 | + }, 50); | ||
84 | + }); | ||
85 | + }); | ||
86 | + | ||
87 | + task('concurrentconcurrent', ['simple1','simple2'], {concurrency: 2}, function () { | ||
88 | + return new Promise((resolve, reject) => { | ||
89 | + setTimeout(() => { | ||
90 | + resolve(); | ||
91 | + }, 50); | ||
92 | + }); | ||
93 | + }); | ||
94 | + | ||
95 | + task('subdep', ['A','Ba'], {concurrency: 2}, function () { | ||
96 | + return new Promise((resolve, reject) => { | ||
97 | + setTimeout(() => { | ||
98 | + resolve(); | ||
99 | + }, 50); | ||
100 | + }); | ||
101 | + }); | ||
102 | + | ||
103 | + task('fail', ['A', 'B', 'Afail'], {concurrency: 3}, function () { | ||
104 | + return new Promise((resolve, reject) => { | ||
105 | + setTimeout(() => { | ||
106 | + resolve(); | ||
107 | + }, 50); | ||
108 | + }); | ||
109 | + }); | ||
110 | + | ||
111 | +}); | ||
112 | + | ||
113 | + |
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +let fs = require('fs'); | ||
22 | +let { publishTask, rmRf, mkdirP } = require(`${PROJECT_DIR}/lib/jake`); | ||
23 | + | ||
24 | +fs.writeFileSync('package.json', '{"version": "0.0.1"}'); | ||
25 | +mkdirP('tmp_publish'); | ||
26 | +fs.writeFileSync('tmp_publish/foo.txt', 'FOO'); | ||
27 | + | ||
28 | +publishTask('zerb', function () { | ||
29 | + this.packageFiles.include([ | ||
30 | + 'package.json' | ||
31 | + , 'tmp_publish/**' | ||
32 | + ]); | ||
33 | + this.publishCmd = 'node -p -e "\'%filename\'"'; | ||
34 | + this.gitCmd = 'echo' | ||
35 | + this.scheduleDelay = 0; | ||
36 | + | ||
37 | + this._ensureRepoClean = function () {}; | ||
38 | + this._getCurrentBranch = function () { | ||
39 | + return 'v0.0' | ||
40 | + }; | ||
41 | +}); | ||
42 | + | ||
43 | +jake.setTaskTimeout(5000); | ||
44 | + | ||
45 | +jake.Task['publish'].on('complete', function () { | ||
46 | + rmRf('tmp_publish', {silent: true}); | ||
47 | + rmRf('package.json', {silent: true}); | ||
48 | +}); | ||
49 | + |
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +let exec = require('child_process').execSync; | ||
22 | +let fs = require('fs'); | ||
23 | +let util = require('util'); | ||
24 | +let { rule, rmRf } = require(`${PROJECT_DIR}/lib/jake`); | ||
25 | + | ||
26 | +directory('tmpsrc'); | ||
27 | +directory('tmpbin'); | ||
28 | + | ||
29 | +//////////////////////////////////////////////////////////// | ||
30 | +// Simple Suffix Rule | ||
31 | +file('tmp', ['tmp_init', 'tmp_dep1.o', 'tmp_dep2.o'], function (params) { | ||
32 | + console.log('tmp task'); | ||
33 | + let data1 = fs.readFileSync('tmp_dep1.o'); | ||
34 | + let data2 = fs.readFileSync('tmp_dep2.o'); | ||
35 | + fs.writeFileSync('tmp', data1 + data2); | ||
36 | +}); | ||
37 | + | ||
38 | +rule('.o', '.c', function () { | ||
39 | + let cmd = util.format('cp %s %s', this.source, this.name); | ||
40 | + console.log(cmd + ' task'); | ||
41 | + exec(cmd); | ||
42 | +}); | ||
43 | + | ||
44 | +file('tmp_dep1.c', function () { | ||
45 | + fs.writeFileSync('tmp_dep1.c', 'src_1'); | ||
46 | + console.log('tmp_dep1.c task'); | ||
47 | +}); | ||
48 | + | ||
49 | +// note that tmp_dep2.o depends on tmp_dep2.c, which is a | ||
50 | +// static file. | ||
51 | +task('tmp_init', function () { | ||
52 | + fs.writeFileSync('tmp_dep2.c', 'src_2'); | ||
53 | + console.log('tmp_dep2.c task'); | ||
54 | +}); | ||
55 | +//////////////////////////////////////////////////////////// | ||
56 | + | ||
57 | +//////////////////////////////////////////////////////////// | ||
58 | +// Pattern Rule | ||
59 | +file('tmp_p', ['tmp_init', 'tmp_dep1.oo', 'tmp_dep2.oo'], function (params) { | ||
60 | + console.log('tmp pattern task'); | ||
61 | + let data1 = fs.readFileSync('tmp_dep1.oo'); | ||
62 | + let data2 = fs.readFileSync('tmp_dep2.oo'); | ||
63 | + fs.writeFileSync('tmp_p', data1 + data2 + ' pattern'); | ||
64 | +}); | ||
65 | + | ||
66 | +rule('%.oo', '%.c', function () { | ||
67 | + let cmd = util.format('cp %s %s', this.source, this.name); | ||
68 | + console.log(cmd + ' task'); | ||
69 | + exec(cmd); | ||
70 | +}); | ||
71 | +//////////////////////////////////////////////////////////// | ||
72 | + | ||
73 | +//////////////////////////////////////////////////////////// | ||
74 | +// Pattern Rule with Folder | ||
75 | +// i.e. rule('tmpbin/%.oo', 'tmpsrc/%.c', ... | ||
76 | +file('tmp_pf', [ | ||
77 | + 'tmp_src_init' | ||
78 | + , 'tmpbin' | ||
79 | + , 'tmpbin/tmp_dep1.oo' | ||
80 | + , 'tmpbin/tmp_dep2.oo' ], function (params) { | ||
81 | + console.log('tmp pattern folder task'); | ||
82 | + let data1 = fs.readFileSync('tmpbin/tmp_dep1.oo'); | ||
83 | + let data2 = fs.readFileSync('tmpbin/tmp_dep2.oo'); | ||
84 | + fs.writeFileSync('tmp_pf', data1 + data2 + ' pattern folder'); | ||
85 | +}); | ||
86 | + | ||
87 | +rule('tmpbin/%.oo', 'tmpsrc/%.c', function () { | ||
88 | + let cmd = util.format('cp %s %s', this.source, this.name); | ||
89 | + console.log(cmd + ' task'); | ||
90 | + exec(cmd); | ||
91 | +}); | ||
92 | + | ||
93 | +file('tmpsrc/tmp_dep2.c',['tmpsrc'], function () { | ||
94 | + fs.writeFileSync('tmpsrc/tmp_dep2.c', 'src/src_2'); | ||
95 | + console.log('tmpsrc/tmp_dep2.c task'); | ||
96 | +}); | ||
97 | + | ||
98 | +// Create static files in folder tmpsrc. | ||
99 | +task('tmp_src_init', ['tmpsrc'], function () { | ||
100 | + fs.writeFileSync('tmpsrc/tmp_dep1.c', 'src/src_1'); | ||
101 | + console.log('tmpsrc/tmp_dep1.c task'); | ||
102 | +}); | ||
103 | +//////////////////////////////////////////////////////////// | ||
104 | + | ||
105 | + | ||
106 | +//////////////////////////////////////////////////////////// | ||
107 | +// Namespace Test. This is a Mixed Test. | ||
108 | +// Test for | ||
109 | +// - rules belonging to different namespace. | ||
110 | +// - rules with folder and pattern | ||
111 | +task('tmp_ns', [ | ||
112 | + 'tmpbin' | ||
113 | + , 'rule:init' | ||
114 | + , 'tmpbin/tmp_dep2.oo' // *** This relies on a rule defined before. | ||
115 | + , 'rule:tmpbin/dep1.oo' | ||
116 | + , 'rule:tmpbin/file2.oo' ], function () { | ||
117 | + console.log('tmp pattern folder namespace task'); | ||
118 | + let data1 = fs.readFileSync('tmpbin/dep1.oo'); | ||
119 | + let data2 = fs.readFileSync('tmpbin/tmp_dep2.oo'); | ||
120 | + let data3 = fs.readFileSync('tmpbin/file2.oo'); | ||
121 | + fs.writeFileSync('tmp_ns', data1 + data2 + data3 + ' pattern folder namespace'); | ||
122 | +}); | ||
123 | + | ||
124 | +namespace('rule', function () { | ||
125 | + task('init', ['tmpsrc'], function () { | ||
126 | + fs.writeFileSync('tmpsrc/file2.c', 'src/src_3'); | ||
127 | + console.log('tmpsrc/file2.c init task'); | ||
128 | + }); | ||
129 | + | ||
130 | + file('tmpsrc/dep1.c',['tmpsrc'], function () { | ||
131 | + fs.writeFileSync('tmpsrc/dep1.c', 'src/src_1'); | ||
132 | + console.log('tmpsrc/dep1.c task'); | ||
133 | + }, {async: true}); | ||
134 | + | ||
135 | + rule('tmpbin/%.oo', 'tmpsrc/%.c', function () { | ||
136 | + let cmd = util.format('cp %s %s', this.source, this.name); | ||
137 | + console.log(cmd + ' ns task'); | ||
138 | + exec(cmd); | ||
139 | + }); | ||
140 | +}); | ||
141 | +//////////////////////////////////////////////////////////// | ||
142 | + | ||
143 | +//////////////////////////////////////////////////////////// | ||
144 | +// Chain rule | ||
145 | +// rule('tmpbin/%.pdf', 'tmpbin/%.dvi', function() { ... | ||
146 | +// rule('tmpbin/%.dvi', 'tmpsrc/%.tex', ['tmpbin'], function() { ... | ||
147 | +task('tmp_cr', [ | ||
148 | + 'chainrule:init' | ||
149 | + , 'chainrule:tmpbin/file1.pdf' | ||
150 | + , 'chainrule:tmpbin/file2.pdf' ], function () { | ||
151 | + console.log('tmp chainrule namespace task'); | ||
152 | + let data1 = fs.readFileSync('tmpbin/file1.pdf'); | ||
153 | + let data2 = fs.readFileSync('tmpbin/file2.pdf'); | ||
154 | + fs.writeFileSync('tmp_cr', data1 + data2 + ' chainrule namespace'); | ||
155 | +}); | ||
156 | + | ||
157 | +namespace('chainrule', function () { | ||
158 | + task('init', ['tmpsrc', 'tmpbin'], function () { | ||
159 | + fs.writeFileSync('tmpsrc/file1.tex', 'tex1 '); | ||
160 | + fs.writeFileSync('tmpsrc/file2.tex', 'tex2 '); | ||
161 | + console.log('chainrule init task'); | ||
162 | + }); | ||
163 | + | ||
164 | + rule('tmpbin/%.pdf', 'tmpbin/%.dvi', function () { | ||
165 | + let cmd = util.format('cp %s %s', this.source, this.name); | ||
166 | + console.log(cmd + ' dvi->pdf task'); | ||
167 | + exec(cmd); | ||
168 | + }); | ||
169 | + | ||
170 | + rule('tmpbin/%.dvi', 'tmpsrc/%.tex', ['tmpbin'], function () { | ||
171 | + let cmd = util.format('cp %s %s', this.source, this.name); | ||
172 | + console.log(cmd + ' tex->dvi task'); | ||
173 | + exec(cmd); | ||
174 | + }); | ||
175 | +}); | ||
176 | +//////////////////////////////////////////////////////////// | ||
177 | +namespace('precedence', function () { | ||
178 | + task('test', ['foo.html'], function () { | ||
179 | + console.log('ran test'); | ||
180 | + }); | ||
181 | + | ||
182 | + rule('.html', '.txt', function () { | ||
183 | + console.log('created html'); | ||
184 | + let data = fs.readFileSync(this.source); | ||
185 | + fs.writeFileSync(this.name, data.toString()); | ||
186 | + }); | ||
187 | +}); | ||
188 | + | ||
189 | +namespace('regexPattern', function () { | ||
190 | + task('test', ['foo.html'], function () { | ||
191 | + console.log('ran test'); | ||
192 | + }); | ||
193 | + | ||
194 | + rule(/\.html$/, '.txt', function () { | ||
195 | + console.log('created html'); | ||
196 | + let data = fs.readFileSync(this.source); | ||
197 | + fs.writeFileSync(this.name, data.toString()); | ||
198 | + }); | ||
199 | +}); | ||
200 | + | ||
201 | +namespace('sourceFunction', function () { | ||
202 | + | ||
203 | + let srcFunc = function (taskName) { | ||
204 | + return taskName.replace(/\.[^.]+$/, '.txt'); | ||
205 | + }; | ||
206 | + | ||
207 | + task('test', ['foo.html'], function () { | ||
208 | + console.log('ran test'); | ||
209 | + }); | ||
210 | + | ||
211 | + rule('.html', srcFunc, function () { | ||
212 | + console.log('created html'); | ||
213 | + let data = fs.readFileSync(this.source); | ||
214 | + fs.writeFileSync(this.name, data.toString()); | ||
215 | + }); | ||
216 | +}); | ||
217 | + | ||
218 | +//////////////////////////////////////////////////////////// | ||
219 | +task('clean', function () { | ||
220 | + rmRf('./foo'); | ||
221 | + rmRf('./tmp'); | ||
222 | +}); |
1 | +let assert = require('assert'); | ||
2 | +let exec = require('child_process').execSync; | ||
3 | + | ||
4 | +suite('publishTask', function () { | ||
5 | + | ||
6 | + this.timeout(7000); | ||
7 | + | ||
8 | + test('default task', function () { | ||
9 | + let out = exec('./node_modules/.bin/jake -q publish').toString().trim(); | ||
10 | + let expected = [ | ||
11 | + 'Fetched remote tags.' | ||
12 | + , 'On branch v0.0' | ||
13 | + , 'Bumped version number to v0.0.2.' | ||
14 | + , 'Created package for zerb v0.0.2' | ||
15 | + , 'Publishing zerb v0.0.2' | ||
16 | + , './pkg/zerb-v0.0.2.tar.gz' | ||
17 | + , 'BOOM! Published.' | ||
18 | + , 'Cleaned up package' | ||
19 | + ].join('\n'); | ||
20 | + assert.equal(expected, out); | ||
21 | + }); | ||
22 | + | ||
23 | +}); | ||
24 | + |
node_modules/jake/test/integration/rule.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +let assert = require('assert'); | ||
22 | +let exec = require('child_process').execSync; | ||
23 | +let fs = require('fs'); | ||
24 | +let { Rule } = require(`${PROJECT_DIR}/lib/rule`); | ||
25 | +let { rmRf } = require(`${PROJECT_DIR}/lib/jake`); | ||
26 | + | ||
27 | +let cleanUpAndNext = function (callback) { | ||
28 | + // Gotta add globbing to file utils rmRf | ||
29 | + let tmpFiles = [ | ||
30 | + 'tmp' | ||
31 | + , 'tmp_ns' | ||
32 | + , 'tmp_cr' | ||
33 | + , 'tmp_p' | ||
34 | + , 'tmp_pf' | ||
35 | + , 'tmpbin' | ||
36 | + , 'tmpsrc' | ||
37 | + , 'tmp_dep1.c' | ||
38 | + , 'tmp_dep1.o' | ||
39 | + , 'tmp_dep1.oo' | ||
40 | + , 'tmp_dep2.c' | ||
41 | + , 'tmp_dep2.o' | ||
42 | + , 'tmp_dep2.oo' | ||
43 | + , 'foo' | ||
44 | + , 'foo.html' | ||
45 | + ]; | ||
46 | + tmpFiles.forEach(function (f) { | ||
47 | + rmRf(f, { | ||
48 | + silent: true | ||
49 | + }); | ||
50 | + }); | ||
51 | + callback && callback(); | ||
52 | +}; | ||
53 | + | ||
54 | +suite('rule', function () { | ||
55 | + | ||
56 | + this.timeout(7000); | ||
57 | + | ||
58 | + setup(function (next) { | ||
59 | + cleanUpAndNext(next); | ||
60 | + }); | ||
61 | + | ||
62 | + | ||
63 | + // - name foo:bin/main.o | ||
64 | + // - pattern bin/%.o | ||
65 | + // - source src/%.c | ||
66 | + // | ||
67 | + // return { | ||
68 | + // 'dep' : 'foo:src/main.c', | ||
69 | + // 'file': 'src/main.c' | ||
70 | + // }; | ||
71 | + test('Rule.getSource', function () { | ||
72 | + let src = Rule.getSource('foo:bin/main.o', 'bin/%.o', 'src/%.c'); | ||
73 | + assert.equal('foo:src/main.c', src); | ||
74 | + }); | ||
75 | + | ||
76 | + test('rule w/o pattern', function () { | ||
77 | + let out = exec( './node_modules/.bin/jake -q tmp').toString().trim(); | ||
78 | + let output = [ | ||
79 | + "tmp_dep2.c task" | ||
80 | + , "tmp_dep1.c task" | ||
81 | + , "cp tmp_dep1.c tmp_dep1.o task" | ||
82 | + , "cp tmp_dep2.c tmp_dep2.o task" | ||
83 | + , "tmp task"]; | ||
84 | + assert.equal( output.join('\n'), out); | ||
85 | + let data = fs.readFileSync(process.cwd() + '/tmp'); | ||
86 | + assert.equal('src_1src_2', data.toString()); | ||
87 | + cleanUpAndNext(); | ||
88 | + }); | ||
89 | + | ||
90 | + test('rule w pattern w/o folder w/o namespace', function () { | ||
91 | + let out = exec( './node_modules/.bin/jake -q tmp_p').toString().trim(); | ||
92 | + let output = [ | ||
93 | + "tmp_dep2.c task" | ||
94 | + , "tmp_dep1.c task" | ||
95 | + , "cp tmp_dep1.c tmp_dep1.oo task" | ||
96 | + , "cp tmp_dep2.c tmp_dep2.oo task" | ||
97 | + , "tmp pattern task"]; | ||
98 | + let data; | ||
99 | + assert.equal( output.join('\n'), out); | ||
100 | + data = fs.readFileSync(process.cwd() + '/tmp_p'); | ||
101 | + assert.equal('src_1src_2 pattern', data.toString()); | ||
102 | + cleanUpAndNext(); | ||
103 | + }); | ||
104 | + | ||
105 | + test('rule w pattern w folder w/o namespace', function () { | ||
106 | + let out = exec( './node_modules/.bin/jake -q tmp_pf').toString().trim(); | ||
107 | + let output = [ | ||
108 | + "tmpsrc/tmp_dep1.c task" | ||
109 | + , "cp tmpsrc/tmp_dep1.c tmpbin/tmp_dep1.oo task" | ||
110 | + , "tmpsrc/tmp_dep2.c task" | ||
111 | + , "cp tmpsrc/tmp_dep2.c tmpbin/tmp_dep2.oo task" | ||
112 | + , "tmp pattern folder task"]; | ||
113 | + let data; | ||
114 | + assert.equal( output.join('\n'), out); | ||
115 | + data = fs.readFileSync(process.cwd() + '/tmp_pf'); | ||
116 | + assert.equal('src/src_1src/src_2 pattern folder', data.toString()); | ||
117 | + cleanUpAndNext(); | ||
118 | + }); | ||
119 | + | ||
120 | + test.skip('rule w pattern w folder w namespace', function () { | ||
121 | + let out = exec( './node_modules/.bin/jake -q tmp_ns').toString().trim(); | ||
122 | + let output = [ | ||
123 | + "tmpsrc/file2.c init task" // yes | ||
124 | + , "tmpsrc/tmp_dep2.c task" // no | ||
125 | + , "cp tmpsrc/tmp_dep2.c tmpbin/tmp_dep2.oo task" // no | ||
126 | + , "tmpsrc/dep1.c task" // no | ||
127 | + , "cp tmpsrc/dep1.c tmpbin/dep1.oo ns task" // no | ||
128 | + , "cp tmpsrc/file2.c tmpbin/file2.oo ns task" // yes | ||
129 | + , "tmp pattern folder namespace task"]; // yes | ||
130 | + let data; | ||
131 | + assert.equal( output.join('\n'), out); | ||
132 | + data = fs.readFileSync(process.cwd() + '/tmp_ns'); | ||
133 | + assert.equal('src/src_1src/src_2src/src_3 pattern folder namespace', data.toString()); | ||
134 | + cleanUpAndNext(); | ||
135 | + }); | ||
136 | + | ||
137 | + test.skip('rule w chain w pattern w folder w namespace', function () { | ||
138 | + let out = exec( './node_modules/.bin/jake -q tmp_cr').toString().trim(); | ||
139 | + let output = [ | ||
140 | + "chainrule init task" | ||
141 | + , "cp tmpsrc/file1.tex tmpbin/file1.dvi tex->dvi task" | ||
142 | + , "cp tmpbin/file1.dvi tmpbin/file1.pdf dvi->pdf task" | ||
143 | + , "cp tmpsrc/file2.tex tmpbin/file2.dvi tex->dvi task" | ||
144 | + , "cp tmpbin/file2.dvi tmpbin/file2.pdf dvi->pdf task" | ||
145 | + , "tmp chainrule namespace task"]; | ||
146 | + let data; | ||
147 | + assert.equal( output.join('\n'), out); | ||
148 | + data = fs.readFileSync(process.cwd() + '/tmp_cr'); | ||
149 | + assert.equal('tex1 tex2 chainrule namespace', data.toString()); | ||
150 | + cleanUpAndNext(); | ||
151 | + }); | ||
152 | + | ||
153 | + | ||
154 | + ['precedence', 'regexPattern', 'sourceFunction'].forEach(function (key) { | ||
155 | + | ||
156 | + test('rule with source file not created yet (' + key + ')', function () { | ||
157 | + let write = process.stderr.write; | ||
158 | + process.stderr.write = () => {}; | ||
159 | + rmRf('foo.txt', {silent: true}); | ||
160 | + rmRf('foo.html', {silent: true}); | ||
161 | + try { | ||
162 | + exec('./node_modules/.bin/jake ' + key + ':test'); | ||
163 | + } | ||
164 | + catch(err) { | ||
165 | + // foo.txt prereq doesn't exist yet | ||
166 | + assert.ok(err.message.indexOf('Unknown task "foo.html"') > -1); | ||
167 | + } | ||
168 | + process.stderr.write = write; | ||
169 | + }); | ||
170 | + | ||
171 | + test('rule with source file now created (' + key + ')', function () { | ||
172 | + fs.writeFileSync('foo.txt', ''); | ||
173 | + let out = exec('./node_modules/.bin/jake -q ' + key + ':test').toString().trim(); | ||
174 | + // Should run prereq and test task | ||
175 | + let output = [ | ||
176 | + 'created html' | ||
177 | + , 'ran test' | ||
178 | + ]; | ||
179 | + assert.equal(output.join('\n'), out); | ||
180 | + }); | ||
181 | + | ||
182 | + test('rule with source file modified (' + key + ')', function (next) { | ||
183 | + setTimeout(function () { | ||
184 | + fs.writeFileSync('foo.txt', ''); | ||
185 | + let out = exec('./node_modules/.bin/jake -q ' + key + ':test').toString().trim(); | ||
186 | + // Should again run both prereq and test task | ||
187 | + let output = [ | ||
188 | + 'created html' | ||
189 | + , 'ran test' | ||
190 | + ]; | ||
191 | + assert.equal(output.join('\n'), out); | ||
192 | + //next(); | ||
193 | + cleanUpAndNext(next); | ||
194 | + }, 1000); // Wait to do the touch to ensure mod-time is different | ||
195 | + }); | ||
196 | + | ||
197 | + test('rule with existing objective file and no source ' + | ||
198 | + ' (should be normal file-task) (' + key + ')', function () { | ||
199 | + // Remove just the source file | ||
200 | + fs.writeFileSync('foo.html', ''); | ||
201 | + rmRf('foo.txt', {silent: true}); | ||
202 | + let out = exec('./node_modules/.bin/jake -q ' + key + ':test').toString().trim(); | ||
203 | + // Should treat existing objective file as plain file-task, | ||
204 | + // and just run test-task | ||
205 | + let output = [ | ||
206 | + 'ran test' | ||
207 | + ]; | ||
208 | + assert.equal(output.join('\n'), out); | ||
209 | + cleanUpAndNext(); | ||
210 | + }); | ||
211 | + | ||
212 | + }); | ||
213 | + | ||
214 | +}); | ||
215 | + | ||
216 | + |
1 | +let assert = require('assert'); | ||
2 | +let exec = require('child_process').execSync; | ||
3 | + | ||
4 | +suite('selfDep', function () { | ||
5 | + | ||
6 | + this.timeout(7000); | ||
7 | + | ||
8 | + let origStderrWrite; | ||
9 | + | ||
10 | + setup(function () { | ||
11 | + origStderrWrite = process.stderr.write; | ||
12 | + process.stderr.write = function () {}; | ||
13 | + }); | ||
14 | + | ||
15 | + teardown(function () { | ||
16 | + process.stderr.write = origStderrWrite; | ||
17 | + }); | ||
18 | + | ||
19 | + test('self dep const', function () { | ||
20 | + try { | ||
21 | + exec('./node_modules/.bin/jake selfdepconst'); | ||
22 | + } | ||
23 | + catch(e) { | ||
24 | + assert(e.message.indexOf('dependency of itself') > -1) | ||
25 | + } | ||
26 | + }); | ||
27 | + | ||
28 | + test('self dep dyn', function () { | ||
29 | + try { | ||
30 | + exec('./node_modules/.bin/jake selfdepdyn'); | ||
31 | + } | ||
32 | + catch(e) { | ||
33 | + assert(e.message.indexOf('dependency of itself') > -1) | ||
34 | + } | ||
35 | + }); | ||
36 | + | ||
37 | +}); | ||
38 | + | ||
39 | + |
1 | +let assert = require('assert'); | ||
2 | +let h = require('./helpers'); | ||
3 | +let exec = require('child_process').execSync; | ||
4 | + | ||
5 | +suite('taskBase', function () { | ||
6 | + | ||
7 | + this.timeout(7000); | ||
8 | + | ||
9 | + test('default task', function () { | ||
10 | + let out; | ||
11 | + out = exec('./node_modules/.bin/jake -q').toString().trim(); | ||
12 | + assert.equal(out, 'default task'); | ||
13 | + out = exec('./node_modules/.bin/jake -q default').toString().trim(); | ||
14 | + assert.equal(out, 'default task'); | ||
15 | + }); | ||
16 | + | ||
17 | + test('task with no action', function () { | ||
18 | + let out = exec('./node_modules/.bin/jake -q noAction').toString().trim(); | ||
19 | + assert.equal(out, 'default task'); | ||
20 | + }); | ||
21 | + | ||
22 | + test('a task with no action and no prereqs', function () { | ||
23 | + exec('./node_modules/.bin/jake noActionNoPrereqs'); | ||
24 | + }); | ||
25 | + | ||
26 | + test('a task that exists at the top-level, and not in the specified namespace, should error', function () { | ||
27 | + let res = require('child_process').spawnSync('./node_modules/.bin/jake', | ||
28 | + ['asdfasdfasdf:zerbofrangazoomy']); | ||
29 | + let err = res.stderr.toString(); | ||
30 | + assert.ok(err.indexOf('Unknown task' > -1)); | ||
31 | + }); | ||
32 | + | ||
33 | + test('passing args to a task', function () { | ||
34 | + let out = exec('./node_modules/.bin/jake -q argsEnvVars[foo,bar]').toString().trim(); | ||
35 | + let parsed = h.parse(out); | ||
36 | + let args = parsed.args; | ||
37 | + assert.equal(args[0], 'foo'); | ||
38 | + assert.equal(args[1], 'bar'); | ||
39 | + }); | ||
40 | + | ||
41 | + test('a task with environment vars', function () { | ||
42 | + let out = exec('./node_modules/.bin/jake -q argsEnvVars foo=bar baz=qux').toString().trim(); | ||
43 | + let parsed = h.parse(out); | ||
44 | + let env = parsed.env; | ||
45 | + assert.equal(env.foo, 'bar'); | ||
46 | + assert.equal(env.baz, 'qux'); | ||
47 | + }); | ||
48 | + | ||
49 | + test('passing args and using environment vars', function () { | ||
50 | + let out = exec('./node_modules/.bin/jake -q argsEnvVars[foo,bar] foo=bar baz=qux').toString().trim(); | ||
51 | + let parsed = h.parse(out); | ||
52 | + let args = parsed.args; | ||
53 | + let env = parsed.env; | ||
54 | + assert.equal(args[0], 'foo'); | ||
55 | + assert.equal(args[1], 'bar'); | ||
56 | + assert.equal(env.foo, 'bar'); | ||
57 | + assert.equal(env.baz, 'qux'); | ||
58 | + }); | ||
59 | + | ||
60 | + test('a simple prereq', function () { | ||
61 | + let out = exec('./node_modules/.bin/jake -q foo:baz').toString().trim(); | ||
62 | + assert.equal(out, 'foo:bar task\nfoo:baz task'); | ||
63 | + }); | ||
64 | + | ||
65 | + test('a duplicate prereq only runs once', function () { | ||
66 | + let out = exec('./node_modules/.bin/jake -q foo:asdf').toString().trim(); | ||
67 | + assert.equal(out, 'foo:bar task\nfoo:baz task\nfoo:asdf task'); | ||
68 | + }); | ||
69 | + | ||
70 | + test('a prereq with command-line args', function () { | ||
71 | + let out = exec('./node_modules/.bin/jake -q foo:qux').toString().trim(); | ||
72 | + assert.equal(out, 'foo:bar[asdf,qwer] task\nfoo:qux task'); | ||
73 | + }); | ||
74 | + | ||
75 | + test('a prereq with args via invoke', function () { | ||
76 | + let out = exec('./node_modules/.bin/jake -q foo:frang[zxcv,uiop]').toString().trim(); | ||
77 | + assert.equal(out, 'foo:bar[zxcv,uiop] task\nfoo:frang task'); | ||
78 | + }); | ||
79 | + | ||
80 | + test('a prereq with args via execute', function () { | ||
81 | + let out = exec('./node_modules/.bin/jake -q foo:zerb[zxcv,uiop]').toString().trim(); | ||
82 | + assert.equal(out, 'foo:bar[zxcv,uiop] task\nfoo:zerb task'); | ||
83 | + }); | ||
84 | + | ||
85 | + test('repeating the task via execute', function () { | ||
86 | + let out = exec('./node_modules/.bin/jake -q foo:voom').toString().trim(); | ||
87 | + assert.equal(out, 'foo:bar task\nfoo:bar task\ncomplete\ncomplete'); | ||
88 | + }); | ||
89 | + | ||
90 | + test('prereq execution-order', function () { | ||
91 | + let out = exec('./node_modules/.bin/jake -q hoge:fuga').toString().trim(); | ||
92 | + assert.equal(out, 'hoge:hoge task\nhoge:piyo task\nhoge:fuga task'); | ||
93 | + }); | ||
94 | + | ||
95 | + test('basic async task', function () { | ||
96 | + let out = exec('./node_modules/.bin/jake -q bar:bar').toString().trim(); | ||
97 | + assert.equal(out, 'bar:foo task\nbar:bar task'); | ||
98 | + }); | ||
99 | + | ||
100 | + test('promise async task', function () { | ||
101 | + let out = exec('./node_modules/.bin/jake -q bar:dependOnpromise').toString().trim(); | ||
102 | + assert.equal(out, 'bar:promise task\nbar:dependOnpromise task saw value 123654'); | ||
103 | + }); | ||
104 | + | ||
105 | + test('failing promise async task', function () { | ||
106 | + try { | ||
107 | + exec('./node_modules/.bin/jake -q bar:brokenPromise'); | ||
108 | + } | ||
109 | + catch(e) { | ||
110 | + assert(e.message.indexOf('Command failed') > -1); | ||
111 | + } | ||
112 | + }); | ||
113 | + | ||
114 | + test('that current-prereq index gets reset', function () { | ||
115 | + let out = exec('./node_modules/.bin/jake -q hoge:kira').toString().trim(); | ||
116 | + assert.equal(out, 'hoge:hoge task\nhoge:piyo task\nhoge:fuga task\n' + | ||
117 | + 'hoge:charan task\nhoge:gero task\nhoge:kira task'); | ||
118 | + }); | ||
119 | + | ||
120 | + test('modifying a task by adding prereq during execution', function () { | ||
121 | + let out = exec('./node_modules/.bin/jake -q voom').toString().trim(); | ||
122 | + assert.equal(out, 2); | ||
123 | + }); | ||
124 | + | ||
125 | + test('listening for task error-event', function () { | ||
126 | + try { | ||
127 | + exec('./node_modules/.bin/jake -q vronk:groo').toString().trim(); | ||
128 | + } | ||
129 | + catch(e) { | ||
130 | + assert(e.message.indexOf('OMFGZONG') > -1); | ||
131 | + } | ||
132 | + }); | ||
133 | + | ||
134 | + test('listening for jake error-event', function () { | ||
135 | + let out = exec('./node_modules/.bin/jake -q throwy').toString().trim(); | ||
136 | + assert(out.indexOf('Emitted\nError: I am bad') > -1); | ||
137 | + }); | ||
138 | + | ||
139 | + test('listening for jake unhandledRejection-event', function () { | ||
140 | + let out = exec('./node_modules/.bin/jake -q promiseRejecter').toString().trim(); | ||
141 | + assert.equal(out, '<promise rejected on purpose>'); | ||
142 | + }); | ||
143 | + | ||
144 | + test('large number of same prereqs', function () { | ||
145 | + let out = exec('./node_modules/.bin/jake -q large:same').toString().trim(); | ||
146 | + assert.equal(out, 'large:leaf\nlarge:same'); | ||
147 | + }); | ||
148 | + | ||
149 | + test('large number of different prereqs', function () { | ||
150 | + let out = exec('./node_modules/.bin/jake -q large:different').toString().trim(); | ||
151 | + assert.equal(out, 'leaf-12\nleaf-123\nlarge:different'); | ||
152 | + }); | ||
153 | + | ||
154 | + test('large number of different prereqs', function () { | ||
155 | + let out = exec('./node_modules/.bin/jake -q usingRequire:test').toString().trim(); | ||
156 | + assert.equal(out, 'howdy test'); | ||
157 | + }); | ||
158 | + | ||
159 | + test('modifying a namespace by adding a new task', function () { | ||
160 | + let out = exec('./node_modules/.bin/jake -q one:two').toString().trim(); | ||
161 | + assert.equal('one:one\none:two', out); | ||
162 | + }); | ||
163 | + | ||
164 | +}); |
node_modules/jake/test/unit/jakefile.js
0 → 100644
1 | + | ||
2 | +task('foo', function () { | ||
3 | + console.log('ran top-level foo'); | ||
4 | +}); | ||
5 | + | ||
6 | +task('bar', function () { | ||
7 | + console.log('ran top-level bar'); | ||
8 | +}); | ||
9 | + | ||
10 | +task('zerb', function () { | ||
11 | + console.log('ran zerb'); | ||
12 | +}); | ||
13 | + | ||
14 | +namespace('zooby', function () { | ||
15 | + task('zerp', function () {}); | ||
16 | + | ||
17 | + task('derp', ['zerp'], function () {}); | ||
18 | + | ||
19 | + namespace('frang', function () { | ||
20 | + | ||
21 | + namespace('w00t', function () { | ||
22 | + task('bar', function () { | ||
23 | + console.log('ran zooby:frang:w00t:bar'); | ||
24 | + }); | ||
25 | + }); | ||
26 | + | ||
27 | + task('asdf', function () {}); | ||
28 | + }); | ||
29 | + | ||
30 | +}); | ||
31 | + | ||
32 | +namespace('hurr', function () { | ||
33 | + namespace('durr'); | ||
34 | +}); | ||
35 | + | ||
36 | + |
node_modules/jake/test/unit/namespace.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +// Load the jake global | ||
22 | +require(`${PROJECT_DIR}/lib/jake`); | ||
23 | +let { Namespace } = require(`${PROJECT_DIR}/lib/namespace`); | ||
24 | + | ||
25 | +require('./jakefile'); | ||
26 | + | ||
27 | +let assert = require('assert'); | ||
28 | + | ||
29 | +suite('namespace', function () { | ||
30 | + | ||
31 | + this.timeout(7000); | ||
32 | + | ||
33 | + test('resolve namespace by relative name', function () { | ||
34 | + let aaa, bbb, ccc; | ||
35 | + aaa = namespace('aaa', function () { | ||
36 | + bbb = namespace('bbb', function () { | ||
37 | + ccc = namespace('ccc', function () { | ||
38 | + }); | ||
39 | + }); | ||
40 | + }); | ||
41 | + | ||
42 | + assert.ok(aaa, Namespace.ROOT_NAMESPACE.resolveNamespace('aaa')); | ||
43 | + assert.ok(bbb === aaa.resolveNamespace('bbb')); | ||
44 | + assert.ok(ccc === aaa.resolveNamespace('bbb:ccc')); | ||
45 | + }); | ||
46 | + | ||
47 | + test('resolve task in sub-namespace by relative path', function () { | ||
48 | + let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('zooby'); | ||
49 | + let task = curr.resolveTask('frang:w00t:bar'); | ||
50 | + assert.ok(task.action.toString().indexOf('zooby:frang:w00t:bar') > -1); | ||
51 | + }); | ||
52 | + | ||
53 | + test('prefer local to top-level', function () { | ||
54 | + let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('zooby:frang:w00t'); | ||
55 | + let task = curr.resolveTask('bar'); | ||
56 | + assert.ok(task.action.toString().indexOf('zooby:frang:w00t:bar') > -1); | ||
57 | + }); | ||
58 | + | ||
59 | + test('does resolve top-level', function () { | ||
60 | + let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('zooby:frang:w00t'); | ||
61 | + let task = curr.resolveTask('foo'); | ||
62 | + assert.ok(task.action.toString().indexOf('top-level foo') > -1); | ||
63 | + }); | ||
64 | + | ||
65 | + test('absolute lookup works from sub-namespaces', function () { | ||
66 | + let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('hurr:durr'); | ||
67 | + let task = curr.resolveTask('zooby:frang:w00t:bar'); | ||
68 | + assert.ok(task.action.toString().indexOf('zooby:frang:w00t:bar') > -1); | ||
69 | + }); | ||
70 | + | ||
71 | + test('resolution miss with throw error', function () { | ||
72 | + let curr = Namespace.ROOT_NAMESPACE; | ||
73 | + let task = curr.resolveTask('asdf:qwer'); | ||
74 | + assert.ok(!task); | ||
75 | + }); | ||
76 | + | ||
77 | +}); |
node_modules/jake/test/unit/parseargs.js
0 → 100644
1 | +/* | ||
2 | + * Jake JavaScript build tool | ||
3 | + * Copyright 2112 Matthew Eernisse (mde@fleegix.org) | ||
4 | + * | ||
5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + * you may not use this file except in compliance with the License. | ||
7 | + * You may obtain a copy of the License at | ||
8 | + * | ||
9 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + * | ||
11 | + * Unless required by applicable law or agreed to in writing, software | ||
12 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + * See the License for the specific language governing permissions and | ||
15 | + * limitations under the License. | ||
16 | + * | ||
17 | +*/ | ||
18 | + | ||
19 | +const PROJECT_DIR = process.env.PROJECT_DIR; | ||
20 | + | ||
21 | +let parseargs = require(`${PROJECT_DIR}/lib/parseargs`); | ||
22 | +let assert = require('assert'); | ||
23 | +let optsReg = [ | ||
24 | + { full: 'directory', | ||
25 | + abbr: 'C', | ||
26 | + preempts: false, | ||
27 | + expectValue: true | ||
28 | + }, | ||
29 | + { full: 'jakefile', | ||
30 | + abbr: 'f', | ||
31 | + preempts: false, | ||
32 | + expectValue: true | ||
33 | + }, | ||
34 | + { full: 'tasks', | ||
35 | + abbr: 'T', | ||
36 | + preempts: true | ||
37 | + }, | ||
38 | + { full: 'tasks', | ||
39 | + abbr: 'ls', | ||
40 | + preempts: true | ||
41 | + }, | ||
42 | + { full: 'trace', | ||
43 | + abbr: 't', | ||
44 | + preempts: false, | ||
45 | + expectValue: false | ||
46 | + }, | ||
47 | + { full: 'help', | ||
48 | + abbr: 'h', | ||
49 | + preempts: true | ||
50 | + }, | ||
51 | + { full: 'version', | ||
52 | + abbr: 'V', | ||
53 | + preempts: true | ||
54 | + } | ||
55 | +]; | ||
56 | +let p = new parseargs.Parser(optsReg); | ||
57 | +let z = function (s) { return s.split(' '); }; | ||
58 | +let res; | ||
59 | + | ||
60 | +suite('parseargs', function () { | ||
61 | + | ||
62 | + test('long preemptive opt and val with equal-sign, ignore further opts', function () { | ||
63 | + res = p.parse(z('--tasks=foo --jakefile=asdf')); | ||
64 | + assert.equal('foo', res.opts.tasks); | ||
65 | + assert.equal(undefined, res.opts.jakefile); | ||
66 | + }); | ||
67 | + | ||
68 | + test('long preemptive opt and val without equal-sign, ignore further opts', function () { | ||
69 | + res = p.parse(z('--tasks foo --jakefile=asdf')); | ||
70 | + assert.equal('foo', res.opts.tasks); | ||
71 | + assert.equal(undefined, res.opts.jakefile); | ||
72 | + }); | ||
73 | + | ||
74 | + test('long preemptive opt and no val, ignore further opts', function () { | ||
75 | + res = p.parse(z('--tasks --jakefile=asdf')); | ||
76 | + assert.equal(true, res.opts.tasks); | ||
77 | + assert.equal(undefined, res.opts.jakefile); | ||
78 | + }); | ||
79 | + | ||
80 | + test('preemptive opt with no val, should be true', function () { | ||
81 | + res = p.parse(z('-T')); | ||
82 | + assert.equal(true, res.opts.tasks); | ||
83 | + }); | ||
84 | + | ||
85 | + test('preemptive opt with no val, should be true and ignore further opts', function () { | ||
86 | + res = p.parse(z('-T -f')); | ||
87 | + assert.equal(true, res.opts.tasks); | ||
88 | + assert.equal(undefined, res.opts.jakefile); | ||
89 | + }); | ||
90 | + | ||
91 | + test('preemptive opt with val, should be val', function () { | ||
92 | + res = p.parse(z('-T zoobie -f foo/bar/baz')); | ||
93 | + assert.equal('zoobie', res.opts.tasks); | ||
94 | + assert.equal(undefined, res.opts.jakefile); | ||
95 | + }); | ||
96 | + | ||
97 | + test('-f expects a value, -t does not (howdy is task-name)', function () { | ||
98 | + res = p.parse(z('-f zoobie -t howdy')); | ||
99 | + assert.equal('zoobie', res.opts.jakefile); | ||
100 | + assert.equal(true, res.opts.trace); | ||
101 | + assert.equal('howdy', res.taskNames[0]); | ||
102 | + }); | ||
103 | + | ||
104 | + test('different order, -f expects a value, -t does not (howdy is task-name)', function () { | ||
105 | + res = p.parse(z('-f zoobie howdy -t')); | ||
106 | + assert.equal('zoobie', res.opts.jakefile); | ||
107 | + assert.equal(true, res.opts.trace); | ||
108 | + assert.equal('howdy', res.taskNames[0]); | ||
109 | + }); | ||
110 | + | ||
111 | + test('-f expects a value, -t does not (foo=bar is env var)', function () { | ||
112 | + res = p.parse(z('-f zoobie -t foo=bar')); | ||
113 | + assert.equal('zoobie', res.opts.jakefile); | ||
114 | + assert.equal(true, res.opts.trace); | ||
115 | + assert.equal('bar', res.envVars.foo); | ||
116 | + assert.equal(undefined, res.taskNames[0]); | ||
117 | + }); | ||
118 | + | ||
119 | + test('-f expects a value, -t does not (foo=bar is env-var, task-name follows)', function () { | ||
120 | + res = p.parse(z('-f zoobie -t howdy foo=bar')); | ||
121 | + assert.equal('zoobie', res.opts.jakefile); | ||
122 | + assert.equal(true, res.opts.trace); | ||
123 | + assert.equal('bar', res.envVars.foo); | ||
124 | + assert.equal('howdy', res.taskNames[0]); | ||
125 | + }); | ||
126 | + | ||
127 | + test('-t does not expect a value, -f does (howdy is task-name)', function () { | ||
128 | + res = p.parse(z('-t howdy -f zoobie')); | ||
129 | + assert.equal(true, res.opts.trace); | ||
130 | + assert.equal('zoobie', res.opts.jakefile); | ||
131 | + assert.equal('howdy', res.taskNames[0]); | ||
132 | + }); | ||
133 | + | ||
134 | + test('--trace does not expect a value, -f does (howdy is task-name)', function () { | ||
135 | + res = p.parse(z('--trace howdy --jakefile zoobie')); | ||
136 | + assert.equal(true, res.opts.trace); | ||
137 | + assert.equal('zoobie', res.opts.jakefile); | ||
138 | + assert.equal('howdy', res.taskNames[0]); | ||
139 | + }); | ||
140 | + | ||
141 | + test('--trace does not expect a value (equal), -f does (throw howdy away)', function () { | ||
142 | + res = p.parse(z('--trace=howdy --jakefile=zoobie')); | ||
143 | + assert.equal(true, res.opts.trace); | ||
144 | + assert.equal('zoobie', res.opts.jakefile); | ||
145 | + assert.equal(undefined, res.taskNames[0]); | ||
146 | + }); | ||
147 | + | ||
148 | + /* | ||
149 | +, test('task-name with positional args', function () { | ||
150 | + res = p.parse(z('foo:bar[asdf,qwer]')); | ||
151 | + assert.equal('asdf', p.taskArgs[0]); | ||
152 | + assert.equal('qwer', p.taskArgs[1]); | ||
153 | + } | ||
154 | + | ||
155 | +, test('opts, env vars, task-name with positional args', function () { | ||
156 | + res = p.parse(z('-f ./tests/Jakefile -t default[asdf,qwer] foo=bar')); | ||
157 | + assert.equal('./tests/Jakefile', res.opts.jakefile); | ||
158 | + assert.equal(true, res.opts.trace); | ||
159 | + assert.equal('bar', res.envVars.foo); | ||
160 | + assert.equal('default', res.taskName); | ||
161 | + assert.equal('asdf', p.taskArgs[0]); | ||
162 | + assert.equal('qwer', p.taskArgs[1]); | ||
163 | + } | ||
164 | +*/ | ||
165 | + | ||
166 | + | ||
167 | +}); | ||
168 | + | ||
169 | + |
node_modules/jake/usage.txt
0 → 100644
1 | +Jake JavaScript build tool | ||
2 | +******************************************************************************** | ||
3 | +If no flags are given, Jake looks for a Jakefile or Jakefile.js in the current directory. | ||
4 | +******************************************************************************** | ||
5 | +{Usage}: jake [options ...] [env variables ...] target | ||
6 | + | ||
7 | +{Options}: | ||
8 | + -f, --jakefile FILE Use FILE as the Jakefile. | ||
9 | + -C, --directory DIRECTORY Change to DIRECTORY before running tasks. | ||
10 | + -B, --always-make Unconditionally make all targets. | ||
11 | + -T/ls, --tasks Display the tasks (matching optional PATTERN) with descriptions, then exit. | ||
12 | + -J, --jakelibdir JAKELIBDIR Auto-import any .jake files in JAKELIBDIR. (default is \'jakelib\') | ||
13 | + -h, --help Display this help message. | ||
14 | + -V/v, --version Display the Jake version. | ||
15 | + -ar, --allow-rejection Keep running even after unhandled promise rejection | ||
16 | + |
node_modules/minimatch/LICENSE
0 → 100644
1 | +The ISC License | ||
2 | + | ||
3 | +Copyright (c) Isaac Z. Schlueter and Contributors | ||
4 | + | ||
5 | +Permission to use, copy, modify, and/or distribute this software for any | ||
6 | +purpose with or without fee is hereby granted, provided that the above | ||
7 | +copyright notice and this permission notice appear in all copies. | ||
8 | + | ||
9 | +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||
15 | +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
node_modules/minimatch/README.md
0 → 100644
1 | +# minimatch | ||
2 | + | ||
3 | +A minimal matching utility. | ||
4 | + | ||
5 | +[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.svg)](http://travis-ci.org/isaacs/minimatch) | ||
6 | + | ||
7 | + | ||
8 | +This is the matching library used internally by npm. | ||
9 | + | ||
10 | +It works by converting glob expressions into JavaScript `RegExp` | ||
11 | +objects. | ||
12 | + | ||
13 | +## Usage | ||
14 | + | ||
15 | +```javascript | ||
16 | +var minimatch = require("minimatch") | ||
17 | + | ||
18 | +minimatch("bar.foo", "*.foo") // true! | ||
19 | +minimatch("bar.foo", "*.bar") // false! | ||
20 | +minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! | ||
21 | +``` | ||
22 | + | ||
23 | +## Features | ||
24 | + | ||
25 | +Supports these glob features: | ||
26 | + | ||
27 | +* Brace Expansion | ||
28 | +* Extended glob matching | ||
29 | +* "Globstar" `**` matching | ||
30 | + | ||
31 | +See: | ||
32 | + | ||
33 | +* `man sh` | ||
34 | +* `man bash` | ||
35 | +* `man 3 fnmatch` | ||
36 | +* `man 5 gitignore` | ||
37 | + | ||
38 | +## Minimatch Class | ||
39 | + | ||
40 | +Create a minimatch object by instantiating the `minimatch.Minimatch` class. | ||
41 | + | ||
42 | +```javascript | ||
43 | +var Minimatch = require("minimatch").Minimatch | ||
44 | +var mm = new Minimatch(pattern, options) | ||
45 | +``` | ||
46 | + | ||
47 | +### Properties | ||
48 | + | ||
49 | +* `pattern` The original pattern the minimatch object represents. | ||
50 | +* `options` The options supplied to the constructor. | ||
51 | +* `set` A 2-dimensional array of regexp or string expressions. | ||
52 | + Each row in the | ||
53 | + array corresponds to a brace-expanded pattern. Each item in the row | ||
54 | + corresponds to a single path-part. For example, the pattern | ||
55 | + `{a,b/c}/d` would expand to a set of patterns like: | ||
56 | + | ||
57 | + [ [ a, d ] | ||
58 | + , [ b, c, d ] ] | ||
59 | + | ||
60 | + If a portion of the pattern doesn't have any "magic" in it | ||
61 | + (that is, it's something like `"foo"` rather than `fo*o?`), then it | ||
62 | + will be left as a string rather than converted to a regular | ||
63 | + expression. | ||
64 | + | ||
65 | +* `regexp` Created by the `makeRe` method. A single regular expression | ||
66 | + expressing the entire pattern. This is useful in cases where you wish | ||
67 | + to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. | ||
68 | +* `negate` True if the pattern is negated. | ||
69 | +* `comment` True if the pattern is a comment. | ||
70 | +* `empty` True if the pattern is `""`. | ||
71 | + | ||
72 | +### Methods | ||
73 | + | ||
74 | +* `makeRe` Generate the `regexp` member if necessary, and return it. | ||
75 | + Will return `false` if the pattern is invalid. | ||
76 | +* `match(fname)` Return true if the filename matches the pattern, or | ||
77 | + false otherwise. | ||
78 | +* `matchOne(fileArray, patternArray, partial)` Take a `/`-split | ||
79 | + filename, and match it against a single row in the `regExpSet`. This | ||
80 | + method is mainly for internal use, but is exposed so that it can be | ||
81 | + used by a glob-walker that needs to avoid excessive filesystem calls. | ||
82 | + | ||
83 | +All other methods are internal, and will be called as necessary. | ||
84 | + | ||
85 | +### minimatch(path, pattern, options) | ||
86 | + | ||
87 | +Main export. Tests a path against the pattern using the options. | ||
88 | + | ||
89 | +```javascript | ||
90 | +var isJS = minimatch(file, "*.js", { matchBase: true }) | ||
91 | +``` | ||
92 | + | ||
93 | +### minimatch.filter(pattern, options) | ||
94 | + | ||
95 | +Returns a function that tests its | ||
96 | +supplied argument, suitable for use with `Array.filter`. Example: | ||
97 | + | ||
98 | +```javascript | ||
99 | +var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) | ||
100 | +``` | ||
101 | + | ||
102 | +### minimatch.match(list, pattern, options) | ||
103 | + | ||
104 | +Match against the list of | ||
105 | +files, in the style of fnmatch or glob. If nothing is matched, and | ||
106 | +options.nonull is set, then return a list containing the pattern itself. | ||
107 | + | ||
108 | +```javascript | ||
109 | +var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) | ||
110 | +``` | ||
111 | + | ||
112 | +### minimatch.makeRe(pattern, options) | ||
113 | + | ||
114 | +Make a regular expression object from the pattern. | ||
115 | + | ||
116 | +## Options | ||
117 | + | ||
118 | +All options are `false` by default. | ||
119 | + | ||
120 | +### debug | ||
121 | + | ||
122 | +Dump a ton of stuff to stderr. | ||
123 | + | ||
124 | +### nobrace | ||
125 | + | ||
126 | +Do not expand `{a,b}` and `{1..3}` brace sets. | ||
127 | + | ||
128 | +### noglobstar | ||
129 | + | ||
130 | +Disable `**` matching against multiple folder names. | ||
131 | + | ||
132 | +### dot | ||
133 | + | ||
134 | +Allow patterns to match filenames starting with a period, even if | ||
135 | +the pattern does not explicitly have a period in that spot. | ||
136 | + | ||
137 | +Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` | ||
138 | +is set. | ||
139 | + | ||
140 | +### noext | ||
141 | + | ||
142 | +Disable "extglob" style patterns like `+(a|b)`. | ||
143 | + | ||
144 | +### nocase | ||
145 | + | ||
146 | +Perform a case-insensitive match. | ||
147 | + | ||
148 | +### nonull | ||
149 | + | ||
150 | +When a match is not found by `minimatch.match`, return a list containing | ||
151 | +the pattern itself if this option is set. When not set, an empty list | ||
152 | +is returned if there are no matches. | ||
153 | + | ||
154 | +### matchBase | ||
155 | + | ||
156 | +If set, then patterns without slashes will be matched | ||
157 | +against the basename of the path if it contains slashes. For example, | ||
158 | +`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. | ||
159 | + | ||
160 | +### nocomment | ||
161 | + | ||
162 | +Suppress the behavior of treating `#` at the start of a pattern as a | ||
163 | +comment. | ||
164 | + | ||
165 | +### nonegate | ||
166 | + | ||
167 | +Suppress the behavior of treating a leading `!` character as negation. | ||
168 | + | ||
169 | +### flipNegate | ||
170 | + | ||
171 | +Returns from negate expressions the same as if they were not negated. | ||
172 | +(Ie, true on a hit, false on a miss.) | ||
173 | + | ||
174 | + | ||
175 | +## Comparisons to other fnmatch/glob implementations | ||
176 | + | ||
177 | +While strict compliance with the existing standards is a worthwhile | ||
178 | +goal, some discrepancies exist between minimatch and other | ||
179 | +implementations, and are intentional. | ||
180 | + | ||
181 | +If the pattern starts with a `!` character, then it is negated. Set the | ||
182 | +`nonegate` flag to suppress this behavior, and treat leading `!` | ||
183 | +characters normally. This is perhaps relevant if you wish to start the | ||
184 | +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` | ||
185 | +characters at the start of a pattern will negate the pattern multiple | ||
186 | +times. | ||
187 | + | ||
188 | +If a pattern starts with `#`, then it is treated as a comment, and | ||
189 | +will not match anything. Use `\#` to match a literal `#` at the | ||
190 | +start of a line, or set the `nocomment` flag to suppress this behavior. | ||
191 | + | ||
192 | +The double-star character `**` is supported by default, unless the | ||
193 | +`noglobstar` flag is set. This is supported in the manner of bsdglob | ||
194 | +and bash 4.1, where `**` only has special significance if it is the only | ||
195 | +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but | ||
196 | +`a/**b` will not. | ||
197 | + | ||
198 | +If an escaped pattern has no matches, and the `nonull` flag is set, | ||
199 | +then minimatch.match returns the pattern as-provided, rather than | ||
200 | +interpreting the character escapes. For example, | ||
201 | +`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than | ||
202 | +`"*a?"`. This is akin to setting the `nullglob` option in bash, except | ||
203 | +that it does not resolve escaped pattern characters. | ||
204 | + | ||
205 | +If brace expansion is not disabled, then it is performed before any | ||
206 | +other interpretation of the glob pattern. Thus, a pattern like | ||
207 | +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded | ||
208 | +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are | ||
209 | +checked for validity. Since those two are valid, matching proceeds. |
node_modules/minimatch/minimatch.js
0 → 100644
1 | +module.exports = minimatch | ||
2 | +minimatch.Minimatch = Minimatch | ||
3 | + | ||
4 | +var path = { sep: '/' } | ||
5 | +try { | ||
6 | + path = require('path') | ||
7 | +} catch (er) {} | ||
8 | + | ||
9 | +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} | ||
10 | +var expand = require('brace-expansion') | ||
11 | + | ||
12 | +var plTypes = { | ||
13 | + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, | ||
14 | + '?': { open: '(?:', close: ')?' }, | ||
15 | + '+': { open: '(?:', close: ')+' }, | ||
16 | + '*': { open: '(?:', close: ')*' }, | ||
17 | + '@': { open: '(?:', close: ')' } | ||
18 | +} | ||
19 | + | ||
20 | +// any single thing other than / | ||
21 | +// don't need to escape / when using new RegExp() | ||
22 | +var qmark = '[^/]' | ||
23 | + | ||
24 | +// * => any number of characters | ||
25 | +var star = qmark + '*?' | ||
26 | + | ||
27 | +// ** when dots are allowed. Anything goes, except .. and . | ||
28 | +// not (^ or / followed by one or two dots followed by $ or /), | ||
29 | +// followed by anything, any number of times. | ||
30 | +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' | ||
31 | + | ||
32 | +// not a ^ or / followed by a dot, | ||
33 | +// followed by anything, any number of times. | ||
34 | +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' | ||
35 | + | ||
36 | +// characters that need to be escaped in RegExp. | ||
37 | +var reSpecials = charSet('().*{}+?[]^$\\!') | ||
38 | + | ||
39 | +// "abc" -> { a:true, b:true, c:true } | ||
40 | +function charSet (s) { | ||
41 | + return s.split('').reduce(function (set, c) { | ||
42 | + set[c] = true | ||
43 | + return set | ||
44 | + }, {}) | ||
45 | +} | ||
46 | + | ||
47 | +// normalizes slashes. | ||
48 | +var slashSplit = /\/+/ | ||
49 | + | ||
50 | +minimatch.filter = filter | ||
51 | +function filter (pattern, options) { | ||
52 | + options = options || {} | ||
53 | + return function (p, i, list) { | ||
54 | + return minimatch(p, pattern, options) | ||
55 | + } | ||
56 | +} | ||
57 | + | ||
58 | +function ext (a, b) { | ||
59 | + a = a || {} | ||
60 | + b = b || {} | ||
61 | + var t = {} | ||
62 | + Object.keys(b).forEach(function (k) { | ||
63 | + t[k] = b[k] | ||
64 | + }) | ||
65 | + Object.keys(a).forEach(function (k) { | ||
66 | + t[k] = a[k] | ||
67 | + }) | ||
68 | + return t | ||
69 | +} | ||
70 | + | ||
71 | +minimatch.defaults = function (def) { | ||
72 | + if (!def || !Object.keys(def).length) return minimatch | ||
73 | + | ||
74 | + var orig = minimatch | ||
75 | + | ||
76 | + var m = function minimatch (p, pattern, options) { | ||
77 | + return orig.minimatch(p, pattern, ext(def, options)) | ||
78 | + } | ||
79 | + | ||
80 | + m.Minimatch = function Minimatch (pattern, options) { | ||
81 | + return new orig.Minimatch(pattern, ext(def, options)) | ||
82 | + } | ||
83 | + | ||
84 | + return m | ||
85 | +} | ||
86 | + | ||
87 | +Minimatch.defaults = function (def) { | ||
88 | + if (!def || !Object.keys(def).length) return Minimatch | ||
89 | + return minimatch.defaults(def).Minimatch | ||
90 | +} | ||
91 | + | ||
92 | +function minimatch (p, pattern, options) { | ||
93 | + if (typeof pattern !== 'string') { | ||
94 | + throw new TypeError('glob pattern string required') | ||
95 | + } | ||
96 | + | ||
97 | + if (!options) options = {} | ||
98 | + | ||
99 | + // shortcut: comments match nothing. | ||
100 | + if (!options.nocomment && pattern.charAt(0) === '#') { | ||
101 | + return false | ||
102 | + } | ||
103 | + | ||
104 | + // "" only matches "" | ||
105 | + if (pattern.trim() === '') return p === '' | ||
106 | + | ||
107 | + return new Minimatch(pattern, options).match(p) | ||
108 | +} | ||
109 | + | ||
110 | +function Minimatch (pattern, options) { | ||
111 | + if (!(this instanceof Minimatch)) { | ||
112 | + return new Minimatch(pattern, options) | ||
113 | + } | ||
114 | + | ||
115 | + if (typeof pattern !== 'string') { | ||
116 | + throw new TypeError('glob pattern string required') | ||
117 | + } | ||
118 | + | ||
119 | + if (!options) options = {} | ||
120 | + pattern = pattern.trim() | ||
121 | + | ||
122 | + // windows support: need to use /, not \ | ||
123 | + if (path.sep !== '/') { | ||
124 | + pattern = pattern.split(path.sep).join('/') | ||
125 | + } | ||
126 | + | ||
127 | + this.options = options | ||
128 | + this.set = [] | ||
129 | + this.pattern = pattern | ||
130 | + this.regexp = null | ||
131 | + this.negate = false | ||
132 | + this.comment = false | ||
133 | + this.empty = false | ||
134 | + | ||
135 | + // make the set of regexps etc. | ||
136 | + this.make() | ||
137 | +} | ||
138 | + | ||
139 | +Minimatch.prototype.debug = function () {} | ||
140 | + | ||
141 | +Minimatch.prototype.make = make | ||
142 | +function make () { | ||
143 | + // don't do it more than once. | ||
144 | + if (this._made) return | ||
145 | + | ||
146 | + var pattern = this.pattern | ||
147 | + var options = this.options | ||
148 | + | ||
149 | + // empty patterns and comments match nothing. | ||
150 | + if (!options.nocomment && pattern.charAt(0) === '#') { | ||
151 | + this.comment = true | ||
152 | + return | ||
153 | + } | ||
154 | + if (!pattern) { | ||
155 | + this.empty = true | ||
156 | + return | ||
157 | + } | ||
158 | + | ||
159 | + // step 1: figure out negation, etc. | ||
160 | + this.parseNegate() | ||
161 | + | ||
162 | + // step 2: expand braces | ||
163 | + var set = this.globSet = this.braceExpand() | ||
164 | + | ||
165 | + if (options.debug) this.debug = console.error | ||
166 | + | ||
167 | + this.debug(this.pattern, set) | ||
168 | + | ||
169 | + // step 3: now we have a set, so turn each one into a series of path-portion | ||
170 | + // matching patterns. | ||
171 | + // These will be regexps, except in the case of "**", which is | ||
172 | + // set to the GLOBSTAR object for globstar behavior, | ||
173 | + // and will not contain any / characters | ||
174 | + set = this.globParts = set.map(function (s) { | ||
175 | + return s.split(slashSplit) | ||
176 | + }) | ||
177 | + | ||
178 | + this.debug(this.pattern, set) | ||
179 | + | ||
180 | + // glob --> regexps | ||
181 | + set = set.map(function (s, si, set) { | ||
182 | + return s.map(this.parse, this) | ||
183 | + }, this) | ||
184 | + | ||
185 | + this.debug(this.pattern, set) | ||
186 | + | ||
187 | + // filter out everything that didn't compile properly. | ||
188 | + set = set.filter(function (s) { | ||
189 | + return s.indexOf(false) === -1 | ||
190 | + }) | ||
191 | + | ||
192 | + this.debug(this.pattern, set) | ||
193 | + | ||
194 | + this.set = set | ||
195 | +} | ||
196 | + | ||
197 | +Minimatch.prototype.parseNegate = parseNegate | ||
198 | +function parseNegate () { | ||
199 | + var pattern = this.pattern | ||
200 | + var negate = false | ||
201 | + var options = this.options | ||
202 | + var negateOffset = 0 | ||
203 | + | ||
204 | + if (options.nonegate) return | ||
205 | + | ||
206 | + for (var i = 0, l = pattern.length | ||
207 | + ; i < l && pattern.charAt(i) === '!' | ||
208 | + ; i++) { | ||
209 | + negate = !negate | ||
210 | + negateOffset++ | ||
211 | + } | ||
212 | + | ||
213 | + if (negateOffset) this.pattern = pattern.substr(negateOffset) | ||
214 | + this.negate = negate | ||
215 | +} | ||
216 | + | ||
217 | +// Brace expansion: | ||
218 | +// a{b,c}d -> abd acd | ||
219 | +// a{b,}c -> abc ac | ||
220 | +// a{0..3}d -> a0d a1d a2d a3d | ||
221 | +// a{b,c{d,e}f}g -> abg acdfg acefg | ||
222 | +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg | ||
223 | +// | ||
224 | +// Invalid sets are not expanded. | ||
225 | +// a{2..}b -> a{2..}b | ||
226 | +// a{b}c -> a{b}c | ||
227 | +minimatch.braceExpand = function (pattern, options) { | ||
228 | + return braceExpand(pattern, options) | ||
229 | +} | ||
230 | + | ||
231 | +Minimatch.prototype.braceExpand = braceExpand | ||
232 | + | ||
233 | +function braceExpand (pattern, options) { | ||
234 | + if (!options) { | ||
235 | + if (this instanceof Minimatch) { | ||
236 | + options = this.options | ||
237 | + } else { | ||
238 | + options = {} | ||
239 | + } | ||
240 | + } | ||
241 | + | ||
242 | + pattern = typeof pattern === 'undefined' | ||
243 | + ? this.pattern : pattern | ||
244 | + | ||
245 | + if (typeof pattern === 'undefined') { | ||
246 | + throw new TypeError('undefined pattern') | ||
247 | + } | ||
248 | + | ||
249 | + if (options.nobrace || | ||
250 | + !pattern.match(/\{.*\}/)) { | ||
251 | + // shortcut. no need to expand. | ||
252 | + return [pattern] | ||
253 | + } | ||
254 | + | ||
255 | + return expand(pattern) | ||
256 | +} | ||
257 | + | ||
258 | +// parse a component of the expanded set. | ||
259 | +// At this point, no pattern may contain "/" in it | ||
260 | +// so we're going to return a 2d array, where each entry is the full | ||
261 | +// pattern, split on '/', and then turned into a regular expression. | ||
262 | +// A regexp is made at the end which joins each array with an | ||
263 | +// escaped /, and another full one which joins each regexp with |. | ||
264 | +// | ||
265 | +// Following the lead of Bash 4.1, note that "**" only has special meaning | ||
266 | +// when it is the *only* thing in a path portion. Otherwise, any series | ||
267 | +// of * is equivalent to a single *. Globstar behavior is enabled by | ||
268 | +// default, and can be disabled by setting options.noglobstar. | ||
269 | +Minimatch.prototype.parse = parse | ||
270 | +var SUBPARSE = {} | ||
271 | +function parse (pattern, isSub) { | ||
272 | + if (pattern.length > 1024 * 64) { | ||
273 | + throw new TypeError('pattern is too long') | ||
274 | + } | ||
275 | + | ||
276 | + var options = this.options | ||
277 | + | ||
278 | + // shortcuts | ||
279 | + if (!options.noglobstar && pattern === '**') return GLOBSTAR | ||
280 | + if (pattern === '') return '' | ||
281 | + | ||
282 | + var re = '' | ||
283 | + var hasMagic = !!options.nocase | ||
284 | + var escaping = false | ||
285 | + // ? => one single character | ||
286 | + var patternListStack = [] | ||
287 | + var negativeLists = [] | ||
288 | + var stateChar | ||
289 | + var inClass = false | ||
290 | + var reClassStart = -1 | ||
291 | + var classStart = -1 | ||
292 | + // . and .. never match anything that doesn't start with ., | ||
293 | + // even when options.dot is set. | ||
294 | + var patternStart = pattern.charAt(0) === '.' ? '' // anything | ||
295 | + // not (start or / followed by . or .. followed by / or end) | ||
296 | + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' | ||
297 | + : '(?!\\.)' | ||
298 | + var self = this | ||
299 | + | ||
300 | + function clearStateChar () { | ||
301 | + if (stateChar) { | ||
302 | + // we had some state-tracking character | ||
303 | + // that wasn't consumed by this pass. | ||
304 | + switch (stateChar) { | ||
305 | + case '*': | ||
306 | + re += star | ||
307 | + hasMagic = true | ||
308 | + break | ||
309 | + case '?': | ||
310 | + re += qmark | ||
311 | + hasMagic = true | ||
312 | + break | ||
313 | + default: | ||
314 | + re += '\\' + stateChar | ||
315 | + break | ||
316 | + } | ||
317 | + self.debug('clearStateChar %j %j', stateChar, re) | ||
318 | + stateChar = false | ||
319 | + } | ||
320 | + } | ||
321 | + | ||
322 | + for (var i = 0, len = pattern.length, c | ||
323 | + ; (i < len) && (c = pattern.charAt(i)) | ||
324 | + ; i++) { | ||
325 | + this.debug('%s\t%s %s %j', pattern, i, re, c) | ||
326 | + | ||
327 | + // skip over any that are escaped. | ||
328 | + if (escaping && reSpecials[c]) { | ||
329 | + re += '\\' + c | ||
330 | + escaping = false | ||
331 | + continue | ||
332 | + } | ||
333 | + | ||
334 | + switch (c) { | ||
335 | + case '/': | ||
336 | + // completely not allowed, even escaped. | ||
337 | + // Should already be path-split by now. | ||
338 | + return false | ||
339 | + | ||
340 | + case '\\': | ||
341 | + clearStateChar() | ||
342 | + escaping = true | ||
343 | + continue | ||
344 | + | ||
345 | + // the various stateChar values | ||
346 | + // for the "extglob" stuff. | ||
347 | + case '?': | ||
348 | + case '*': | ||
349 | + case '+': | ||
350 | + case '@': | ||
351 | + case '!': | ||
352 | + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) | ||
353 | + | ||
354 | + // all of those are literals inside a class, except that | ||
355 | + // the glob [!a] means [^a] in regexp | ||
356 | + if (inClass) { | ||
357 | + this.debug(' in class') | ||
358 | + if (c === '!' && i === classStart + 1) c = '^' | ||
359 | + re += c | ||
360 | + continue | ||
361 | + } | ||
362 | + | ||
363 | + // if we already have a stateChar, then it means | ||
364 | + // that there was something like ** or +? in there. | ||
365 | + // Handle the stateChar, then proceed with this one. | ||
366 | + self.debug('call clearStateChar %j', stateChar) | ||
367 | + clearStateChar() | ||
368 | + stateChar = c | ||
369 | + // if extglob is disabled, then +(asdf|foo) isn't a thing. | ||
370 | + // just clear the statechar *now*, rather than even diving into | ||
371 | + // the patternList stuff. | ||
372 | + if (options.noext) clearStateChar() | ||
373 | + continue | ||
374 | + | ||
375 | + case '(': | ||
376 | + if (inClass) { | ||
377 | + re += '(' | ||
378 | + continue | ||
379 | + } | ||
380 | + | ||
381 | + if (!stateChar) { | ||
382 | + re += '\\(' | ||
383 | + continue | ||
384 | + } | ||
385 | + | ||
386 | + patternListStack.push({ | ||
387 | + type: stateChar, | ||
388 | + start: i - 1, | ||
389 | + reStart: re.length, | ||
390 | + open: plTypes[stateChar].open, | ||
391 | + close: plTypes[stateChar].close | ||
392 | + }) | ||
393 | + // negation is (?:(?!js)[^/]*) | ||
394 | + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' | ||
395 | + this.debug('plType %j %j', stateChar, re) | ||
396 | + stateChar = false | ||
397 | + continue | ||
398 | + | ||
399 | + case ')': | ||
400 | + if (inClass || !patternListStack.length) { | ||
401 | + re += '\\)' | ||
402 | + continue | ||
403 | + } | ||
404 | + | ||
405 | + clearStateChar() | ||
406 | + hasMagic = true | ||
407 | + var pl = patternListStack.pop() | ||
408 | + // negation is (?:(?!js)[^/]*) | ||
409 | + // The others are (?:<pattern>)<type> | ||
410 | + re += pl.close | ||
411 | + if (pl.type === '!') { | ||
412 | + negativeLists.push(pl) | ||
413 | + } | ||
414 | + pl.reEnd = re.length | ||
415 | + continue | ||
416 | + | ||
417 | + case '|': | ||
418 | + if (inClass || !patternListStack.length || escaping) { | ||
419 | + re += '\\|' | ||
420 | + escaping = false | ||
421 | + continue | ||
422 | + } | ||
423 | + | ||
424 | + clearStateChar() | ||
425 | + re += '|' | ||
426 | + continue | ||
427 | + | ||
428 | + // these are mostly the same in regexp and glob | ||
429 | + case '[': | ||
430 | + // swallow any state-tracking char before the [ | ||
431 | + clearStateChar() | ||
432 | + | ||
433 | + if (inClass) { | ||
434 | + re += '\\' + c | ||
435 | + continue | ||
436 | + } | ||
437 | + | ||
438 | + inClass = true | ||
439 | + classStart = i | ||
440 | + reClassStart = re.length | ||
441 | + re += c | ||
442 | + continue | ||
443 | + | ||
444 | + case ']': | ||
445 | + // a right bracket shall lose its special | ||
446 | + // meaning and represent itself in | ||
447 | + // a bracket expression if it occurs | ||
448 | + // first in the list. -- POSIX.2 2.8.3.2 | ||
449 | + if (i === classStart + 1 || !inClass) { | ||
450 | + re += '\\' + c | ||
451 | + escaping = false | ||
452 | + continue | ||
453 | + } | ||
454 | + | ||
455 | + // handle the case where we left a class open. | ||
456 | + // "[z-a]" is valid, equivalent to "\[z-a\]" | ||
457 | + if (inClass) { | ||
458 | + // split where the last [ was, make sure we don't have | ||
459 | + // an invalid re. if so, re-walk the contents of the | ||
460 | + // would-be class to re-translate any characters that | ||
461 | + // were passed through as-is | ||
462 | + // TODO: It would probably be faster to determine this | ||
463 | + // without a try/catch and a new RegExp, but it's tricky | ||
464 | + // to do safely. For now, this is safe and works. | ||
465 | + var cs = pattern.substring(classStart + 1, i) | ||
466 | + try { | ||
467 | + RegExp('[' + cs + ']') | ||
468 | + } catch (er) { | ||
469 | + // not a valid class! | ||
470 | + var sp = this.parse(cs, SUBPARSE) | ||
471 | + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' | ||
472 | + hasMagic = hasMagic || sp[1] | ||
473 | + inClass = false | ||
474 | + continue | ||
475 | + } | ||
476 | + } | ||
477 | + | ||
478 | + // finish up the class. | ||
479 | + hasMagic = true | ||
480 | + inClass = false | ||
481 | + re += c | ||
482 | + continue | ||
483 | + | ||
484 | + default: | ||
485 | + // swallow any state char that wasn't consumed | ||
486 | + clearStateChar() | ||
487 | + | ||
488 | + if (escaping) { | ||
489 | + // no need | ||
490 | + escaping = false | ||
491 | + } else if (reSpecials[c] | ||
492 | + && !(c === '^' && inClass)) { | ||
493 | + re += '\\' | ||
494 | + } | ||
495 | + | ||
496 | + re += c | ||
497 | + | ||
498 | + } // switch | ||
499 | + } // for | ||
500 | + | ||
501 | + // handle the case where we left a class open. | ||
502 | + // "[abc" is valid, equivalent to "\[abc" | ||
503 | + if (inClass) { | ||
504 | + // split where the last [ was, and escape it | ||
505 | + // this is a huge pita. We now have to re-walk | ||
506 | + // the contents of the would-be class to re-translate | ||
507 | + // any characters that were passed through as-is | ||
508 | + cs = pattern.substr(classStart + 1) | ||
509 | + sp = this.parse(cs, SUBPARSE) | ||
510 | + re = re.substr(0, reClassStart) + '\\[' + sp[0] | ||
511 | + hasMagic = hasMagic || sp[1] | ||
512 | + } | ||
513 | + | ||
514 | + // handle the case where we had a +( thing at the *end* | ||
515 | + // of the pattern. | ||
516 | + // each pattern list stack adds 3 chars, and we need to go through | ||
517 | + // and escape any | chars that were passed through as-is for the regexp. | ||
518 | + // Go through and escape them, taking care not to double-escape any | ||
519 | + // | chars that were already escaped. | ||
520 | + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { | ||
521 | + var tail = re.slice(pl.reStart + pl.open.length) | ||
522 | + this.debug('setting tail', re, pl) | ||
523 | + // maybe some even number of \, then maybe 1 \, followed by a | | ||
524 | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { | ||
525 | + if (!$2) { | ||
526 | + // the | isn't already escaped, so escape it. | ||
527 | + $2 = '\\' | ||
528 | + } | ||
529 | + | ||
530 | + // need to escape all those slashes *again*, without escaping the | ||
531 | + // one that we need for escaping the | character. As it works out, | ||
532 | + // escaping an even number of slashes can be done by simply repeating | ||
533 | + // it exactly after itself. That's why this trick works. | ||
534 | + // | ||
535 | + // I am sorry that you have to see this. | ||
536 | + return $1 + $1 + $2 + '|' | ||
537 | + }) | ||
538 | + | ||
539 | + this.debug('tail=%j\n %s', tail, tail, pl, re) | ||
540 | + var t = pl.type === '*' ? star | ||
541 | + : pl.type === '?' ? qmark | ||
542 | + : '\\' + pl.type | ||
543 | + | ||
544 | + hasMagic = true | ||
545 | + re = re.slice(0, pl.reStart) + t + '\\(' + tail | ||
546 | + } | ||
547 | + | ||
548 | + // handle trailing things that only matter at the very end. | ||
549 | + clearStateChar() | ||
550 | + if (escaping) { | ||
551 | + // trailing \\ | ||
552 | + re += '\\\\' | ||
553 | + } | ||
554 | + | ||
555 | + // only need to apply the nodot start if the re starts with | ||
556 | + // something that could conceivably capture a dot | ||
557 | + var addPatternStart = false | ||
558 | + switch (re.charAt(0)) { | ||
559 | + case '.': | ||
560 | + case '[': | ||
561 | + case '(': addPatternStart = true | ||
562 | + } | ||
563 | + | ||
564 | + // Hack to work around lack of negative lookbehind in JS | ||
565 | + // A pattern like: *.!(x).!(y|z) needs to ensure that a name | ||
566 | + // like 'a.xyz.yz' doesn't match. So, the first negative | ||
567 | + // lookahead, has to look ALL the way ahead, to the end of | ||
568 | + // the pattern. | ||
569 | + for (var n = negativeLists.length - 1; n > -1; n--) { | ||
570 | + var nl = negativeLists[n] | ||
571 | + | ||
572 | + var nlBefore = re.slice(0, nl.reStart) | ||
573 | + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) | ||
574 | + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) | ||
575 | + var nlAfter = re.slice(nl.reEnd) | ||
576 | + | ||
577 | + nlLast += nlAfter | ||
578 | + | ||
579 | + // Handle nested stuff like *(*.js|!(*.json)), where open parens | ||
580 | + // mean that we should *not* include the ) in the bit that is considered | ||
581 | + // "after" the negated section. | ||
582 | + var openParensBefore = nlBefore.split('(').length - 1 | ||
583 | + var cleanAfter = nlAfter | ||
584 | + for (i = 0; i < openParensBefore; i++) { | ||
585 | + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') | ||
586 | + } | ||
587 | + nlAfter = cleanAfter | ||
588 | + | ||
589 | + var dollar = '' | ||
590 | + if (nlAfter === '' && isSub !== SUBPARSE) { | ||
591 | + dollar = '$' | ||
592 | + } | ||
593 | + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast | ||
594 | + re = newRe | ||
595 | + } | ||
596 | + | ||
597 | + // if the re is not "" at this point, then we need to make sure | ||
598 | + // it doesn't match against an empty path part. | ||
599 | + // Otherwise a/* will match a/, which it should not. | ||
600 | + if (re !== '' && hasMagic) { | ||
601 | + re = '(?=.)' + re | ||
602 | + } | ||
603 | + | ||
604 | + if (addPatternStart) { | ||
605 | + re = patternStart + re | ||
606 | + } | ||
607 | + | ||
608 | + // parsing just a piece of a larger pattern. | ||
609 | + if (isSub === SUBPARSE) { | ||
610 | + return [re, hasMagic] | ||
611 | + } | ||
612 | + | ||
613 | + // skip the regexp for non-magical patterns | ||
614 | + // unescape anything in it, though, so that it'll be | ||
615 | + // an exact match against a file etc. | ||
616 | + if (!hasMagic) { | ||
617 | + return globUnescape(pattern) | ||
618 | + } | ||
619 | + | ||
620 | + var flags = options.nocase ? 'i' : '' | ||
621 | + try { | ||
622 | + var regExp = new RegExp('^' + re + '$', flags) | ||
623 | + } catch (er) { | ||
624 | + // If it was an invalid regular expression, then it can't match | ||
625 | + // anything. This trick looks for a character after the end of | ||
626 | + // the string, which is of course impossible, except in multi-line | ||
627 | + // mode, but it's not a /m regex. | ||
628 | + return new RegExp('$.') | ||
629 | + } | ||
630 | + | ||
631 | + regExp._glob = pattern | ||
632 | + regExp._src = re | ||
633 | + | ||
634 | + return regExp | ||
635 | +} | ||
636 | + | ||
637 | +minimatch.makeRe = function (pattern, options) { | ||
638 | + return new Minimatch(pattern, options || {}).makeRe() | ||
639 | +} | ||
640 | + | ||
641 | +Minimatch.prototype.makeRe = makeRe | ||
642 | +function makeRe () { | ||
643 | + if (this.regexp || this.regexp === false) return this.regexp | ||
644 | + | ||
645 | + // at this point, this.set is a 2d array of partial | ||
646 | + // pattern strings, or "**". | ||
647 | + // | ||
648 | + // It's better to use .match(). This function shouldn't | ||
649 | + // be used, really, but it's pretty convenient sometimes, | ||
650 | + // when you just want to work with a regex. | ||
651 | + var set = this.set | ||
652 | + | ||
653 | + if (!set.length) { | ||
654 | + this.regexp = false | ||
655 | + return this.regexp | ||
656 | + } | ||
657 | + var options = this.options | ||
658 | + | ||
659 | + var twoStar = options.noglobstar ? star | ||
660 | + : options.dot ? twoStarDot | ||
661 | + : twoStarNoDot | ||
662 | + var flags = options.nocase ? 'i' : '' | ||
663 | + | ||
664 | + var re = set.map(function (pattern) { | ||
665 | + return pattern.map(function (p) { | ||
666 | + return (p === GLOBSTAR) ? twoStar | ||
667 | + : (typeof p === 'string') ? regExpEscape(p) | ||
668 | + : p._src | ||
669 | + }).join('\\\/') | ||
670 | + }).join('|') | ||
671 | + | ||
672 | + // must match entire pattern | ||
673 | + // ending in a * or ** will make it less strict. | ||
674 | + re = '^(?:' + re + ')$' | ||
675 | + | ||
676 | + // can match anything, as long as it's not this. | ||
677 | + if (this.negate) re = '^(?!' + re + ').*$' | ||
678 | + | ||
679 | + try { | ||
680 | + this.regexp = new RegExp(re, flags) | ||
681 | + } catch (ex) { | ||
682 | + this.regexp = false | ||
683 | + } | ||
684 | + return this.regexp | ||
685 | +} | ||
686 | + | ||
687 | +minimatch.match = function (list, pattern, options) { | ||
688 | + options = options || {} | ||
689 | + var mm = new Minimatch(pattern, options) | ||
690 | + list = list.filter(function (f) { | ||
691 | + return mm.match(f) | ||
692 | + }) | ||
693 | + if (mm.options.nonull && !list.length) { | ||
694 | + list.push(pattern) | ||
695 | + } | ||
696 | + return list | ||
697 | +} | ||
698 | + | ||
699 | +Minimatch.prototype.match = match | ||
700 | +function match (f, partial) { | ||
701 | + this.debug('match', f, this.pattern) | ||
702 | + // short-circuit in the case of busted things. | ||
703 | + // comments, etc. | ||
704 | + if (this.comment) return false | ||
705 | + if (this.empty) return f === '' | ||
706 | + | ||
707 | + if (f === '/' && partial) return true | ||
708 | + | ||
709 | + var options = this.options | ||
710 | + | ||
711 | + // windows: need to use /, not \ | ||
712 | + if (path.sep !== '/') { | ||
713 | + f = f.split(path.sep).join('/') | ||
714 | + } | ||
715 | + | ||
716 | + // treat the test path as a set of pathparts. | ||
717 | + f = f.split(slashSplit) | ||
718 | + this.debug(this.pattern, 'split', f) | ||
719 | + | ||
720 | + // just ONE of the pattern sets in this.set needs to match | ||
721 | + // in order for it to be valid. If negating, then just one | ||
722 | + // match means that we have failed. | ||
723 | + // Either way, return on the first hit. | ||
724 | + | ||
725 | + var set = this.set | ||
726 | + this.debug(this.pattern, 'set', set) | ||
727 | + | ||
728 | + // Find the basename of the path by looking for the last non-empty segment | ||
729 | + var filename | ||
730 | + var i | ||
731 | + for (i = f.length - 1; i >= 0; i--) { | ||
732 | + filename = f[i] | ||
733 | + if (filename) break | ||
734 | + } | ||
735 | + | ||
736 | + for (i = 0; i < set.length; i++) { | ||
737 | + var pattern = set[i] | ||
738 | + var file = f | ||
739 | + if (options.matchBase && pattern.length === 1) { | ||
740 | + file = [filename] | ||
741 | + } | ||
742 | + var hit = this.matchOne(file, pattern, partial) | ||
743 | + if (hit) { | ||
744 | + if (options.flipNegate) return true | ||
745 | + return !this.negate | ||
746 | + } | ||
747 | + } | ||
748 | + | ||
749 | + // didn't get any hits. this is success if it's a negative | ||
750 | + // pattern, failure otherwise. | ||
751 | + if (options.flipNegate) return false | ||
752 | + return this.negate | ||
753 | +} | ||
754 | + | ||
755 | +// set partial to true to test if, for example, | ||
756 | +// "/a/b" matches the start of "/*/b/*/d" | ||
757 | +// Partial means, if you run out of file before you run | ||
758 | +// out of pattern, then that's fine, as long as all | ||
759 | +// the parts match. | ||
760 | +Minimatch.prototype.matchOne = function (file, pattern, partial) { | ||
761 | + var options = this.options | ||
762 | + | ||
763 | + this.debug('matchOne', | ||
764 | + { 'this': this, file: file, pattern: pattern }) | ||
765 | + | ||
766 | + this.debug('matchOne', file.length, pattern.length) | ||
767 | + | ||
768 | + for (var fi = 0, | ||
769 | + pi = 0, | ||
770 | + fl = file.length, | ||
771 | + pl = pattern.length | ||
772 | + ; (fi < fl) && (pi < pl) | ||
773 | + ; fi++, pi++) { | ||
774 | + this.debug('matchOne loop') | ||
775 | + var p = pattern[pi] | ||
776 | + var f = file[fi] | ||
777 | + | ||
778 | + this.debug(pattern, p, f) | ||
779 | + | ||
780 | + // should be impossible. | ||
781 | + // some invalid regexp stuff in the set. | ||
782 | + if (p === false) return false | ||
783 | + | ||
784 | + if (p === GLOBSTAR) { | ||
785 | + this.debug('GLOBSTAR', [pattern, p, f]) | ||
786 | + | ||
787 | + // "**" | ||
788 | + // a/**/b/**/c would match the following: | ||
789 | + // a/b/x/y/z/c | ||
790 | + // a/x/y/z/b/c | ||
791 | + // a/b/x/b/x/c | ||
792 | + // a/b/c | ||
793 | + // To do this, take the rest of the pattern after | ||
794 | + // the **, and see if it would match the file remainder. | ||
795 | + // If so, return success. | ||
796 | + // If not, the ** "swallows" a segment, and try again. | ||
797 | + // This is recursively awful. | ||
798 | + // | ||
799 | + // a/**/b/**/c matching a/b/x/y/z/c | ||
800 | + // - a matches a | ||
801 | + // - doublestar | ||
802 | + // - matchOne(b/x/y/z/c, b/**/c) | ||
803 | + // - b matches b | ||
804 | + // - doublestar | ||
805 | + // - matchOne(x/y/z/c, c) -> no | ||
806 | + // - matchOne(y/z/c, c) -> no | ||
807 | + // - matchOne(z/c, c) -> no | ||
808 | + // - matchOne(c, c) yes, hit | ||
809 | + var fr = fi | ||
810 | + var pr = pi + 1 | ||
811 | + if (pr === pl) { | ||
812 | + this.debug('** at the end') | ||
813 | + // a ** at the end will just swallow the rest. | ||
814 | + // We have found a match. | ||
815 | + // however, it will not swallow /.x, unless | ||
816 | + // options.dot is set. | ||
817 | + // . and .. are *never* matched by **, for explosively | ||
818 | + // exponential reasons. | ||
819 | + for (; fi < fl; fi++) { | ||
820 | + if (file[fi] === '.' || file[fi] === '..' || | ||
821 | + (!options.dot && file[fi].charAt(0) === '.')) return false | ||
822 | + } | ||
823 | + return true | ||
824 | + } | ||
825 | + | ||
826 | + // ok, let's see if we can swallow whatever we can. | ||
827 | + while (fr < fl) { | ||
828 | + var swallowee = file[fr] | ||
829 | + | ||
830 | + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) | ||
831 | + | ||
832 | + // XXX remove this slice. Just pass the start index. | ||
833 | + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { | ||
834 | + this.debug('globstar found match!', fr, fl, swallowee) | ||
835 | + // found a match. | ||
836 | + return true | ||
837 | + } else { | ||
838 | + // can't swallow "." or ".." ever. | ||
839 | + // can only swallow ".foo" when explicitly asked. | ||
840 | + if (swallowee === '.' || swallowee === '..' || | ||
841 | + (!options.dot && swallowee.charAt(0) === '.')) { | ||
842 | + this.debug('dot detected!', file, fr, pattern, pr) | ||
843 | + break | ||
844 | + } | ||
845 | + | ||
846 | + // ** swallows a segment, and continue. | ||
847 | + this.debug('globstar swallow a segment, and continue') | ||
848 | + fr++ | ||
849 | + } | ||
850 | + } | ||
851 | + | ||
852 | + // no match was found. | ||
853 | + // However, in partial mode, we can't say this is necessarily over. | ||
854 | + // If there's more *pattern* left, then | ||
855 | + if (partial) { | ||
856 | + // ran out of file | ||
857 | + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) | ||
858 | + if (fr === fl) return true | ||
859 | + } | ||
860 | + return false | ||
861 | + } | ||
862 | + | ||
863 | + // something other than ** | ||
864 | + // non-magic patterns just have to match exactly | ||
865 | + // patterns with magic have been turned into regexps. | ||
866 | + var hit | ||
867 | + if (typeof p === 'string') { | ||
868 | + if (options.nocase) { | ||
869 | + hit = f.toLowerCase() === p.toLowerCase() | ||
870 | + } else { | ||
871 | + hit = f === p | ||
872 | + } | ||
873 | + this.debug('string match', p, f, hit) | ||
874 | + } else { | ||
875 | + hit = f.match(p) | ||
876 | + this.debug('pattern match', p, f, hit) | ||
877 | + } | ||
878 | + | ||
879 | + if (!hit) return false | ||
880 | + } | ||
881 | + | ||
882 | + // Note: ending in / means that we'll get a final "" | ||
883 | + // at the end of the pattern. This can only match a | ||
884 | + // corresponding "" at the end of the file. | ||
885 | + // If the file ends in /, then it can only match a | ||
886 | + // a pattern that ends in /, unless the pattern just | ||
887 | + // doesn't have any more for it. But, a/b/ should *not* | ||
888 | + // match "a/b/*", even though "" matches against the | ||
889 | + // [^/]*? pattern, except in partial mode, where it might | ||
890 | + // simply not be reached yet. | ||
891 | + // However, a/b/ should still satisfy a/* | ||
892 | + | ||
893 | + // now either we fell off the end of the pattern, or we're done. | ||
894 | + if (fi === fl && pi === pl) { | ||
895 | + // ran out of pattern and filename at the same time. | ||
896 | + // an exact hit! | ||
897 | + return true | ||
898 | + } else if (fi === fl) { | ||
899 | + // ran out of file, but still had pattern left. | ||
900 | + // this is ok if we're doing the match as part of | ||
901 | + // a glob fs traversal. | ||
902 | + return partial | ||
903 | + } else if (pi === pl) { | ||
904 | + // ran out of pattern, still have file left. | ||
905 | + // this is only acceptable if we're on the very last | ||
906 | + // empty segment of a file with a trailing slash. | ||
907 | + // a/* should match a/b/ | ||
908 | + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') | ||
909 | + return emptyFileEnd | ||
910 | + } | ||
911 | + | ||
912 | + // should be unreachable. | ||
913 | + throw new Error('wtf?') | ||
914 | +} | ||
915 | + | ||
916 | +// replace stuff like \* with * | ||
917 | +function globUnescape (s) { | ||
918 | + return s.replace(/\\(.)/g, '$1') | ||
919 | +} | ||
920 | + | ||
921 | +function regExpEscape (s) { | ||
922 | + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') | ||
923 | +} |
node_modules/minimatch/package.json
0 → 100644
1 | +{ | ||
2 | + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", | ||
3 | + "name": "minimatch", | ||
4 | + "description": "a glob matcher in javascript", | ||
5 | + "version": "3.0.4", | ||
6 | + "repository": { | ||
7 | + "type": "git", | ||
8 | + "url": "git://github.com/isaacs/minimatch.git" | ||
9 | + }, | ||
10 | + "main": "minimatch.js", | ||
11 | + "scripts": { | ||
12 | + "test": "tap test/*.js --cov", | ||
13 | + "preversion": "npm test", | ||
14 | + "postversion": "npm publish", | ||
15 | + "postpublish": "git push origin --all; git push origin --tags" | ||
16 | + }, | ||
17 | + "engines": { | ||
18 | + "node": "*" | ||
19 | + }, | ||
20 | + "dependencies": { | ||
21 | + "brace-expansion": "^1.1.7" | ||
22 | + }, | ||
23 | + "devDependencies": { | ||
24 | + "tap": "^10.3.2" | ||
25 | + }, | ||
26 | + "license": "ISC", | ||
27 | + "files": [ | ||
28 | + "minimatch.js" | ||
29 | + ] | ||
30 | +} |
node_modules/supports-color/browser.js
0 → 100644
node_modules/supports-color/index.js
0 → 100644
1 | +'use strict'; | ||
2 | +const os = require('os'); | ||
3 | +const hasFlag = require('has-flag'); | ||
4 | + | ||
5 | +const env = process.env; | ||
6 | + | ||
7 | +let forceColor; | ||
8 | +if (hasFlag('no-color') || | ||
9 | + hasFlag('no-colors') || | ||
10 | + hasFlag('color=false')) { | ||
11 | + forceColor = false; | ||
12 | +} else if (hasFlag('color') || | ||
13 | + hasFlag('colors') || | ||
14 | + hasFlag('color=true') || | ||
15 | + hasFlag('color=always')) { | ||
16 | + forceColor = true; | ||
17 | +} | ||
18 | +if ('FORCE_COLOR' in env) { | ||
19 | + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; | ||
20 | +} | ||
21 | + | ||
22 | +function translateLevel(level) { | ||
23 | + if (level === 0) { | ||
24 | + return false; | ||
25 | + } | ||
26 | + | ||
27 | + return { | ||
28 | + level, | ||
29 | + hasBasic: true, | ||
30 | + has256: level >= 2, | ||
31 | + has16m: level >= 3 | ||
32 | + }; | ||
33 | +} | ||
34 | + | ||
35 | +function supportsColor(stream) { | ||
36 | + if (forceColor === false) { | ||
37 | + return 0; | ||
38 | + } | ||
39 | + | ||
40 | + if (hasFlag('color=16m') || | ||
41 | + hasFlag('color=full') || | ||
42 | + hasFlag('color=truecolor')) { | ||
43 | + return 3; | ||
44 | + } | ||
45 | + | ||
46 | + if (hasFlag('color=256')) { | ||
47 | + return 2; | ||
48 | + } | ||
49 | + | ||
50 | + if (stream && !stream.isTTY && forceColor !== true) { | ||
51 | + return 0; | ||
52 | + } | ||
53 | + | ||
54 | + const min = forceColor ? 1 : 0; | ||
55 | + | ||
56 | + if (process.platform === 'win32') { | ||
57 | + // Node.js 7.5.0 is the first version of Node.js to include a patch to | ||
58 | + // libuv that enables 256 color output on Windows. Anything earlier and it | ||
59 | + // won't work. However, here we target Node.js 8 at minimum as it is an LTS | ||
60 | + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows | ||
61 | + // release that supports 256 colors. Windows 10 build 14931 is the first release | ||
62 | + // that supports 16m/TrueColor. | ||
63 | + const osRelease = os.release().split('.'); | ||
64 | + if ( | ||
65 | + Number(process.versions.node.split('.')[0]) >= 8 && | ||
66 | + Number(osRelease[0]) >= 10 && | ||
67 | + Number(osRelease[2]) >= 10586 | ||
68 | + ) { | ||
69 | + return Number(osRelease[2]) >= 14931 ? 3 : 2; | ||
70 | + } | ||
71 | + | ||
72 | + return 1; | ||
73 | + } | ||
74 | + | ||
75 | + if ('CI' in env) { | ||
76 | + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { | ||
77 | + return 1; | ||
78 | + } | ||
79 | + | ||
80 | + return min; | ||
81 | + } | ||
82 | + | ||
83 | + if ('TEAMCITY_VERSION' in env) { | ||
84 | + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; | ||
85 | + } | ||
86 | + | ||
87 | + if (env.COLORTERM === 'truecolor') { | ||
88 | + return 3; | ||
89 | + } | ||
90 | + | ||
91 | + if ('TERM_PROGRAM' in env) { | ||
92 | + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); | ||
93 | + | ||
94 | + switch (env.TERM_PROGRAM) { | ||
95 | + case 'iTerm.app': | ||
96 | + return version >= 3 ? 3 : 2; | ||
97 | + case 'Apple_Terminal': | ||
98 | + return 2; | ||
99 | + // No default | ||
100 | + } | ||
101 | + } | ||
102 | + | ||
103 | + if (/-256(color)?$/i.test(env.TERM)) { | ||
104 | + return 2; | ||
105 | + } | ||
106 | + | ||
107 | + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { | ||
108 | + return 1; | ||
109 | + } | ||
110 | + | ||
111 | + if ('COLORTERM' in env) { | ||
112 | + return 1; | ||
113 | + } | ||
114 | + | ||
115 | + if (env.TERM === 'dumb') { | ||
116 | + return min; | ||
117 | + } | ||
118 | + | ||
119 | + return min; | ||
120 | +} | ||
121 | + | ||
122 | +function getSupportLevel(stream) { | ||
123 | + const level = supportsColor(stream); | ||
124 | + return translateLevel(level); | ||
125 | +} | ||
126 | + | ||
127 | +module.exports = { | ||
128 | + supportsColor: getSupportLevel, | ||
129 | + stdout: getSupportLevel(process.stdout), | ||
130 | + stderr: getSupportLevel(process.stderr) | ||
131 | +}; |
node_modules/supports-color/license
0 → 100644
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
6 | + | ||
7 | +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
8 | + | ||
9 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
node_modules/supports-color/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "supports-color", | ||
3 | + "version": "5.5.0", | ||
4 | + "description": "Detect whether a terminal supports color", | ||
5 | + "license": "MIT", | ||
6 | + "repository": "chalk/supports-color", | ||
7 | + "author": { | ||
8 | + "name": "Sindre Sorhus", | ||
9 | + "email": "sindresorhus@gmail.com", | ||
10 | + "url": "sindresorhus.com" | ||
11 | + }, | ||
12 | + "engines": { | ||
13 | + "node": ">=4" | ||
14 | + }, | ||
15 | + "scripts": { | ||
16 | + "test": "xo && ava" | ||
17 | + }, | ||
18 | + "files": [ | ||
19 | + "index.js", | ||
20 | + "browser.js" | ||
21 | + ], | ||
22 | + "keywords": [ | ||
23 | + "color", | ||
24 | + "colour", | ||
25 | + "colors", | ||
26 | + "terminal", | ||
27 | + "console", | ||
28 | + "cli", | ||
29 | + "ansi", | ||
30 | + "styles", | ||
31 | + "tty", | ||
32 | + "rgb", | ||
33 | + "256", | ||
34 | + "shell", | ||
35 | + "xterm", | ||
36 | + "command-line", | ||
37 | + "support", | ||
38 | + "supports", | ||
39 | + "capability", | ||
40 | + "detect", | ||
41 | + "truecolor", | ||
42 | + "16m" | ||
43 | + ], | ||
44 | + "dependencies": { | ||
45 | + "has-flag": "^3.0.0" | ||
46 | + }, | ||
47 | + "devDependencies": { | ||
48 | + "ava": "^0.25.0", | ||
49 | + "import-fresh": "^2.0.0", | ||
50 | + "xo": "^0.20.0" | ||
51 | + }, | ||
52 | + "browser": "browser.js" | ||
53 | +} |
node_modules/supports-color/readme.md
0 → 100644
1 | +# supports-color [![Build Status](https://travis-ci.org/chalk/supports-color.svg?branch=master)](https://travis-ci.org/chalk/supports-color) | ||
2 | + | ||
3 | +> Detect whether a terminal supports color | ||
4 | + | ||
5 | + | ||
6 | +## Install | ||
7 | + | ||
8 | +``` | ||
9 | +$ npm install supports-color | ||
10 | +``` | ||
11 | + | ||
12 | + | ||
13 | +## Usage | ||
14 | + | ||
15 | +```js | ||
16 | +const supportsColor = require('supports-color'); | ||
17 | + | ||
18 | +if (supportsColor.stdout) { | ||
19 | + console.log('Terminal stdout supports color'); | ||
20 | +} | ||
21 | + | ||
22 | +if (supportsColor.stdout.has256) { | ||
23 | + console.log('Terminal stdout supports 256 colors'); | ||
24 | +} | ||
25 | + | ||
26 | +if (supportsColor.stderr.has16m) { | ||
27 | + console.log('Terminal stderr supports 16 million colors (truecolor)'); | ||
28 | +} | ||
29 | +``` | ||
30 | + | ||
31 | + | ||
32 | +## API | ||
33 | + | ||
34 | +Returns an `Object` with a `stdout` and `stderr` property for testing either streams. Each property is an `Object`, or `false` if color is not supported. | ||
35 | + | ||
36 | +The `stdout`/`stderr` objects specifies a level of support for color through a `.level` property and a corresponding flag: | ||
37 | + | ||
38 | +- `.level = 1` and `.hasBasic = true`: Basic color support (16 colors) | ||
39 | +- `.level = 2` and `.has256 = true`: 256 color support | ||
40 | +- `.level = 3` and `.has16m = true`: Truecolor support (16 million colors) | ||
41 | + | ||
42 | + | ||
43 | +## Info | ||
44 | + | ||
45 | +It obeys the `--color` and `--no-color` CLI flags. | ||
46 | + | ||
47 | +Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. | ||
48 | + | ||
49 | +Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. | ||
50 | + | ||
51 | + | ||
52 | +## Related | ||
53 | + | ||
54 | +- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module | ||
55 | +- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right | ||
56 | + | ||
57 | + | ||
58 | +## Maintainers | ||
59 | + | ||
60 | +- [Sindre Sorhus](https://github.com/sindresorhus) | ||
61 | +- [Josh Junon](https://github.com/qix-) | ||
62 | + | ||
63 | + | ||
64 | +## License | ||
65 | + | ||
66 | +MIT |
... | @@ -10,6 +10,7 @@ | ... | @@ -10,6 +10,7 @@ |
10 | "license": "ISC", | 10 | "license": "ISC", |
11 | "dependencies": { | 11 | "dependencies": { |
12 | "body-parser": "^1.19.0", | 12 | "body-parser": "^1.19.0", |
13 | + "ejs": "^3.1.6", | ||
13 | "express": "^4.17.1", | 14 | "express": "^4.17.1", |
14 | "mongodb": "^3.6.4" | 15 | "mongodb": "^3.6.4" |
15 | } | 16 | } |
... | @@ -26,11 +27,32 @@ | ... | @@ -26,11 +27,32 @@ |
26 | "node": ">= 0.6" | 27 | "node": ">= 0.6" |
27 | } | 28 | } |
28 | }, | 29 | }, |
30 | + "node_modules/ansi-styles": { | ||
31 | + "version": "3.2.1", | ||
32 | + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", | ||
33 | + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", | ||
34 | + "dependencies": { | ||
35 | + "color-convert": "^1.9.0" | ||
36 | + }, | ||
37 | + "engines": { | ||
38 | + "node": ">=4" | ||
39 | + } | ||
40 | + }, | ||
29 | "node_modules/array-flatten": { | 41 | "node_modules/array-flatten": { |
30 | "version": "1.1.1", | 42 | "version": "1.1.1", |
31 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", | 43 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", |
32 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" | 44 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" |
33 | }, | 45 | }, |
46 | + "node_modules/async": { | ||
47 | + "version": "0.9.2", | ||
48 | + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", | ||
49 | + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" | ||
50 | + }, | ||
51 | + "node_modules/balanced-match": { | ||
52 | + "version": "1.0.2", | ||
53 | + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | ||
54 | + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" | ||
55 | + }, | ||
34 | "node_modules/bl": { | 56 | "node_modules/bl": { |
35 | "version": "2.2.1", | 57 | "version": "2.2.1", |
36 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", | 58 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", |
... | @@ -60,6 +82,15 @@ | ... | @@ -60,6 +82,15 @@ |
60 | "node": ">= 0.8" | 82 | "node": ">= 0.8" |
61 | } | 83 | } |
62 | }, | 84 | }, |
85 | + "node_modules/brace-expansion": { | ||
86 | + "version": "1.1.11", | ||
87 | + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||
88 | + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | ||
89 | + "dependencies": { | ||
90 | + "balanced-match": "^1.0.0", | ||
91 | + "concat-map": "0.0.1" | ||
92 | + } | ||
93 | + }, | ||
63 | "node_modules/bson": { | 94 | "node_modules/bson": { |
64 | "version": "1.1.6", | 95 | "version": "1.1.6", |
65 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", | 96 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", |
... | @@ -76,6 +107,37 @@ | ... | @@ -76,6 +107,37 @@ |
76 | "node": ">= 0.8" | 107 | "node": ">= 0.8" |
77 | } | 108 | } |
78 | }, | 109 | }, |
110 | + "node_modules/chalk": { | ||
111 | + "version": "2.4.2", | ||
112 | + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", | ||
113 | + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", | ||
114 | + "dependencies": { | ||
115 | + "ansi-styles": "^3.2.1", | ||
116 | + "escape-string-regexp": "^1.0.5", | ||
117 | + "supports-color": "^5.3.0" | ||
118 | + }, | ||
119 | + "engines": { | ||
120 | + "node": ">=4" | ||
121 | + } | ||
122 | + }, | ||
123 | + "node_modules/color-convert": { | ||
124 | + "version": "1.9.3", | ||
125 | + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", | ||
126 | + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", | ||
127 | + "dependencies": { | ||
128 | + "color-name": "1.1.3" | ||
129 | + } | ||
130 | + }, | ||
131 | + "node_modules/color-name": { | ||
132 | + "version": "1.1.3", | ||
133 | + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", | ||
134 | + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" | ||
135 | + }, | ||
136 | + "node_modules/concat-map": { | ||
137 | + "version": "0.0.1", | ||
138 | + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||
139 | + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" | ||
140 | + }, | ||
79 | "node_modules/content-disposition": { | 141 | "node_modules/content-disposition": { |
80 | "version": "0.5.3", | 142 | "version": "0.5.3", |
81 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", | 143 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", |
... | @@ -147,6 +209,20 @@ | ... | @@ -147,6 +209,20 @@ |
147 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | 209 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
148 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" | 210 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" |
149 | }, | 211 | }, |
212 | + "node_modules/ejs": { | ||
213 | + "version": "3.1.6", | ||
214 | + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", | ||
215 | + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", | ||
216 | + "dependencies": { | ||
217 | + "jake": "^10.6.1" | ||
218 | + }, | ||
219 | + "bin": { | ||
220 | + "ejs": "bin/cli.js" | ||
221 | + }, | ||
222 | + "engines": { | ||
223 | + "node": ">=0.10.0" | ||
224 | + } | ||
225 | + }, | ||
150 | "node_modules/encodeurl": { | 226 | "node_modules/encodeurl": { |
151 | "version": "1.0.2", | 227 | "version": "1.0.2", |
152 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", | 228 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", |
... | @@ -160,6 +236,14 @@ | ... | @@ -160,6 +236,14 @@ |
160 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", | 236 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", |
161 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" | 237 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" |
162 | }, | 238 | }, |
239 | + "node_modules/escape-string-regexp": { | ||
240 | + "version": "1.0.5", | ||
241 | + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||
242 | + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", | ||
243 | + "engines": { | ||
244 | + "node": ">=0.8.0" | ||
245 | + } | ||
246 | + }, | ||
163 | "node_modules/etag": { | 247 | "node_modules/etag": { |
164 | "version": "1.8.1", | 248 | "version": "1.8.1", |
165 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", | 249 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", |
... | @@ -208,6 +292,14 @@ | ... | @@ -208,6 +292,14 @@ |
208 | "node": ">= 0.10.0" | 292 | "node": ">= 0.10.0" |
209 | } | 293 | } |
210 | }, | 294 | }, |
295 | + "node_modules/filelist": { | ||
296 | + "version": "1.0.2", | ||
297 | + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", | ||
298 | + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", | ||
299 | + "dependencies": { | ||
300 | + "minimatch": "^3.0.4" | ||
301 | + } | ||
302 | + }, | ||
211 | "node_modules/finalhandler": { | 303 | "node_modules/finalhandler": { |
212 | "version": "1.1.2", | 304 | "version": "1.1.2", |
213 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", | 305 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", |
... | @@ -241,6 +333,14 @@ | ... | @@ -241,6 +333,14 @@ |
241 | "node": ">= 0.6" | 333 | "node": ">= 0.6" |
242 | } | 334 | } |
243 | }, | 335 | }, |
336 | + "node_modules/has-flag": { | ||
337 | + "version": "3.0.0", | ||
338 | + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", | ||
339 | + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", | ||
340 | + "engines": { | ||
341 | + "node": ">=4" | ||
342 | + } | ||
343 | + }, | ||
244 | "node_modules/http-errors": { | 344 | "node_modules/http-errors": { |
245 | "version": "1.7.2", | 345 | "version": "1.7.2", |
246 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", | 346 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", |
... | @@ -285,6 +385,23 @@ | ... | @@ -285,6 +385,23 @@ |
285 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | 385 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", |
286 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" | 386 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" |
287 | }, | 387 | }, |
388 | + "node_modules/jake": { | ||
389 | + "version": "10.8.2", | ||
390 | + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", | ||
391 | + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", | ||
392 | + "dependencies": { | ||
393 | + "async": "0.9.x", | ||
394 | + "chalk": "^2.4.2", | ||
395 | + "filelist": "^1.0.1", | ||
396 | + "minimatch": "^3.0.4" | ||
397 | + }, | ||
398 | + "bin": { | ||
399 | + "jake": "bin/cli.js" | ||
400 | + }, | ||
401 | + "engines": { | ||
402 | + "node": "*" | ||
403 | + } | ||
404 | + }, | ||
288 | "node_modules/media-typer": { | 405 | "node_modules/media-typer": { |
289 | "version": "0.3.0", | 406 | "version": "0.3.0", |
290 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", | 407 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", |
... | @@ -342,6 +459,17 @@ | ... | @@ -342,6 +459,17 @@ |
342 | "node": ">= 0.6" | 459 | "node": ">= 0.6" |
343 | } | 460 | } |
344 | }, | 461 | }, |
462 | + "node_modules/minimatch": { | ||
463 | + "version": "3.0.4", | ||
464 | + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | ||
465 | + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", | ||
466 | + "dependencies": { | ||
467 | + "brace-expansion": "^1.1.7" | ||
468 | + }, | ||
469 | + "engines": { | ||
470 | + "node": "*" | ||
471 | + } | ||
472 | + }, | ||
345 | "node_modules/mongodb": { | 473 | "node_modules/mongodb": { |
346 | "version": "3.6.4", | 474 | "version": "3.6.4", |
347 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", | 475 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", |
... | @@ -597,6 +725,17 @@ | ... | @@ -597,6 +725,17 @@ |
597 | "safe-buffer": "~5.1.0" | 725 | "safe-buffer": "~5.1.0" |
598 | } | 726 | } |
599 | }, | 727 | }, |
728 | + "node_modules/supports-color": { | ||
729 | + "version": "5.5.0", | ||
730 | + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", | ||
731 | + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", | ||
732 | + "dependencies": { | ||
733 | + "has-flag": "^3.0.0" | ||
734 | + }, | ||
735 | + "engines": { | ||
736 | + "node": ">=4" | ||
737 | + } | ||
738 | + }, | ||
600 | "node_modules/toidentifier": { | 739 | "node_modules/toidentifier": { |
601 | "version": "1.0.0", | 740 | "version": "1.0.0", |
602 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", | 741 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", |
... | @@ -657,11 +796,29 @@ | ... | @@ -657,11 +796,29 @@ |
657 | "negotiator": "0.6.2" | 796 | "negotiator": "0.6.2" |
658 | } | 797 | } |
659 | }, | 798 | }, |
799 | + "ansi-styles": { | ||
800 | + "version": "3.2.1", | ||
801 | + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", | ||
802 | + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", | ||
803 | + "requires": { | ||
804 | + "color-convert": "^1.9.0" | ||
805 | + } | ||
806 | + }, | ||
660 | "array-flatten": { | 807 | "array-flatten": { |
661 | "version": "1.1.1", | 808 | "version": "1.1.1", |
662 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", | 809 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", |
663 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" | 810 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" |
664 | }, | 811 | }, |
812 | + "async": { | ||
813 | + "version": "0.9.2", | ||
814 | + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", | ||
815 | + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" | ||
816 | + }, | ||
817 | + "balanced-match": { | ||
818 | + "version": "1.0.2", | ||
819 | + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | ||
820 | + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" | ||
821 | + }, | ||
665 | "bl": { | 822 | "bl": { |
666 | "version": "2.2.1", | 823 | "version": "2.2.1", |
667 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", | 824 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", |
... | @@ -688,6 +845,15 @@ | ... | @@ -688,6 +845,15 @@ |
688 | "type-is": "~1.6.17" | 845 | "type-is": "~1.6.17" |
689 | } | 846 | } |
690 | }, | 847 | }, |
848 | + "brace-expansion": { | ||
849 | + "version": "1.1.11", | ||
850 | + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||
851 | + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | ||
852 | + "requires": { | ||
853 | + "balanced-match": "^1.0.0", | ||
854 | + "concat-map": "0.0.1" | ||
855 | + } | ||
856 | + }, | ||
691 | "bson": { | 857 | "bson": { |
692 | "version": "1.1.6", | 858 | "version": "1.1.6", |
693 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", | 859 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", |
... | @@ -698,6 +864,34 @@ | ... | @@ -698,6 +864,34 @@ |
698 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", | 864 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", |
699 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" | 865 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" |
700 | }, | 866 | }, |
867 | + "chalk": { | ||
868 | + "version": "2.4.2", | ||
869 | + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", | ||
870 | + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", | ||
871 | + "requires": { | ||
872 | + "ansi-styles": "^3.2.1", | ||
873 | + "escape-string-regexp": "^1.0.5", | ||
874 | + "supports-color": "^5.3.0" | ||
875 | + } | ||
876 | + }, | ||
877 | + "color-convert": { | ||
878 | + "version": "1.9.3", | ||
879 | + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", | ||
880 | + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", | ||
881 | + "requires": { | ||
882 | + "color-name": "1.1.3" | ||
883 | + } | ||
884 | + }, | ||
885 | + "color-name": { | ||
886 | + "version": "1.1.3", | ||
887 | + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", | ||
888 | + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" | ||
889 | + }, | ||
890 | + "concat-map": { | ||
891 | + "version": "0.0.1", | ||
892 | + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||
893 | + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" | ||
894 | + }, | ||
701 | "content-disposition": { | 895 | "content-disposition": { |
702 | "version": "0.5.3", | 896 | "version": "0.5.3", |
703 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", | 897 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", |
... | @@ -754,6 +948,14 @@ | ... | @@ -754,6 +948,14 @@ |
754 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", | 948 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
755 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" | 949 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" |
756 | }, | 950 | }, |
951 | + "ejs": { | ||
952 | + "version": "3.1.6", | ||
953 | + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", | ||
954 | + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", | ||
955 | + "requires": { | ||
956 | + "jake": "^10.6.1" | ||
957 | + } | ||
958 | + }, | ||
757 | "encodeurl": { | 959 | "encodeurl": { |
758 | "version": "1.0.2", | 960 | "version": "1.0.2", |
759 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", | 961 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", |
... | @@ -764,6 +966,11 @@ | ... | @@ -764,6 +966,11 @@ |
764 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", | 966 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", |
765 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" | 967 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" |
766 | }, | 968 | }, |
969 | + "escape-string-regexp": { | ||
970 | + "version": "1.0.5", | ||
971 | + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||
972 | + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" | ||
973 | + }, | ||
767 | "etag": { | 974 | "etag": { |
768 | "version": "1.8.1", | 975 | "version": "1.8.1", |
769 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", | 976 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", |
... | @@ -806,6 +1013,14 @@ | ... | @@ -806,6 +1013,14 @@ |
806 | "vary": "~1.1.2" | 1013 | "vary": "~1.1.2" |
807 | } | 1014 | } |
808 | }, | 1015 | }, |
1016 | + "filelist": { | ||
1017 | + "version": "1.0.2", | ||
1018 | + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", | ||
1019 | + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", | ||
1020 | + "requires": { | ||
1021 | + "minimatch": "^3.0.4" | ||
1022 | + } | ||
1023 | + }, | ||
809 | "finalhandler": { | 1024 | "finalhandler": { |
810 | "version": "1.1.2", | 1025 | "version": "1.1.2", |
811 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", | 1026 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", |
... | @@ -830,6 +1045,11 @@ | ... | @@ -830,6 +1045,11 @@ |
830 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", | 1045 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", |
831 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" | 1046 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" |
832 | }, | 1047 | }, |
1048 | + "has-flag": { | ||
1049 | + "version": "3.0.0", | ||
1050 | + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", | ||
1051 | + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" | ||
1052 | + }, | ||
833 | "http-errors": { | 1053 | "http-errors": { |
834 | "version": "1.7.2", | 1054 | "version": "1.7.2", |
835 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", | 1055 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", |
... | @@ -865,6 +1085,17 @@ | ... | @@ -865,6 +1085,17 @@ |
865 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | 1085 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", |
866 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" | 1086 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" |
867 | }, | 1087 | }, |
1088 | + "jake": { | ||
1089 | + "version": "10.8.2", | ||
1090 | + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", | ||
1091 | + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", | ||
1092 | + "requires": { | ||
1093 | + "async": "0.9.x", | ||
1094 | + "chalk": "^2.4.2", | ||
1095 | + "filelist": "^1.0.1", | ||
1096 | + "minimatch": "^3.0.4" | ||
1097 | + } | ||
1098 | + }, | ||
868 | "media-typer": { | 1099 | "media-typer": { |
869 | "version": "0.3.0", | 1100 | "version": "0.3.0", |
870 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", | 1101 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", |
... | @@ -904,6 +1135,14 @@ | ... | @@ -904,6 +1135,14 @@ |
904 | "mime-db": "1.51.0" | 1135 | "mime-db": "1.51.0" |
905 | } | 1136 | } |
906 | }, | 1137 | }, |
1138 | + "minimatch": { | ||
1139 | + "version": "3.0.4", | ||
1140 | + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | ||
1141 | + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", | ||
1142 | + "requires": { | ||
1143 | + "brace-expansion": "^1.1.7" | ||
1144 | + } | ||
1145 | + }, | ||
907 | "mongodb": { | 1146 | "mongodb": { |
908 | "version": "3.6.4", | 1147 | "version": "3.6.4", |
909 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", | 1148 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", |
... | @@ -1097,6 +1336,14 @@ | ... | @@ -1097,6 +1336,14 @@ |
1097 | "safe-buffer": "~5.1.0" | 1336 | "safe-buffer": "~5.1.0" |
1098 | } | 1337 | } |
1099 | }, | 1338 | }, |
1339 | + "supports-color": { | ||
1340 | + "version": "5.5.0", | ||
1341 | + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", | ||
1342 | + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", | ||
1343 | + "requires": { | ||
1344 | + "has-flag": "^3.0.0" | ||
1345 | + } | ||
1346 | + }, | ||
1100 | "toidentifier": { | 1347 | "toidentifier": { |
1101 | "version": "1.0.0", | 1348 | "version": "1.0.0", |
1102 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", | 1349 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", | ... | ... |
... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
14 | "license": "ISC", | 14 | "license": "ISC", |
15 | "dependencies": { | 15 | "dependencies": { |
16 | "body-parser": "^1.19.0", | 16 | "body-parser": "^1.19.0", |
17 | + "ejs": "^3.1.6", | ||
17 | "express": "^4.17.1", | 18 | "express": "^4.17.1", |
18 | "mongodb": "^3.6.4" | 19 | "mongodb": "^3.6.4" |
19 | } | 20 | } | ... | ... |
... | @@ -2,6 +2,7 @@ const express = require('express'); | ... | @@ -2,6 +2,7 @@ const express = require('express'); |
2 | const app = express(); | 2 | const app = express(); |
3 | const bodyParser = require('body-parser') | 3 | const bodyParser = require('body-parser') |
4 | app.use(bodyParser.urlencoded({extended : true})); | 4 | app.use(bodyParser.urlencoded({extended : true})); |
5 | +app.set('view engine', 'ejs'); | ||
5 | 6 | ||
6 | var db; | 7 | var db; |
7 | const MongoClient = require('mongodb').MongoClient; | 8 | const MongoClient = require('mongodb').MongoClient; |
... | @@ -10,13 +11,8 @@ MongoClient.connect('mongodb+srv://admin:qwer1234@cluster0.m2pvs.mongodb.net/myF | ... | @@ -10,13 +11,8 @@ MongoClient.connect('mongodb+srv://admin:qwer1234@cluster0.m2pvs.mongodb.net/myF |
10 | if(에러){ | 11 | if(에러){ |
11 | return console.log(에러); | 12 | return console.log(에러); |
12 | } | 13 | } |
13 | - | ||
14 | db = clinet.db('todoapp'); | 14 | db = clinet.db('todoapp'); |
15 | 15 | ||
16 | - db.collection('post').insertOne({이름 : 'John', _id : 100}, function(에러, 결과){ | ||
17 | - console.log('저장완료') | ||
18 | - }); | ||
19 | - | ||
20 | app.listen(8080, function(){ | 16 | app.listen(8080, function(){ |
21 | console.log('listening on 8080') | 17 | console.log('listening on 8080') |
22 | }); | 18 | }); |
... | @@ -41,7 +37,11 @@ app.get('/write', function(요청, 응답){ | ... | @@ -41,7 +37,11 @@ app.get('/write', function(요청, 응답){ |
41 | 37 | ||
42 | app.post('/add', function(요청, 응답){ | 38 | app.post('/add', function(요청, 응답){ |
43 | 응답.send('전송완료'); | 39 | 응답.send('전송완료'); |
44 | - db.collection('post').insertOne({제목 : 요청.body.title, 날짜 : 요청.body.date ,_id : 500}, function(에러, 결과){ | 40 | + db.collection('post').insertOne({제목 : 요청.body.title, 날짜 : 요청.body.date}, function(에러, 결과){ |
45 | console.log('저장완료') | 41 | console.log('저장완료') |
46 | }); | 42 | }); |
47 | }); | 43 | }); |
44 | + | ||
45 | +app.get('/list',function(요청, 응답){ | ||
46 | + 응답.render('list.ejs'); | ||
47 | +}); | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
views/list.ejs
0 → 100644
1 | +<!doctype html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <!-- Required meta tags --> | ||
5 | + <meta charset="utf-8"> | ||
6 | + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
7 | + | ||
8 | + <!-- Bootstrap CSS --> | ||
9 | + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous"> | ||
10 | + | ||
11 | + | ||
12 | + </head> | ||
13 | + <body> | ||
14 | + | ||
15 | + <nav class="navbar navbar-expand-lg navbar-light bg-light"> | ||
16 | + <a class="navbar-brand" href="#">Todo App</a> | ||
17 | + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> | ||
18 | + <span class="navbar-toggler-icon"></span> | ||
19 | + </button> | ||
20 | + <div class="collapse navbar-collapse" id="navbarNav"> | ||
21 | + <ul class="navbar-nav"> | ||
22 | + <li class="nav-item active"> | ||
23 | + <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> | ||
24 | + </li> | ||
25 | + <li class="nav-item" | ||
26 | + <a class="nav-link" href="#">Write</a> | ||
27 | + </li> | ||
28 | + <li class="nav-item"> | ||
29 | + <a class="nav-link" href="#">임시</a> | ||
30 | + </li> | ||
31 | + </ul> | ||
32 | + </div> | ||
33 | + </nav> | ||
34 | + | ||
35 | + <!--서버에서 가져온 할 일 리스트--> | ||
36 | + <h4>할일 제목 : <%= %></h4> | ||
37 | + <p>할일 마감날짜 : ???</p> | ||
38 | + | ||
39 | + <!-- Optional JavaScript; choose one of the two! --> | ||
40 | + | ||
41 | + <!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) --> | ||
42 | + <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> | ||
43 | + <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script> | ||
44 | + | ||
45 | + <!-- Option 2: Separate Popper and Bootstrap JS --> | ||
46 | + <!-- | ||
47 | + <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> | ||
48 | + <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script> | ||
49 | + <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script> | ||
50 | + --> | ||
51 | + </body> | ||
52 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment