├── .github ├── dependabot.yml └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── action.yml ├── dist └── index.js ├── index.js ├── lib ├── app-octokit.js ├── app-stats.js └── octokit-plugin-stdout-progress.js ├── package-lock.json ├── package.json └── test ├── README.md └── success ├── README.md ├── index.js └── package.json /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | versioning-strategy: "increase" 8 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | name: release 6 | jobs: 7 | release: 8 | name: release 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | - run: npm ci 16 | - run: npm run build 17 | - run: rm .gitignore # remove ignore for dist/index.js 18 | - run: npx semantic-release 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | - run: "git push https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git HEAD:refs/heads/v1" 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | on: [push] 2 | name: Test 3 | jobs: 4 | success: 5 | name: "[TEST] README example" 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | - uses: actions/setup-node@v1 10 | with: 11 | node-version: 12 12 | - run: npm ci 13 | - run: npm run build 14 | - uses: ./ 15 | with: 16 | cwd: test/success 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | - Using welcoming and inclusive language 12 | - Being respectful of differing viewpoints and experiences 13 | - Gracefully accepting constructive criticism 14 | - Focusing on what is best for the community 15 | - Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | - Trolling, insulting/derogatory comments, and personal or political attacks 21 | - Public or private harassment 22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | - Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at gregor+coc@martynus.net. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). 4 | By participating in this project you agree to abide by its terms. 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2020 Gregor Martynus 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Skypack Quality Score Action 2 | 3 | > Integrate Skypack's Quality Score check into your CI 4 | 5 | [![Build Status](https://github.com/gr2m/skypack-quality-score-action/workflows/Test/badge.svg)](https://github.com/gr2m/skypack-quality-score-action/actions) 6 | 7 | ## Usage 8 | 9 | ```yml 10 | name: Skypack Package Score 11 | on: 12 | push: 13 | branches: 14 | - main 15 | pull_request: 16 | types: 17 | - opened 18 | - synchronize 19 | 20 | jobs: 21 | packageScore: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v2 25 | - uses: gr2m/skypack-quality-score-action@v1 26 | # optional: set custom directory path to run the check in 27 | with: 28 | cwd: packages/my-package 29 | ``` 30 | 31 | ## Debugging 32 | 33 | To see additional debug logs, create a secret with the name: `ACTIONS_STEP_DEBUG` and value `true`. 34 | 35 | ## Contributing 36 | 37 | See [CONTRIBUTING.md](CONTRIBUTING.md) 38 | 39 | ## License 40 | 41 | [ISC](LICENSE) 42 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: Skypack Quality Score 2 | description: "Integrate Skypack's Quality Score check into your CI" 3 | branding: 4 | icon: "check-square" 5 | color: blue 6 | runs: 7 | using: "node12" 8 | main: "dist/index.js" 9 | inputs: 10 | cwd: 11 | description: "directory path to run the check in. Defaults to the repository's root folder" 12 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | /******/ (function(modules, runtime) { // webpackBootstrap 3 | /******/ "use strict"; 4 | /******/ // The module cache 5 | /******/ var installedModules = {}; 6 | /******/ 7 | /******/ // The require function 8 | /******/ function __webpack_require__(moduleId) { 9 | /******/ 10 | /******/ // Check if module is in cache 11 | /******/ if(installedModules[moduleId]) { 12 | /******/ return installedModules[moduleId].exports; 13 | /******/ } 14 | /******/ // Create a new module (and put it into the cache) 15 | /******/ var module = installedModules[moduleId] = { 16 | /******/ i: moduleId, 17 | /******/ l: false, 18 | /******/ exports: {} 19 | /******/ }; 20 | /******/ 21 | /******/ // Execute the module function 22 | /******/ var threw = true; 23 | /******/ try { 24 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 25 | /******/ threw = false; 26 | /******/ } finally { 27 | /******/ if(threw) delete installedModules[moduleId]; 28 | /******/ } 29 | /******/ 30 | /******/ // Flag the module as loaded 31 | /******/ module.l = true; 32 | /******/ 33 | /******/ // Return the exports of the module 34 | /******/ return module.exports; 35 | /******/ } 36 | /******/ 37 | /******/ 38 | /******/ __webpack_require__.ab = __dirname + "/"; 39 | /******/ 40 | /******/ // the startup function 41 | /******/ function startup() { 42 | /******/ // Load entry module and return exports 43 | /******/ return __webpack_require__(104); 44 | /******/ }; 45 | /******/ 46 | /******/ // run startup 47 | /******/ return startup(); 48 | /******/ }) 49 | /************************************************************************/ 50 | /******/ ({ 51 | 52 | /***/ 82: 53 | /***/ (function(__unusedmodule, exports) { 54 | 55 | "use strict"; 56 | 57 | // We use any as a valid input type 58 | /* eslint-disable @typescript-eslint/no-explicit-any */ 59 | Object.defineProperty(exports, "__esModule", { value: true }); 60 | /** 61 | * Sanitizes an input into a string so it can be passed into issueCommand safely 62 | * @param input input to sanitize into a string 63 | */ 64 | function toCommandValue(input) { 65 | if (input === null || input === undefined) { 66 | return ''; 67 | } 68 | else if (typeof input === 'string' || input instanceof String) { 69 | return input; 70 | } 71 | return JSON.stringify(input); 72 | } 73 | exports.toCommandValue = toCommandValue; 74 | //# sourceMappingURL=utils.js.map 75 | 76 | /***/ }), 77 | 78 | /***/ 87: 79 | /***/ (function(module) { 80 | 81 | module.exports = require("os"); 82 | 83 | /***/ }), 84 | 85 | /***/ 102: 86 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 87 | 88 | "use strict"; 89 | 90 | // For internal use, subject to change. 91 | var __importStar = (this && this.__importStar) || function (mod) { 92 | if (mod && mod.__esModule) return mod; 93 | var result = {}; 94 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 95 | result["default"] = mod; 96 | return result; 97 | }; 98 | Object.defineProperty(exports, "__esModule", { value: true }); 99 | // We use any as a valid input type 100 | /* eslint-disable @typescript-eslint/no-explicit-any */ 101 | const fs = __importStar(__webpack_require__(747)); 102 | const os = __importStar(__webpack_require__(87)); 103 | const utils_1 = __webpack_require__(82); 104 | function issueCommand(command, message) { 105 | const filePath = process.env[`GITHUB_${command}`]; 106 | if (!filePath) { 107 | throw new Error(`Unable to find environment variable for file command ${command}`); 108 | } 109 | if (!fs.existsSync(filePath)) { 110 | throw new Error(`Missing file at path: ${filePath}`); 111 | } 112 | fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { 113 | encoding: 'utf8' 114 | }); 115 | } 116 | exports.issueCommand = issueCommand; 117 | //# sourceMappingURL=file-command.js.map 118 | 119 | /***/ }), 120 | 121 | /***/ 104: 122 | /***/ (function(__unusedmodule, __unusedexports, __webpack_require__) { 123 | 124 | const path = __webpack_require__(622); 125 | const core = __webpack_require__(470); 126 | 127 | main(); 128 | 129 | async function main() { 130 | const cwd = core.getInput("cwd"); 131 | 132 | try { 133 | const args = []; 134 | if (cwd) { 135 | core.info(`Setting working directory to ${path.resolve(cwd)}`); 136 | args.push("--cwd", path.resolve(cwd)); 137 | } 138 | 139 | const cli = __webpack_require__(177); 140 | const run = cli.run || cli.cli || cli.default; 141 | await run(args); 142 | } catch (error) { 143 | core.error(error); 144 | core.setFailed(error.message); 145 | } 146 | } 147 | 148 | 149 | /***/ }), 150 | 151 | /***/ 119: 152 | /***/ (function(__unusedmodule, exports) { 153 | 154 | let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true; 155 | if (typeof process !== 'undefined') { 156 | ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env); 157 | isTTY = process.stdout && process.stdout.isTTY; 158 | } 159 | 160 | const $ = exports.$ = { 161 | enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && ( 162 | FORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY 163 | ) 164 | } 165 | 166 | function init(x, y) { 167 | let rgx = new RegExp(`\\x1b\\[${y}m`, 'g'); 168 | let open = `\x1b[${x}m`, close = `\x1b[${y}m`; 169 | 170 | return function (txt) { 171 | if (!$.enabled || txt == null) return txt; 172 | return open + ((''+txt).includes(close) ? txt.replace(rgx, close + open) : txt) + close; 173 | }; 174 | } 175 | 176 | // modifiers 177 | exports.reset = init(0, 0); 178 | exports.bold = init(1, 22); 179 | exports.dim = init(2, 22); 180 | exports.italic = init(3, 23); 181 | exports.underline = init(4, 24); 182 | exports.inverse = init(7, 27); 183 | exports.hidden = init(8, 28); 184 | exports.strikethrough = init(9, 29); 185 | 186 | // colors 187 | exports.black = init(30, 39); 188 | exports.red = init(31, 39); 189 | exports.green = init(32, 39); 190 | exports.yellow = init(33, 39); 191 | exports.blue = init(34, 39); 192 | exports.magenta = init(35, 39); 193 | exports.cyan = init(36, 39); 194 | exports.white = init(37, 39); 195 | exports.gray = init(90, 39); 196 | exports.grey = init(90, 39); 197 | 198 | // background colors 199 | exports.bgBlack = init(40, 49); 200 | exports.bgRed = init(41, 49); 201 | exports.bgGreen = init(42, 49); 202 | exports.bgYellow = init(43, 49); 203 | exports.bgBlue = init(44, 49); 204 | exports.bgMagenta = init(45, 49); 205 | exports.bgCyan = init(46, 49); 206 | exports.bgWhite = init(47, 49); 207 | 208 | 209 | /***/ }), 210 | 211 | /***/ 123: 212 | /***/ (function(module, __unusedexports, __webpack_require__) { 213 | 214 | "use strict"; 215 | 216 | 217 | var util = __webpack_require__(669); 218 | var fs = __webpack_require__(747); 219 | var path = __webpack_require__(622); 220 | 221 | function camelCase(str) { 222 | str = str.toLocaleLowerCase(); 223 | if (str.indexOf('-') === -1 && str.indexOf('_') === -1) { 224 | return str; 225 | } 226 | else { 227 | let camelcase = ''; 228 | let nextChrUpper = false; 229 | const leadingHyphens = str.match(/^-+/); 230 | for (let i = leadingHyphens ? leadingHyphens[0].length : 0; i < str.length; i++) { 231 | let chr = str.charAt(i); 232 | if (nextChrUpper) { 233 | nextChrUpper = false; 234 | chr = chr.toLocaleUpperCase(); 235 | } 236 | if (i !== 0 && (chr === '-' || chr === '_')) { 237 | nextChrUpper = true; 238 | continue; 239 | } 240 | else if (chr !== '-' && chr !== '_') { 241 | camelcase += chr; 242 | } 243 | } 244 | return camelcase; 245 | } 246 | } 247 | function decamelize(str, joinString) { 248 | const lowercase = str.toLocaleLowerCase(); 249 | joinString = joinString || '-'; 250 | let notCamelcase = ''; 251 | for (let i = 0; i < str.length; i++) { 252 | const chrLower = lowercase.charAt(i); 253 | const chrString = str.charAt(i); 254 | if (chrLower !== chrString && i > 0) { 255 | notCamelcase += `${joinString}${lowercase.charAt(i)}`; 256 | } 257 | else { 258 | notCamelcase += chrString; 259 | } 260 | } 261 | return notCamelcase; 262 | } 263 | function looksLikeNumber(x) { 264 | if (x === null || x === undefined) 265 | return false; 266 | if (typeof x === 'number') 267 | return true; 268 | if (/^0x[0-9a-f]+$/i.test(x)) 269 | return true; 270 | if (x.length > 1 && x[0] === '0') 271 | return false; 272 | return /^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); 273 | } 274 | 275 | function tokenizeArgString(argString) { 276 | if (Array.isArray(argString)) { 277 | return argString.map(e => typeof e !== 'string' ? e + '' : e); 278 | } 279 | argString = argString.trim(); 280 | let i = 0; 281 | let prevC = null; 282 | let c = null; 283 | let opening = null; 284 | const args = []; 285 | for (let ii = 0; ii < argString.length; ii++) { 286 | prevC = c; 287 | c = argString.charAt(ii); 288 | if (c === ' ' && !opening) { 289 | if (!(prevC === ' ')) { 290 | i++; 291 | } 292 | continue; 293 | } 294 | if (c === opening) { 295 | opening = null; 296 | } 297 | else if ((c === "'" || c === '"') && !opening) { 298 | opening = c; 299 | } 300 | if (!args[i]) 301 | args[i] = ''; 302 | args[i] += c; 303 | } 304 | return args; 305 | } 306 | 307 | let mixin; 308 | class YargsParser { 309 | constructor(_mixin) { 310 | mixin = _mixin; 311 | } 312 | parse(argsInput, options) { 313 | const opts = Object.assign({ 314 | alias: undefined, 315 | array: undefined, 316 | boolean: undefined, 317 | config: undefined, 318 | configObjects: undefined, 319 | configuration: undefined, 320 | coerce: undefined, 321 | count: undefined, 322 | default: undefined, 323 | envPrefix: undefined, 324 | narg: undefined, 325 | normalize: undefined, 326 | string: undefined, 327 | number: undefined, 328 | __: undefined, 329 | key: undefined 330 | }, options); 331 | const args = tokenizeArgString(argsInput); 332 | const aliases = combineAliases(Object.assign(Object.create(null), opts.alias)); 333 | const configuration = Object.assign({ 334 | 'boolean-negation': true, 335 | 'camel-case-expansion': true, 336 | 'combine-arrays': false, 337 | 'dot-notation': true, 338 | 'duplicate-arguments-array': true, 339 | 'flatten-duplicate-arrays': true, 340 | 'greedy-arrays': true, 341 | 'halt-at-non-option': false, 342 | 'nargs-eats-options': false, 343 | 'negation-prefix': 'no-', 344 | 'parse-numbers': true, 345 | 'parse-positional-numbers': true, 346 | 'populate--': false, 347 | 'set-placeholder-key': false, 348 | 'short-option-groups': true, 349 | 'strip-aliased': false, 350 | 'strip-dashed': false, 351 | 'unknown-options-as-args': false 352 | }, opts.configuration); 353 | const defaults = Object.assign(Object.create(null), opts.default); 354 | const configObjects = opts.configObjects || []; 355 | const envPrefix = opts.envPrefix; 356 | const notFlagsOption = configuration['populate--']; 357 | const notFlagsArgv = notFlagsOption ? '--' : '_'; 358 | const newAliases = Object.create(null); 359 | const defaulted = Object.create(null); 360 | const __ = opts.__ || mixin.format; 361 | const flags = { 362 | aliases: Object.create(null), 363 | arrays: Object.create(null), 364 | bools: Object.create(null), 365 | strings: Object.create(null), 366 | numbers: Object.create(null), 367 | counts: Object.create(null), 368 | normalize: Object.create(null), 369 | configs: Object.create(null), 370 | nargs: Object.create(null), 371 | coercions: Object.create(null), 372 | keys: [] 373 | }; 374 | const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/; 375 | const negatedBoolean = new RegExp('^--' + configuration['negation-prefix'] + '(.+)'); 376 | [].concat(opts.array || []).filter(Boolean).forEach(function (opt) { 377 | const key = typeof opt === 'object' ? opt.key : opt; 378 | const assignment = Object.keys(opt).map(function (key) { 379 | const arrayFlagKeys = { 380 | boolean: 'bools', 381 | string: 'strings', 382 | number: 'numbers' 383 | }; 384 | return arrayFlagKeys[key]; 385 | }).filter(Boolean).pop(); 386 | if (assignment) { 387 | flags[assignment][key] = true; 388 | } 389 | flags.arrays[key] = true; 390 | flags.keys.push(key); 391 | }); 392 | [].concat(opts.boolean || []).filter(Boolean).forEach(function (key) { 393 | flags.bools[key] = true; 394 | flags.keys.push(key); 395 | }); 396 | [].concat(opts.string || []).filter(Boolean).forEach(function (key) { 397 | flags.strings[key] = true; 398 | flags.keys.push(key); 399 | }); 400 | [].concat(opts.number || []).filter(Boolean).forEach(function (key) { 401 | flags.numbers[key] = true; 402 | flags.keys.push(key); 403 | }); 404 | [].concat(opts.count || []).filter(Boolean).forEach(function (key) { 405 | flags.counts[key] = true; 406 | flags.keys.push(key); 407 | }); 408 | [].concat(opts.normalize || []).filter(Boolean).forEach(function (key) { 409 | flags.normalize[key] = true; 410 | flags.keys.push(key); 411 | }); 412 | if (typeof opts.narg === 'object') { 413 | Object.entries(opts.narg).forEach(([key, value]) => { 414 | if (typeof value === 'number') { 415 | flags.nargs[key] = value; 416 | flags.keys.push(key); 417 | } 418 | }); 419 | } 420 | if (typeof opts.coerce === 'object') { 421 | Object.entries(opts.coerce).forEach(([key, value]) => { 422 | if (typeof value === 'function') { 423 | flags.coercions[key] = value; 424 | flags.keys.push(key); 425 | } 426 | }); 427 | } 428 | if (typeof opts.config !== 'undefined') { 429 | if (Array.isArray(opts.config) || typeof opts.config === 'string') { 430 | [].concat(opts.config).filter(Boolean).forEach(function (key) { 431 | flags.configs[key] = true; 432 | }); 433 | } 434 | else if (typeof opts.config === 'object') { 435 | Object.entries(opts.config).forEach(([key, value]) => { 436 | if (typeof value === 'boolean' || typeof value === 'function') { 437 | flags.configs[key] = value; 438 | } 439 | }); 440 | } 441 | } 442 | extendAliases(opts.key, aliases, opts.default, flags.arrays); 443 | Object.keys(defaults).forEach(function (key) { 444 | (flags.aliases[key] || []).forEach(function (alias) { 445 | defaults[alias] = defaults[key]; 446 | }); 447 | }); 448 | let error = null; 449 | checkConfiguration(); 450 | let notFlags = []; 451 | const argv = Object.assign(Object.create(null), { _: [] }); 452 | const argvReturn = {}; 453 | for (let i = 0; i < args.length; i++) { 454 | const arg = args[i]; 455 | let broken; 456 | let key; 457 | let letters; 458 | let m; 459 | let next; 460 | let value; 461 | if (arg !== '--' && isUnknownOptionAsArg(arg)) { 462 | pushPositional(arg); 463 | } 464 | else if (arg.match(/^--.+=/) || (!configuration['short-option-groups'] && arg.match(/^-.+=/))) { 465 | m = arg.match(/^--?([^=]+)=([\s\S]*)$/); 466 | if (m !== null && Array.isArray(m) && m.length >= 3) { 467 | if (checkAllAliases(m[1], flags.arrays)) { 468 | i = eatArray(i, m[1], args, m[2]); 469 | } 470 | else if (checkAllAliases(m[1], flags.nargs) !== false) { 471 | i = eatNargs(i, m[1], args, m[2]); 472 | } 473 | else { 474 | setArg(m[1], m[2]); 475 | } 476 | } 477 | } 478 | else if (arg.match(negatedBoolean) && configuration['boolean-negation']) { 479 | m = arg.match(negatedBoolean); 480 | if (m !== null && Array.isArray(m) && m.length >= 2) { 481 | key = m[1]; 482 | setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false); 483 | } 484 | } 485 | else if (arg.match(/^--.+/) || (!configuration['short-option-groups'] && arg.match(/^-[^-]+/))) { 486 | m = arg.match(/^--?(.+)/); 487 | if (m !== null && Array.isArray(m) && m.length >= 2) { 488 | key = m[1]; 489 | if (checkAllAliases(key, flags.arrays)) { 490 | i = eatArray(i, key, args); 491 | } 492 | else if (checkAllAliases(key, flags.nargs) !== false) { 493 | i = eatNargs(i, key, args); 494 | } 495 | else { 496 | next = args[i + 1]; 497 | if (next !== undefined && (!next.match(/^-/) || 498 | next.match(negative)) && 499 | !checkAllAliases(key, flags.bools) && 500 | !checkAllAliases(key, flags.counts)) { 501 | setArg(key, next); 502 | i++; 503 | } 504 | else if (/^(true|false)$/.test(next)) { 505 | setArg(key, next); 506 | i++; 507 | } 508 | else { 509 | setArg(key, defaultValue(key)); 510 | } 511 | } 512 | } 513 | } 514 | else if (arg.match(/^-.\..+=/)) { 515 | m = arg.match(/^-([^=]+)=([\s\S]*)$/); 516 | if (m !== null && Array.isArray(m) && m.length >= 3) { 517 | setArg(m[1], m[2]); 518 | } 519 | } 520 | else if (arg.match(/^-.\..+/) && !arg.match(negative)) { 521 | next = args[i + 1]; 522 | m = arg.match(/^-(.\..+)/); 523 | if (m !== null && Array.isArray(m) && m.length >= 2) { 524 | key = m[1]; 525 | if (next !== undefined && !next.match(/^-/) && 526 | !checkAllAliases(key, flags.bools) && 527 | !checkAllAliases(key, flags.counts)) { 528 | setArg(key, next); 529 | i++; 530 | } 531 | else { 532 | setArg(key, defaultValue(key)); 533 | } 534 | } 535 | } 536 | else if (arg.match(/^-[^-]+/) && !arg.match(negative)) { 537 | letters = arg.slice(1, -1).split(''); 538 | broken = false; 539 | for (let j = 0; j < letters.length; j++) { 540 | next = arg.slice(j + 2); 541 | if (letters[j + 1] && letters[j + 1] === '=') { 542 | value = arg.slice(j + 3); 543 | key = letters[j]; 544 | if (checkAllAliases(key, flags.arrays)) { 545 | i = eatArray(i, key, args, value); 546 | } 547 | else if (checkAllAliases(key, flags.nargs) !== false) { 548 | i = eatNargs(i, key, args, value); 549 | } 550 | else { 551 | setArg(key, value); 552 | } 553 | broken = true; 554 | break; 555 | } 556 | if (next === '-') { 557 | setArg(letters[j], next); 558 | continue; 559 | } 560 | if (/[A-Za-z]/.test(letters[j]) && 561 | /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && 562 | checkAllAliases(next, flags.bools) === false) { 563 | setArg(letters[j], next); 564 | broken = true; 565 | break; 566 | } 567 | if (letters[j + 1] && letters[j + 1].match(/\W/)) { 568 | setArg(letters[j], next); 569 | broken = true; 570 | break; 571 | } 572 | else { 573 | setArg(letters[j], defaultValue(letters[j])); 574 | } 575 | } 576 | key = arg.slice(-1)[0]; 577 | if (!broken && key !== '-') { 578 | if (checkAllAliases(key, flags.arrays)) { 579 | i = eatArray(i, key, args); 580 | } 581 | else if (checkAllAliases(key, flags.nargs) !== false) { 582 | i = eatNargs(i, key, args); 583 | } 584 | else { 585 | next = args[i + 1]; 586 | if (next !== undefined && (!/^(-|--)[^-]/.test(next) || 587 | next.match(negative)) && 588 | !checkAllAliases(key, flags.bools) && 589 | !checkAllAliases(key, flags.counts)) { 590 | setArg(key, next); 591 | i++; 592 | } 593 | else if (/^(true|false)$/.test(next)) { 594 | setArg(key, next); 595 | i++; 596 | } 597 | else { 598 | setArg(key, defaultValue(key)); 599 | } 600 | } 601 | } 602 | } 603 | else if (arg.match(/^-[0-9]$/) && 604 | arg.match(negative) && 605 | checkAllAliases(arg.slice(1), flags.bools)) { 606 | key = arg.slice(1); 607 | setArg(key, defaultValue(key)); 608 | } 609 | else if (arg === '--') { 610 | notFlags = args.slice(i + 1); 611 | break; 612 | } 613 | else if (configuration['halt-at-non-option']) { 614 | notFlags = args.slice(i); 615 | break; 616 | } 617 | else { 618 | pushPositional(arg); 619 | } 620 | } 621 | applyEnvVars(argv, true); 622 | applyEnvVars(argv, false); 623 | setConfig(argv); 624 | setConfigObjects(); 625 | applyDefaultsAndAliases(argv, flags.aliases, defaults, true); 626 | applyCoercions(argv); 627 | if (configuration['set-placeholder-key']) 628 | setPlaceholderKeys(argv); 629 | Object.keys(flags.counts).forEach(function (key) { 630 | if (!hasKey(argv, key.split('.'))) 631 | setArg(key, 0); 632 | }); 633 | if (notFlagsOption && notFlags.length) 634 | argv[notFlagsArgv] = []; 635 | notFlags.forEach(function (key) { 636 | argv[notFlagsArgv].push(key); 637 | }); 638 | if (configuration['camel-case-expansion'] && configuration['strip-dashed']) { 639 | Object.keys(argv).filter(key => key !== '--' && key.includes('-')).forEach(key => { 640 | delete argv[key]; 641 | }); 642 | } 643 | if (configuration['strip-aliased']) { 644 | [].concat(...Object.keys(aliases).map(k => aliases[k])).forEach(alias => { 645 | if (configuration['camel-case-expansion'] && alias.includes('-')) { 646 | delete argv[alias.split('.').map(prop => camelCase(prop)).join('.')]; 647 | } 648 | delete argv[alias]; 649 | }); 650 | } 651 | function pushPositional(arg) { 652 | const maybeCoercedNumber = maybeCoerceNumber('_', arg); 653 | if (typeof maybeCoercedNumber === 'string' || typeof maybeCoercedNumber === 'number') { 654 | argv._.push(maybeCoercedNumber); 655 | } 656 | } 657 | function eatNargs(i, key, args, argAfterEqualSign) { 658 | let ii; 659 | let toEat = checkAllAliases(key, flags.nargs); 660 | toEat = typeof toEat !== 'number' || isNaN(toEat) ? 1 : toEat; 661 | if (toEat === 0) { 662 | if (!isUndefined(argAfterEqualSign)) { 663 | error = Error(__('Argument unexpected for: %s', key)); 664 | } 665 | setArg(key, defaultValue(key)); 666 | return i; 667 | } 668 | let available = isUndefined(argAfterEqualSign) ? 0 : 1; 669 | if (configuration['nargs-eats-options']) { 670 | if (args.length - (i + 1) + available < toEat) { 671 | error = Error(__('Not enough arguments following: %s', key)); 672 | } 673 | available = toEat; 674 | } 675 | else { 676 | for (ii = i + 1; ii < args.length; ii++) { 677 | if (!args[ii].match(/^-[^0-9]/) || args[ii].match(negative) || isUnknownOptionAsArg(args[ii])) 678 | available++; 679 | else 680 | break; 681 | } 682 | if (available < toEat) 683 | error = Error(__('Not enough arguments following: %s', key)); 684 | } 685 | let consumed = Math.min(available, toEat); 686 | if (!isUndefined(argAfterEqualSign) && consumed > 0) { 687 | setArg(key, argAfterEqualSign); 688 | consumed--; 689 | } 690 | for (ii = i + 1; ii < (consumed + i + 1); ii++) { 691 | setArg(key, args[ii]); 692 | } 693 | return (i + consumed); 694 | } 695 | function eatArray(i, key, args, argAfterEqualSign) { 696 | let argsToSet = []; 697 | let next = argAfterEqualSign || args[i + 1]; 698 | const nargsCount = checkAllAliases(key, flags.nargs); 699 | if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) { 700 | argsToSet.push(true); 701 | } 702 | else if (isUndefined(next) || 703 | (isUndefined(argAfterEqualSign) && /^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) { 704 | if (defaults[key] !== undefined) { 705 | const defVal = defaults[key]; 706 | argsToSet = Array.isArray(defVal) ? defVal : [defVal]; 707 | } 708 | } 709 | else { 710 | if (!isUndefined(argAfterEqualSign)) { 711 | argsToSet.push(processValue(key, argAfterEqualSign)); 712 | } 713 | for (let ii = i + 1; ii < args.length; ii++) { 714 | if ((!configuration['greedy-arrays'] && argsToSet.length > 0) || 715 | (nargsCount && typeof nargsCount === 'number' && argsToSet.length >= nargsCount)) 716 | break; 717 | next = args[ii]; 718 | if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) 719 | break; 720 | i = ii; 721 | argsToSet.push(processValue(key, next)); 722 | } 723 | } 724 | if (typeof nargsCount === 'number' && ((nargsCount && argsToSet.length < nargsCount) || 725 | (isNaN(nargsCount) && argsToSet.length === 0))) { 726 | error = Error(__('Not enough arguments following: %s', key)); 727 | } 728 | setArg(key, argsToSet); 729 | return i; 730 | } 731 | function setArg(key, val) { 732 | if (/-/.test(key) && configuration['camel-case-expansion']) { 733 | const alias = key.split('.').map(function (prop) { 734 | return camelCase(prop); 735 | }).join('.'); 736 | addNewAlias(key, alias); 737 | } 738 | const value = processValue(key, val); 739 | const splitKey = key.split('.'); 740 | setKey(argv, splitKey, value); 741 | if (flags.aliases[key]) { 742 | flags.aliases[key].forEach(function (x) { 743 | const keyProperties = x.split('.'); 744 | setKey(argv, keyProperties, value); 745 | }); 746 | } 747 | if (splitKey.length > 1 && configuration['dot-notation']) { 748 | (flags.aliases[splitKey[0]] || []).forEach(function (x) { 749 | let keyProperties = x.split('.'); 750 | const a = [].concat(splitKey); 751 | a.shift(); 752 | keyProperties = keyProperties.concat(a); 753 | if (!(flags.aliases[key] || []).includes(keyProperties.join('.'))) { 754 | setKey(argv, keyProperties, value); 755 | } 756 | }); 757 | } 758 | if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) { 759 | const keys = [key].concat(flags.aliases[key] || []); 760 | keys.forEach(function (key) { 761 | Object.defineProperty(argvReturn, key, { 762 | enumerable: true, 763 | get() { 764 | return val; 765 | }, 766 | set(value) { 767 | val = typeof value === 'string' ? mixin.normalize(value) : value; 768 | } 769 | }); 770 | }); 771 | } 772 | } 773 | function addNewAlias(key, alias) { 774 | if (!(flags.aliases[key] && flags.aliases[key].length)) { 775 | flags.aliases[key] = [alias]; 776 | newAliases[alias] = true; 777 | } 778 | if (!(flags.aliases[alias] && flags.aliases[alias].length)) { 779 | addNewAlias(alias, key); 780 | } 781 | } 782 | function processValue(key, val) { 783 | if (typeof val === 'string' && 784 | (val[0] === "'" || val[0] === '"') && 785 | val[val.length - 1] === val[0]) { 786 | val = val.substring(1, val.length - 1); 787 | } 788 | if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) { 789 | if (typeof val === 'string') 790 | val = val === 'true'; 791 | } 792 | let value = Array.isArray(val) 793 | ? val.map(function (v) { return maybeCoerceNumber(key, v); }) 794 | : maybeCoerceNumber(key, val); 795 | if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) { 796 | value = increment(); 797 | } 798 | if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) { 799 | if (Array.isArray(val)) 800 | value = val.map((val) => { return mixin.normalize(val); }); 801 | else 802 | value = mixin.normalize(val); 803 | } 804 | return value; 805 | } 806 | function maybeCoerceNumber(key, value) { 807 | if (!configuration['parse-positional-numbers'] && key === '_') 808 | return value; 809 | if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) { 810 | const shouldCoerceNumber = looksLikeNumber(value) && configuration['parse-numbers'] && (Number.isSafeInteger(Math.floor(parseFloat(`${value}`)))); 811 | if (shouldCoerceNumber || (!isUndefined(value) && checkAllAliases(key, flags.numbers))) { 812 | value = Number(value); 813 | } 814 | } 815 | return value; 816 | } 817 | function setConfig(argv) { 818 | const configLookup = Object.create(null); 819 | applyDefaultsAndAliases(configLookup, flags.aliases, defaults); 820 | Object.keys(flags.configs).forEach(function (configKey) { 821 | const configPath = argv[configKey] || configLookup[configKey]; 822 | if (configPath) { 823 | try { 824 | let config = null; 825 | const resolvedConfigPath = mixin.resolve(mixin.cwd(), configPath); 826 | const resolveConfig = flags.configs[configKey]; 827 | if (typeof resolveConfig === 'function') { 828 | try { 829 | config = resolveConfig(resolvedConfigPath); 830 | } 831 | catch (e) { 832 | config = e; 833 | } 834 | if (config instanceof Error) { 835 | error = config; 836 | return; 837 | } 838 | } 839 | else { 840 | config = mixin.require(resolvedConfigPath); 841 | } 842 | setConfigObject(config); 843 | } 844 | catch (ex) { 845 | if (ex.name === 'PermissionDenied') 846 | error = ex; 847 | else if (argv[configKey]) 848 | error = Error(__('Invalid JSON config file: %s', configPath)); 849 | } 850 | } 851 | }); 852 | } 853 | function setConfigObject(config, prev) { 854 | Object.keys(config).forEach(function (key) { 855 | const value = config[key]; 856 | const fullKey = prev ? prev + '.' + key : key; 857 | if (typeof value === 'object' && value !== null && !Array.isArray(value) && configuration['dot-notation']) { 858 | setConfigObject(value, fullKey); 859 | } 860 | else { 861 | if (!hasKey(argv, fullKey.split('.')) || (checkAllAliases(fullKey, flags.arrays) && configuration['combine-arrays'])) { 862 | setArg(fullKey, value); 863 | } 864 | } 865 | }); 866 | } 867 | function setConfigObjects() { 868 | if (typeof configObjects !== 'undefined') { 869 | configObjects.forEach(function (configObject) { 870 | setConfigObject(configObject); 871 | }); 872 | } 873 | } 874 | function applyEnvVars(argv, configOnly) { 875 | if (typeof envPrefix === 'undefined') 876 | return; 877 | const prefix = typeof envPrefix === 'string' ? envPrefix : ''; 878 | const env = mixin.env(); 879 | Object.keys(env).forEach(function (envVar) { 880 | if (prefix === '' || envVar.lastIndexOf(prefix, 0) === 0) { 881 | const keys = envVar.split('__').map(function (key, i) { 882 | if (i === 0) { 883 | key = key.substring(prefix.length); 884 | } 885 | return camelCase(key); 886 | }); 887 | if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && !hasKey(argv, keys)) { 888 | setArg(keys.join('.'), env[envVar]); 889 | } 890 | } 891 | }); 892 | } 893 | function applyCoercions(argv) { 894 | let coerce; 895 | const applied = new Set(); 896 | Object.keys(argv).forEach(function (key) { 897 | if (!applied.has(key)) { 898 | coerce = checkAllAliases(key, flags.coercions); 899 | if (typeof coerce === 'function') { 900 | try { 901 | const value = maybeCoerceNumber(key, coerce(argv[key])); 902 | ([].concat(flags.aliases[key] || [], key)).forEach(ali => { 903 | applied.add(ali); 904 | argv[ali] = value; 905 | }); 906 | } 907 | catch (err) { 908 | error = err; 909 | } 910 | } 911 | } 912 | }); 913 | } 914 | function setPlaceholderKeys(argv) { 915 | flags.keys.forEach((key) => { 916 | if (~key.indexOf('.')) 917 | return; 918 | if (typeof argv[key] === 'undefined') 919 | argv[key] = undefined; 920 | }); 921 | return argv; 922 | } 923 | function applyDefaultsAndAliases(obj, aliases, defaults, canLog = false) { 924 | Object.keys(defaults).forEach(function (key) { 925 | if (!hasKey(obj, key.split('.'))) { 926 | setKey(obj, key.split('.'), defaults[key]); 927 | if (canLog) 928 | defaulted[key] = true; 929 | (aliases[key] || []).forEach(function (x) { 930 | if (hasKey(obj, x.split('.'))) 931 | return; 932 | setKey(obj, x.split('.'), defaults[key]); 933 | }); 934 | } 935 | }); 936 | } 937 | function hasKey(obj, keys) { 938 | let o = obj; 939 | if (!configuration['dot-notation']) 940 | keys = [keys.join('.')]; 941 | keys.slice(0, -1).forEach(function (key) { 942 | o = (o[key] || {}); 943 | }); 944 | const key = keys[keys.length - 1]; 945 | if (typeof o !== 'object') 946 | return false; 947 | else 948 | return key in o; 949 | } 950 | function setKey(obj, keys, value) { 951 | let o = obj; 952 | if (!configuration['dot-notation']) 953 | keys = [keys.join('.')]; 954 | keys.slice(0, -1).forEach(function (key) { 955 | key = sanitizeKey(key); 956 | if (typeof o === 'object' && o[key] === undefined) { 957 | o[key] = {}; 958 | } 959 | if (typeof o[key] !== 'object' || Array.isArray(o[key])) { 960 | if (Array.isArray(o[key])) { 961 | o[key].push({}); 962 | } 963 | else { 964 | o[key] = [o[key], {}]; 965 | } 966 | o = o[key][o[key].length - 1]; 967 | } 968 | else { 969 | o = o[key]; 970 | } 971 | }); 972 | const key = sanitizeKey(keys[keys.length - 1]); 973 | const isTypeArray = checkAllAliases(keys.join('.'), flags.arrays); 974 | const isValueArray = Array.isArray(value); 975 | let duplicate = configuration['duplicate-arguments-array']; 976 | if (!duplicate && checkAllAliases(key, flags.nargs)) { 977 | duplicate = true; 978 | if ((!isUndefined(o[key]) && flags.nargs[key] === 1) || (Array.isArray(o[key]) && o[key].length === flags.nargs[key])) { 979 | o[key] = undefined; 980 | } 981 | } 982 | if (value === increment()) { 983 | o[key] = increment(o[key]); 984 | } 985 | else if (Array.isArray(o[key])) { 986 | if (duplicate && isTypeArray && isValueArray) { 987 | o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : (Array.isArray(o[key][0]) ? o[key] : [o[key]]).concat([value]); 988 | } 989 | else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) { 990 | o[key] = value; 991 | } 992 | else { 993 | o[key] = o[key].concat([value]); 994 | } 995 | } 996 | else if (o[key] === undefined && isTypeArray) { 997 | o[key] = isValueArray ? value : [value]; 998 | } 999 | else if (duplicate && !(o[key] === undefined || 1000 | checkAllAliases(key, flags.counts) || 1001 | checkAllAliases(key, flags.bools))) { 1002 | o[key] = [o[key], value]; 1003 | } 1004 | else { 1005 | o[key] = value; 1006 | } 1007 | } 1008 | function extendAliases(...args) { 1009 | args.forEach(function (obj) { 1010 | Object.keys(obj || {}).forEach(function (key) { 1011 | if (flags.aliases[key]) 1012 | return; 1013 | flags.aliases[key] = [].concat(aliases[key] || []); 1014 | flags.aliases[key].concat(key).forEach(function (x) { 1015 | if (/-/.test(x) && configuration['camel-case-expansion']) { 1016 | const c = camelCase(x); 1017 | if (c !== key && flags.aliases[key].indexOf(c) === -1) { 1018 | flags.aliases[key].push(c); 1019 | newAliases[c] = true; 1020 | } 1021 | } 1022 | }); 1023 | flags.aliases[key].concat(key).forEach(function (x) { 1024 | if (x.length > 1 && /[A-Z]/.test(x) && configuration['camel-case-expansion']) { 1025 | const c = decamelize(x, '-'); 1026 | if (c !== key && flags.aliases[key].indexOf(c) === -1) { 1027 | flags.aliases[key].push(c); 1028 | newAliases[c] = true; 1029 | } 1030 | } 1031 | }); 1032 | flags.aliases[key].forEach(function (x) { 1033 | flags.aliases[x] = [key].concat(flags.aliases[key].filter(function (y) { 1034 | return x !== y; 1035 | })); 1036 | }); 1037 | }); 1038 | }); 1039 | } 1040 | function checkAllAliases(key, flag) { 1041 | const toCheck = [].concat(flags.aliases[key] || [], key); 1042 | const keys = Object.keys(flag); 1043 | const setAlias = toCheck.find(key => keys.includes(key)); 1044 | return setAlias ? flag[setAlias] : false; 1045 | } 1046 | function hasAnyFlag(key) { 1047 | const flagsKeys = Object.keys(flags); 1048 | const toCheck = [].concat(flagsKeys.map(k => flags[k])); 1049 | return toCheck.some(function (flag) { 1050 | return Array.isArray(flag) ? flag.includes(key) : flag[key]; 1051 | }); 1052 | } 1053 | function hasFlagsMatching(arg, ...patterns) { 1054 | const toCheck = [].concat(...patterns); 1055 | return toCheck.some(function (pattern) { 1056 | const match = arg.match(pattern); 1057 | return match && hasAnyFlag(match[1]); 1058 | }); 1059 | } 1060 | function hasAllShortFlags(arg) { 1061 | if (arg.match(negative) || !arg.match(/^-[^-]+/)) { 1062 | return false; 1063 | } 1064 | let hasAllFlags = true; 1065 | let next; 1066 | const letters = arg.slice(1).split(''); 1067 | for (let j = 0; j < letters.length; j++) { 1068 | next = arg.slice(j + 2); 1069 | if (!hasAnyFlag(letters[j])) { 1070 | hasAllFlags = false; 1071 | break; 1072 | } 1073 | if ((letters[j + 1] && letters[j + 1] === '=') || 1074 | next === '-' || 1075 | (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) || 1076 | (letters[j + 1] && letters[j + 1].match(/\W/))) { 1077 | break; 1078 | } 1079 | } 1080 | return hasAllFlags; 1081 | } 1082 | function isUnknownOptionAsArg(arg) { 1083 | return configuration['unknown-options-as-args'] && isUnknownOption(arg); 1084 | } 1085 | function isUnknownOption(arg) { 1086 | if (arg.match(negative)) { 1087 | return false; 1088 | } 1089 | if (hasAllShortFlags(arg)) { 1090 | return false; 1091 | } 1092 | const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/; 1093 | const normalFlag = /^-+([^=]+?)$/; 1094 | const flagEndingInHyphen = /^-+([^=]+?)-$/; 1095 | const flagEndingInDigits = /^-+([^=]+?\d+)$/; 1096 | const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/; 1097 | return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters); 1098 | } 1099 | function defaultValue(key) { 1100 | if (!checkAllAliases(key, flags.bools) && 1101 | !checkAllAliases(key, flags.counts) && 1102 | `${key}` in defaults) { 1103 | return defaults[key]; 1104 | } 1105 | else { 1106 | return defaultForType(guessType(key)); 1107 | } 1108 | } 1109 | function defaultForType(type) { 1110 | const def = { 1111 | boolean: true, 1112 | string: '', 1113 | number: undefined, 1114 | array: [] 1115 | }; 1116 | return def[type]; 1117 | } 1118 | function guessType(key) { 1119 | let type = 'boolean'; 1120 | if (checkAllAliases(key, flags.strings)) 1121 | type = 'string'; 1122 | else if (checkAllAliases(key, flags.numbers)) 1123 | type = 'number'; 1124 | else if (checkAllAliases(key, flags.bools)) 1125 | type = 'boolean'; 1126 | else if (checkAllAliases(key, flags.arrays)) 1127 | type = 'array'; 1128 | return type; 1129 | } 1130 | function isUndefined(num) { 1131 | return num === undefined; 1132 | } 1133 | function checkConfiguration() { 1134 | Object.keys(flags.counts).find(key => { 1135 | if (checkAllAliases(key, flags.arrays)) { 1136 | error = Error(__('Invalid configuration: %s, opts.count excludes opts.array.', key)); 1137 | return true; 1138 | } 1139 | else if (checkAllAliases(key, flags.nargs)) { 1140 | error = Error(__('Invalid configuration: %s, opts.count excludes opts.narg.', key)); 1141 | return true; 1142 | } 1143 | return false; 1144 | }); 1145 | } 1146 | return { 1147 | aliases: Object.assign({}, flags.aliases), 1148 | argv: Object.assign(argvReturn, argv), 1149 | configuration: configuration, 1150 | defaulted: Object.assign({}, defaulted), 1151 | error: error, 1152 | newAliases: Object.assign({}, newAliases) 1153 | }; 1154 | } 1155 | } 1156 | function combineAliases(aliases) { 1157 | const aliasArrays = []; 1158 | const combined = Object.create(null); 1159 | let change = true; 1160 | Object.keys(aliases).forEach(function (key) { 1161 | aliasArrays.push([].concat(aliases[key], key)); 1162 | }); 1163 | while (change) { 1164 | change = false; 1165 | for (let i = 0; i < aliasArrays.length; i++) { 1166 | for (let ii = i + 1; ii < aliasArrays.length; ii++) { 1167 | const intersect = aliasArrays[i].filter(function (v) { 1168 | return aliasArrays[ii].indexOf(v) !== -1; 1169 | }); 1170 | if (intersect.length) { 1171 | aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]); 1172 | aliasArrays.splice(ii, 1); 1173 | change = true; 1174 | break; 1175 | } 1176 | } 1177 | } 1178 | } 1179 | aliasArrays.forEach(function (aliasArray) { 1180 | aliasArray = aliasArray.filter(function (v, i, self) { 1181 | return self.indexOf(v) === i; 1182 | }); 1183 | const lastAlias = aliasArray.pop(); 1184 | if (lastAlias !== undefined && typeof lastAlias === 'string') { 1185 | combined[lastAlias] = aliasArray; 1186 | } 1187 | }); 1188 | return combined; 1189 | } 1190 | function increment(orig) { 1191 | return orig !== undefined ? orig + 1 : 1; 1192 | } 1193 | function sanitizeKey(key) { 1194 | if (key === '__proto__') 1195 | return '___proto___'; 1196 | return key; 1197 | } 1198 | 1199 | const minNodeVersion = (process && process.env && process.env.YARGS_MIN_NODE_VERSION) 1200 | ? Number(process.env.YARGS_MIN_NODE_VERSION) : 10; 1201 | if (process && process.version) { 1202 | const major = Number(process.version.match(/v([^.]+)/)[1]); 1203 | if (major < minNodeVersion) { 1204 | throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`); 1205 | } 1206 | } 1207 | const env = process ? process.env : {}; 1208 | const parser = new YargsParser({ 1209 | cwd: process.cwd, 1210 | env: () => { 1211 | return env; 1212 | }, 1213 | format: util.format, 1214 | normalize: path.normalize, 1215 | resolve: path.resolve, 1216 | require: (path) => { 1217 | if (true) { 1218 | return __webpack_require__(555)(path); 1219 | } 1220 | else {} 1221 | } 1222 | }); 1223 | const yargsParser = function Parser(args, opts) { 1224 | const result = parser.parse(args.slice(), opts); 1225 | return result.argv; 1226 | }; 1227 | yargsParser.detailed = function (args, opts) { 1228 | return parser.parse(args.slice(), opts); 1229 | }; 1230 | yargsParser.camelCase = camelCase; 1231 | yargsParser.decamelize = decamelize; 1232 | yargsParser.looksLikeNumber = looksLikeNumber; 1233 | 1234 | module.exports = yargsParser; 1235 | 1236 | 1237 | /***/ }), 1238 | 1239 | /***/ 177: 1240 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 1241 | 1242 | "use strict"; 1243 | 1244 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 1245 | if (k2 === undefined) k2 = k; 1246 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 1247 | }) : (function(o, m, k, k2) { 1248 | if (k2 === undefined) k2 = k; 1249 | o[k2] = m[k]; 1250 | })); 1251 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 1252 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 1253 | }) : function(o, v) { 1254 | o["default"] = v; 1255 | }); 1256 | var __importStar = (this && this.__importStar) || function (mod) { 1257 | if (mod && mod.__esModule) return mod; 1258 | var result = {}; 1259 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 1260 | __setModuleDefault(result, mod); 1261 | return result; 1262 | }; 1263 | var __importDefault = (this && this.__importDefault) || function (mod) { 1264 | return (mod && mod.__esModule) ? mod : { "default": mod }; 1265 | }; 1266 | Object.defineProperty(exports, "__esModule", { value: true }); 1267 | exports.cli = void 0; 1268 | const fs_1 = __importDefault(__webpack_require__(747)); 1269 | const path_1 = __importDefault(__webpack_require__(622)); 1270 | const yargs_parser_1 = __importDefault(__webpack_require__(123)); 1271 | const colors = __importStar(__webpack_require__(119)); 1272 | const get_repo_url_1 = __webpack_require__(489); 1273 | function runCheck({ pass, title, url }) { 1274 | try { 1275 | const result = pass(); 1276 | if (result) { 1277 | console.error(colors.green(`✓`) + colors.dim(` ${title}`)); 1278 | } 1279 | else if (!result) { 1280 | console.error(colors.red(`✖ ${title}`)); 1281 | console.error(''); 1282 | console.error(colors.red('check failed:'), title); 1283 | console.error(colors.red(' how to fix:'), url); 1284 | process.exit(1); 1285 | } 1286 | } 1287 | catch (err) { 1288 | console.error('run failed (internal tool error, please report this!)'); 1289 | throw err; 1290 | } 1291 | } 1292 | async function cli(args) { 1293 | const cliFlags = yargs_parser_1.default(args, {}); 1294 | const cwd = cliFlags.cwd ? path_1.default.resolve(cliFlags.cwd) : process.cwd(); 1295 | const files = fs_1.default.readdirSync(cwd); 1296 | // Check: Has a package.json 1297 | runCheck({ 1298 | title: 'package.json', 1299 | url: 'https://docs.skypack.dev/package-authors/package-checks#esm', 1300 | pass: () => { 1301 | return !!files.includes('package.json'); 1302 | }, 1303 | }); 1304 | // Load package.json 1305 | const pkg = await fs_1.default.promises 1306 | .readFile(path_1.default.join(cwd, 'package.json'), { 1307 | encoding: 'utf-8', 1308 | }) 1309 | .then((packageJsonContents) => JSON.parse(packageJsonContents)); 1310 | // Check: Has ESM 1311 | runCheck({ 1312 | title: 'ES Module Entrypoint', 1313 | url: 'https://docs.skypack.dev/package-authors/package-checks#esm', 1314 | pass: () => { 1315 | if (pkg.type === 'module') { 1316 | return true; 1317 | } 1318 | if (pkg.module) { 1319 | return true; 1320 | } 1321 | if (typeof pkg.main === 'string' && pkg.main.endsWith('.mjs')) { 1322 | return true; 1323 | } 1324 | if (pkg.exports && 1325 | (pkg.exports['import'] || 1326 | !!Object.values(pkg.exports).find((x) => typeof x === 'object' && x.import))) { 1327 | return true; 1328 | } 1329 | return false; 1330 | }, 1331 | }); 1332 | // Check: Export Map 1333 | runCheck({ 1334 | title: 'Export Map', 1335 | url: 'https://docs.skypack.dev/package-authors/package-checks#export-map', 1336 | pass: () => { 1337 | return !!pkg.exports; 1338 | }, 1339 | }); 1340 | // Check: Has "files" 1341 | runCheck({ 1342 | title: 'No Unnecessary Files', 1343 | url: 'https://docs.skypack.dev/package-authors/package-checks#files', 1344 | pass: () => { 1345 | return !!pkg.files; 1346 | }, 1347 | }); 1348 | // Check: Has "keywords" 1349 | runCheck({ 1350 | title: 'Keywords', 1351 | url: 'https://docs.skypack.dev/package-authors/package-checks#keywords', 1352 | pass: () => { 1353 | return !!pkg.keywords; 1354 | }, 1355 | }); 1356 | // Check: Has "keywords" 1357 | runCheck({ 1358 | title: 'Keywords (Empty)', 1359 | url: 'https://docs.skypack.dev/package-authors/package-checks#keywords', 1360 | pass: () => { 1361 | return !!pkg.keywords.length; 1362 | }, 1363 | }); 1364 | // Check: Has "license" 1365 | runCheck({ 1366 | title: 'License', 1367 | url: 'https://docs.skypack.dev/package-authors/package-checks#license', 1368 | pass: () => { 1369 | return !!pkg.license; 1370 | }, 1371 | }); 1372 | // Check: Has "repository url" 1373 | runCheck({ 1374 | title: 'Repository URL', 1375 | url: 'https://docs.skypack.dev/package-authors/package-checks#repository', 1376 | pass: () => { 1377 | let repositoryUrl; 1378 | if (!pkg.repository) { 1379 | return false; 1380 | } 1381 | if (typeof pkg.repository === 'string') { 1382 | return true; 1383 | } 1384 | if (pkg.repository.url) { 1385 | return !!new URL(get_repo_url_1.repoURL(pkg.repository.url)); 1386 | } 1387 | return false; 1388 | }, 1389 | }); 1390 | // Check: Has types 1391 | runCheck({ 1392 | title: 'TypeScript Types', 1393 | url: 'https://docs.skypack.dev/package-authors/package-checks#types', 1394 | pass: () => { 1395 | const isOk = !!pkg.types || !!pkg.typings || !!pkg.typesVersions; 1396 | if (isOk) { 1397 | return true; 1398 | } 1399 | if (files.includes('index.d.ts')) { 1400 | console.error(colors.yellow('"./index.d.ts" file found, but package.json "types" entry is missing.')); 1401 | console.error(colors.yellow('Learn more about why this is still required: https://github.com/skypackjs/package-check/issues/6#issuecomment-714840634')); 1402 | return false; 1403 | } 1404 | return false; 1405 | }, 1406 | }); 1407 | // Check: Has "README" 1408 | runCheck({ 1409 | title: 'README', 1410 | url: 'https://docs.skypack.dev/package-authors/package-checks#readme', 1411 | pass: () => { 1412 | return !!files.find((f) => /^readme\.?/i.test(f)); 1413 | }, 1414 | }); 1415 | console.error(''); 1416 | console.error(colors.green(`[100/100] ${pkg.name} passes all quality checks.`)); 1417 | } 1418 | exports.cli = cli; 1419 | //# sourceMappingURL=index.js.map 1420 | 1421 | /***/ }), 1422 | 1423 | /***/ 431: 1424 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 1425 | 1426 | "use strict"; 1427 | 1428 | var __importStar = (this && this.__importStar) || function (mod) { 1429 | if (mod && mod.__esModule) return mod; 1430 | var result = {}; 1431 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 1432 | result["default"] = mod; 1433 | return result; 1434 | }; 1435 | Object.defineProperty(exports, "__esModule", { value: true }); 1436 | const os = __importStar(__webpack_require__(87)); 1437 | const utils_1 = __webpack_require__(82); 1438 | /** 1439 | * Commands 1440 | * 1441 | * Command Format: 1442 | * ::name key=value,key=value::message 1443 | * 1444 | * Examples: 1445 | * ::warning::This is the message 1446 | * ::set-env name=MY_VAR::some value 1447 | */ 1448 | function issueCommand(command, properties, message) { 1449 | const cmd = new Command(command, properties, message); 1450 | process.stdout.write(cmd.toString() + os.EOL); 1451 | } 1452 | exports.issueCommand = issueCommand; 1453 | function issue(name, message = '') { 1454 | issueCommand(name, {}, message); 1455 | } 1456 | exports.issue = issue; 1457 | const CMD_STRING = '::'; 1458 | class Command { 1459 | constructor(command, properties, message) { 1460 | if (!command) { 1461 | command = 'missing.command'; 1462 | } 1463 | this.command = command; 1464 | this.properties = properties; 1465 | this.message = message; 1466 | } 1467 | toString() { 1468 | let cmdStr = CMD_STRING + this.command; 1469 | if (this.properties && Object.keys(this.properties).length > 0) { 1470 | cmdStr += ' '; 1471 | let first = true; 1472 | for (const key in this.properties) { 1473 | if (this.properties.hasOwnProperty(key)) { 1474 | const val = this.properties[key]; 1475 | if (val) { 1476 | if (first) { 1477 | first = false; 1478 | } 1479 | else { 1480 | cmdStr += ','; 1481 | } 1482 | cmdStr += `${key}=${escapeProperty(val)}`; 1483 | } 1484 | } 1485 | } 1486 | } 1487 | cmdStr += `${CMD_STRING}${escapeData(this.message)}`; 1488 | return cmdStr; 1489 | } 1490 | } 1491 | function escapeData(s) { 1492 | return utils_1.toCommandValue(s) 1493 | .replace(/%/g, '%25') 1494 | .replace(/\r/g, '%0D') 1495 | .replace(/\n/g, '%0A'); 1496 | } 1497 | function escapeProperty(s) { 1498 | return utils_1.toCommandValue(s) 1499 | .replace(/%/g, '%25') 1500 | .replace(/\r/g, '%0D') 1501 | .replace(/\n/g, '%0A') 1502 | .replace(/:/g, '%3A') 1503 | .replace(/,/g, '%2C'); 1504 | } 1505 | //# sourceMappingURL=command.js.map 1506 | 1507 | /***/ }), 1508 | 1509 | /***/ 470: 1510 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 1511 | 1512 | "use strict"; 1513 | 1514 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 1515 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 1516 | return new (P || (P = Promise))(function (resolve, reject) { 1517 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 1518 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 1519 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 1520 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 1521 | }); 1522 | }; 1523 | var __importStar = (this && this.__importStar) || function (mod) { 1524 | if (mod && mod.__esModule) return mod; 1525 | var result = {}; 1526 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 1527 | result["default"] = mod; 1528 | return result; 1529 | }; 1530 | Object.defineProperty(exports, "__esModule", { value: true }); 1531 | const command_1 = __webpack_require__(431); 1532 | const file_command_1 = __webpack_require__(102); 1533 | const utils_1 = __webpack_require__(82); 1534 | const os = __importStar(__webpack_require__(87)); 1535 | const path = __importStar(__webpack_require__(622)); 1536 | /** 1537 | * The code to exit an action 1538 | */ 1539 | var ExitCode; 1540 | (function (ExitCode) { 1541 | /** 1542 | * A code indicating that the action was successful 1543 | */ 1544 | ExitCode[ExitCode["Success"] = 0] = "Success"; 1545 | /** 1546 | * A code indicating that the action was a failure 1547 | */ 1548 | ExitCode[ExitCode["Failure"] = 1] = "Failure"; 1549 | })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); 1550 | //----------------------------------------------------------------------- 1551 | // Variables 1552 | //----------------------------------------------------------------------- 1553 | /** 1554 | * Sets env variable for this action and future actions in the job 1555 | * @param name the name of the variable to set 1556 | * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify 1557 | */ 1558 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 1559 | function exportVariable(name, val) { 1560 | const convertedVal = utils_1.toCommandValue(val); 1561 | process.env[name] = convertedVal; 1562 | const filePath = process.env['GITHUB_ENV'] || ''; 1563 | if (filePath) { 1564 | const delimiter = '_GitHubActionsFileCommandDelimeter_'; 1565 | const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; 1566 | file_command_1.issueCommand('ENV', commandValue); 1567 | } 1568 | else { 1569 | command_1.issueCommand('set-env', { name }, convertedVal); 1570 | } 1571 | } 1572 | exports.exportVariable = exportVariable; 1573 | /** 1574 | * Registers a secret which will get masked from logs 1575 | * @param secret value of the secret 1576 | */ 1577 | function setSecret(secret) { 1578 | command_1.issueCommand('add-mask', {}, secret); 1579 | } 1580 | exports.setSecret = setSecret; 1581 | /** 1582 | * Prepends inputPath to the PATH (for this action and future actions) 1583 | * @param inputPath 1584 | */ 1585 | function addPath(inputPath) { 1586 | const filePath = process.env['GITHUB_PATH'] || ''; 1587 | if (filePath) { 1588 | file_command_1.issueCommand('PATH', inputPath); 1589 | } 1590 | else { 1591 | command_1.issueCommand('add-path', {}, inputPath); 1592 | } 1593 | process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; 1594 | } 1595 | exports.addPath = addPath; 1596 | /** 1597 | * Gets the value of an input. The value is also trimmed. 1598 | * 1599 | * @param name name of the input to get 1600 | * @param options optional. See InputOptions. 1601 | * @returns string 1602 | */ 1603 | function getInput(name, options) { 1604 | const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; 1605 | if (options && options.required && !val) { 1606 | throw new Error(`Input required and not supplied: ${name}`); 1607 | } 1608 | return val.trim(); 1609 | } 1610 | exports.getInput = getInput; 1611 | /** 1612 | * Sets the value of an output. 1613 | * 1614 | * @param name name of the output to set 1615 | * @param value value to store. Non-string values will be converted to a string via JSON.stringify 1616 | */ 1617 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 1618 | function setOutput(name, value) { 1619 | command_1.issueCommand('set-output', { name }, value); 1620 | } 1621 | exports.setOutput = setOutput; 1622 | /** 1623 | * Enables or disables the echoing of commands into stdout for the rest of the step. 1624 | * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. 1625 | * 1626 | */ 1627 | function setCommandEcho(enabled) { 1628 | command_1.issue('echo', enabled ? 'on' : 'off'); 1629 | } 1630 | exports.setCommandEcho = setCommandEcho; 1631 | //----------------------------------------------------------------------- 1632 | // Results 1633 | //----------------------------------------------------------------------- 1634 | /** 1635 | * Sets the action status to failed. 1636 | * When the action exits it will be with an exit code of 1 1637 | * @param message add error issue message 1638 | */ 1639 | function setFailed(message) { 1640 | process.exitCode = ExitCode.Failure; 1641 | error(message); 1642 | } 1643 | exports.setFailed = setFailed; 1644 | //----------------------------------------------------------------------- 1645 | // Logging Commands 1646 | //----------------------------------------------------------------------- 1647 | /** 1648 | * Gets whether Actions Step Debug is on or not 1649 | */ 1650 | function isDebug() { 1651 | return process.env['RUNNER_DEBUG'] === '1'; 1652 | } 1653 | exports.isDebug = isDebug; 1654 | /** 1655 | * Writes debug message to user log 1656 | * @param message debug message 1657 | */ 1658 | function debug(message) { 1659 | command_1.issueCommand('debug', {}, message); 1660 | } 1661 | exports.debug = debug; 1662 | /** 1663 | * Adds an error issue 1664 | * @param message error issue message. Errors will be converted to string via toString() 1665 | */ 1666 | function error(message) { 1667 | command_1.issue('error', message instanceof Error ? message.toString() : message); 1668 | } 1669 | exports.error = error; 1670 | /** 1671 | * Adds an warning issue 1672 | * @param message warning issue message. Errors will be converted to string via toString() 1673 | */ 1674 | function warning(message) { 1675 | command_1.issue('warning', message instanceof Error ? message.toString() : message); 1676 | } 1677 | exports.warning = warning; 1678 | /** 1679 | * Writes info to log with console.log. 1680 | * @param message info message 1681 | */ 1682 | function info(message) { 1683 | process.stdout.write(message + os.EOL); 1684 | } 1685 | exports.info = info; 1686 | /** 1687 | * Begin an output group. 1688 | * 1689 | * Output until the next `groupEnd` will be foldable in this group 1690 | * 1691 | * @param name The name of the output group 1692 | */ 1693 | function startGroup(name) { 1694 | command_1.issue('group', name); 1695 | } 1696 | exports.startGroup = startGroup; 1697 | /** 1698 | * End an output group. 1699 | */ 1700 | function endGroup() { 1701 | command_1.issue('endgroup'); 1702 | } 1703 | exports.endGroup = endGroup; 1704 | /** 1705 | * Wrap an asynchronous function call in a group. 1706 | * 1707 | * Returns the same type as the function itself. 1708 | * 1709 | * @param name The name of the group 1710 | * @param fn The function to wrap in the group 1711 | */ 1712 | function group(name, fn) { 1713 | return __awaiter(this, void 0, void 0, function* () { 1714 | startGroup(name); 1715 | let result; 1716 | try { 1717 | result = yield fn(); 1718 | } 1719 | finally { 1720 | endGroup(); 1721 | } 1722 | return result; 1723 | }); 1724 | } 1725 | exports.group = group; 1726 | //----------------------------------------------------------------------- 1727 | // Wrapper action state 1728 | //----------------------------------------------------------------------- 1729 | /** 1730 | * Saves state for current action, the state can only be retrieved by this action's post job execution. 1731 | * 1732 | * @param name name of the state to store 1733 | * @param value value to store. Non-string values will be converted to a string via JSON.stringify 1734 | */ 1735 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 1736 | function saveState(name, value) { 1737 | command_1.issueCommand('save-state', { name }, value); 1738 | } 1739 | exports.saveState = saveState; 1740 | /** 1741 | * Gets the value of an state set by this action's main execution. 1742 | * 1743 | * @param name name of the state to get 1744 | * @returns string 1745 | */ 1746 | function getState(name) { 1747 | return process.env[`STATE_${name}`] || ''; 1748 | } 1749 | exports.getState = getState; 1750 | //# sourceMappingURL=core.js.map 1751 | 1752 | /***/ }), 1753 | 1754 | /***/ 489: 1755 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 1756 | 1757 | "use strict"; 1758 | 1759 | var __importDefault = (this && this.__importDefault) || function (mod) { 1760 | return (mod && mod.__esModule) ? mod : { "default": mod }; 1761 | }; 1762 | Object.defineProperty(exports, "__esModule", { value: true }); 1763 | exports.repoURL = exports.repoAssetURL = void 0; 1764 | const path_1 = __importDefault(__webpack_require__(622)); 1765 | /** Get URL for any asset from a repo */ 1766 | function repoAssetURL(url, filepath, version) { 1767 | let sanitizedURL = repoURL(url); 1768 | // @ts-ignore this is a real thing 1769 | const { hostname, pathname } = new URL(sanitizedURL); 1770 | switch (hostname) { 1771 | case "bitbucket.org": { 1772 | return `https://bitbucket.org${path_1.default.join("/", pathname, version || "HEAD", filepath)}`; 1773 | } 1774 | case "github.com": { 1775 | const [repo, dir] = pathname.split("/tree/"); 1776 | return `https://raw.githubusercontent.com${path_1.default.join("/", repo, version || "HEAD", dir ? dir.replace(/[^/]+/, "") : "", filepath)}`; 1777 | } 1778 | case "gitlab.com": { 1779 | return `https://gitlab.com${path_1.default.join("/", pathname, "-", "raw", version || "HEAD", filepath)}`; 1780 | } 1781 | default: { 1782 | return undefined; // Dunno what this is; return as-is 1783 | } 1784 | } 1785 | } 1786 | exports.repoAssetURL = repoAssetURL; 1787 | /** Turn repo URL into normal URL */ 1788 | function repoURL(url) { 1789 | return url 1790 | .trim() 1791 | .replace(/^git\+/i, "") 1792 | .replace(/\.git$/i, "") 1793 | .replace(/git@/, "") 1794 | .replace(/(bitbucket|github|gitlab)\.([a-z]+):/, "$1.$2/") 1795 | .replace(/bitbucket:/, "$1.org/") 1796 | .replace(/(github|gitlab):/, "$1.com/") 1797 | .replace(/^(http\s*:\/\/|https\s*:\/\/|\/\/)?/, "https://"); 1798 | } 1799 | exports.repoURL = repoURL; 1800 | //# sourceMappingURL=get-repo-url.js.map 1801 | 1802 | /***/ }), 1803 | 1804 | /***/ 555: 1805 | /***/ (function(module) { 1806 | 1807 | function webpackEmptyContext(req) { 1808 | if (typeof req === 'number' && __webpack_require__.m[req]) 1809 | return __webpack_require__(req); 1810 | try { return require(req) } 1811 | catch (e) { if (e.code !== 'MODULE_NOT_FOUND') throw e } 1812 | var e = new Error("Cannot find module '" + req + "'"); 1813 | e.code = 'MODULE_NOT_FOUND'; 1814 | throw e; 1815 | } 1816 | webpackEmptyContext.keys = function() { return []; }; 1817 | webpackEmptyContext.resolve = webpackEmptyContext; 1818 | module.exports = webpackEmptyContext; 1819 | webpackEmptyContext.id = 555; 1820 | 1821 | /***/ }), 1822 | 1823 | /***/ 622: 1824 | /***/ (function(module) { 1825 | 1826 | module.exports = require("path"); 1827 | 1828 | /***/ }), 1829 | 1830 | /***/ 669: 1831 | /***/ (function(module) { 1832 | 1833 | module.exports = require("util"); 1834 | 1835 | /***/ }), 1836 | 1837 | /***/ 747: 1838 | /***/ (function(module) { 1839 | 1840 | module.exports = require("fs"); 1841 | 1842 | /***/ }) 1843 | 1844 | /******/ }); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const core = require("@actions/core"); 3 | 4 | main(); 5 | 6 | async function main() { 7 | const cwd = core.getInput("cwd"); 8 | 9 | try { 10 | const args = []; 11 | if (cwd) { 12 | core.info(`Setting working directory to ${path.resolve(cwd)}`); 13 | args.push("--cwd", path.resolve(cwd)); 14 | } 15 | 16 | const cli = require("@skypack/package-check"); 17 | const run = cli.run || cli.cli || cli.default; 18 | await run(args); 19 | } catch (error) { 20 | core.error(error); 21 | core.setFailed(error.message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/app-octokit.js: -------------------------------------------------------------------------------- 1 | const { createAppAuth } = require("@octokit/auth-app"); 2 | const { Octokit } = require("@octokit/core"); 3 | const { paginateRest } = require("@octokit/plugin-paginate-rest"); 4 | const { retry } = require("@octokit/plugin-retry"); 5 | const { throttling } = require("@octokit/plugin-throttling"); 6 | 7 | const octokitPluginStdoutProgress = require("./octokit-plugin-stdout-progress"); 8 | 9 | module.exports = Octokit.plugin( 10 | paginateRest, 11 | retry, 12 | throttling, 13 | octokitPluginStdoutProgress 14 | ).defaults({ 15 | authStrategy: createAppAuth, 16 | throttle: { 17 | onRateLimit: (retryAfter, options, octokit) => { 18 | octokit.log.warn( 19 | `Request quota exhausted for request ${options.method} ${options.url}` 20 | ); 21 | 22 | if (options.request.retryCount === 0) { 23 | // only retries once 24 | octokit.log.info(`Retrying after ${retryAfter} seconds!`); 25 | return true; 26 | } 27 | }, 28 | onAbuseLimit: (retryAfter, options, octokit) => { 29 | // does not retry, only logs a warning 30 | octokit.log.warn( 31 | `Abuse detected for request ${options.method} ${options.url}` 32 | ); 33 | }, 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /lib/app-stats.js: -------------------------------------------------------------------------------- 1 | module.exports = getAppStats; 2 | 3 | const Octokit = require("./app-octokit"); 4 | 5 | async function getAppStats({ id, privateKey }) { 6 | try { 7 | const octokit = new Octokit({ 8 | auth: { 9 | id, 10 | privateKey, 11 | }, 12 | }); 13 | 14 | const installations = await octokit.paginate( 15 | "GET /app/installations", 16 | { 17 | mediaType: { previews: ["machine-man"] }, 18 | per_page: 100, 19 | }, 20 | (response) => 21 | response.data.map((installation) => { 22 | const { 23 | id, 24 | account: { login }, 25 | suspended_at, 26 | } = installation; 27 | 28 | return { id, login, suspended: !!suspended_at }; 29 | }) 30 | ); 31 | 32 | const accounts = []; 33 | let suspendedInstallations = 0; 34 | for (const installation of installations) { 35 | if (installation.suspended) { 36 | suspendedInstallations++; 37 | continue; 38 | } 39 | 40 | const installationOctokit = new Octokit({ 41 | auth: { 42 | id, 43 | privateKey, 44 | installationId: installation.id, 45 | }, 46 | }); 47 | 48 | const repositories = await installationOctokit.paginate( 49 | "GET /installation/repositories", 50 | { 51 | mediaType: { previews: ["machine-man"] }, 52 | per_page: 100, 53 | }, 54 | (response) => 55 | response.data.map((repository) => { 56 | return { 57 | private: repository.private, 58 | stars: repository.stargazers_count, 59 | }; 60 | }) 61 | ); 62 | 63 | const stars = repositories 64 | .filter((repository) => !repository.private) 65 | .reduce((stars, repository) => { 66 | return stars + repository.stars; 67 | }, 0); 68 | 69 | accounts.push({ ...installation, stars }); 70 | } 71 | 72 | console.log(""); 73 | return { 74 | installations: accounts.length + suspendedInstallations, 75 | suspendedInstallations, 76 | popularRepositories: accounts 77 | .sort((a, b) => b.stars - a.stars) 78 | .slice(0, 10) 79 | .map(({ suspended, ...account }) => account), 80 | }; 81 | } catch (error) { 82 | console.log(error); 83 | throw error; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/octokit-plugin-stdout-progress.js: -------------------------------------------------------------------------------- 1 | module.exports = octokitPluginStdoutProgress; 2 | 3 | function octokitPluginStdoutProgress(octokit) { 4 | octokit.hook.before("request", () => process.stdout.write(".")); 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skypack-quality-score-action", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "GitHub action that creates a check run with Skypack's quality score report", 6 | "main": "index.js", 7 | "scripts": { 8 | "build": "ncc build index.js -o dist" 9 | }, 10 | "keywords": [ 11 | "action" 12 | ], 13 | "repository": "https://github.com/gr2m/skypack-quality-score-action", 14 | "author": "Gregor Martynus (https://twitter.com/gr2m)", 15 | "license": "ISC", 16 | "dependencies": { 17 | "@actions/core": "^1.2.4", 18 | "@skypack/package-check": "0.2.2" 19 | }, 20 | "devDependencies": { 21 | "@semantic-release/git": "^9.0.0", 22 | "@zeit/ncc": "^0.22.3", 23 | "semantic-release": "^17.3.0" 24 | }, 25 | "release": { 26 | "branches": [ 27 | "main" 28 | ], 29 | "plugins": [ 30 | "@semantic-release/commit-analyzer", 31 | "@semantic-release/release-notes-generator", 32 | [ 33 | "@semantic-release/git", 34 | { 35 | "assets": [ 36 | "dist/index.js" 37 | ], 38 | "message": "build(release): compiled action for ${nextRelease.version}\n\n[skip ci]" 39 | } 40 | ], 41 | "@semantic-release/github" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | This folder contains different test cases to run the action against 2 | -------------------------------------------------------------------------------- /test/success/README.md: -------------------------------------------------------------------------------- 1 | success test 2 | -------------------------------------------------------------------------------- /test/success/index.js: -------------------------------------------------------------------------------- 1 | export function helloWorld() { 2 | console.log("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /test/success/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skypack-package-check-test", 3 | "version": "1.0.0", 4 | "author": "Gregor Martynus (https://twitter.com/gr2m)", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "@skypack/package-check": "^0.1.0" 8 | }, 9 | "exports": { 10 | "import": "index.js" 11 | }, 12 | "files": [ 13 | "index.js" 14 | ], 15 | "keywords": [ 16 | "test" 17 | ], 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/skypackjs/package-check" 21 | }, 22 | "types": "index.d.ts" 23 | } 24 | --------------------------------------------------------------------------------