├── .editorconfig ├── .gitignore ├── .npmignore ├── .nvmrc ├── LICENSE ├── README.md ├── TODO.md ├── eslint.config.js ├── index.js ├── main.js ├── package-lock.json ├── package.json ├── test ├── advanced-usage │ ├── .gitignore │ ├── assets │ │ ├── test-a │ │ │ └── a.jpg │ │ ├── test-b │ │ │ └── b.jpg │ │ └── test-c │ │ │ └── c.txt │ ├── copy-files-from-to.cjson │ ├── expected-output │ │ ├── public │ │ │ ├── copy-to-flat-directory │ │ │ │ ├── a.jpg │ │ │ │ ├── b.jpg │ │ │ │ └── c.txt │ │ │ └── images │ │ │ │ ├── test-a │ │ │ │ └── a.jpg │ │ │ │ ├── test-b │ │ │ │ └── b.jpg │ │ │ │ └── test-c │ │ │ │ └── c.txt │ │ └── scripts │ │ │ ├── console-panel │ │ │ └── console-panel.js │ │ │ └── underscore.js │ ├── node_modules │ │ ├── jquery │ │ │ └── dist │ │ │ │ ├── jquery.min.js │ │ │ │ └── jquery.min.map │ │ └── native-promise-only │ │ │ └── npo.js │ ├── package-lock.json │ └── package.json ├── basic-usage │ ├── .gitignore │ ├── copy-files-from-to.json │ ├── expected-output │ │ └── scripts │ │ │ ├── console-panel │ │ │ ├── console-panel.css │ │ │ └── console-panel.js │ │ │ └── jquery │ │ │ └── jquery.js │ └── node_modules │ │ └── jquery │ │ └── dist │ │ └── jquery.js ├── test-copy-directory │ ├── .gitignore │ ├── copy-files-from-to.json │ └── source-dir │ │ ├── dir1 │ │ ├── file1.txt │ │ └── file2.txt │ │ └── dir2 │ │ ├── file1.txt │ │ └── file2.txt ├── test-copy-file-in-custom-mode │ ├── .gitignore │ ├── copy-files-from-to.cjson │ └── expected-output │ │ └── scripts │ │ └── underscore.js.map ├── test-copy-files-from-parent-folder │ ├── .gitignore │ ├── code │ │ ├── console-panel.css │ │ └── console-panel.js │ └── folder-input-1 │ │ └── folder-input-2 │ │ └── copy-files-from-to.cjson ├── test-copy-files-to-a-directory │ ├── .gitignore │ ├── copy-files-from-to.json │ ├── expected-output │ │ └── console-panel.js │ └── source-dir │ │ ├── file1.txt │ │ ├── file2.txt │ │ ├── readme1.md │ │ └── readme2.md ├── test-copy-instructions-from-package-json │ ├── .gitignore │ ├── node_modules │ │ └── jquery │ │ │ └── dist │ │ │ └── jquery.js │ ├── package-lock.json │ └── package.json ├── test-minify-js-with-terser-options │ ├── .gitignore │ ├── copy-files-from-to.cjson │ ├── expected-output │ │ └── dist │ │ │ └── console-panel.js │ ├── node_modules │ │ └── console-panel │ │ │ └── src │ │ │ └── console-panel.js │ ├── package-lock.json │ └── package.json ├── test-minify-js │ ├── .gitignore │ ├── copy-files-from-to.cjson │ ├── expected-output │ │ └── dist │ │ │ └── console-panel.js │ ├── node_modules │ │ └── console-panel │ │ │ └── src │ │ │ └── console-panel.js │ ├── package-lock.json │ └── package.json └── test.js └── utils.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is provided by the package "node-editorconfig": 2 | # https://github.com/webextensions/node-editorconfig 3 | # https://www.npmjs.com/package/node-editorconfig 4 | # 5 | # To generate this file: 6 | # $ npx node-editorconfig@latest 7 | # 8 | # To update this file: 9 | # $ npx node-editorconfig@latest --overwrite 10 | # 11 | # References: 12 | # http://editorconfig.org/ (Official Site) 13 | # http://editorconfig.org/#download (Plugins) 14 | # http://davidensinger.com/2013/07/why-i-use-editorconfig/ (Reference) 15 | # https://github.com/eslint/eslint/blob/master/.editorconfig (Sample file) 16 | 17 | # No .editorconfig files above the root directory 18 | root = true 19 | 20 | [*] 21 | charset = utf-8 22 | end_of_line = lf 23 | indent_size = 4 24 | indent_style = space 25 | insert_final_newline = true 26 | trim_trailing_whitespace = true 27 | 28 | [{.babelrc,bower.json,nodemon.json,*.yml}] 29 | indent_size = 2 30 | 31 | [Makefile] 32 | indent_style = tab 33 | 34 | [{*.json,.node-version,.nvmrc,*.svg}] 35 | insert_final_newline = false 36 | 37 | [{*.markdown,*.md,*.mdown,*.mkd,*.mkdn,*.text}] # https://superuser.com/questions/249436/file-extension-for-markdown-files/285878#285878 38 | trim_trailing_whitespace = false # https://stackoverflow.com/editing-help#linebreaks 39 | 40 | [/node_modules/**] # Glob/minimatch pattern to match the "node_modules" directory at the project root 41 | charset = unset 42 | end_of_line = unset 43 | indent_size = unset 44 | indent_style = unset 45 | insert_final_newline = false 46 | trim_trailing_whitespace = false 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # File generated by "$ npm pack" 2 | *.tgz 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directories 33 | /node_modules/ 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional REPL history 40 | .node_repl_history 41 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Because it is relatively large in size 2 | test/ 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 webextensions.org 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # copy-files-from-to 2 | Copy files from one path to another, based on the instructions provided in a configuration file. 3 | 4 | # Use cases 5 | 6 | * This tool is useful when a few files need to be copied / updated frequently 7 | * This tool works as a basic alternative for `npm` / `bower` when you wish to copy the scripts out of `node_modules` / `bower_components` folder 8 | * You may like to use this tool if you prefer to keep some third-party dependencies (eg: from `node_modules`) updated and/or committed to your project's repository 9 | 10 | 11 | # Installation 12 | ```sh 13 | $ npm install -g copy-files-from-to 14 | ``` 15 | 16 | # How to use 17 | In your `package.json` file, add the `"copyFiles"` and `"copyFilesSettings"` (optional) instructions as described in this section. 18 | 19 | Alternatively, you may create a file, say, `copy-files-from-to.json` or `copy-files-from-to.cjson` [(JSON with comments)](https://github.com/kof/node-cjson) in your project and refer to the following usage examples. 20 | 21 | ## Basic usage 22 | Sample file: [package.json](test/test-copy-instructions-from-package-json/package.json) 23 | ```json 24 | { 25 | "name": "my-application", 26 | "version": "1.0.0", 27 | "dependencies": { 28 | "jquery": "3.4.0" 29 | }, 30 | "copyFiles": [ 31 | { 32 | "from": "node_modules/jquery/dist/jquery.js", 33 | "to": "scripts/jquery/jquery.js" 34 | }, 35 | { 36 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js", 37 | "to": "scripts/console-panel/console-panel.js" 38 | }, 39 | { 40 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.css", 41 | "to": "scripts/console-panel/console-panel.css" 42 | } 43 | ] 44 | } 45 | ``` 46 | 47 | Sample file: [copy-files-from-to.json](test/basic-usage/copy-files-from-to.json) 48 | ```json 49 | { 50 | "copyFiles": [ 51 | { 52 | "from": "node_modules/jquery/dist/jquery.js", 53 | "to": "scripts/jquery/jquery.js" 54 | }, 55 | { 56 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js", 57 | "to": "scripts/console-panel/console-panel.js" 58 | }, 59 | { 60 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.css", 61 | "to": "scripts/console-panel/console-panel.css" 62 | } 63 | ] 64 | } 65 | ``` 66 | 67 | ### Command and output 68 | ``` 69 | $ copy-files-from-to 70 | ``` 71 | 72 | ``` 73 | Reading copy instructions from file copy-files-from-to.json 74 | 75 | Starting copy operation in "default" mode: 76 | ✓ Copied [ utf8 ] node_modules/jquery/dist/jquery.js to scripts/jquery/jquery.js 77 | ✓ Copied [binary] assets/logo.png to build/logo.png 78 | ✓ Copied [remote] https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.css to scripts/console-panel/console-panel.css 79 | ✓ Copied [remote] https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js to scripts/console-panel/console-panel.js 80 | ``` 81 | 82 | 83 | ## Advanced usage 84 | Sample file: [copy-files-from-to.cjson](test/advanced-usage/copy-files-from-to.cjson) 85 | ```js 86 | // This is a CJSON file (JSON with comments) 87 | { 88 | "copyFiles": [ 89 | // In "development" mode, copy from the full version of the library, in all other modes, use the minified version 90 | { 91 | "from": { 92 | "default": "https://raw.githubusercontent.com/jashkenas/underscore/master/underscore-min.js", 93 | "development": "https://raw.githubusercontent.com/jashkenas/underscore/master/underscore.js" 94 | }, 95 | "to": "scripts/underscore.js" 96 | }, 97 | 98 | // Copy this file only in "pre-production" mode 99 | { 100 | "from": "https://raw.githubusercontent.com/jashkenas/underscore/master/underscore-min.js.map", 101 | "to": { 102 | "default": { 103 | "skip": true 104 | }, 105 | "pre-production": "scripts/underscore.js.map" 106 | } 107 | }, 108 | 109 | // Copy this file in "pre-production" and "production" mode only 110 | { 111 | "from": { 112 | "default": { 113 | "skip": true 114 | }, 115 | "pre-production": "node_modules/native-promise-only/npo.js", 116 | "production": "node_modules/native-promise-only/npo.js" 117 | }, 118 | "to": "scripts/native-promise-only.js" 119 | }, 120 | 121 | // Copy this file in all modes except "production" mode 122 | { 123 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js", 124 | "to": { 125 | "default": "scripts/console-panel/console-panel.js", 126 | "production": { 127 | "skip": true 128 | } 129 | } 130 | }, 131 | 132 | // Copy the contents of the directory "src/app/images" to "public/assets" 133 | { 134 | "from": "src/app/images", 135 | "to": "public/assets" 136 | }, 137 | 138 | // Copy the file at the mentioned path into the target directory 139 | { 140 | "from": "src/app/images/favicon.ico", 141 | "to": "public/" 142 | }, 143 | 144 | // Copy the files matching the "glob" pattern (matching files, along with the their folder structure go into the "to" directory) 145 | { 146 | "from": "assets/**/*.jpg", 147 | "to": "public/images/" 148 | }, 149 | 150 | // Copy the files matching the "glob" pattern (all of the matching files directly go into the "to" directory) since "toFlat" is set to "true" 151 | { 152 | "from": "assets/**/*.jpg", 153 | "to": "public/copy-all-jpg-files-to-this-directory/", 154 | "toFlat": true 155 | } 156 | ], 157 | "copyFilesSettings": { 158 | "whenFileExists": "notify-about-available-change", 159 | "addReferenceToSourceOfOrigin": false, 160 | "ignoreDotFilesAndFolders": true, 161 | "removeSourceMappingURL": false, 162 | "minifyJs": true, // via https://www.npmjs.com/package/terser 163 | "minifyJsTerserOptions": { // Reference: https://terser.org/docs/options/ 164 | // Default options if "minifyJsTerserOptions" is not set 165 | "compress": { 166 | "sequences": false 167 | }, 168 | "mangle": false, 169 | "format": { 170 | "semicolons": false 171 | } 172 | } 173 | } 174 | } 175 | ``` 176 | 177 | ### Command and output 178 | 179 |
180 | $ copy-files-from-to 181 |

182 | 183 | ``` 184 | Reading copy instructions from file copy-files-from-to.cjson 185 | 186 | Starting copy operation in "default" mode: 187 | ✓ Copied [remote] https://raw.githubusercontent.com/jashkenas/underscore/master/underscore-min.js to scripts/underscore.js 188 | ✓ Copied [remote] https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js to scripts/console-panel/console-panel.js 189 | ``` 190 |

191 |
192 | 193 |
194 | $ copy-files-from-to --mode development 195 |

196 | 197 | ``` 198 | Reading copy instructions from file copy-files-from-to.cjson 199 | 200 | Starting copy operation in "development" mode: 201 | ✓ Copied [remote] https://raw.githubusercontent.com/jashkenas/underscore/master/underscore.js to scripts/underscore.js 202 | ✓ Copied [remote] https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js to scripts/console-panel/console-panel.js 203 | ``` 204 |

205 |
206 | 207 |
208 | $ copy-files-from-to --mode production 209 |

210 | 211 | ``` 212 | Reading copy instructions from file copy-files-from-to.cjson 213 | 214 | Starting copy operation in "production" mode: 215 | ✓ Copied [ utf8 ] node_modules/native-promise-only/npo.js to scripts/native-promise-only.js 216 | ✓ Copied [remote] https://raw.githubusercontent.com/jashkenas/underscore/master/underscore-min.js to scripts/underscore.js 217 | ``` 218 |

219 |
220 | 221 |
222 | $ copy-files-from-to --mode pre-production --config copy-files-from-to.cjson 223 |

224 | 225 | ``` 226 | Reading copy instructions from file copy-files-from-to.cjson 227 | 228 | Starting copy operation in "pre-production" mode: 229 | ✓ Copied [ utf8 ] node_modules/native-promise-only/npo.js to scripts/native-promise-only.js 230 | ✓ Copied [remote] https://raw.githubusercontent.com/jashkenas/underscore/master/underscore-min.js to scripts/underscore.js 231 | ✓ Copied [remote] https://raw.githubusercontent.com/jashkenas/underscore/master/underscore-min.js.map to scripts/underscore.js.map 232 | ✓ Copied [remote] https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js to scripts/console-panel/console-panel.js 233 | ``` 234 |

235 |
236 | 237 | # Configuration 238 | 239 | ## Structure of "copyFiles" instruction file 240 | * You can provide the "copyFiles" instructions in a JSON or [CJSON](https://github.com/kof/node-cjson) file 241 | * The file can be structured like: 242 | ```js 243 | { 244 | // copyFiles (required parameter) 245 | // Summary: This is the instruction set for the files to be copied 246 | // Data type: array (of objects) 247 | "copyFiles": [ 248 | // Using "from" and "to", both, as simple strings 249 | { 250 | // from (required parameter) 251 | // Summary: This contains the path of a file which is either on disk or accessible via "http"/"https" URL 252 | // Data type: string, array, or object 253 | // Note: When it is set as a string, it would be used for all modes. When it is set as an object, it can be 254 | // configured differently for different modes (refer to the next example) 255 | // When it is set as an array, it describes an array of glob patterns and settings 256 | "from": "http://example.com/index.html", 257 | 258 | // to (required parameter) 259 | // Data type: string or object 260 | // Summary: This instruction set would write a file to this path on the disk 261 | // Note: When it is set as a string, it would be used for all modes. When it is set as an object, it can be 262 | // configured differently for different modes 263 | "to": "example-index.html" 264 | }, 265 | 266 | // Using "from" as an array of glob expressions 267 | { 268 | // from (required parameter) 269 | // Data type: array 270 | // Note: When it is set as an array, it describes an array of glob patterns and settings 271 | // Any strings in the array are used as glob patterns. 272 | // Any objects are used as fast-glob options: (See https://www.npmjs.com/package/fast-glob) 273 | "from": [ 274 | // The first entry here is also used to figure out the "non-magic parent path" from a glob string 275 | // Copy all files from the public folder 276 | "public/**/*", 277 | // A "!" at the beginning of the pattern will ignore any files matching that pattern 278 | // This ignores all files in the public/tmp folder 279 | "!public/tmp/**/*", 280 | // Any objects in the array will be collected together to pass to fast-glob as options 281 | // This will copy any files starting with a .* 282 | // This will not copy symlinked folders 283 | { dot: true, followSymlinkedDirectories: false } 284 | ], 285 | // to (required parameter) 286 | // Data type: string 287 | // Summary: This instruction set would write all the files found with the glob patterns and settings 288 | // to this folder. 289 | // Note: When using glob patterns for the "from" value the target "to" path needs to be a folder 290 | "to": "build/" 291 | }, 292 | 293 | // Using "from" and "to", both, as objects (and use string based mode entries) 294 | { 295 | "from": { 296 | // The "from" section should contain details about at least one mode 297 | 298 | // "default" mode (optional parameter, recommended to have) 299 | // Summary: "default" mode would be used when the command is executed without any mode or when the command 300 | // is executed in a mode which is not described for the given entry 301 | // Data type: string or object 302 | "default": "node_modules/example/index.js", 303 | 304 | // mode (optional parameter if any other mode exists) 305 | "development": "node_modules/example/dev.js", 306 | 307 | // mode (optional parameter if any other mode exists) 308 | "production": "node_modules/example/production.js" 309 | 310 | // More mode entries 311 | }, 312 | "to": { 313 | "default": "example.js" 314 | } 315 | }, 316 | 317 | // Using "from" and "to", both, as objects (and use object based mode entries) 318 | { 319 | "from": { 320 | "default": { 321 | // src (required parameter) 322 | // Summary: This contains the path of a file which is either on disk or accessible via "http"/"https" URL 323 | // Data type: string 324 | "src": "http://example.com/index-1.0.0.js.map", 325 | 326 | // latest (optional parameter) 327 | // Summary: This contains the path of a file which is either on disk or accessible via "http"/"https" URL 328 | // Data type: string 329 | // Note: When this tools is executed with "--outdated" parameter, then the file from "latest" would be 330 | // compared with the file from "src", and if there are any differences, it would be notified that 331 | // an update is available 332 | "latest": "http://example.com/index.js.map" 333 | } 334 | }, 335 | "to": { 336 | "default": { 337 | // dest (required parameter, when not using "skip" parameter set as true) 338 | // Summary: This instruction set would write a file to this path on the disk 339 | // Data type: string 340 | "dest": "scripts/index.js.map", 341 | 342 | // removeSourceMappingURL (optional parameter) 343 | // Summary: When set to true, any contents after "//# sourceMappingURL=" would be removed before 344 | // the copy operation 345 | // Data type: boolean 346 | // Default value: false 347 | "removeSourceMappingURL": false, 348 | 349 | // minifyJs (optional parameter) 350 | // Summary: When set to true, this JavaScript file would be minified before the copy operation 351 | // (via https://www.npmjs.com/package/terser) 352 | // Data type: boolean 353 | // Default value: undefined 354 | "minifyJs": false 355 | }, 356 | "production": { 357 | // skip (required parameter, when not using "dest" parameter) 358 | // Summary: If you wish to skip a file in some particular mode, add "skip" as true, otherwise a warning 359 | // would be raised when you run this tool for that particular mode 360 | // Data type: boolean 361 | // Default value: false 362 | "skip": true 363 | } 364 | } 365 | } 366 | 367 | // Add more object entries with "from" and "to" details, and you can use any of the supported data types to 368 | // represent the values of "from", "to" and their "default" or modes 369 | ], 370 | 371 | // copyFilesSettings (optional parameter) 372 | // Summary: Settings for the copy files operation 373 | // Data type: object 374 | "copyFilesSettings": { 375 | // whenFileExists (optional parameter) 376 | // Summary: When the file at "to" path already exists, what action should be taken 377 | // Data type: string 378 | // Supported values: "do-nothing" / "overwrite" / "notify-about-available-change" 379 | // Default value: "do-nothing" 380 | "whenFileExists": "notify-about-available-change", 381 | 382 | // addReferenceToSourceOfOrigin (optional parameter) 383 | // Summary: When set to true, the copy operation would create a file ".source.txt" 384 | // which would contain a link to the "from" path 385 | // Data type: boolean 386 | // Default value: false 387 | "addReferenceToSourceOfOrigin": false 388 | 389 | // ignoreDotFilesAndFolders (optional parameter) 390 | // Summary: When set to true, globbing will ignore files and folders starting with a "." dot. 391 | // Data type: boolean 392 | // Default value: false 393 | "ignoreDotFilesAndFolders": true 394 | 395 | // removeSourceMappingURL (optional parameter) 396 | // Summary: When set to true, any contents after "//# sourceMappingURL=" would be removed before 397 | // the copy operation 398 | // Data type: boolean 399 | // Default value: false 400 | "removeSourceMappingURL": false, 401 | 402 | // minifyJs (optional parameter) 403 | // Summary: When set to true, the JavaScript files would be uglified before the copy operation 404 | // (via https://www.npmjs.com/package/terser) 405 | // Data type: boolean 406 | // Default value: false 407 | "minifyJs": true, 408 | 409 | // minifyJsTerserOptions (optional parameter) 410 | // Summary: Options for the terser minification operation 411 | // Data type: object 412 | // Default value: 413 | // Reference: https://terser.org/docs/options/ 414 | "minifyJsTerserOptions": { 415 | // Default options if "minifyJsTerserOptions" is not set 416 | // Note: By default, only license information is preserved in "comments" (via a custom function defintion), set `minifyJsTerserOptions.format.comments` to `null` or an appropriate value to override that 417 | "compress": { 418 | "sequences": false 419 | }, 420 | "mangle": false, 421 | "format": { 422 | "semicolons": false 423 | } 424 | } 425 | } 426 | } 427 | ``` 428 | 429 | ## Command line options 430 | 431 | ```sh 432 | $ copy-files-from-to --help 433 | ``` 434 | 435 | ``` 436 | Usage: 437 | copy-files-from-to [--config ] [--mode ] [...] 438 | 439 | Examples: 440 | copy-files-from-to 441 | copy-files-from-to --config copy-files-from-to.json 442 | copy-files-from-to --mode production 443 | copy-files-from-to -h 444 | copy-files-from-to --version 445 | 446 | Options: 447 | --config Path to configuration file 448 | When unspecified, it looks for: 449 | 1) copy-files-from-to.cjson 450 | 2) copy-files-from-to.json 451 | 3) package.json 452 | --mode Mode to use for copying the files 453 | When unspecified, it uses "default" mode 454 | --when-file-exists Override "whenFileExists" setting specified in configuration file 455 | can be "notify-about-available-change" or "overwrite" or "do-nothing" 456 | --outdated Notify about outdated parts of the configuration file 457 | (takes cue from "latest" property, wherever specified) 458 | --verbose Verbose logging 459 | --silent Reduced logging (log only warnings and errors) 460 | -v --version Output the version number 461 | -h --help Show help 462 | ``` 463 | 464 | # TODO 465 | 466 | See [TODO.md](TODO.md) 467 | 468 | 469 | # About this project 470 | 471 | ## Author 472 | 473 | * Priyank Parashar - [GitHub](https://github.com/paras20xx) | [Twitter](https://twitter.com/paras20xx) | [LinkedIn](https://linkedin.com/in/ParasharPriyank/) 474 | 475 | ## Connect with us 476 | 477 | * https://www.webextensions.org/ 478 | * [GitHub](https://github.com/webextensions/live-css-editor) 479 | * [Twitter](https://twitter.com/webextensions) 480 | 481 | ## License 482 | 483 | * [MIT](LICENSE) 484 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | * Refactor code 4 | * Check the support for copying files across different partition (w.r.t. executing program) on Windows 5 | * If the operation attempts to modify a file outside the `process.cwd()`/config-file-directory, then `--unsafe` parameter must be passed 6 | * Consider adding support for npm modules via https://unpkg.com/ 7 | * Consider adding option to use soft links, rather than copying the files 8 | * Check if any speed improvements (probably via changes in parallelisation) can be done 9 | * Add `--clean` option (to "Delete the files mentioned in `"to"` entries (for all modes)") 10 | * Also add an option to "clean empty directories" 11 | * Add support for loading `.js` files as configuration 12 | * Add even more logging when running with `--verbose` option 13 | * Consider adding support to auto convert GitHub links to raw content links 14 | * Consider adding support for `bower.json` 15 | * Write more test-cases 16 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | const globals = require('globals'); 2 | const js = require('@eslint/js'); 3 | 4 | module.exports = [ 5 | { 6 | ignores: [ 7 | 'test/**/*.js', 8 | '!test/test.js' 9 | ] 10 | }, 11 | js.configs.recommended, 12 | { 13 | languageOptions: { 14 | globals: { 15 | ...globals.node 16 | } 17 | }, 18 | 19 | rules: { 20 | indent: ["error", 4], 21 | "linebreak-style": ["error", "unix"], 22 | "no-console": "off", 23 | "no-debugger": "off", 24 | "no-shadow": "off", 25 | quotes: "off", 26 | semi: ["error", "always"] 27 | } 28 | } 29 | ]; 30 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // To debug: 4 | // $ node --inspect-brk ./index.js --config test//copy-files-from-to.json 5 | 6 | var path = require('path'), 7 | fs = require('fs'); 8 | 9 | var unixify = require('unixify'); 10 | var cjson = require('cjson'); 11 | 12 | var utils = require('./utils.js'); 13 | const logger = utils.logger; 14 | var chalk = logger.chalk; 15 | 16 | var argv = require('yargs') 17 | .help(false) 18 | .version(false) 19 | .argv; 20 | 21 | var main = require('./main.js'); 22 | 23 | var paramHelp = argv.h || argv.help, 24 | paramVersion = argv.v || argv.version, 25 | paramVerbose = argv.verbose, 26 | paramSilent = argv.silent, 27 | paramOutdated = argv.outdated, 28 | paramWhenFileExists = argv.whenFileExists; 29 | 30 | var packageJson = require('./package.json'); 31 | 32 | var nodeVersion = process.versions.node; 33 | 34 | var cwd = unixify(process.cwd()); 35 | 36 | if (paramSilent) { 37 | logger.log = function () {}; 38 | logger.info = function () {}; 39 | logger.success = function () {}; 40 | } 41 | 42 | if (!module.parent) { 43 | var showHelp = function () { 44 | logger.log([ 45 | '', 46 | chalk.bold('Usage:'), 47 | ' copy-files-from-to [--config ] [--mode ] [...]', 48 | '', 49 | chalk.bold('Examples:'), 50 | ' copy-files-from-to', 51 | ' copy-files-from-to --config copy-files-from-to.json', 52 | ' copy-files-from-to --mode production', 53 | ' copy-files-from-to -h', 54 | ' copy-files-from-to --version', 55 | '', 56 | chalk.bold('Options:'), 57 | ' --config Path to configuration file', 58 | ' When unspecified, it looks for:', 59 | ' 1) copy-files-from-to.cjson', 60 | ' 2) copy-files-from-to.json', 61 | ' 3) package.json', 62 | ' --mode Mode to use for copying the files', 63 | ' When unspecified, it uses "default" mode', 64 | ' --when-file-exists Override "whenFileExists" setting specified in configuration file', 65 | ' can be "notify-about-available-change" or "overwrite" or "do-nothing"', 66 | ' --outdated Notify about outdated parts of the configuration file', 67 | ' (takes cue from "latest" property, wherever specified)', 68 | ' --verbose Verbose logging', 69 | ' --silent Reduced logging (log only warnings and errors)', 70 | ' -v --version Output the version number', 71 | ' -h --help Show help', 72 | '' 73 | ].join('\n')); 74 | }; 75 | 76 | if (paramHelp) { 77 | showHelp(); 78 | process.exit(0); 79 | } 80 | 81 | if (paramVersion || paramVerbose) { 82 | logger.log(packageJson.name + ' version: ' + packageJson.version); 83 | logger.log('Node JS version: ' + nodeVersion); 84 | if (paramVersion) { 85 | process.exit(0); 86 | } 87 | } 88 | 89 | var configFile = null; 90 | 91 | configFile = argv.config; 92 | if (!configFile) { 93 | if (fs.existsSync(path.resolve(cwd, 'copy-files-from-to.cjson'))) { 94 | configFile = 'copy-files-from-to.cjson'; 95 | } else if (fs.existsSync(path.resolve(cwd, 'copy-files-from-to.json'))) { 96 | configFile = 'copy-files-from-to.json'; 97 | } else if (fs.existsSync(path.resolve(cwd, 'package.json'))) { 98 | configFile = 'package.json'; 99 | } else { 100 | logger.error( 101 | '\n' + 102 | chalk.bold('Error:') + ' Please ensure that you have passed correct arguments. Exiting with error (code 1).' 103 | ); 104 | showHelp(); 105 | process.exit(1); 106 | } 107 | } 108 | 109 | var configFileSource, 110 | configFileSourceDirectory; 111 | 112 | if (configFile.indexOf('/') === 0 || configFile.indexOf('\\') === 0) { // readListFromFile has an absolute path 113 | configFileSource = configFile; 114 | } else { // readListFromFile has a relative path 115 | configFileSource = path.resolve(cwd, configFile); 116 | } 117 | configFileSourceDirectory = unixify(path.dirname(configFileSource)); 118 | 119 | var cjsonText; 120 | try { 121 | logger.info('Reading copy instructions from file ' + utils.getRelativePath(cwd, configFileSource)); 122 | cjsonText = fs.readFileSync(configFileSource, 'utf8'); 123 | cjsonText = utils.stripBom(cjsonText); 124 | } catch (e) { 125 | utils.exitWithError(e, 'Error in reading file: ' + configFileSource); 126 | } 127 | 128 | var copyFiles = [], 129 | copyFilesSettings = {}; 130 | try { 131 | var cjsonData = cjson.parse(cjsonText); 132 | if (cjsonData instanceof Object) { 133 | if (Array.isArray(cjsonData.copyFiles)) { 134 | copyFiles = cjsonData.copyFiles; 135 | } 136 | if (cjsonData.copyFilesSettings instanceof Object) { 137 | copyFilesSettings = cjsonData.copyFilesSettings; 138 | } 139 | } 140 | } catch (e) { 141 | utils.exitWithError(e, 'Invalid (C)JSON data:\n ' + cjsonText.replace(/\n/g, '\n ')); 142 | } 143 | 144 | main({ 145 | paramVerbose: paramVerbose, 146 | paramOutdated: paramOutdated, 147 | paramWhenFileExists: paramWhenFileExists, 148 | cwd: cwd, 149 | copyFiles: copyFiles, 150 | copyFilesSettings: copyFilesSettings, 151 | configFileSourceDirectory: configFileSourceDirectory, 152 | mode: argv.mode 153 | }); 154 | } 155 | 156 | module.exports = main; 157 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copy-files-from-to", 3 | "version": "3.12.1", 4 | "description": "Copy files from one path to another, based on the instructions provided in a configuration file.", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "main": "index.js", 9 | "bin": { 10 | "copy-files-from-to": "./index.js" 11 | }, 12 | "directories": { 13 | "test": "test" 14 | }, 15 | "files": [ 16 | ".editorconfig", 17 | ".eslintignore", 18 | ".eslintrc", 19 | ".nvmrc", 20 | "index.js", 21 | "LICENSE", 22 | "main.js", 23 | "package.json", 24 | "README.md", 25 | "TODO.md", 26 | "utils.js" 27 | ], 28 | "scripts": { 29 | "lint": "eslint .", 30 | "start": "node index.js", 31 | "mocha": "mocha", 32 | "mocha:inspect-brk": "mocha --inspect-brk", 33 | "test": "npm run lint && npm run mocha" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "git+https://github.com/webextensions/copy-files-from-to.git" 38 | }, 39 | "keywords": [ 40 | "copy", 41 | "file", 42 | "files", 43 | "from", 44 | "one", 45 | "path", 46 | "to", 47 | "another", 48 | "folder", 49 | "directory", 50 | "create", 51 | "instructions", 52 | "configuration", 53 | "node_modules", 54 | "request", 55 | "http", 56 | "https", 57 | "remote", 58 | "url", 59 | "resource", 60 | "source", 61 | "code" 62 | ], 63 | "author": "Priyank Parashar", 64 | "license": "MIT", 65 | "bugs": { 66 | "url": "https://github.com/webextensions/copy-files-from-to/issues" 67 | }, 68 | "homepage": "https://github.com/webextensions/copy-files-from-to#readme", 69 | "dependencies": { 70 | "async": "^3.2.6", 71 | "axios": "^1.7.9", 72 | "chalk": "=4.1.2", 73 | "cjson": "^0.5.0", 74 | "fast-glob": "^3.3.3", 75 | "glob-parent": "^6.0.2", 76 | "is-glob": "^4.0.3", 77 | "is-utf8": "^0.2.1", 78 | "lodash": "^4.17.21", 79 | "md5": "^2.3.0", 80 | "mkdirp": "^3.0.1", 81 | "note-down": "=1.0.2", 82 | "terser": "^5.39.0", 83 | "unixify": "^1.0.0", 84 | "yargs": "^17.7.2" 85 | }, 86 | "devDependencies": { 87 | "@eslint/js": "^9.20.0", 88 | "chai": "=4.5.0", 89 | "chai-files": "^1.4.0", 90 | "eslint": "^9.20.1", 91 | "globals": "^15.15.0", 92 | "mocha": "^11.1.0", 93 | "rimraf": "^6.0.1", 94 | "shelljs": "^0.8.5" 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /test/advanced-usage/.gitignore: -------------------------------------------------------------------------------- 1 | # https://stackoverflow.com/questions/35278885/gitignore-exclusion-is-not-working-for-a-single-file/35279076#35279076 2 | /node_modules/** 3 | !node_modules/native-promise-only/ 4 | !node_modules/native-promise-only/npo.js 5 | 6 | !node_modules/jquery/ 7 | !node_modules/jquery/dist/ 8 | !node_modules/jquery/dist/jquery.min.js 9 | !node_modules/jquery/dist/jquery.min.map 10 | 11 | /scripts/ 12 | /public/ 13 | -------------------------------------------------------------------------------- /test/advanced-usage/assets/test-a/a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/assets/test-a/a.jpg -------------------------------------------------------------------------------- /test/advanced-usage/assets/test-b/b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/assets/test-b/b.jpg -------------------------------------------------------------------------------- /test/advanced-usage/assets/test-c/c.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/assets/test-c/c.txt -------------------------------------------------------------------------------- /test/advanced-usage/copy-files-from-to.cjson: -------------------------------------------------------------------------------- 1 | // This is a CJSON file (JSON with comments) 2 | { 3 | "copyFiles": [ 4 | // In "development" mode, copy from the full version of the library, in all other modes, use the minified version 5 | { 6 | "from": { 7 | "default": "https://raw.githubusercontent.com/jashkenas/underscore/1.9.1/underscore-min.js", 8 | "development": "https://raw.githubusercontent.com/jashkenas/underscore/1.9.1/underscore.js" 9 | }, 10 | "to": "scripts/underscore.js" 11 | }, 12 | 13 | // Copy this file only in "pre-production" mode 14 | { 15 | "from": "https://raw.githubusercontent.com/jashkenas/underscore/1.9.1/underscore-min.js.map", 16 | "to": { 17 | "default": { 18 | "skip": true 19 | }, 20 | "pre-production": "scripts/underscore.js.map" 21 | } 22 | }, 23 | 24 | // Copy this file in "pre-production" and "production" mode only 25 | { 26 | "from": { 27 | "default": { 28 | "skip": true 29 | }, 30 | "pre-production": "node_modules/native-promise-only/npo.js", 31 | "production": "node_modules/native-promise-only/npo.js" 32 | }, 33 | "to": "scripts/native-promise-only.js" 34 | }, 35 | 36 | // Copy this file in all modes except "production" mode 37 | { 38 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/v1.0.3/src/console-panel.js", 39 | "to": { 40 | "default": "scripts/console-panel/console-panel.js", 41 | "production": { 42 | "skip": true 43 | } 44 | } 45 | }, 46 | 47 | { 48 | // TODO: FIXME: https://github.com/webextensions/copy-files-from-to/issues/27 49 | // "from": "node_modules/jquery/dist/jquery.min.(js|map)", 50 | "from": "node_modules/jquery/dist/jquery.min.*", 51 | "to": "public/scripts/" 52 | }, 53 | 54 | // Copy the files matching the "glob" pattern 55 | { 56 | "from": "assets/**/*.jpg", 57 | "to": "public/images/" 58 | }, 59 | 60 | // Copy the files matching the "glob" pattern 61 | { 62 | "from": "assets/**/*", 63 | "to": "public/images/" 64 | }, 65 | 66 | // Copy the files matching the "glob" pattern (paste them directly into the "to" directory) 67 | { 68 | "from": "assets/**/*.*", 69 | "to": "public/copy-to-flat-directory/", 70 | "toFlat": true 71 | }, 72 | 73 | // Copy the files matching the "glob" pattern 74 | // Don't copy files from the assets/tmp folder 75 | // Don't copy files starting with a . (i.e. the MacOS .DS_Store files) 76 | // Note that this "dot" option overrides the global "ignoreDotFilesAndFolders" settings if set. 77 | { 78 | "from": ["assets/**/*", "!assets/tmp/**/*", { "dot": false }], 79 | "to": "public/images/" 80 | } 81 | ], 82 | "copyFilesSettings": { 83 | "whenFileExists": "notify-about-available-change", 84 | "addReferenceToSourceOfOrigin": false, 85 | "ignoreDotFilesAndFolders": true, 86 | "removeSourceMappingURL": false, 87 | "minifyJs": true, // via https://www.npmjs.com/package/terser 88 | "minifyJsTerserOptions": { // Reference: https://terser.org/docs/options/ 89 | // Default options if "minifyJsTerserOptions" is not set 90 | "compress": { 91 | "sequences": false 92 | }, 93 | "mangle": false, 94 | "format": { 95 | "semicolons": false 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/public/copy-to-flat-directory/a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/expected-output/public/copy-to-flat-directory/a.jpg -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/public/copy-to-flat-directory/b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/expected-output/public/copy-to-flat-directory/b.jpg -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/public/copy-to-flat-directory/c.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/expected-output/public/copy-to-flat-directory/c.txt -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/public/images/test-a/a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/expected-output/public/images/test-a/a.jpg -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/public/images/test-b/b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/expected-output/public/images/test-b/b.jpg -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/public/images/test-c/c.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/copy-files-from-to/b55a947bad87042b8fe4570fd3f0559caed6bc24/test/advanced-usage/expected-output/public/images/test-c/c.txt -------------------------------------------------------------------------------- /test/advanced-usage/expected-output/scripts/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore may be freely distributed under the MIT license. 2 | !function(){var n="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this||{},r=n._,e=Array.prototype,o=Object.prototype,s="undefined"!=typeof Symbol?Symbol.prototype:null,u=e.push,c=e.slice,p=o.toString,i=o.hasOwnProperty,t=Array.isArray,a=Object.keys,l=Object.create,f=function(){},h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)} 3 | "undefined"==typeof exports||exports.nodeType?n._=h:("undefined"!=typeof module&&!module.nodeType&&module.exports&&(exports=module.exports=h),exports._=h),h.VERSION="1.9.1" 4 | var v,y=function(u,i,n){if(void 0===i)return u 5 | switch(null==n?3:n){case 1:return function(n){return u.call(i,n)} 6 | case 3:return function(n,r,t){return u.call(i,n,r,t)} 7 | case 4:return function(n,r,t,e){return u.call(i,n,r,t,e)}}return function(){return u.apply(i,arguments)}},d=function(n,r,t){return h.iteratee!==v?h.iteratee(n,r):null==n?h.identity:h.isFunction(n)?y(n,r,t):h.isObject(n)&&!h.isArray(n)?h.matcher(n):h.property(n)} 8 | h.iteratee=v=function(n,r){return d(n,r,1/0)} 9 | var g=function(u,i){return i=null==i?u.length-1:+i,function(){for(var n=Math.max(arguments.length-i,0),r=Array(n),t=0;t":">",'"':""","'":"'","`":"`"},P=h.invert(L),W=function(r){var t=function(n){return r[n]},n="(?:"+h.keys(r).join("|")+")",e=RegExp(n),u=RegExp(n,"g") 175 | return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}} 176 | h.escape=W(L),h.unescape=W(P),h.result=function(n,r,t){h.isArray(r)||(r=[r]) 177 | var e=r.length 178 | if(!e)return h.isFunction(t)?t.call(n):t 179 | for(var u=0;u/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g} 184 | var J=/(.)^/,U={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},V=/\\|'|\r|\n|\u2028|\u2029/g,$=function(n){return"\\"+U[n]} 185 | h.template=function(i,n,r){!n&&r&&(n=r),n=h.defaults({},n,h.templateSettings) 186 | var t,e=RegExp([(n.escape||J).source,(n.interpolate||J).source,(n.evaluate||J).source].join("|")+"|$","g"),o=0,a="__p+='" 187 | i.replace(e,(function(n,r,t,e,u){return a+=i.slice(o,u).replace(V,$),o=u+n.length,r?a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":t?a+="'+\n((__t=("+t+"))==null?'':__t)+\n'":e&&(a+="';\n"+e+"\n__p+='"),n})),a+="';\n",n.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n" 188 | try{t=new Function(n.variable||"obj","_",a)}catch(n){throw n.source=a,n}var u=function(n){return t.call(this,n,h)},c=n.variable||"obj" 189 | return u.source="function("+c+"){\n"+a+"}",u},h.chain=function(n){var r=h(n) 190 | return r._chain=!0,r} 191 | var G=function(n,r){return n._chain?h(r).chain():r} 192 | h.mixin=function(t){return h.each(h.functions(t),(function(n){var r=h[n]=t[n] 193 | h.prototype[n]=function(){var n=[this._wrapped] 194 | return u.apply(n,arguments),G(this,r.apply(h,n))}})),h},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],(function(r){var t=e[r] 195 | h.prototype[r]=function(){var n=this._wrapped 196 | return t.apply(n,arguments),"shift"!==r&&"splice"!==r||0!==n.length||delete n[0],G(this,n)}})),h.each(["concat","join","slice"],(function(n){var r=e[n] 197 | h.prototype[n]=function(){return G(this,r.apply(this._wrapped,arguments))}})),h.prototype.value=function(){return this._wrapped},h.prototype.valueOf=h.prototype.toJSON=h.prototype.value,h.prototype.toString=function(){return String(this._wrapped)},"function"==typeof define&&define.amd&&define("underscore",[],(function(){return h}))}() 198 | -------------------------------------------------------------------------------- /test/advanced-usage/node_modules/native-promise-only/npo.js: -------------------------------------------------------------------------------- 1 | /*! Native Promise Only 2 | v0.8.1 (c) Kyle Simpson 3 | MIT License: http://getify.mit-license.org 4 | */ 5 | !function(t,n,e){n[t]=n[t]||e(),"undefined"!=typeof module&&module.exports?module.exports=n[t]:"function"==typeof define&&define.amd&&define(function(){return n[t]})}("Promise","undefined"!=typeof global?global:this,function(){"use strict";function t(t,n){l.add(t,n),h||(h=y(l.drain))}function n(t){var n,e=typeof t;return null==t||"object"!=e&&"function"!=e||(n=t.then),"function"==typeof n?n:!1}function e(){for(var t=0;t0&&t(e,u))}catch(a){i.call(new f(u),a)}}}function i(n){var o=this;o.triggered||(o.triggered=!0,o.def&&(o=o.def),o.msg=n,o.state=2,o.chain.length>0&&t(e,o))}function c(t,n,e,o){for(var r=0;r span { 262 | white-space: pre-wrap; 263 | } 264 | 265 | #console-panel .log-mode-info, 266 | #console-panel .log-mode-warn, 267 | #console-panel .log-mode-error, 268 | #console-panel .log-mode-window-onerror { 269 | background-repeat: no-repeat; 270 | } 271 | 272 | #console-panel .log-mode-info { 273 | /* chrome-devtools://devtools/bundled/Images/smallIcons_2x.png */ 274 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsKDw81VUJejQAAAsxJREFUOMutVFtLVFEU/vbex5lxjjIqlWVXsKQL4UORRb0WJZSKmQVRD0UE9hLRjSDqqRtdXnqpH1BvXpDeoiBIgyYyGcuCUuli6ejczzmzL6uHypzRJNDvae+1v/Wtb7FZi2EaNDVFfCNwG7Q0dZ4yNcqYCqUIWpmvWZdeKCPbgsnRtkhkXzY/l+UHag/2NHpS34prWuYSYPIJ2kA5CpmYO5h15ckfPTtaJz+Lv65IVNXsvTGe1XdGFYUkAAJQFrJQu60UyYxBIq0BzsB9Ar5iXwmImkXRftsZWfkYeEoAYP0RpFDftR9pdSom/3oSguHBldVYssCHeEphZ0vklygAxhjseTaY4Ke12kTxfpwFAA4AB46/bYy66lQsm9ugHeBYPN8HAAgVWaj4fZ6MYGkh7DL7TLDyUT0AiKZLEZ+KU+dgKluST/YkQWrCsoV+dD4bQ+uT6HR/CL9dgPS4s9Ur33OXHTrR3zwQcx+OOiqHJDiDXchzYmnXQGuaVjQxksG3gfg+iwH1cU9PIVQuDaD15pqc2JHLH9Ddm5xW0C7xgzPUcUeZzdJMrfp+0MG6va8wNOzhfyAKBCy/2MIVUTnmCJaPL+IgzBkYMcMtwYbnSlBKPcwDgnUVcDZrMS01lGeec0ZoD/mtWQumYy4MmQ7ul6nWeYXWAJuFSTKExIgzpIudDhEO3zPVm1qGGKE5NWmOly/y4/7FVVi+MAAhflWrripCcVAg/DaVIxgfTlMm6RyW/Q19E74aj0auf0tnT/+Z52CAo7rKnuLm+5jEx8/uxD0z7iL6NXE1+W7X+Zxts37J2nN6sJcEsTNjUiPjGnS9Sc7YZibqUCrqXE++e3Hhnwt298E39Wmpbye0WeESweRRyBB0RsKNuZ88T538/np7+4wbGwA2HHtZEBpDvZSoc43ZrI2p0NJASvqisrpbKt1eporbw+GNMj/3Jz2CZsrrkClGAAAAAElFTkSuQmCC"); 275 | background-size: 11px 11px; 276 | background-position: 7px 4px; 277 | 278 | background-color: #edebfb; 279 | border-bottom-color: #e5e1ff; 280 | } 281 | 282 | #console-panel .log-mode-warn { 283 | /* chrome-devtools://devtools/bundled/Images/smallIcons_2x.png */ 284 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsKDwIt84C4lgAAAbFJREFUOMudlLtOG0EUhr9dr9esL7uz4MvKSkIRiZKaDvECeYRADSjCBmoeIZKL1IZHSIMrEzp3kVKCEJcgCHgxdizLyNg4RbhkYXfWZLqZc+afb/45ZxRCxu4XPqQtygBui4XZRb7K8hVZsFbCFBnO3mZJAPy8pNOsk5/5xO+gPapMcBCjmBv/KwaQGycxiFH8L8JaCdPKcv4uQ/zf9dM63bNz8nMFmq8i7OusOsIrBpCzMWIGhVcRPtClDOLNtjcmUtDpBlNqfoK3UYqOIH5yAdMfh57Yjy2FSQfjqkkB2Ai9cq2EmbZZ16PBxkc1mBCs73xGhAoGeTeql+pzugnBmowujFKV0UUiMOh3n+qy3yUSkVOqMjqRAvdk93HuHn/DTskpVZl3VhLcw8rjvH5UwUzKvVSD6Ib3Rdpzt5/Kqb6Nch8LolTDXnYqs0enqtCpKkxl90NfXPHr2SGjDcWnx7W7MVYd21/s4NS/U96/8doCkLUx3BYrmpVgSddG/CAlOboGIsmyJvtxbBO+l73htJCepWqNNvPA5piO7ZdhJb1Xvu3Dr8bLvJse1402838AjWeMl7yfz78AAAAASUVORK5CYII="); 285 | background-size: 10px 10px; 286 | background-position: 7px 5px; 287 | 288 | background-color: #fffbe5; 289 | border-bottom-color: #fff5c2; 290 | } 291 | 292 | #console-panel .log-mode-error, 293 | #console-panel .log-mode-window-onerror { 294 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsKDxgoM8e2wgAAAxlJREFUOMudlMtPE1EUxr97Z+ZOh0I7pTxKwbZAjCaNxhijkBiNbowx8hD1D1DDgvhCMJq4cYuCGjUuXOAejAKJKxMJmCgmLkyMGjGA5WGRVx9IKcPMHRdg40B56Fmec88v557vu5cgTbQFwZQpVk1Ns1Jmyj6BMi8AGFz7saDNvzNM0pHM0zpOf4K2spesTLwoyKyRRXbH4/T4XBkuMIFZ6pqhITIXQXg2HEouJuuPh+efpwW2AUKmX23y2PMbCh0FoIRgveAmx+hsGBO/Jm+/C0Wu3wQ4AIh/DjhKPU1bsvIb8pRsbCYoofA5CqFIylUiyiYGxq+lJny53V+TIzufFmW48T8xMjeFyWS0+kj/SAdtCwaZLCot3gyX5ZDtRAWoS109mUuF7USFJVdkd0Nhyv22YJAJdd6ckx6b85ydsr9glchsvAxWvhdady/MZDIFcz5oge3YUfBIFPqXr8tCEFAqOnWy8JEKEqtyiDarkq96oA8MQigphvPRPVC3G1RV4bjfDKGkGEZoGFrPa0uPQ7JBFFgl6SsvGyqFElh1NVWF40EzxNISGKOjgM4hBHwwQsOInb8CPj2zah3feGKQSlTKT2uLaBTxC43Qv4cgFBUtwUbH1oQBgCyyAgpBWldBsolMqiIwTrnExtP6bPnKQsAPY2RsedJCOB+2gLrT24uL0jjlTH6rU7r2/kLDiNVdQryufkkovy8tVKcEBpPfUCLKnfNMthTZ4YNLsMEhxOoug0/PLO30YiOMwSEIfh/Ywf2WnoQsg4qsi7yvrZXEn/F+7+REgJimxdhady94JLrK2OzQASSfdaVyJiEIu3OHRRvfSgDgw6kz1fZfsWdqdOa/nl5MzTbjmc6q3e2tXRQAdrW3Pk+oObfnHOo/w+ayVCTU3Kbd7a1dAJBSY+e2guvxvC23YjlemJRsCDIpRTzXa8Y9vqYd2zw31jTV57MNVdD0u/aZ8YA8G4WwaP2UDYlhIUtFIjt/iIusPvikuXNDl76vrZUU5FZRwitJcqFM0DXvss/GDFnpM4nZOW9Od+55/HhxZe9vO6ohHl8Nk3cAAAAASUVORK5CYII="); 295 | background-size: 11px 11px; 296 | background-position: 7px 5px; 297 | 298 | background-color: #fff0f0; 299 | border-bottom-color: #ffd6d6; 300 | } 301 | 302 | #console-panel .log-mode-unhandled { 303 | background-color: #eff; 304 | } 305 | 306 | #console-panel .dev-tools-console-message { 307 | margin-left: 24px; 308 | word-wrap: break-word; 309 | font-family: monospace; 310 | } 311 | 312 | 313 | #console-panel .dev-tools-console-message-code-line { 314 | float: right; 315 | } 316 | 317 | #console-panel .log-call-stack { 318 | white-space: pre-wrap; 319 | } 320 | 321 | #console-panel .log-value-window-onerror { 322 | color: #f00; 323 | } 324 | 325 | #console-panel .log-value-unknown { 326 | color: #000; 327 | } 328 | 329 | #console-panel .log-value-boolean, 330 | #console-panel .log-value-number { 331 | color: #1c00cf; 332 | } 333 | 334 | #console-panel .log-value-null, 335 | #console-panel .log-value-undefined, 336 | #console-panel .log-value-console-clear { 337 | color: #808080; 338 | } 339 | 340 | #console-panel .log-value-console-clear { 341 | font-style: italic; 342 | } 343 | 344 | #console-panel .log-value-string:before, 345 | #console-panel .log-value-string:after { 346 | content: '"'; 347 | color: #222; 348 | } 349 | #console-panel .log-value-string { 350 | color: #c41a16; 351 | } 352 | 353 | #console-panel .log-value-dom-text:before, 354 | #console-panel .log-value-dom-text:after { 355 | color: #888; 356 | font-style: italic; 357 | } 358 | #console-panel .log-value-dom-text:before { 359 | content: '#text "'; 360 | } 361 | #console-panel .log-value-dom-text:after { 362 | content: '"'; 363 | } 364 | 365 | #console-panel .log-value-dom { 366 | color: #881280; 367 | } 368 | 369 | /* This helps in keeping the console-panel-expand-collapse icon together with the highlighted 370 | code (for example when multiple items are logged via single console.log()) */ 371 | #console-panel .log-value-dom { 372 | display: inline-block; 373 | } 374 | /* But, the above rule may cause the console-panel-expand-collapse icon to move to the next 375 | line even when it is the first child, but that case may be better to ignore (to avoid 376 | that extra line). For example: when we log an element which contains huge HTML code, which 377 | would need to get wrapped */ 378 | #console-panel .dev-tools-console-message .log-value-dom:first-child { 379 | display: inline; 380 | } 381 | 382 | #console-panel .jsoneditor-not-available.log-value-array, 383 | #console-panel .jsoneditor-not-available.log-value-object { 384 | color: #808080; 385 | } 386 | #console-panel .jsoneditor-not-available.log-value-array:before, 387 | #console-panel .jsoneditor-not-available.log-value-object:before { 388 | color: rgb(33, 33, 33); 389 | } 390 | #console-panel .jsoneditor-not-available.log-value-array:before { 391 | content: 'Array '; 392 | } 393 | #console-panel .jsoneditor-not-available.log-value-object:before { 394 | content: 'Object '; 395 | } 396 | 397 | /* CSS fixes for JSON Editor */ 398 | #console-panel div.jsoneditor-menu { 399 | display: none; 400 | } 401 | #console-panel div.jsoneditor-outer { 402 | margin-top: 0; 403 | padding-top: 0; 404 | } 405 | #console-panel div.jsoneditor { 406 | border-width: 0; 407 | } 408 | #console-panel div.jsoneditor-tree div.jsoneditor-tree-inner { 409 | padding-bottom: 0; 410 | } 411 | 412 | /* Without this, a scroll seems to come up */ 413 | #console-panel div.jsoneditor-tree { 414 | display: inline; 415 | } 416 | 417 | #console-panel .jsoneditor, 418 | #console-panel .jsoneditor-outer, 419 | #console-panel .jsoneditor-tree-inner, 420 | #console-panel .jsoneditor-outer > .jsoneditor-tree, 421 | #console-panel .jsoneditor-outer > .jsoneditor-tree > .jsoneditor-tree-inner > .jsoneditor-tree { 422 | display: inline; 423 | } 424 | 425 | /* This style may be useful in older browsers */ 426 | #console-panel div.jsoneditor-value.jsoneditor-array, 427 | #console-panel div.jsoneditor-value.jsoneditor-object { 428 | min-width: unset; 429 | } 430 | 431 | 432 | #console-panel div.jsoneditor-value { 433 | width: max-content; 434 | } 435 | 436 | #console-panel div.jsoneditor-tree button.jsoneditor-button, 437 | #console-panel div.jsoneditor-tree button.jsoneditor-button.jsoneditor-expanded { 438 | background-position: 0px 2px; 439 | } 440 | 441 | #console-panel div.jsoneditor-tree button.jsoneditor-button { 442 | width: 10px; 443 | height: 10px; 444 | background-repeat: no-repeat; 445 | 446 | /* chrome-devtools://devtools/bundled/Images/treeoutlineTriangles.png */ 447 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAICAQAAABwz0azAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJRj/Z+u0AAAAL0lEQVQI12NgyGBgZICD/wy7GGQRnP8MHxjSEJz/DP8ZtjJIMTEga0BXhmQAktEApfUQ8zThbVYAAAAASUVORK5CYII="); 448 | } 449 | 450 | #console-panel div.jsoneditor-tree button.jsoneditor-button.jsoneditor-expanded { 451 | /* chrome-devtools://devtools/bundled/Images/treeoutlineTriangles.png */ 452 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAQAAAC7znxOAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJDGkzkKZAAAAP0lEQVQI12Ng4Ga4xfAfDu8x8DIwMDBYMfyBCvxlsGOAgm6oUBcDHLAzXGL4z3CNgYMBCRgyfGUwZUAD2jAGAEP7FIhkSA3EAAAAAElFTkSuQmCC"); 453 | } 454 | 455 | 456 | #console-panel div.jsoneditor-readonly, 457 | #console-panel div.jsoneditor-value { 458 | padding: 0; 459 | margin: 0; 460 | } 461 | 462 | #console-panel div.jsoneditor-field, 463 | #console-panel div.jsoneditor-readonly, 464 | #console-panel div.jsoneditor-value { 465 | min-height: 0px; 466 | min-width: 0px; /* Useful for keeping widths for property names as small as possible */ 467 | } 468 | 469 | #console-panel .jsoneditor-schema-error, 470 | #console-panel div.jsoneditor td, 471 | #console-panel div.jsoneditor textarea, 472 | #console-panel div.jsoneditor th, 473 | #console-panel div.jsoneditor-field, 474 | #console-panel div.jsoneditor-value { 475 | font-size: 11px; 476 | font-family: monospace; 477 | } 478 | 479 | 480 | #console-panel div.jsoneditor td.jsoneditor-tree { 481 | vertical-align: middle; 482 | } 483 | 484 | 485 | /* Begin: Styles to make JSON Editor match Chrome DevTools UI */ 486 | #console-panel div.jsoneditor-field { 487 | color: #881391; 488 | } 489 | 490 | #console-panel div.jsoneditor-value.jsoneditor-string { 491 | color: #c41a16; 492 | } 493 | 494 | #console-panel div.jsoneditor-value.jsoneditor-string:before, 495 | #console-panel div.jsoneditor-value.jsoneditor-string:after { 496 | content: '"'; 497 | color: #222; 498 | } 499 | 500 | #console-panel div.jsoneditor-empty { 501 | border-width: 0; 502 | } 503 | 504 | #console-panel .jsoneditor-expandable .jsoneditor-readonly { 505 | text-transform: capitalize; 506 | color: rgb(33, 33, 33); 507 | } 508 | 509 | #console-panel div.jsoneditor-tree button.jsoneditor-button:focus { 510 | background-color: transparent; 511 | outline: none; 512 | } 513 | 514 | /* End */ 515 | 516 | 517 | /* Begin: Styles to make Prism JS match Chrome DevTools */ 518 | #console-panel .only-first-line-of-code code.language-markup:after { 519 | content: '…'; 520 | } 521 | 522 | #console-panel pre.language-markup { 523 | background-color: transparent; 524 | padding: 0; 525 | margin: 0; 526 | 527 | display: inline-block; 528 | } 529 | /* End */ 530 | 531 | 532 | #console-panel .all-lines-of-code { 533 | display: inline-block; 534 | } 535 | 536 | #console-panel .console-panel-expand-collapse { 537 | display: inline-block; 538 | width: 10px; 539 | height: 10px; 540 | } 541 | 542 | #console-panel .console-panel-expand-collapse.console-panel-collapsed, 543 | #console-panel .console-panel-expand-collapse.console-panel-expanded { 544 | cursor: pointer; 545 | background-repeat: no-repeat; 546 | } 547 | #console-panel .console-panel-expand-collapse.console-panel-expanded { 548 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAQAAAC7znxOAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJDGkzkKZAAAAP0lEQVQI12Ng4Ga4xfAfDu8x8DIwMDBYMfyBCvxlsGOAgm6oUBcDHLAzXGL4z3CNgYMBCRgyfGUwZUAD2jAGAEP7FIhkSA3EAAAAAElFTkSuQmCC"); 549 | background-position: 0px 2px; 550 | } 551 | 552 | #console-panel .console-panel-expand-collapse.console-panel-collapsed { 553 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAICAQAAABwz0azAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJRj/Z+u0AAAAL0lEQVQI12NgyGBgZICD/wy7GGQRnP8MHxjSEJz/DP8ZtjJIMTEga0BXhmQAktEApfUQ8zThbVYAAAAASUVORK5CYII="); 554 | } 555 | 556 | #console-panel .only-first-line-of-code { 557 | vertical-align: top; 558 | vertical-align: text-top; 559 | } 560 | #console-panel .all-lines-of-code { 561 | vertical-align: top; 562 | } 563 | #console-panel code[class*="language-"], 564 | #console-panel pre[class*="language-"] { 565 | white-space: pre-wrap; 566 | word-break: break-word; 567 | } 568 | 569 | /* Begin: Useful styles when Prism JS is not available */ 570 | #console-panel .log-value-dom .all-lines-of-code pre, 571 | #console-panel .log-value-dom .only-first-line-of-code pre { 572 | display: inline; 573 | } 574 | /* End */ 575 | 576 | /* Begin: Match Prism JS with DevTools style */ 577 | #console-panel code[class*="language-"], 578 | #console-panel pre[class*="language-"] { 579 | font-family: monospace; 580 | } 581 | 582 | #console-panel .token.tag { 583 | color: #881280; 584 | } 585 | #console-panel .token.attr-name { 586 | color: #994500; 587 | } 588 | 589 | #console-panel .token.attr-value { 590 | color: #1a1aa6; 591 | } 592 | 593 | #console-panel .token.comment { 594 | color: #236e25; 595 | } 596 | /* */ 597 | 598 | 599 | /* Begin: Resize related CSS */ 600 | html #console-panel .dev-tools-resize-handle { 601 | top: 0; 602 | height: inherit; 603 | padding-top: inherit; 604 | padding-bottom: inherit; 605 | position: absolute; 606 | width: 100%; 607 | left: 0; 608 | display: block; 609 | } 610 | 611 | #console-panel .dev-tools { 612 | top: unset !important; 613 | bottom: 0 !important; 614 | } 615 | /* End */ 616 | 617 | /* Begin: jQuery UI related fix */ 618 | #console-panel .dev-tools { 619 | position: fixed; 620 | } 621 | /* End */ 622 | -------------------------------------------------------------------------------- /test/test-copy-directory/.gitignore: -------------------------------------------------------------------------------- 1 | /target-dir/ 2 | 3 | /target (dir)/ 4 | -------------------------------------------------------------------------------- /test/test-copy-directory/copy-files-from-to.json: -------------------------------------------------------------------------------- 1 | { 2 | "copyFiles": [ 3 | { 4 | "from": "source-dir", 5 | "to": "target-dir" 6 | }, 7 | { 8 | "from": "source (dir)", 9 | "to": "target (dir)" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /test/test-copy-directory/source-dir/dir1/file1.txt: -------------------------------------------------------------------------------- 1 | dir1 > file1.txt 2 | -------------------------------------------------------------------------------- /test/test-copy-directory/source-dir/dir1/file2.txt: -------------------------------------------------------------------------------- 1 | dir1 > file2.txt 2 | -------------------------------------------------------------------------------- /test/test-copy-directory/source-dir/dir2/file1.txt: -------------------------------------------------------------------------------- 1 | dir2 > file1.txt 2 | -------------------------------------------------------------------------------- /test/test-copy-directory/source-dir/dir2/file2.txt: -------------------------------------------------------------------------------- 1 | dir2 > file2.txt 2 | -------------------------------------------------------------------------------- /test/test-copy-file-in-custom-mode/.gitignore: -------------------------------------------------------------------------------- 1 | /scripts/ 2 | -------------------------------------------------------------------------------- /test/test-copy-file-in-custom-mode/copy-files-from-to.cjson: -------------------------------------------------------------------------------- 1 | { 2 | "copyFiles": [ 3 | // Copy this file only in "pre-production" mode 4 | { 5 | "from": "https://raw.githubusercontent.com/jashkenas/underscore/36eef3c118041ae6386b6bba2b48b099e57ca0e5/underscore-min.js.map", 6 | "to": { 7 | "pre-production": "scripts/underscore.js.map" 8 | } 9 | } 10 | ], 11 | "copyFilesSettings": { 12 | "whenFileExists": "overwrite" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/test-copy-file-in-custom-mode/expected-output/scripts/underscore.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["underscore.js"],"names":["root","self","global","this","previousUnderscore","_","ArrayProto","Array","prototype","ObjProto","Object","SymbolProto","Symbol","push","slice","toString","hasOwnProperty","nativeIsArray","isArray","nativeKeys","keys","nativeCreate","create","Ctor","obj","_wrapped","exports","nodeType","module","VERSION","builtinIteratee","optimizeCb","func","context","argCount","value","call","index","collection","accumulator","apply","arguments","cb","iteratee","identity","isFunction","isObject","matcher","property","Infinity","restArguments","startIndex","length","Math","max","rest","args","baseCreate","result","shallowProperty","key","has","path","deepGet","i","MAX_ARRAY_INDEX","pow","getLength","isArrayLike","each","forEach","map","collect","results","currentKey","createReduce","dir","memo","initial","reducer","reduce","foldl","inject","reduceRight","foldr","find","detect","predicate","findIndex","findKey","filter","select","list","reject","negate","every","all","some","any","contains","includes","include","item","fromIndex","guard","values","indexOf","invoke","contextPath","method","pluck","where","attrs","findWhere","computed","lastComputed","v","min","shuffle","sample","n","random","clone","last","rand","temp","sortBy","criteria","sort","left","right","a","b","group","behavior","partition","groupBy","indexBy","countBy","reStrSymbol","toArray","isString","match","size","pass","first","head","take","array","tail","drop","compact","Boolean","flatten","input","shallow","strict","output","idx","isArguments","j","len","without","otherArrays","difference","uniq","unique","isSorted","isBoolean","seen","union","arrays","intersection","argsLength","unzip","zip","object","createPredicateIndexFinder","findLastIndex","sortedIndex","low","high","mid","floor","createIndexFinder","predicateFind","isNaN","lastIndexOf","range","start","stop","step","ceil","chunk","count","executeBound","sourceFunc","boundFunc","callingContext","bind","TypeError","bound","callArgs","concat","partial","boundArgs","placeholder","position","bindAll","Error","memoize","hasher","cache","address","delay","wait","setTimeout","defer","throttle","options","timeout","previous","later","leading","now","throttled","remaining","clearTimeout","trailing","cancel","debounce","immediate","debounced","callNow","wrap","wrapper","compose","after","times","before","once","hasEnumBug","propertyIsEnumerable","nonEnumerableProps","collectNonEnumProps","nonEnumIdx","constructor","proto","prop","allKeys","mapObject","pairs","invert","functions","methods","names","createAssigner","keysFunc","defaults","source","l","extend","extendOwn","assign","eq","deepEq","keyInObj","pick","omit","String","props","tap","interceptor","isMatch","aStack","bStack","type","className","valueOf","areArrays","aCtor","bCtor","pop","isEqual","isEmpty","isElement","name","nodelist","document","childNodes","Int8Array","isFinite","isSymbol","parseFloat","isNumber","isNull","isUndefined","noConflict","constant","noop","propertyOf","matches","accum","Date","getTime","escapeMap","&","<",">","\"","'","`","unescapeMap","createEscaper","escaper","join","testRegexp","RegExp","replaceRegexp","string","test","replace","escape","unescape","fallback","idCounter","uniqueId","prefix","id","templateSettings","evaluate","interpolate","noMatch","escapes","\\","\r","\n","
","
","escapeRegExp","escapeChar","template","text","settings","oldSettings","render","offset","variable","Function","e","data","argument","chain","instance","_chain","chainResult","mixin","toJSON","define","amd"],"mappings":"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"} -------------------------------------------------------------------------------- /test/test-copy-files-from-parent-folder/.gitignore: -------------------------------------------------------------------------------- 1 | /dest/ 2 | -------------------------------------------------------------------------------- /test/test-copy-files-from-parent-folder/code/console-panel.css: -------------------------------------------------------------------------------- 1 | /*! 2 | console-panel 3 | A console panel within webpage to help in the following use-cases: 4 | * Get notification on console messages 5 | * Console logging on mobile and tablet devices 6 | * Console logging on Microsoft Edge / Internet Explorer (without opening native Developer Tools) 7 | https://github.com/webextensions/console-panel 8 | by Priyank Parashar (https://webextensions.org/) 9 | MIT License 10 | */ 11 | 12 | #console-panel .dev-tools-icon-container, 13 | #console-panel .dev-tools-icon-container *, 14 | #console-panel .dev-tools-console, 15 | #console-panel .dev-tools-console * { 16 | font-family: monospace; 17 | } 18 | 19 | #console-panel .dev-tools-header, 20 | #console-panel .dev-tools-header * { 21 | font-family: sans-serif; 22 | } 23 | 24 | #console-panel .dev-tools-icon-container { 25 | position: fixed; 26 | z-index: 2000000001; 27 | } 28 | #console-panel .dev-tools-icon-container-left-top, 29 | #console-panel .dev-tools-icon-container-top-left { 30 | top: 20px; 31 | left: 20px; 32 | } 33 | #console-panel .dev-tools-icon-container-top-right, 34 | #console-panel .dev-tools-icon-container-right-top { 35 | top: 20px; 36 | right: 20px; 37 | } 38 | #console-panel .dev-tools-icon-container-bottom-left, 39 | #console-panel .dev-tools-icon-container-left-bottom { 40 | bottom: 20px; 41 | left: 20px; 42 | } 43 | #console-panel .dev-tools-icon-container-bottom-right, 44 | #console-panel .dev-tools-icon-container-right-bottom { 45 | right: 20px; 46 | bottom: 20px; 47 | } 48 | 49 | #console-panel .dev-tools-icon { 50 | width: 32px; 51 | height: 32px; 52 | line-height: 35px; /* Keeping height a little more than height, so that it looks better middle-aligned (since we are going to render numbers inside it) */ 53 | border-radius: 999px; 54 | 55 | cursor: pointer; 56 | 57 | text-align: center; 58 | font-size: 14px; 59 | 60 | /* This may help in improving CPU usage for some of the animations */ 61 | transform: translateZ(0); 62 | } 63 | 64 | 65 | #console-panel .dev-tools-icon.no-unread-messages { 66 | /* https://github.com/mozilla/gecko-dev/blob/7aef56cc4e682e5c99fcc282f30abbf8212efd50/devtools/client/definitions.js */ 67 | /* chrome://devtools/skin/images/tool-webconsole.svg */ 68 | background-image: url("data:image/svg+xml;base64,PCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9ImNvbnRleHQtZmlsbCAjMGIwYjBiIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogIDxwYXRoIGQ9Ik0xNCA0VjNIMnYxaDEyem0wIDF2OEgyVjVoMTJ6TTEgMy4wMDJDMSAyLjQ1IDEuNDUgMiAyLjAwNyAyaDExLjk4NkExLjAxIDEuMDEgMCAwIDEgMTUgMy4wMDJ2OS45OTZDMTUgMTMuNTUgMTQuNTUgMTQgMTMuOTkzIDE0SDIuMDA3QTEuMDEgMS4wMSAwIDAgMSAxIDEyLjk5OFYzLjAwMnoiLz4KICA8cGF0aCBkPSJNNC4wOSA3Ljg1OWwyLjA2MiAyLS4wMDYtLjcxMy0yLjA2MSAyLjA2MmEuNS41IDAgMCAwIC43MDcuNzA3bDIuMDYyLTIuMDYxYS41LjUgMCAwIDAtLjAwNi0uNzEzbC0yLjA2MS0yYS41LjUgMCAxIDAtLjY5Ny43MTh6Ii8+Cjwvc3ZnPg=="); 69 | background-repeat: no-repeat; 70 | background-position: center center; 71 | 72 | opacity: 0.5; 73 | } 74 | #console-panel .dev-tools-icon.no-unread-messages:hover { 75 | opacity: 1; 76 | } 77 | 78 | #console-panel .dev-tools-icon { background-color: #e7e7e7; box-shadow: inset 0 0 15px 1px #979797; } 79 | #console-panel .dev-tools-icon:hover { background-color: #d0d0d0; } 80 | #console-panel .dev-tools-icon.found-something, 81 | #console-panel .dev-tools-icon.found-log { background-color: #d3d3d3; box-shadow: inset 0 0 15px 1px #777; } 82 | #console-panel .dev-tools-icon.found-something:hover, 83 | #console-panel .dev-tools-icon.found-log:hover { background-color: #b9b9b9; } 84 | #console-panel .dev-tools-icon.found-info { background-color: #dad4dd; box-shadow: inset 0 0 15px 1px #6e61bf; } 85 | #console-panel .dev-tools-icon.found-info:hover { background-color: #cbb6d6; } 86 | #console-panel .dev-tools-icon.found-warn { background-color: #ffea83; box-shadow: inset 0 0 15px 1px #f8981b; } 87 | #console-panel .dev-tools-icon.found-warn:hover { background-color: #f9d626; } 88 | #console-panel .dev-tools-icon.found-error { background-color: #ffc5c5; box-shadow: inset 0 0 15px 1px #ff5858; } 89 | #console-panel .dev-tools-icon.found-error:hover { background-color: #fc9292; box-shadow: inset 0 0 15px 1px #f00; } 90 | 91 | #console-panel .dev-tools-icon.found-error { 92 | /* Limiting the animation to 5 times. Otherwise, the CSS animation may cause high CPU usage. */ 93 | animation: console-panel-animation-notify-error 3s 5; 94 | } 95 | @keyframes console-panel-animation-notify-error { 96 | 50% { 97 | background-color: #ffa500; 98 | box-shadow: inset 0 0 15px 1px #f00; 99 | } 100 | } 101 | 102 | #console-panel .dev-tools-icon-container .strong-notification:before, 103 | #console-panel .dev-tools-icon-container .strong-notification:after { 104 | display: block; 105 | content: ''; 106 | position: absolute; 107 | top: 0; right: 0; bottom: 0; left: 0; 108 | border-radius: 50%; 109 | z-index: -1; 110 | } 111 | 112 | #console-panel .dev-tools-icon-container .strong-notification:before { background-color: rgba(255, 0, 0, 0.5); } 113 | #console-panel .dev-tools-icon-container .strong-notification:after { background-color: rgba(255,177,0, 0.5); } 114 | 115 | /* To ensure that the CSS animation does not cause high CPU usage, we remove 116 | the "strong-notification" class via JavaScript, once it is not required 117 | anymore. */ 118 | #console-panel .dev-tools-icon-container .strong-notification:before { animation: console-panel-animation-ripple 0.75s ease-in infinite; } 119 | #console-panel .dev-tools-icon-container .strong-notification:after { animation: console-panel-animation-ripple 0.75s ease-out infinite; } 120 | 121 | /* https://stackoverflow.com/questions/32955459/rings-with-ripple-animation-css-only/32955876#32955876 */ 122 | @keyframes console-panel-animation-ripple { 123 | 0% { 124 | top: 0px; 125 | right: 0px; 126 | bottom: 0px; 127 | left: 0px; 128 | } 129 | 25% { 130 | top: -10vh; 131 | top: -10vmin; 132 | right: -10vh; 133 | right: -10vmin; 134 | bottom: -10vh; 135 | bottom: -10vmin; 136 | left: -10vh; 137 | left: -10vmin; 138 | opacity: 0.5; 139 | } 140 | 90% { 141 | opacity: 0.2; 142 | } 143 | 100% { 144 | top: -20vh; 145 | top: -20vmin; 146 | right: -20vh; 147 | right: -20vmin; 148 | bottom: -20vh; 149 | bottom: -20vmin; 150 | left: -20vh; 151 | left: -20vmin; 152 | opacity: 0; 153 | } 154 | } 155 | 156 | #console-panel .dev-tools { 157 | position: fixed; 158 | z-index: 2000000000; 159 | 160 | display: block; 161 | bottom: 0; 162 | right: 0; 163 | box-sizing: border-box; 164 | background-color: #fff; 165 | border-top: 1px solid #d0d0d0; 166 | width: 100%; 167 | 168 | /* Values much higher than this may not work so well in different mobile device orientation since the "vh"/"vmin" might be calculated 169 | w.r.t. full-screen size, while the toolbar is also visible (which eats some of that height) */ 170 | max-height: 80vh; 171 | max-height: 80vmin; 172 | 173 | height: 250px; 174 | min-height: 90px; 175 | padding: 0; 176 | 177 | color: #303942; 178 | /* A mix and match of font-family names from Chrome DevTools (ui/inspectorStyle.css) */ 179 | font-family: 'Segoe UI', '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', Roboto, Ubuntu, Tahoma, Arial, sans-serif; 180 | 181 | font-size: 11px; 182 | } 183 | 184 | #console-panel .dev-tools-header { 185 | height: 27px; 186 | line-height: 27px; 187 | background-color: #f3f3f3; 188 | padding: 2px 0px 2px 6px; 189 | border-bottom: 1px solid #d0d0d0; 190 | font-size: 12px; 191 | } 192 | 193 | #console-panel .dev-tools-clear-console-icon { 194 | width: 13px; 195 | height: 13px; 196 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsJFi8Kd+JgAwAAAblJREFUSMellj1PQjEUhh8SGU3EuCkjfoVJ/BgciYNxwMmBxN/A4sfgDzAOOgjhRxBNSJwUwYG4sqJxIJEYVsHFqIBLb3Jz0vb2Xpp0OT1vn7anPacxgtsSsA/sAPNAUtm7wAdQA6rAKxHbOlAHxo79GdgOA4gDZWAUAuL1EVBSc1jbLPBkmegb6AH9AGADSNh2ooN8AZfApljptIpdxbD7hmlnZcPqCg7HnQHaGm1ROm5YYvIH5B1gM0BTE7OM36kRcOausDmgI7Q1b3BZE5OCmjwKLKdZ6CLAqTBeKUF+AlhL6I4BHoVxyyeICjsTmgdU6vAMP5orGQWWFf4vAAOfoWcQhoWtCN+BBH1aVnkA/GpghxrftPDry6MbqxfPhDvb0x1dTRhzAYF2gV2I8XuAE2GsOFxfGyyuapV/7MgrbNa0ERJ2q3mwKU8kC1xb5a4osLEpBXnVVCbVpspdk8CGwJoUlDSOHYfLEQduDKBrk8CUxVsqrWTVY1wFdoFz4N2gqdtKesKhZLj0uq2U+3dWjPg5GarjmgrzG0oDdyEgNV3gvRZzAKZ8H8gksOD7QHZVmakCb7ZJ/gEMg1YzMOnqgwAAAABJRU5ErkJggg=="); 197 | float: left; 198 | background-size: contain; 199 | opacity: 0.5; 200 | margin-right: 5px; 201 | margin-top: 7px; 202 | cursor: pointer; 203 | } 204 | #console-panel .dev-tools-clear-console-icon:hover { 205 | opacity: 0.85; 206 | } 207 | 208 | #console-panel .dev-tools-header-cross-icon, 209 | #console-panel .dev-tools-header-disable-icon { 210 | float: right; 211 | cursor: pointer; 212 | width: 13px; 213 | height: 13px; 214 | opacity: 0.5; 215 | background-repeat: no-repeat; 216 | height: 24px; 217 | } 218 | 219 | #console-panel .dev-tools-header-cross-icon { 220 | width: 30px; 221 | 222 | /* Source: chrome-devtools://devtools/bundled/Images/largeIcons_2x.png (in Google Chrome browser) */ 223 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsGFTI1ZM2PLQAAAKdJREFUOMutlUsOwjAMRB8cgIqzdGGuHnEANpwFuScoC1LJQq1rW4mUTZR5+c048GsT0IAH+TYDT+COgb2AFViS0Bn4dO17g7Y+sHUFJACTPtdq2/8qa3Cnexq1mgz0FJaBhmERaBrmXbYejEnFDntdK549grqwayEZF4px8o6cStTQR/GskU5UxGdhaMa0p9BKAlzo8PJ1MwVWRxRY+wVIwbPStRPAF611ou20opYrAAAAAElFTkSuQmCC"); 224 | background-position: 9px 8px; 225 | background-size: 10px 10px; 226 | } 227 | 228 | #console-panel .dev-tools-header-disable-icon { 229 | width: 20px; 230 | 231 | /* Source: https://www.iconfinder.com/icons/1608429/off_power_icon */ 232 | background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB3aWR0aD0iMTc5MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTY2NCA4OTZxMCAxNTYtNjEgMjk4dC0xNjQgMjQ1LTI0NSAxNjQtMjk4IDYxLTI5OC02MS0yNDUtMTY0LTE2NC0yNDUtNjEtMjk4cTAtMTgyIDgwLjUtMzQzdDIyNi41LTI3MHE0My0zMiA5NS41LTI1dDgzLjUgNTBxMzIgNDIgMjQuNSA5NC41dC00OS41IDg0LjVxLTk4IDc0LTE1MS41IDE4MXQtNTMuNSAyMjhxMCAxMDQgNDAuNSAxOTguNXQxMDkuNSAxNjMuNSAxNjMuNSAxMDkuNSAxOTguNSA0MC41IDE5OC41LTQwLjUgMTYzLjUtMTA5LjUgMTA5LjUtMTYzLjUgNDAuNS0xOTguNXEwLTEyMS01My41LTIyOHQtMTUxLjUtMTgxcS00Mi0zMi00OS41LTg0LjV0MjQuNS05NC41cTMxLTQzIDg0LTUwdDk1IDI1cTE0NiAxMDkgMjI2LjUgMjcwdDgwLjUgMzQzem0tNjQwLTc2OHY2NDBxMCA1Mi0zOCA5MHQtOTAgMzgtOTAtMzgtMzgtOTB2LTY0MHEwLTUyIDM4LTkwdDkwLTM4IDkwIDM4IDM4IDkweiIvPjwvc3ZnPg=="); 233 | background-size: 14px 14px; 234 | background-position: 3px 6px; 235 | } 236 | 237 | #console-panel .dev-tools-header-cross-icon:hover, 238 | #console-panel .dev-tools-header-disable-icon:hover { 239 | opacity: 0.75; 240 | } 241 | 242 | #console-panel .dev-tools-console { 243 | clear: both; 244 | overflow: auto; 245 | height: calc(100% - 31px); 246 | } 247 | 248 | #console-panel .dev-tools-console-body { 249 | overflow: auto; 250 | } 251 | 252 | #console-panel .dev-tools-console-message-wrapper { 253 | line-height: 13px; 254 | border-top: 1px solid transparent; 255 | border-bottom: 1px solid #f0f0f0; 256 | line-height: 17px; 257 | padding: 3px 22px 1px 0; 258 | } 259 | 260 | /* This helps in ensuring that the texts show proper whitespace (also useful in showing function definitions) */ 261 | #console-panel .dev-tools-console-message > span { 262 | white-space: pre-wrap; 263 | } 264 | 265 | #console-panel .log-mode-info, 266 | #console-panel .log-mode-warn, 267 | #console-panel .log-mode-error, 268 | #console-panel .log-mode-window-onerror { 269 | background-repeat: no-repeat; 270 | } 271 | 272 | #console-panel .log-mode-info { 273 | /* chrome-devtools://devtools/bundled/Images/smallIcons_2x.png */ 274 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsKDw81VUJejQAAAsxJREFUOMutVFtLVFEU/vbex5lxjjIqlWVXsKQL4UORRb0WJZSKmQVRD0UE9hLRjSDqqRtdXnqpH1BvXpDeoiBIgyYyGcuCUuli6ejczzmzL6uHypzRJNDvae+1v/Wtb7FZi2EaNDVFfCNwG7Q0dZ4yNcqYCqUIWpmvWZdeKCPbgsnRtkhkXzY/l+UHag/2NHpS34prWuYSYPIJ2kA5CpmYO5h15ckfPTtaJz+Lv65IVNXsvTGe1XdGFYUkAAJQFrJQu60UyYxBIq0BzsB9Ar5iXwmImkXRftsZWfkYeEoAYP0RpFDftR9pdSom/3oSguHBldVYssCHeEphZ0vklygAxhjseTaY4Ke12kTxfpwFAA4AB46/bYy66lQsm9ugHeBYPN8HAAgVWaj4fZ6MYGkh7DL7TLDyUT0AiKZLEZ+KU+dgKluST/YkQWrCsoV+dD4bQ+uT6HR/CL9dgPS4s9Ur33OXHTrR3zwQcx+OOiqHJDiDXchzYmnXQGuaVjQxksG3gfg+iwH1cU9PIVQuDaD15pqc2JHLH9Ddm5xW0C7xgzPUcUeZzdJMrfp+0MG6va8wNOzhfyAKBCy/2MIVUTnmCJaPL+IgzBkYMcMtwYbnSlBKPcwDgnUVcDZrMS01lGeec0ZoD/mtWQumYy4MmQ7ul6nWeYXWAJuFSTKExIgzpIudDhEO3zPVm1qGGKE5NWmOly/y4/7FVVi+MAAhflWrripCcVAg/DaVIxgfTlMm6RyW/Q19E74aj0auf0tnT/+Z52CAo7rKnuLm+5jEx8/uxD0z7iL6NXE1+W7X+Zxts37J2nN6sJcEsTNjUiPjGnS9Sc7YZibqUCrqXE++e3Hhnwt298E39Wmpbye0WeESweRRyBB0RsKNuZ88T538/np7+4wbGwA2HHtZEBpDvZSoc43ZrI2p0NJASvqisrpbKt1eporbw+GNMj/3Jz2CZsrrkClGAAAAAElFTkSuQmCC"); 275 | background-size: 11px 11px; 276 | background-position: 7px 4px; 277 | 278 | background-color: #edebfb; 279 | border-bottom-color: #e5e1ff; 280 | } 281 | 282 | #console-panel .log-mode-warn { 283 | /* chrome-devtools://devtools/bundled/Images/smallIcons_2x.png */ 284 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsKDwIt84C4lgAAAbFJREFUOMudlLtOG0EUhr9dr9esL7uz4MvKSkIRiZKaDvECeYRADSjCBmoeIZKL1IZHSIMrEzp3kVKCEJcgCHgxdizLyNg4RbhkYXfWZLqZc+afb/45ZxRCxu4XPqQtygBui4XZRb7K8hVZsFbCFBnO3mZJAPy8pNOsk5/5xO+gPapMcBCjmBv/KwaQGycxiFH8L8JaCdPKcv4uQ/zf9dM63bNz8nMFmq8i7OusOsIrBpCzMWIGhVcRPtClDOLNtjcmUtDpBlNqfoK3UYqOIH5yAdMfh57Yjy2FSQfjqkkB2Ai9cq2EmbZZ16PBxkc1mBCs73xGhAoGeTeql+pzugnBmowujFKV0UUiMOh3n+qy3yUSkVOqMjqRAvdk93HuHn/DTskpVZl3VhLcw8rjvH5UwUzKvVSD6Ib3Rdpzt5/Kqb6Nch8LolTDXnYqs0enqtCpKkxl90NfXPHr2SGjDcWnx7W7MVYd21/s4NS/U96/8doCkLUx3BYrmpVgSddG/CAlOboGIsmyJvtxbBO+l73htJCepWqNNvPA5piO7ZdhJb1Xvu3Dr8bLvJse1402838AjWeMl7yfz78AAAAASUVORK5CYII="); 285 | background-size: 10px 10px; 286 | background-position: 7px 5px; 287 | 288 | background-color: #fffbe5; 289 | border-bottom-color: #fff5c2; 290 | } 291 | 292 | #console-panel .log-mode-error, 293 | #console-panel .log-mode-window-onerror { 294 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gsKDxgoM8e2wgAAAxlJREFUOMudlMtPE1EUxr97Z+ZOh0I7pTxKwbZAjCaNxhijkBiNbowx8hD1D1DDgvhCMJq4cYuCGjUuXOAejAKJKxMJmCgmLkyMGjGA5WGRVx9IKcPMHRdg40B56Fmec88v557vu5cgTbQFwZQpVk1Ns1Jmyj6BMi8AGFz7saDNvzNM0pHM0zpOf4K2spesTLwoyKyRRXbH4/T4XBkuMIFZ6pqhITIXQXg2HEouJuuPh+efpwW2AUKmX23y2PMbCh0FoIRgveAmx+hsGBO/Jm+/C0Wu3wQ4AIh/DjhKPU1bsvIb8pRsbCYoofA5CqFIylUiyiYGxq+lJny53V+TIzufFmW48T8xMjeFyWS0+kj/SAdtCwaZLCot3gyX5ZDtRAWoS109mUuF7USFJVdkd0Nhyv22YJAJdd6ckx6b85ydsr9glchsvAxWvhdady/MZDIFcz5oge3YUfBIFPqXr8tCEFAqOnWy8JEKEqtyiDarkq96oA8MQigphvPRPVC3G1RV4bjfDKGkGEZoGFrPa0uPQ7JBFFgl6SsvGyqFElh1NVWF40EzxNISGKOjgM4hBHwwQsOInb8CPj2zah3feGKQSlTKT2uLaBTxC43Qv4cgFBUtwUbH1oQBgCyyAgpBWldBsolMqiIwTrnExtP6bPnKQsAPY2RsedJCOB+2gLrT24uL0jjlTH6rU7r2/kLDiNVdQryufkkovy8tVKcEBpPfUCLKnfNMthTZ4YNLsMEhxOoug0/PLO30YiOMwSEIfh/Ywf2WnoQsg4qsi7yvrZXEn/F+7+REgJimxdhady94JLrK2OzQASSfdaVyJiEIu3OHRRvfSgDgw6kz1fZfsWdqdOa/nl5MzTbjmc6q3e2tXRQAdrW3Pk+oObfnHOo/w+ayVCTU3Kbd7a1dAJBSY+e2guvxvC23YjlemJRsCDIpRTzXa8Y9vqYd2zw31jTV57MNVdD0u/aZ8YA8G4WwaP2UDYlhIUtFIjt/iIusPvikuXNDl76vrZUU5FZRwitJcqFM0DXvss/GDFnpM4nZOW9Od+55/HhxZe9vO6ohHl8Nk3cAAAAASUVORK5CYII="); 295 | background-size: 11px 11px; 296 | background-position: 7px 5px; 297 | 298 | background-color: #fff0f0; 299 | border-bottom-color: #ffd6d6; 300 | } 301 | 302 | #console-panel .log-mode-unhandled { 303 | background-color: #eff; 304 | } 305 | 306 | #console-panel .dev-tools-console-message { 307 | margin-left: 24px; 308 | word-wrap: break-word; 309 | font-family: monospace; 310 | } 311 | 312 | 313 | #console-panel .dev-tools-console-message-code-line { 314 | float: right; 315 | } 316 | 317 | #console-panel .log-call-stack { 318 | white-space: pre-wrap; 319 | } 320 | 321 | #console-panel .log-value-window-onerror { 322 | color: #f00; 323 | } 324 | 325 | #console-panel .log-value-unknown { 326 | color: #000; 327 | } 328 | 329 | #console-panel .log-value-boolean, 330 | #console-panel .log-value-number { 331 | color: #1c00cf; 332 | } 333 | 334 | #console-panel .log-value-null, 335 | #console-panel .log-value-undefined, 336 | #console-panel .log-value-console-clear { 337 | color: #808080; 338 | } 339 | 340 | #console-panel .log-value-console-clear { 341 | font-style: italic; 342 | } 343 | 344 | #console-panel .log-value-string:before, 345 | #console-panel .log-value-string:after { 346 | content: '"'; 347 | color: #222; 348 | } 349 | #console-panel .log-value-string { 350 | color: #c41a16; 351 | } 352 | 353 | #console-panel .log-value-dom-text:before, 354 | #console-panel .log-value-dom-text:after { 355 | color: #888; 356 | font-style: italic; 357 | } 358 | #console-panel .log-value-dom-text:before { 359 | content: '#text "'; 360 | } 361 | #console-panel .log-value-dom-text:after { 362 | content: '"'; 363 | } 364 | 365 | #console-panel .log-value-dom { 366 | color: #881280; 367 | } 368 | 369 | /* This helps in keeping the console-panel-expand-collapse icon together with the highlighted 370 | code (for example when multiple items are logged via single console.log()) */ 371 | #console-panel .log-value-dom { 372 | display: inline-block; 373 | } 374 | /* But, the above rule may cause the console-panel-expand-collapse icon to move to the next 375 | line even when it is the first child, but that case may be better to ignore (to avoid 376 | that extra line). For example: when we log an element which contains huge HTML code, which 377 | would need to get wrapped */ 378 | #console-panel .dev-tools-console-message .log-value-dom:first-child { 379 | display: inline; 380 | } 381 | 382 | #console-panel .jsoneditor-not-available.log-value-array, 383 | #console-panel .jsoneditor-not-available.log-value-object { 384 | color: #808080; 385 | } 386 | #console-panel .jsoneditor-not-available.log-value-array:before, 387 | #console-panel .jsoneditor-not-available.log-value-object:before { 388 | color: rgb(33, 33, 33); 389 | } 390 | #console-panel .jsoneditor-not-available.log-value-array:before { 391 | content: 'Array '; 392 | } 393 | #console-panel .jsoneditor-not-available.log-value-object:before { 394 | content: 'Object '; 395 | } 396 | 397 | /* CSS fixes for JSON Editor */ 398 | #console-panel div.jsoneditor-menu { 399 | display: none; 400 | } 401 | #console-panel div.jsoneditor-outer { 402 | margin-top: 0; 403 | padding-top: 0; 404 | } 405 | #console-panel div.jsoneditor { 406 | border-width: 0; 407 | } 408 | #console-panel div.jsoneditor-tree div.jsoneditor-tree-inner { 409 | padding-bottom: 0; 410 | } 411 | 412 | /* Without this, a scroll seems to come up */ 413 | #console-panel div.jsoneditor-tree { 414 | display: inline; 415 | } 416 | 417 | #console-panel .jsoneditor, 418 | #console-panel .jsoneditor-outer, 419 | #console-panel .jsoneditor-tree-inner, 420 | #console-panel .jsoneditor-outer > .jsoneditor-tree, 421 | #console-panel .jsoneditor-outer > .jsoneditor-tree > .jsoneditor-tree-inner > .jsoneditor-tree { 422 | display: inline; 423 | } 424 | 425 | /* This style may be useful in older browsers */ 426 | #console-panel div.jsoneditor-value.jsoneditor-array, 427 | #console-panel div.jsoneditor-value.jsoneditor-object { 428 | min-width: unset; 429 | } 430 | 431 | 432 | #console-panel div.jsoneditor-value { 433 | width: max-content; 434 | } 435 | 436 | #console-panel div.jsoneditor-tree button.jsoneditor-button, 437 | #console-panel div.jsoneditor-tree button.jsoneditor-button.jsoneditor-expanded { 438 | background-position: 0px 2px; 439 | } 440 | 441 | #console-panel div.jsoneditor-tree button.jsoneditor-button { 442 | width: 10px; 443 | height: 10px; 444 | background-repeat: no-repeat; 445 | 446 | /* chrome-devtools://devtools/bundled/Images/treeoutlineTriangles.png */ 447 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAICAQAAABwz0azAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJRj/Z+u0AAAAL0lEQVQI12NgyGBgZICD/wy7GGQRnP8MHxjSEJz/DP8ZtjJIMTEga0BXhmQAktEApfUQ8zThbVYAAAAASUVORK5CYII="); 448 | } 449 | 450 | #console-panel div.jsoneditor-tree button.jsoneditor-button.jsoneditor-expanded { 451 | /* chrome-devtools://devtools/bundled/Images/treeoutlineTriangles.png */ 452 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAQAAAC7znxOAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJDGkzkKZAAAAP0lEQVQI12Ng4Ga4xfAfDu8x8DIwMDBYMfyBCvxlsGOAgm6oUBcDHLAzXGL4z3CNgYMBCRgyfGUwZUAD2jAGAEP7FIhkSA3EAAAAAElFTkSuQmCC"); 453 | } 454 | 455 | 456 | #console-panel div.jsoneditor-readonly, 457 | #console-panel div.jsoneditor-value { 458 | padding: 0; 459 | margin: 0; 460 | } 461 | 462 | #console-panel div.jsoneditor-field, 463 | #console-panel div.jsoneditor-readonly, 464 | #console-panel div.jsoneditor-value { 465 | min-height: 0px; 466 | min-width: 0px; /* Useful for keeping widths for property names as small as possible */ 467 | } 468 | 469 | #console-panel .jsoneditor-schema-error, 470 | #console-panel div.jsoneditor td, 471 | #console-panel div.jsoneditor textarea, 472 | #console-panel div.jsoneditor th, 473 | #console-panel div.jsoneditor-field, 474 | #console-panel div.jsoneditor-value { 475 | font-size: 11px; 476 | font-family: monospace; 477 | } 478 | 479 | 480 | #console-panel div.jsoneditor td.jsoneditor-tree { 481 | vertical-align: middle; 482 | } 483 | 484 | 485 | /* Begin: Styles to make JSON Editor match Chrome DevTools UI */ 486 | #console-panel div.jsoneditor-field { 487 | color: #881391; 488 | } 489 | 490 | #console-panel div.jsoneditor-value.jsoneditor-string { 491 | color: #c41a16; 492 | } 493 | 494 | #console-panel div.jsoneditor-value.jsoneditor-string:before, 495 | #console-panel div.jsoneditor-value.jsoneditor-string:after { 496 | content: '"'; 497 | color: #222; 498 | } 499 | 500 | #console-panel div.jsoneditor-empty { 501 | border-width: 0; 502 | } 503 | 504 | #console-panel .jsoneditor-expandable .jsoneditor-readonly { 505 | text-transform: capitalize; 506 | color: rgb(33, 33, 33); 507 | } 508 | 509 | #console-panel div.jsoneditor-tree button.jsoneditor-button:focus { 510 | background-color: transparent; 511 | outline: none; 512 | } 513 | 514 | /* End */ 515 | 516 | 517 | /* Begin: Styles to make Prism JS match Chrome DevTools */ 518 | #console-panel .only-first-line-of-code code.language-markup:after { 519 | content: '…'; 520 | } 521 | 522 | #console-panel pre.language-markup { 523 | background-color: transparent; 524 | padding: 0; 525 | margin: 0; 526 | 527 | display: inline-block; 528 | } 529 | /* End */ 530 | 531 | 532 | #console-panel .all-lines-of-code { 533 | display: inline-block; 534 | } 535 | 536 | #console-panel .console-panel-expand-collapse { 537 | display: inline-block; 538 | width: 10px; 539 | height: 10px; 540 | } 541 | 542 | #console-panel .console-panel-expand-collapse.console-panel-collapsed, 543 | #console-panel .console-panel-expand-collapse.console-panel-expanded { 544 | cursor: pointer; 545 | background-repeat: no-repeat; 546 | } 547 | #console-panel .console-panel-expand-collapse.console-panel-expanded { 548 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAQAAAC7znxOAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJDGkzkKZAAAAP0lEQVQI12Ng4Ga4xfAfDu8x8DIwMDBYMfyBCvxlsGOAgm6oUBcDHLAzXGL4z3CNgYMBCRgyfGUwZUAD2jAGAEP7FIhkSA3EAAAAAElFTkSuQmCC"); 549 | background-position: 0px 2px; 550 | } 551 | 552 | #console-panel .console-panel-expand-collapse.console-panel-collapsed { 553 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAICAQAAABwz0azAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiCxITJRj/Z+u0AAAAL0lEQVQI12NgyGBgZICD/wy7GGQRnP8MHxjSEJz/DP8ZtjJIMTEga0BXhmQAktEApfUQ8zThbVYAAAAASUVORK5CYII="); 554 | } 555 | 556 | #console-panel .only-first-line-of-code { 557 | vertical-align: top; 558 | vertical-align: text-top; 559 | } 560 | #console-panel .all-lines-of-code { 561 | vertical-align: top; 562 | } 563 | #console-panel code[class*="language-"], 564 | #console-panel pre[class*="language-"] { 565 | white-space: pre-wrap; 566 | word-break: break-word; 567 | } 568 | 569 | /* Begin: Useful styles when Prism JS is not available */ 570 | #console-panel .log-value-dom .all-lines-of-code pre, 571 | #console-panel .log-value-dom .only-first-line-of-code pre { 572 | display: inline; 573 | } 574 | /* End */ 575 | 576 | /* Begin: Match Prism JS with DevTools style */ 577 | #console-panel code[class*="language-"], 578 | #console-panel pre[class*="language-"] { 579 | font-family: monospace; 580 | } 581 | 582 | #console-panel .token.tag { 583 | color: #881280; 584 | } 585 | #console-panel .token.attr-name { 586 | color: #994500; 587 | } 588 | 589 | #console-panel .token.attr-value { 590 | color: #1a1aa6; 591 | } 592 | 593 | #console-panel .token.comment { 594 | color: #236e25; 595 | } 596 | /* */ 597 | 598 | 599 | /* Begin: Resize related CSS */ 600 | html #console-panel .dev-tools-resize-handle { 601 | top: 0; 602 | height: inherit; 603 | padding-top: inherit; 604 | padding-bottom: inherit; 605 | position: absolute; 606 | width: 100%; 607 | left: 0; 608 | display: block; 609 | } 610 | 611 | #console-panel .dev-tools { 612 | top: unset !important; 613 | bottom: 0 !important; 614 | } 615 | /* End */ 616 | 617 | /* Begin: jQuery UI related fix */ 618 | #console-panel .dev-tools { 619 | position: fixed; 620 | } 621 | /* End */ 622 | -------------------------------------------------------------------------------- /test/test-copy-files-from-parent-folder/folder-input-1/folder-input-2/copy-files-from-to.cjson: -------------------------------------------------------------------------------- 1 | { 2 | "copyFiles": [ 3 | { 4 | "from": "../../code/*.*", 5 | "to": "../../dest/folder-output-1/" 6 | }, 7 | { 8 | "from": "../../code/*.{js,css}", 9 | "to": "../../dest/folder-output-2/" 10 | } 11 | ], 12 | "copyFilesSettings": { 13 | "whenFileExists": "overwrite" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/test-copy-files-to-a-directory/.gitignore: -------------------------------------------------------------------------------- 1 | /target-dir/ 2 | -------------------------------------------------------------------------------- /test/test-copy-files-to-a-directory/copy-files-from-to.json: -------------------------------------------------------------------------------- 1 | { 2 | "copyFiles": [ 3 | { 4 | "from": "source-dir/file1.txt", 5 | "to": "target-dir/" 6 | }, 7 | { 8 | "from": "source-dir/file2.*", 9 | "to": "target-dir/" 10 | }, 11 | { 12 | "from": "source-dir/*.md", 13 | "to": "target-dir/" 14 | }, 15 | { 16 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/v1.0.3/src/console-panel.js", 17 | "to": "target-dir/remote/" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /test/test-copy-files-to-a-directory/source-dir/file1.txt: -------------------------------------------------------------------------------- 1 | file1.txt 2 | -------------------------------------------------------------------------------- /test/test-copy-files-to-a-directory/source-dir/file2.txt: -------------------------------------------------------------------------------- 1 | file2.txt 2 | -------------------------------------------------------------------------------- /test/test-copy-files-to-a-directory/source-dir/readme1.md: -------------------------------------------------------------------------------- 1 | readme1.md 2 | -------------------------------------------------------------------------------- /test/test-copy-files-to-a-directory/source-dir/readme2.md: -------------------------------------------------------------------------------- 1 | readme2.md 2 | -------------------------------------------------------------------------------- /test/test-copy-instructions-from-package-json/.gitignore: -------------------------------------------------------------------------------- 1 | # https://stackoverflow.com/questions/35278885/gitignore-exclusion-is-not-working-for-a-single-file/35279076#35279076 2 | /node_modules/** 3 | !/node_modules/jquery 4 | !/node_modules/jquery/dist 5 | !/node_modules/jquery/dist/jquery.js 6 | 7 | /scripts/ 8 | -------------------------------------------------------------------------------- /test/test-copy-instructions-from-package-json/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-application", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "my-application", 9 | "version": "1.0.0", 10 | "dependencies": { 11 | "jquery": "=3.7.1" 12 | } 13 | }, 14 | "node_modules/jquery": { 15 | "version": "3.7.1", 16 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", 17 | "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/test-copy-instructions-from-package-json/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-application", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "jquery": "=3.7.1" 6 | }, 7 | "copyFiles": [ 8 | { 9 | "from": "node_modules/jquery/dist/jquery.js", 10 | "to": "scripts/jquery/jquery.js" 11 | }, 12 | { 13 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.js", 14 | "to": "scripts/console-panel/console-panel.js" 15 | }, 16 | { 17 | "from": "https://raw.githubusercontent.com/webextensions/console-panel/master/src/console-panel.css", 18 | "to": "scripts/console-panel/console-panel.css" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /test/test-minify-js-with-terser-options/.gitignore: -------------------------------------------------------------------------------- 1 | # https://stackoverflow.com/questions/35278885/gitignore-exclusion-is-not-working-for-a-single-file/35279076#35279076 2 | /node_modules/** 3 | !node_modules/console-panel/ 4 | !node_modules/console-panel/src/ 5 | !node_modules/console-panel/src/console-panel.js 6 | 7 | /dist/ 8 | -------------------------------------------------------------------------------- /test/test-minify-js-with-terser-options/copy-files-from-to.cjson: -------------------------------------------------------------------------------- 1 | { 2 | "copyFiles": [ 3 | { 4 | "from": "node_modules/console-panel/src/console-panel.js", 5 | "to": "dist/console-panel.js" 6 | } 7 | ], 8 | "copyFilesSettings": { 9 | "minifyJs": true, 10 | "minifyJsTerserOptions": { 11 | "mangle": true 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/test-minify-js-with-terser-options/expected-output/dist/console-panel.js: -------------------------------------------------------------------------------- 1 | /*! 2 | console-panel 3 | A console panel within webpage to help in the following use-cases: 4 | * Get notification on console messages 5 | * Console logging on mobile and tablet devices 6 | * Console logging on Microsoft Edge / Internet Explorer (without opening native Developer Tools) 7 | https://github.com/webextensions/console-panel 8 | by Priyank Parashar (https://webextensions.org/) 9 | MIT License 10 | */ 11 | !function(e){if(!window.consolePanel){ 12 | /*! (C) WebReflection Mit Style License */ 13 | var o=function(e,o){var n="~",t="\\x"+("0"+n.charCodeAt(0).toString(16)).slice(-2),r="\\"+t,i=new o(t,"g"),l=new o(r,"g"),s=new o("(?:^|([^\\\\]))"+r),a=[].indexOf||function(e){for(var o=this.length;o--&&this[o]!==e;);return o},c=String;function d(e,o,t){return o instanceof Array?function(e,o,n){for(var t=0,r=o.length;t','
','
','
',n,"
","
","
",""].join(""),h)try{var v=r.firstChild.firstChild.firstChild;v.addEventListener("mouseenter",(function(){v.style.transition="opacity 0.3s ease-out",v.style.opacity="0",v.style.pointerEvents="none"}),!1)}catch(e){}r.style.display="",t.appendChild(r),l(),e=o.setTimeout((function(){i(r)}),s||5e3)};return s.hide=function(){i(r),l()},s}(),t="Disable for this instance",r={}; 14 | /*! 15 | devtools-detect 16 | Detect if DevTools is open 17 | https://github.com/sindresorhus/devtools-detect 18 | by Sindre Sorhus 19 | MIT License 20 | */ 21 | !function(e){"use strict";var o={open:!1,orientation:null},n=160,t=function(e,o){window.dispatchEvent(new CustomEvent("console-panel-devtoolschange",{detail:{open:e,orientation:o}}))};(e=e||{}).getDevToolsStatus=function(){var e={},o=window.outerWidth-window.innerWidth>n,t=window.outerHeight-window.innerHeight>n,r=o?"vertical":"horizontal";return t&&o||!(window.Firebug&&window.Firebug.chrome&&window.Firebug.chrome.isInitialized||o||t)?(e.open=!1,e.orientation=null):(e.open=!0,e.orientation=r),e};var r=function(){var e=window.outerWidth-window.innerWidth>n,r=window.outerHeight-window.innerHeight>n,i=e?"vertical":"horizontal";return r&&e||!(window.Firebug&&window.Firebug.chrome&&window.Firebug.chrome.isInitialized||e||r)?(o.open&&t(!1,null),o.open=!1,o.orientation=null):(o.open&&o.orientation===i||t(!0,i),o.open=!0,o.orientation=i),o};e.updateDevToolsStatus=r,window.addEventListener("resize",(function(e){e.target===window&&r()}))}(r);var i=function(e){"loading"!==document.readyState?e():document.addEventListener("DOMContentLoaded",e)},l=function(e){return"userPreference-"+e},s={};s[l("consolePanelHeight")]="250";var a,c=function(e,o){var n=l(e);if(void 0!==o)return function(e,o){try{return localStorage[e]=o,!0}catch(e){return!1}}(n,o);var t=function(e){try{return localStorage[e]}catch(e){return}}(n);return void 0===t?s[n]:t},d=function(e){return(""+e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},u=function(e,o){e.innerHTML=d(o)},f=function(e){return e=(e=(e=e||"").replace(/:[0-9]+$/,"")).replace(/:[0-9]+$/,"")},p=function(e){var o,n=e.skipLevels||1,t="";if(Object.keys(e).indexOf("stack")>=0)t=e.stack?e.stack:"";else try{throw new Error("")}catch(e){t=e.stack||""}-1!==navigator.userAgent.toLowerCase().indexOf("gecko")&&-1===navigator.userAgent.toLowerCase().indexOf("like gecko")?(o=t.split(/\n[\s]*/).map((function(e){var o=e.split("@");return o[o.length-1]}))).splice(0,n-1):(o=t.split(/\n[\s]+at[\s]/)).splice(0,n);var r=t.split(/\n/);"Error"===r[0]?r.splice(1,n-1):r.splice(0,n-1),r=r.join("\n");var i,l=o[0];return l&&l.indexOf("(")>=0&&(l=(l=l.substr(l.indexOf("(")+1)).substr(0,l.indexOf(")"))),{stack:r,resourceLineCharacter:(i=l,i=(i=i||"").split("/").pop()),resourceUrlLineCharacter:l,resourceUrl:f(l)}},g=function(e,o,n,t){t=t||e;var r=e[o];return e[o]=function(){"function"==typeof r&&r.apply(t,arguments),n.apply(t,arguments)},r};a=Object.getPrototypeOf(console).log?Object.getPrototypeOf(console):console;var h=function(){var f=function(){this.originals={},this.arrLogs=[],this.config={reportLogLines:!0},this.domReady=!1,this.enabled=!1};return f.prototype.setButtonPosition=function(e){this.devToolsIconContainer.className="dev-tools-icon-container dev-tools-icon-container-"+e},f.prototype.showDevToolsIconContainer=function(){this.isConsolePanelVisible()||(this.devToolsIconContainer.style.display="block")},f.prototype.hideDevToolsIconContainer=function(){this.devToolsIconContainer.style.display="none"},f.prototype.isDevToolsIconContainerVisible=function(){return"block"===this.devToolsIconContainer.style.display},f.prototype.isConsolePanelVisible=function(){return"block"===this.devTools.style.display},f.prototype.hideConsolePanel=function(){this.devTools.style.display="none"},f.prototype.showConsolePanel=function(){this.devTools.style.display="block",this.flushLogsToUIAsync()},f.prototype.hideBecauseDevToolsIsOpen=function(){var e=this;n("Disabled console-panel",null,{verticalAlignment:"bottom",horizontalAlignment:"right"}),e.disable(),e.hideDevToolsIconContainer(),e.hideConsolePanel()},f.prototype.showBecauseDevToolsIsClosed=function(){var e=this;e.enable(e.config),e.isDevToolsIconContainerVisible()?n.hide():n("Enabled console-panel",null,{verticalAlignment:"bottom",horizontalAlignment:"right"})},f.prototype.hasStrongNotification=function(){for(var e=this.config.strongNotificationFor,o=this.config.skipStrongNotificationIfNoStackTrace,n=!1,t=this.arrLogs,r=0;r=0||"error"===l&&e.indexOf("console.error")>=0||"warn"===l&&e.indexOf("console.warn")>=0||"info"===l&&e.indexOf("console.info")>=0||"log"===l&&e.indexOf("console.log")>=0){n=!0;break}}return n},f.prototype.getRecommendedClassNameForDevToolsIcon=function(){for(var e="found-something",o=!1,n=!1,t=!1,r=!1,i=this.arrLogs,l=0;l=0)return!0}}return!1},f.prototype.flushCountToIcon=function(){var e=this.devToolsIconStrongNotification,o=this.devToolsIcon;if(this.config.showOnlyForTheseRelevantMessages){var n=this.config.showOnlyForTheseRelevantMessages;this.areThereUnreadRelevantMessages(n)&&this.showDevToolsIconContainer()}var t=this.arrLogs;if(t.length){o.innerHTML=t.length,o.title=t.length+" unread message"+(1===t.length?"":"s");var r=this.getRecommendedClassNameForDevToolsIcon(),i=this.hasStrongNotification();if(o.className="dev-tools-icon "+r,e.className=i?"strong-notification":"",i){var l=Date.now();e.setAttribute("data-last-strong-notification",l);setTimeout((function(){l===parseInt(e.getAttribute("data-last-strong-notification"),10)&&(e.removeAttribute("data-last-strong-notification"),e.classList.remove("strong-notification"))}),1500)}}else o.innerHTML="",o.removeAttribute("title"),o.className="dev-tools-icon no-unread-messages",e.classList.remove("strong-notification")},f.prototype.flushLogsToUIAsync=function(){var e=this;requestAnimationFrame((function(){requestAnimationFrame((function(){e.flushLogsToUI()}))}))},f.prototype.flushLogsToUI=function(){if(this.flushCountToIcon(),this.isConsolePanelVisible()){var e=!1,o=this.logger;o.scrollHeight===o.scrollTop+o.offsetHeight&&(e=!0);for(var n=this.arrLogs;n.length;){var t=n.shift(),r=t.logMode,i=t.logEntry,l=t.initiator,s=t.time,a=document.createElement("div");this.loggerBody.appendChild(a),a.title="Logged at "+s.toTimeString().substring(0,8),a.className="dev-tools-console-message-wrapper "+("log"===r?"log-mode-log":"info"===r?"log-mode-info":"warn"===r?"log-mode-warn":"error"===r?"log-mode-error":"window.onerror"===r?"log-mode-window-onerror":"clear"===r?"log-mode-clear":"unhandled"===r?"log-mode-unhandled":"log-mode-unknown");var c=document.createElement("div");a.appendChild(c),c.className="dev-tools-console-message-code-line",c.innerHTML=function(e){return e.resourceLineCharacter?''+d(e.resourceLineCharacter)+"":""}(l);var f,p=document.createElement("div");if(a.appendChild(p),p.className="dev-tools-console-message",0===i.length)f=document.createElement("span"),p.appendChild(f),f.innerHTML=" ";else for(var g=0;g0){var h=document.createElement("span");p.appendChild(h),h.innerHTML=" "}f=document.createElement("span"),p.appendChild(f);!function(e){var o=e.className||"log-value-unknown",n=e.valueToLog,t=f;if(t.className=o,"log-value-unknown"===o||"log-value-object"===o||"log-value-array"===o)if("undefined"==typeof JSONEditor)t.classList.add("jsoneditor-not-available"),Array.isArray(n)?u(t,String("["+n.length+"]")):u(t,"object"==typeof n?String("{"+Object.keys(n).length+"}"):String(typeof n)+" ("+String(n)+")");else{var r=new JSONEditor(t,{mode:"view",navigationBar:!1,search:!1,sortObjectKeys:!0});r.set(n),r.collapseAll()}else if("log-value-dom"===o){var i=n.split("\n")[0],l=!1;i!==n&&(l=!0);var s=function(){var e=document.createElement("span");return t.appendChild(e),e.className="all-lines-of-code",e.innerHTML='
'+d(n)+"
","undefined"!=typeof Prism&&Prism.highlightAllUnder(e),e};if(l){var a,c=document.createElement("span");t.appendChild(c),c.className="console-panel-expand-collapse console-panel-collapsed";var p=document.createElement("span");t.appendChild(p),p.className="only-first-line-of-code",p.innerHTML='
'+d(i)+"
","undefined"!=typeof Prism&&Prism.highlightAllUnder(p),c.addEventListener("click",(function(e){c.classList.contains("console-panel-collapsed")?(p.style.display="none",a?a.style.display="":a=s()):(p.style.display="",a.style.display="none"),c.classList.toggle("console-panel-collapsed"),c.classList.toggle("console-panel-expanded")}))}else s()}else t.innerHTML=String(n)}(i[g])}if(["error","warn"].indexOf(r)>=0&&l.stack){var v=document.createElement("div");p.appendChild(v),v.className="log-call-stack";var m=l.stack.split("\n");m.shift(),m=m.join("\n"),v.innerHTML=d(m)}}e&&a&&a.scrollIntoView(!1),this.flushCountToIcon()}},f.prototype.logArrayEntry=function(e){var n,t,r=e.type||"unknown",i=e.initiator||{},l=e.value,s="log-value-unknown",a="not-handled";if("boolean"===r)s="log-value-boolean",a=l;else if("number"===r)s="log-value-number",a=l;else if("string"===r)s="log-value-string",a=d((n=l.toString(),!(t=5003)||t<=3?n:n.length>t?n.substr(0,t-3)+"...":n));else if("document.all"===r)s="log-value-document-all",a=l;else if("undefined"===r)s="log-value-undefined",a=l;else if("null"===r)s="log-value-null",a=l;else if("function"===r)s="log-value-function",a=l;else if("console.clear"===r)s="log-value-console-clear",a=l;else if("dom"===r)s="log-value-dom",a=l.outerHTML;else if("dom-text"===r)s="log-value-dom-text",a=l.textContent;else if("window.onerror"===r){s="log-value-window-onerror";var c=function(){var e="An error occurred",o=l.error;try{e=o[4].stack}catch(o){try{e=l.error[0]+"\n"+l.error[1]+":"+l.error[2]+(void 0===l.error[3]?"":":"+l.error[3])}catch(e){}}return e}();a=d(c)}else"array"===r?(s="log-value-array",a=JSON.parse(o.stringify(l,null,"","[Circular]"))):"object"===r?(s="log-value-object",a=JSON.parse(o.stringify(l,null,"","[Circular]"))):(s="log-value-unknown",a=JSON.parse(o.stringify(l,null,"","[Circular]")));return{className:s,initiator:i,valueToLog:a}},f.prototype.markLogEntry=function(e,o){for(var n=[],t=0;t=0?t():o};o["window.onerror"]=t("window.onerror",o["window.onerror"],(function(){return g(window,"onerror",(function(){e.markLogEntry("window.onerror",[{error:arguments}])}))})),o["console.clear"]=g(a,"clear",(function(){e.clear()}),console),o["console.log"]=t("console.log",o["console.log"],(function(){return g(a,"log",(function(){e.markLogEntry("log",arguments)}),console)})),o["console.info"]=t("console.info",o["console.info"],(function(){return g(a,"info",(function(){e.markLogEntry("info",arguments)}),console)})),o["console.warn"]=t("console.warn",o["console.warn"],(function(){return g(a,"warn",(function(){e.markLogEntry("warn",arguments)}),console)})),o["console.error"]=t("console.error",o["console.error"],(function(){return g(a,"error",(function(){e.markLogEntry("error",arguments)}),console)})),Object.keys(a).forEach((function(n){-1===["log","info","warn","error","clear"].indexOf(n)&&"function"==typeof a[n]&&(o["console."+n]=t(n,o["console."+n],(function(){return g(a,n,(function(){e.markLogEntry("unhandled",arguments)}),console)})))}))},f.prototype.render=function(){var o=this,i=document.createElement("div");i.id="console-panel",document.body.appendChild(i);var a=document.createElement("div");this.devToolsIconContainer=a,i.appendChild(a);var d=document.createElement("div");this.devToolsIconStrongNotification=d,a.appendChild(d);var u=document.createElement("div");this.devToolsIcon=u,u.className="dev-tools-icon no-unread-messages",u.addEventListener("click",(function(e){o.showConsolePanel(),o.hideDevToolsIconContainer()})),this.hideDevToolsIconContainer(),d.appendChild(u);var f,p=document.createElement("div");this.devTools=p,i.appendChild(p),p.className="dev-tools",this.hideConsolePanel(),p.style.height=((f=parseInt(c("consolePanelHeight"),10))>=0&&f<=1/0||(f=s[l("consolePanelHeight")]),f+"px");var g=document.createElement("div");p.appendChild(g),g.className="dev-tools-header";var h=document.createElement("div");g.appendChild(h),h.className="dev-tools-resize-handle",h.innerHTML=" ";var v=document.createElement("div");g.appendChild(v),v.title="Close",v.className="dev-tools-header-cross-icon",v.addEventListener("click",(function(e){o.hideConsolePanel(),o.showDevToolsIconContainer()}));var m=document.createElement("div");o.disableIcon=m,m.title=t,m.className="dev-tools-header-disable-icon",m.addEventListener("click",(function(e){if(o.config&&"function"==typeof o.config.beforeDisableButtonClick&&!1===o.config.beforeDisableButtonClick())return;o.hideConsolePanel(),o.disable()})),g.appendChild(m);var y=document.createElement("div");g.appendChild(y),y.title="Clear",y.className="dev-tools-clear-console-icon",y.addEventListener("click",(function(e){o.clear(),console.clear()}));var w=document.createElement("div");if(g.appendChild(w),w.innerHTML="Console",w.style.cssFloat="left",e&&e.fn&&e.fn.resizable)try{var b=e(".dev-tools");e.ui?(h.classList.add("ui-resizable-handle"),h.classList.add("ui-resizable-n"),b.resizable({handles:{n:b.find(".dev-tools-resize-handle")},stop:function(e,o){c("consolePanelHeight",o.size.height)}})):b.resizable({handleSelector:".dev-tools-resize-handle",resizeWidth:!1,resizeHeightFrom:"top",onDragEnd:function(e,o,n){c("consolePanelHeight",o.outerHeight())}}),h.style.cursor="n-resize"}catch(e){n('Error in setting up "resize" for console-panel (Learn more)',1e4)}var T=document.createElement("div");this.logger=T,p.appendChild(T),T.className="dev-tools-console";var L=document.createElement("div");T.appendChild(L),L.className="dev-tools-console-header";var C=document.createElement("div");this.loggerBody=C,T.appendChild(C),C.className="dev-tools-console-body",window.addEventListener("console-panel-devtoolschange",(function(e){o.config.doNotUseWhenDevToolsMightBeOpenInTab&&(e.detail.open?o.hideBecauseDevToolsIsOpen():o.showBecauseDevToolsIsClosed())})),r.updateDevToolsStatus()},f.prototype.enable=function(e){e=e||{};var o=this;o.enabled&&o.disable();var n=Array.isArray(e.functionsToIntercept)?e.functionsToIntercept:"all",l=e.showOnlyForTheseRelevantMessages||null,s=e.strongNotificationFor||["window.onerror","console.error"],a=e.skipStrongNotificationIfNoStackTrace||!1,c=void 0===e.reportLogLines||!!e.reportLogLines,d=void 0!==e.doNotUseWhenDevToolsMightBeOpenInTab&&e.doNotUseWhenDevToolsMightBeOpenInTab,u="string"==typeof e.disableButtonTitle&&""!==e.disableButtonTitle?e.disableButtonTitle:t,f=e.beforeDisableButtonClick,p=function(){switch(e.position){case"top-left":case"top-right":case"bottom-left":case"bottom-right":case"left-top":case"left-bottom":case"right-top":case"right-bottom":return e.position;default:return"bottom-right"}}();!function(e){e.functionsToIntercept=n,e.showOnlyForTheseRelevantMessages=l,e.strongNotificationFor=s,e.skipStrongNotificationIfNoStackTrace=a,e.doNotUseWhenDevToolsMightBeOpenInTab=d,e.disableButtonTitle=u,e.beforeDisableButtonClick=f,e.position=p}(o.config),o.setupIntercept(),c?o.enableReportLogLines():o.disableReportLogLines(),o.domReady||i((function(){o.render(),o.domReady=!0})),i((function(){var e;o.setButtonPosition(p),o.disableIcon.title=u,l||o.config.doNotUseWhenDevToolsMightBeOpenInTab&&((e=r.getDevToolsStatus())&&e.open)||o.showDevToolsIconContainer(),o.flushLogsToUIAsync()})),o.enabled=!0},f.prototype.disable=function(){var e=this;window.onerror=e.originals["window.onerror"],Object.keys(a).forEach((function(o){e.originals["console."+o]&&(a[o]=e.originals["console."+o])})),e.enabled=!1},f.prototype.enableReportLogLines=function(){this.config.reportLogLines=!0},f.prototype.disableReportLogLines=function(){this.config.reportLogLines=!1},f}();window.consolePanel=new h}}(window.jQuery); -------------------------------------------------------------------------------- /test/test-minify-js-with-terser-options/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "example", 9 | "version": "0.0.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "console-panel": "=1.0.4" 13 | } 14 | }, 15 | "node_modules/console-panel": { 16 | "version": "1.0.4", 17 | "resolved": "https://registry.npmjs.org/console-panel/-/console-panel-1.0.4.tgz", 18 | "integrity": "sha512-cPm/NquYrJmoWZMp/hbZCldRD/SEjd74J0f7xKseLDZ955iJZ7u6GdOtfTxKih0iCbRPEtSR3Z5hlUseAiVCcQ==", 19 | "dev": true 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/test-minify-js-with-terser-options/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.0", 4 | "description": "Example", 5 | "license": "MIT", 6 | "repository": "https://github.com/webextensions/copy-files-from-to", 7 | "devDependencies": { 8 | "console-panel": "=1.0.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/test-minify-js/.gitignore: -------------------------------------------------------------------------------- 1 | # https://stackoverflow.com/questions/35278885/gitignore-exclusion-is-not-working-for-a-single-file/35279076#35279076 2 | /node_modules/** 3 | !node_modules/console-panel/ 4 | !node_modules/console-panel/src/ 5 | !node_modules/console-panel/src/console-panel.js 6 | 7 | /dist/ 8 | -------------------------------------------------------------------------------- /test/test-minify-js/copy-files-from-to.cjson: -------------------------------------------------------------------------------- 1 | { 2 | "copyFiles": [ 3 | { 4 | "from": "node_modules/console-panel/src/console-panel.js", 5 | "to": "dist/console-panel.js" 6 | } 7 | ], 8 | "copyFilesSettings": { 9 | "minifyJs": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/test-minify-js/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "example", 9 | "version": "0.0.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "console-panel": "=1.0.4" 13 | } 14 | }, 15 | "node_modules/console-panel": { 16 | "version": "1.0.4", 17 | "resolved": "https://registry.npmjs.org/console-panel/-/console-panel-1.0.4.tgz", 18 | "integrity": "sha512-cPm/NquYrJmoWZMp/hbZCldRD/SEjd74J0f7xKseLDZ955iJZ7u6GdOtfTxKih0iCbRPEtSR3Z5hlUseAiVCcQ==", 19 | "dev": true 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/test-minify-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.0", 4 | "description": "Example", 5 | "license": "MIT", 6 | "repository": "https://github.com/webextensions/copy-files-from-to", 7 | "devDependencies": { 8 | "console-panel": "=1.0.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /* globals describe, it */ 2 | 3 | var path = require('path'); 4 | 5 | var shell = require('shelljs'); 6 | 7 | var chai = require('chai'); 8 | var chaiFiles = require('chai-files'); 9 | 10 | chai.use(chaiFiles); 11 | 12 | var expect = chai.expect; 13 | var file = chaiFiles.file; 14 | 15 | var { rimrafSync } = require('rimraf'); 16 | 17 | var copyFilesFromTo = require('../index.js'); // eslint-disable-line no-unused-vars 18 | 19 | // const SILENT = false; // DEV-HELPER: DEBUG-HELPER: 20 | const SILENT = true; 21 | 22 | // const COMMAND_TO_RUN = 'node --inspect-brk ' + path.join(__dirname, '..', 'index.js'); // DEV-HELPER: DEBUG-HELPER: 23 | const COMMAND_TO_RUN = path.join(__dirname, '..', 'index.js'); 24 | 25 | describe('package', function() { 26 | describe('copy-files-from-to', function() { 27 | this.timeout(10000); 28 | 29 | // If there would be an error in require, the code would not reach this point 30 | it('should load fine when using require', function(done) { 31 | done(); 32 | }); 33 | 34 | it('should be able to copy files from a json config', function (done) { 35 | var basicUsageDir = path.join(__dirname, 'basic-usage'); 36 | 37 | rimrafSync(path.join(basicUsageDir, 'scripts')); 38 | 39 | var 40 | consolePanelJsOriginal = path.join(basicUsageDir, 'expected-output', 'scripts', 'console-panel', 'console-panel.js'), 41 | consolePanelJs = path.join(basicUsageDir, 'scripts', 'console-panel', 'console-panel.js'), 42 | 43 | consolePanelCssOriginal = path.join(basicUsageDir, 'expected-output', 'scripts', 'console-panel', 'console-panel.css'), 44 | consolePanelCss = path.join(basicUsageDir, 'scripts', 'console-panel', 'console-panel.css'), 45 | 46 | jqueryJsOriginal = path.join(basicUsageDir, 'node_modules', 'jquery', 'dist', 'jquery.js'), 47 | jqueryJs = path.join(basicUsageDir, 'scripts', 'jquery', 'jquery.js'); 48 | 49 | shell.exec( 50 | COMMAND_TO_RUN, 51 | { 52 | silent: SILENT, 53 | cwd: basicUsageDir 54 | }, 55 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 56 | expect(file(jqueryJs)).to.equal(file(jqueryJsOriginal)); 57 | expect(file(consolePanelJs)).to.equal(file(consolePanelJsOriginal)); 58 | expect(file(consolePanelCss)).to.equal(file(consolePanelCssOriginal)); 59 | 60 | done(); 61 | } 62 | ); 63 | }); 64 | 65 | it('should be able to copy files from a cjson config', function (done) { 66 | var advancedUsageDir = path.join(__dirname, 'advanced-usage'); 67 | 68 | rimrafSync(path.join(advancedUsageDir, 'public')); 69 | rimrafSync(path.join(advancedUsageDir, 'scripts')); 70 | 71 | var 72 | underscoreJsOriginal = path.join(advancedUsageDir, 'expected-output', 'scripts', 'underscore.js'), 73 | underscoreJs = path.join(advancedUsageDir, 'scripts', 'underscore.js'), 74 | 75 | consolePanelJsOriginal = path.join(advancedUsageDir, 'expected-output', 'scripts', 'console-panel', 'console-panel.js'), 76 | consolePanelJs = path.join(advancedUsageDir, 'scripts', 'console-panel', 'console-panel.js'), 77 | 78 | aJpgOriginal = path.join(advancedUsageDir, 'expected-output', 'public', 'images', 'test-a', 'a.jpg'), 79 | bJpgOriginal = path.join(advancedUsageDir, 'expected-output', 'public', 'images', 'test-b', 'b.jpg'), 80 | cTxtOriginal = path.join(advancedUsageDir, 'expected-output', 'public', 'images', 'test-c', 'c.txt'), 81 | 82 | aJpg = path.join(advancedUsageDir, 'public', 'images', 'test-a', 'a.jpg'), 83 | bJpg = path.join(advancedUsageDir, 'public', 'images', 'test-b', 'b.jpg'), 84 | cTxt = path.join(advancedUsageDir, 'public', 'images', 'test-c', 'c.txt'), 85 | 86 | aJpgFlat = path.join(advancedUsageDir, 'public', 'copy-to-flat-directory', 'a.jpg'), 87 | bJpgFlat = path.join(advancedUsageDir, 'public', 'copy-to-flat-directory', 'b.jpg'), 88 | cTxtFlat = path.join(advancedUsageDir, 'public', 'copy-to-flat-directory', 'c.txt'); 89 | 90 | shell.exec( 91 | COMMAND_TO_RUN, 92 | { 93 | silent: SILENT, 94 | cwd: advancedUsageDir 95 | }, 96 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 97 | expect(file(underscoreJs)).to.equal(file(underscoreJsOriginal)); 98 | expect(file(consolePanelJs)).to.equal(file(consolePanelJsOriginal)); 99 | 100 | expect(file(aJpg)).to.equal(file(aJpgOriginal)); 101 | expect(file(bJpg)).to.equal(file(bJpgOriginal)); 102 | expect(file(cTxt)).to.equal(file(cTxtOriginal)); 103 | 104 | expect(file(aJpgFlat)).to.equal(file(aJpgOriginal)); 105 | expect(file(bJpgFlat)).to.equal(file(bJpgOriginal)); 106 | expect(file(cTxtFlat)).to.equal(file(cTxtOriginal)); 107 | 108 | done(); 109 | } 110 | ); 111 | }); 112 | 113 | it('should be able to copy a file in custom mode', function (done) { 114 | var dirToUse = path.join(__dirname, 'test-copy-file-in-custom-mode'); 115 | 116 | rimrafSync(path.join(dirToUse, 'scripts')); 117 | 118 | var 119 | underscoreJsMapOriginal = path.join(dirToUse, 'expected-output', 'scripts', 'underscore.js.map'), 120 | underscoreJsMap = path.join(dirToUse, 'scripts', 'underscore.js.map'); 121 | 122 | shell.exec( 123 | COMMAND_TO_RUN + ' --mode pre-production', 124 | { 125 | silent: SILENT, 126 | cwd: dirToUse 127 | }, 128 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 129 | expect(file(underscoreJsMap)).to.equal(file(underscoreJsMapOriginal)); 130 | 131 | done(); 132 | } 133 | ); 134 | }); 135 | 136 | it('should be able to copy files from parent folder', function (done) { 137 | var testCopyFilesFromParentFolderDir = path.join(__dirname, 'test-copy-files-from-parent-folder'); 138 | var cwdToUse = path.join(testCopyFilesFromParentFolderDir, 'folder-input-1', 'folder-input-2'); 139 | 140 | rimrafSync(path.join(testCopyFilesFromParentFolderDir, 'dest')); 141 | 142 | var 143 | consolePanelJsOriginal = path.join(testCopyFilesFromParentFolderDir, 'code', 'console-panel.js'), 144 | consolePanelCssOriginal = path.join(testCopyFilesFromParentFolderDir, 'code', 'console-panel.css'), 145 | 146 | consolePanelJsGlob1 = path.join(testCopyFilesFromParentFolderDir, 'dest', 'folder-output-1', 'console-panel.js'), 147 | consolePanelCssGlob1 = path.join(testCopyFilesFromParentFolderDir, 'dest', 'folder-output-1', 'console-panel.css'), 148 | 149 | consolePanelJsGlob2 = path.join(testCopyFilesFromParentFolderDir, 'dest', 'folder-output-2', 'console-panel.js'), 150 | consolePanelCssGlob2 = path.join(testCopyFilesFromParentFolderDir, 'dest', 'folder-output-2', 'console-panel.css'); 151 | 152 | shell.exec( 153 | COMMAND_TO_RUN, 154 | { 155 | silent: SILENT, 156 | cwd: cwdToUse 157 | }, 158 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 159 | expect(file(consolePanelJsGlob1)).to.equal(file(consolePanelJsOriginal)); 160 | expect(file(consolePanelCssGlob1)).to.equal(file(consolePanelCssOriginal)); 161 | 162 | expect(file(consolePanelJsGlob2)).to.equal(file(consolePanelJsOriginal)); 163 | expect(file(consolePanelCssGlob2)).to.equal(file(consolePanelCssOriginal)); 164 | 165 | done(); 166 | } 167 | ); 168 | }); 169 | 170 | it('should be able to read copy instructions from package.json file as a fallback', function (done) { 171 | var cwdToUse = path.join(__dirname, 'test-copy-instructions-from-package-json'); 172 | 173 | rimrafSync(path.join(cwdToUse, 'scripts')); 174 | 175 | // There are multiple files which are being copied, but we need to test only one of them to verify 176 | // if instructions are being read from package.json file 177 | var 178 | jqueryJsOriginal = path.join(cwdToUse, 'node_modules', 'jquery', 'dist', 'jquery.js'), 179 | jqueryJs = path.join(cwdToUse, 'scripts', 'jquery', 'jquery.js'); 180 | 181 | shell.exec( 182 | COMMAND_TO_RUN, 183 | { 184 | silent: SILENT, 185 | cwd: cwdToUse 186 | }, 187 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 188 | expect(file(jqueryJs)).to.equal(file(jqueryJsOriginal)); 189 | 190 | done(); 191 | } 192 | ); 193 | }); 194 | 195 | it('should be able to copy a directory', function (done) { 196 | const testCopyDirectory = path.join(__dirname, 'test-copy-directory'); 197 | const cwdToUse = testCopyDirectory; 198 | 199 | rimrafSync(path.join(cwdToUse, 'target-dir')); 200 | 201 | const 202 | dir1File1Source = path.join(testCopyDirectory, 'source-dir', 'dir1', 'file1.txt'), 203 | dir1File2Source = path.join(testCopyDirectory, 'source-dir', 'dir1', 'file2.txt'), 204 | dir2File1Source = path.join(testCopyDirectory, 'source-dir', 'dir2', 'file1.txt'), 205 | dir2File2Source = path.join(testCopyDirectory, 'source-dir', 'dir2', 'file2.txt'); 206 | 207 | const 208 | dir1File1Target = path.join(testCopyDirectory, 'target-dir', 'dir1', 'file1.txt'), 209 | dir1File2Target = path.join(testCopyDirectory, 'target-dir', 'dir1', 'file2.txt'), 210 | dir2File1Target = path.join(testCopyDirectory, 'target-dir', 'dir2', 'file1.txt'), 211 | dir2File2Target = path.join(testCopyDirectory, 'target-dir', 'dir2', 'file2.txt'); 212 | 213 | shell.exec( 214 | COMMAND_TO_RUN, 215 | { 216 | silent: SILENT, 217 | cwd: cwdToUse 218 | }, 219 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 220 | expect(file(dir1File1Target)).to.equal(file(dir1File1Source)); 221 | expect(file(dir1File2Target)).to.equal(file(dir1File2Source)); 222 | 223 | expect(file(dir2File1Target)).to.equal(file(dir2File1Source)); 224 | expect(file(dir2File2Target)).to.equal(file(dir2File2Source)); 225 | 226 | done(); 227 | } 228 | ); 229 | }); 230 | 231 | it('should be able to copy files to a directory', function (done) { 232 | const testDir = path.join(__dirname, 'test-copy-files-to-a-directory'); 233 | const cwdToUse = testDir; 234 | 235 | rimrafSync(path.join(cwdToUse, 'target-dir')); 236 | 237 | const 238 | file1TxtSource = path.join(testDir, 'source-dir', 'file1.txt'), 239 | file2TxtSource = path.join(testDir, 'source-dir', 'file2.txt'), 240 | readme1MdSource = path.join(testDir, 'source-dir', 'readme1.md'), 241 | readme2MdSource = path.join(testDir, 'source-dir', 'readme2.md'), 242 | webFileSource = path.join(testDir, 'expected-output', 'console-panel.js'); 243 | 244 | const 245 | file1TxtTarget = path.join(testDir, 'target-dir', 'file1.txt'), 246 | file2TxtTarget = path.join(testDir, 'target-dir', 'file2.txt'), 247 | readme1MdTarget = path.join(testDir, 'target-dir', 'readme1.md'), 248 | readme2MdTarget = path.join(testDir, 'target-dir', 'readme2.md'), 249 | webFileTarget = path.join(testDir, 'target-dir', 'remote', 'console-panel.js'); 250 | 251 | shell.exec( 252 | COMMAND_TO_RUN, 253 | { 254 | silent: SILENT, 255 | cwd: cwdToUse 256 | }, 257 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 258 | expect(file(file1TxtTarget)).to.equal(file(file1TxtSource)); 259 | expect(file(file2TxtTarget)).to.equal(file(file2TxtSource)); 260 | 261 | expect(file(readme1MdTarget)).to.equal(file(readme1MdSource)); 262 | expect(file(readme2MdTarget)).to.equal(file(readme2MdSource)); 263 | 264 | expect(file(webFileTarget)).to.equal(file(webFileSource)); 265 | 266 | done(); 267 | } 268 | ); 269 | }); 270 | 271 | it('should be able to minify a JS file', function (done) { 272 | const testDir = path.join(__dirname, 'test-minify-js'); 273 | const cwdToUse = testDir; 274 | 275 | rimrafSync(path.join(cwdToUse, 'dist')); 276 | 277 | const 278 | consolePanelJsOriginal = path.join(testDir, 'expected-output', 'dist', 'console-panel.js'), 279 | consolePanelJs = path.join(testDir, 'dist', 'console-panel.js'); 280 | 281 | shell.exec( 282 | COMMAND_TO_RUN, 283 | { 284 | silent: SILENT, 285 | cwd: cwdToUse 286 | }, 287 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 288 | expect(file(consolePanelJs)).to.equal(file(consolePanelJsOriginal)); 289 | 290 | done(); 291 | } 292 | ); 293 | }); 294 | 295 | it('should be able to minify a JS file with custom terser options', function (done) { 296 | const testDir = path.join(__dirname, 'test-minify-js-with-terser-options'); 297 | const cwdToUse = testDir; 298 | 299 | rimrafSync(path.join(cwdToUse, 'dist')); 300 | 301 | const 302 | consolePanelJsOriginal = path.join(testDir, 'expected-output', 'dist', 'console-panel.js'), 303 | consolePanelJs = path.join(testDir, 'dist', 'console-panel.js'); 304 | 305 | shell.exec( 306 | COMMAND_TO_RUN, 307 | { 308 | silent: SILENT, 309 | cwd: cwdToUse 310 | }, 311 | function (exitCode, stdout, stderr) { // eslint-disable-line no-unused-vars 312 | expect(file(consolePanelJs)).to.equal(file(consolePanelJsOriginal)); 313 | 314 | done(); 315 | } 316 | ); 317 | }); 318 | }); 319 | }); 320 | -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path'), 2 | fs = require('fs'); 3 | 4 | var axios = require('axios'), 5 | mkdirp = require('mkdirp'), 6 | { minify: minifyViaTerser } = require('terser'), 7 | isUtf8 = require('is-utf8'); 8 | 9 | var unixify = require('unixify'); 10 | 11 | var { createNoteDownInstance } = require('note-down'); 12 | const logger = createNoteDownInstance(); 13 | logger.removeOption('showLogLine'); 14 | var chalk = logger.chalk; 15 | 16 | var utils = { 17 | logger, 18 | 19 | // https://github.com/sindresorhus/strip-bom/blob/f01a9435b8e7d31bb2bd757e67436d0a1864db0e/index.js 20 | // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string 21 | // conversion translates it to FEFF (UTF-16 BOM) 22 | stripBom: function (string) { 23 | if (string.charCodeAt(0) === 0xFEFF) { 24 | return string.slice(1); 25 | } 26 | return string; 27 | }, 28 | 29 | getEncoding: function(contents) { 30 | return isUtf8(contents) ? 'utf8' : 'binary'; 31 | }, 32 | getColoredTypeString: function(encoding) { 33 | switch (encoding) { 34 | case 'remote': return chalk.cyan('remote'); 35 | case 'binary': return chalk.yellow('binary'); 36 | case 'utf8': return ' utf8 '; 37 | default: return chalk.red(encoding); 38 | } 39 | }, 40 | isRemoteResource: function (resourcePath) { 41 | if ( 42 | resourcePath.indexOf('https://') === 0 || 43 | resourcePath.indexOf('http://') === 0 || 44 | resourcePath.indexOf('ftp://') === 0 45 | ) { 46 | return true; 47 | } 48 | return false; 49 | }, 50 | getRelativePath: function (wrt, fullPath) { 51 | if (utils.isRemoteResource(fullPath)) { 52 | return fullPath; 53 | } 54 | return unixify(path.relative(wrt, fullPath)); 55 | }, 56 | 57 | exitWithError: function (e, errMsg) { 58 | if (errMsg) { 59 | logger.log(chalk.magenta(errMsg)); 60 | } 61 | if (e) { 62 | logger.error(e); 63 | } 64 | process.exit(1); 65 | }, 66 | 67 | // Returns true/false/ 68 | booleanIntention: function (val, defaultValue) { 69 | if (val === undefined) { 70 | return defaultValue; 71 | } else { 72 | return !!val; 73 | } 74 | }, 75 | 76 | ensureDirectoryExistence: function(dirPath) { 77 | var dirname = ( 78 | dirPath[dirPath.length-1] === '/' ? 79 | unixify(path.normalize(dirPath)) : 80 | unixify(path.dirname(dirPath)) 81 | ); 82 | if (!fs.existsSync(dirPath)) { 83 | try { 84 | mkdirp.sync(dirname); 85 | } catch (e) { 86 | logger.error('\n' + chalk.bold.underline('Error:')); 87 | logger.error('Unable to create directory ' + dirname); 88 | 89 | logger.error('\n' + chalk.bold.underline('Error details:')); 90 | logger.error(e); 91 | 92 | process.exit(1); 93 | } 94 | } 95 | }, 96 | 97 | additionalProcessing: async function (additionalOptions, code) { 98 | var needsMinify = additionalOptions.needsMinify; 99 | var minifyJsTerserOptions = additionalOptions.minifyJsTerserOptions; 100 | var removeSourceMappingURL = additionalOptions.removeSourceMappingURL; 101 | var data = {}; 102 | 103 | if (removeSourceMappingURL) { 104 | // LAZY: This approach is simple enough and seems to work well for the common known cases. 105 | // As and when any issues are encountered, this code can be improved. 106 | code = String(code).split('//# sourceMappingURL=')[0]; 107 | data.consoleCommand = data.consoleCommand || {}; 108 | data.consoleCommand.sourceMappingUrl = 'Note: Removed "sourceMappingURL"'; 109 | } 110 | 111 | if (needsMinify) { 112 | const terserOptionsToUse = ( 113 | minifyJsTerserOptions || 114 | // Equivalent to: terser --compress sequences=false --format semicolons=false --output 115 | { 116 | compress: { 117 | sequences: false 118 | }, 119 | mangle: false, 120 | format: { 121 | semicolons: false 122 | } 123 | } 124 | ); 125 | 126 | if (typeof ((terserOptionsToUse || {}).format || {}).comments === 'undefined') { 127 | try { 128 | terserOptionsToUse.format = terserOptionsToUse.format || {}; 129 | terserOptionsToUse.format.comments = function (_, comment) { 130 | if ( 131 | comment.value.charAt(0) === '!' || 132 | /cc_on|copyright|license|preserve/i.test(comment.value) 133 | ) { 134 | return true; 135 | } else { 136 | return false; 137 | } 138 | 139 | // if (comment.type === 'comment2') { // multiline comment 140 | // return /@preserve|@license|@cc_on/i.test(comment.value); 141 | // } else if (comment.type === 'comment1') { // single line comment 142 | // if (comment.value.indexOf('!') === 0) { 143 | // return true; 144 | // } else { 145 | // return /@preserve|@license|@cc_on/i.test(comment.value); 146 | // } 147 | // } else { 148 | // return false; 149 | // } 150 | }; 151 | } catch (e) { 152 | logger.error('Error: Unable to set terser options for preserving code comments. Please check your configuration.'); 153 | logger.error(e); 154 | 155 | process.exit(1); 156 | } 157 | } 158 | var result = await minifyViaTerser( 159 | String(code), 160 | terserOptionsToUse 161 | ); 162 | var consoleCommand; 163 | if (minifyJsTerserOptions) { 164 | consoleCommand = 'terser.minify() with options ' + JSON.stringify(minifyJsTerserOptions); 165 | } else { 166 | consoleCommand = 'terser --compress sequences=false --format semicolons=false --output '; 167 | } 168 | 169 | data.code = result.code || code; 170 | data.consoleCommand = data.consoleCommand || {}; 171 | data.consoleCommand.minifyJs = consoleCommand; 172 | } else { 173 | data.code = code; 174 | } 175 | 176 | return data; 177 | }, 178 | 179 | readContents: function (sourceFullPath, cb) { 180 | if (utils.isRemoteResource(sourceFullPath)) { 181 | axios({ 182 | method: 'get', 183 | url: sourceFullPath, 184 | responseType: 'arraybuffer', 185 | timeout: 30000 186 | }) 187 | .then(function (response) { 188 | if (response.status === 200) { 189 | cb(null, response.data, 'remote'); 190 | } else { 191 | cb('Unexpected statusCode (' + response.status + ') for response of: ' + sourceFullPath); 192 | } 193 | }) 194 | .catch(function (err) { 195 | cb(err); 196 | }); 197 | } else { 198 | try { 199 | var rawContents = fs.readFileSync(sourceFullPath); 200 | var encoding = utils.getEncoding(rawContents); 201 | var contents = encoding === 'binary' 202 | ? rawContents 203 | : rawContents.toString('utf8'); 204 | cb(null, contents, encoding); 205 | } catch (e) { 206 | cb(e); 207 | } 208 | } 209 | } 210 | }; 211 | 212 | module.exports = utils; 213 | --------------------------------------------------------------------------------