├── .brigade ├── brigade.ts ├── package.json ├── project.yaml └── yarn.lock ├── .gitignore ├── CODEOWNERS ├── CONTRIBUTING.md ├── DEVELOPERS.md ├── LICENSE ├── README.md ├── package.json ├── src ├── events.ts ├── group.ts ├── index.ts ├── job.ts └── logger.ts ├── test ├── brigadier.ts ├── events.ts ├── group.ts ├── job.ts └── mock.ts ├── tsconfig.json ├── tslint.json └── yarn.lock /.brigade/brigade.ts: -------------------------------------------------------------------------------- 1 | import { ConcurrentGroup, events, Event, Job } from "@brigadecore/brigadier" 2 | 3 | const nodeImage = "node:12.22.7-bullseye" 4 | 5 | // A map of all jobs. When a check_run:rerequested event wants to re-run a 6 | // single job, this allows us to easily find that job by name. 7 | const jobs: { [key: string]: (event: Event) => Job } = {} 8 | 9 | const buildJobName = "build" 10 | const buildJob = (event: Event) => { 11 | const job = new Job(buildJobName, nodeImage, event) 12 | job.primaryContainer.sourceMountPath = "/src" 13 | job.primaryContainer.workingDirectory = "/src" 14 | job.primaryContainer.command = ["sh"] 15 | job.primaryContainer.arguments = [ 16 | "-c", 17 | "yarn install && yarn compile && yarn test" 18 | ] 19 | return job 20 | } 21 | jobs[buildJobName] = buildJob 22 | 23 | const auditJobName = "audit" 24 | const auditJob = (event: Event) => { 25 | const job = new Job(auditJobName, nodeImage, event) 26 | job.primaryContainer.sourceMountPath = "/src" 27 | job.primaryContainer.workingDirectory = "/src" 28 | job.primaryContainer.command = ["sh"] 29 | job.primaryContainer.arguments = [ 30 | "-c", 31 | "yarn install && yarn audit" 32 | ] 33 | job.fallible = true 34 | return job 35 | } 36 | jobs[auditJobName] = auditJob 37 | 38 | const publishJobName = "publish" 39 | const publishJob = (event: Event, version: string) => { 40 | const job = new Job(publishJobName, nodeImage, event) 41 | job.primaryContainer.environment = { 42 | "VERSION": version, 43 | "NPM_TOKEN": event.project.secrets.npmToken 44 | } 45 | job.primaryContainer.sourceMountPath = "/src" 46 | job.primaryContainer.workingDirectory = "/src" 47 | job.primaryContainer.command = ["sh"] 48 | job.primaryContainer.arguments = [ 49 | "-c", 50 | "yarn publish --new-version $(printf $VERSION | cut -c 2- ) --access public --no-git-tag-version" 51 | ] 52 | return job 53 | } 54 | 55 | async function runSuite(event: Event): Promise { 56 | await new ConcurrentGroup( // Basic tests 57 | buildJob(event), 58 | auditJob(event) 59 | ).run() 60 | } 61 | 62 | // Either of these events should initiate execution of the entire test suite. 63 | events.on("brigade.sh/github", "check_suite:requested", runSuite) 64 | events.on("brigade.sh/github", "check_suite:rerequested", runSuite) 65 | 66 | // This event indicates a specific job is to be re-run. 67 | events.on("brigade.sh/github", "check_run:rerequested", async event => { 68 | // Check run names are of the form :, so we strip 69 | // event.project.id.length + 1 characters off the start of the check run name 70 | // to find the job name. 71 | const jobName = JSON.parse(event.payload).check_run.name.slice(event.project.id.length + 1) 72 | const job = jobs[jobName] 73 | if (job) { 74 | await job(event).run() 75 | return 76 | } 77 | throw new Error(`No job found with name: ${jobName}`) 78 | }) 79 | 80 | events.on("brigade.sh/github", "release:published", async event => { 81 | const version = JSON.parse(event.payload).release.tag_name 82 | await publishJob(event, version).run() 83 | }) 84 | 85 | events.process() 86 | -------------------------------------------------------------------------------- /.brigade/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "brigadier-ci-cd", 3 | "dependencies": { 4 | "@brigadecore/brigadier": "^2.2.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.brigade/project.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://schemas.brigade.sh/schemas-v2/project.json 2 | apiVersion: brigade.sh/v2 3 | kind: Project 4 | metadata: 5 | id: brigadier 6 | description: Brigadier v1.x built with Brigade 2! 7 | spec: 8 | eventSubscriptions: 9 | - source: brigade.sh/github 10 | qualifiers: 11 | repo: brigadecore/brigadier 12 | types: 13 | - check_run:rerequested 14 | - check_suite:requested 15 | - check_suite:rerequested 16 | - release:published 17 | workerTemplate: 18 | logLevel: DEBUG 19 | git: 20 | cloneURL: https://github.com/brigadecore/brigadier.git 21 | -------------------------------------------------------------------------------- /.brigade/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@brigadecore/brigadier@^2.2.0": 6 | version "2.2.0" 7 | resolved "https://registry.yarnpkg.com/@brigadecore/brigadier/-/brigadier-2.2.0.tgz#0345375108c3f482f396811d24b3c49bf1fb02ed" 8 | integrity sha512-4LKi9vY1n91qz3LDtdD6JxNZgwsWUJClMzUb0YsXfUdtHVldhlFMTnoZJIx/6wjJgJkf3kV6EV8zww28ymRNnQ== 9 | dependencies: 10 | "@types/node" "^16.10.3" 11 | typescript "4.4.3" 12 | 13 | "@types/node@^16.10.3": 14 | version "16.11.13" 15 | resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.13.tgz#6b71641b81a98c6a538d89892440c06f147edddc" 16 | integrity sha512-eUXZzHLHoZqj1frtUetNkUetYoJ6X55UmrVnFD4DMhVeAmwLjniZhtBmsRiemQh4uq4G3vUra/Ws/hs9vEvL3Q== 17 | 18 | typescript@4.4.3: 19 | version "4.4.3" 20 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" 21 | integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | out/ 3 | .brigade/secrets.yaml 4 | .brigade/node_modules/ 5 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This file is described here: https://help.github.com/en/articles/about-code-owners 2 | 3 | # Global Owners: These members are Core Maintainers of Brigade 4 | * @brigadecore/maintainers 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | 3 | See our Brigade project [Contributing Guide](https://github.com/brigadecore/community/blob/master/contributing.md). -------------------------------------------------------------------------------- /DEVELOPERS.md: -------------------------------------------------------------------------------- 1 | # Contributing to Brigadier 2 | 3 | Brigadier is part of the [Brigade Core](https://github.com/brigadecore/brigade). Make sure you test your changes with Brigade. 4 | 5 | ## Publishing Brigadier 6 | 7 | Members of the Brigade Core project can publish Brigadier libraries by running `npm publish` or `yarn publish` -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2019 The Brigade Authors. 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > ⚠️  This repo contains the source for Brigadier v1.x, which is 2 | > compatible with Brigade v1.x. Brigade v1.x reached end-of-life on June 1, 3 | > 2022. Brigadier lives on as a Brigade v2.x-compatible library. Please refer to 4 | > the [main Brigade repository](https://github.com/brigadecore/brigade) to find 5 | > the latest Brigadier source code. 6 | 7 | # Brigadier: The JS library for Brigade 8 | 9 | Brigadier is the events and jobs library for [Brigade](https://brigade.sh). 10 | 11 | This is the core of the Brigadier library, but the Kubernetes runtime is part of Brigade itself. 12 | To run a `brigade.js` file in Kubernetes, it will need to be executed within Brigade. 13 | 14 | ## What is it good for? 15 | 16 | This library is useful for: 17 | 18 | - testing `brigade.js` files 19 | - extending Brigade's worker 20 | - supporting code completion in tooling 21 | - implementing alternative Brigade backends 22 | 23 | Because there is no `JobRunner` implementation, executing `job.run()` is a no-op unless you override the appropriate methods on the `Job` class. 24 | 25 | ## Installation 26 | 27 | [![NPM](https://nodei.co/npm/@brigadecore/brigadier.png)](https://www.npmjs.com/package/@brigadecore/brigadier) 28 | 29 | Install with Yarn, NPM, etc.: 30 | 31 | ```console 32 | $ yarn add @brigadecore/brigadier 33 | ``` 34 | 35 | While this library is fairly stable, it is considered best to match the version of this library 36 | to the version of Brigade that you are using. 37 | 38 | 39 | ## Usage 40 | 41 | The API is the same here as in [Brigade's API](https://docs.brigade.sh/topics/javascript): 42 | 43 | ```javascript 44 | const {events, Job} = require("@brigadecore/brigadier"); 45 | 46 | events.on("push", (e, p) => { 47 | console.log("Got a push event"); 48 | const j = new Job("example", "alpine:3.7"); 49 | j.run().then((res) => { 50 | console.log(`result: ${ res.toString() } `) 51 | }); 52 | }); 53 | ``` 54 | 55 | To learn more, visit the [official scripting guide](https://docs.brigade.sh/topics/scripting). 56 | 57 | # Contributing 58 | 59 | This Brigade project accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted. 60 | 61 | ## Signed commits 62 | 63 | A DCO sign-off is required for contributions to repos in the brigadecore org. See the documentation in 64 | [Brigade's Contributing guide](https://github.com/brigadecore/brigade/blob/master/CONTRIBUTING.md#signed-commits) 65 | for how this is done. 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@brigadecore/brigadier", 3 | "version": "placeholder", 4 | "description": "Brigade library for pipelines and events", 5 | "main": "out/index.js", 6 | "types": "out/index.d.ts", 7 | "author": "Brigade Core Maintainers", 8 | "license": "Apache-2.0", 9 | "homepage": "https://github.com/brigadecore/brigadier", 10 | "bugs": { 11 | "url": "https://github.com/brigadecore/brigadier/issues" 12 | }, 13 | "scripts": { 14 | "compile": "tsc -p ./", 15 | "watch": "tsc -watch -p ./", 16 | "test": "mocha --require ts-node/register --recursive ./test/**/*.ts" 17 | }, 18 | "keywords": [ 19 | "kubernetes", 20 | "brigade" 21 | ], 22 | "files": [ 23 | "out/*.js", 24 | "out/*.ts" 25 | ], 26 | "devDependencies": { 27 | "@types/chai": "^4.0.1", 28 | "@types/mocha": "^2.2.41", 29 | "@types/node": "^12.20.37", 30 | "chai": "^4.1.0", 31 | "mocha": "^9.1.3", 32 | "prettier": "^1.9.1", 33 | "rimraf": "^2.6.2", 34 | "ts-node": "^7.0.0", 35 | "typedoc": "^0.17.8", 36 | "typescript": "^3.8.3" 37 | }, 38 | "dependencies": { 39 | "@kubernetes/client-node": "^0.10.1", 40 | "child-process-promise": "^2.2.1", 41 | "pretty-error": "^3.0.4", 42 | "ulid": "^0.2.0" 43 | }, 44 | "resolutions": { 45 | "handlebars": "^4.3.0", 46 | "minimist": "^1.2.3" 47 | } 48 | } -------------------------------------------------------------------------------- /src/events.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The events package provides event handling support. 3 | * 4 | * Brigade scripts are event-driven. Each brigade JS file declares one or more events 5 | * that it can handle. When the Brigade controller emits a matching event, the 6 | * appropriate handler is kicked off. 7 | */ 8 | 9 | import { EventEmitter } from "events"; 10 | import { LogLevel } from "./logger"; 11 | 12 | /** 13 | * BrigadeEvent describes an event. 14 | * 15 | * Brigade is an event-based system. The BrigadeEvent object describes such an 16 | * event. 17 | * 18 | * Every event has a `type` and a `provider`, where the type indicates what 19 | * sort of event it is (e.g. `push`) and the provider indicates what system 20 | * provided the event (`github`, `acr`). 21 | * 22 | * Most events also have a commit ID, which is associated with the underlying 23 | * VCS, and a `payload`, which contains the message received from the provider. 24 | * 25 | * For example, when a GitHub Push event happens, the BrigadeEvent will have: 26 | * 27 | * - type set to `push` 28 | * - provider set to `github` 29 | * - commit set to the Git commit ID (e.g. `c0ff3312345...`) 30 | * - payload set to a string that contains the JSON document received from 31 | * GitHub. 32 | * - buildID set to the build ID. 33 | * 34 | * Note that the payload is considered "opaque": It is up to the script to parse 35 | * it. 36 | */ 37 | export class BrigadeEvent { 38 | /** 39 | * buildID is the unique ID for this build. 40 | */ 41 | buildID?: string; 42 | /** 43 | * workerID is the ID of the worker responsible for handling this event. 44 | */ 45 | workerID?: string; 46 | /** 47 | * type is the event type ("push", "pull_request") 48 | */ 49 | type: string = "unknown"; 50 | /** 51 | * provider is the thing that triggered the event ("github", "vsts") 52 | */ 53 | provider?: string; 54 | /** 55 | * cloneURL is an optional URL for cloning the source code to be built. 56 | * If set, it overrides the project-level cloneURL. This is useful for 57 | * builds that need to build source from a fork. 58 | */ 59 | cloneURL?: string; 60 | /** 61 | * revision describes a vcs revision. 62 | */ 63 | revision?: Revision; 64 | /** 65 | * payload is the event body. 66 | * This is the original source from upstream. If upstream returned a string, 67 | * it is _not_ parsed. For example, 68 | * if the upstream provider sends a JSON document, this will contain the 69 | * JSON as a string that must be decoded with something like `JSON.parse()` 70 | */ 71 | payload?: any; 72 | 73 | /** 74 | * logLevel is the level at which the Brigade worker will print logs to console. 75 | * Permitted values are the names of the logLevel enum. 76 | */ 77 | logLevel: LogLevel = LogLevel.ALL; 78 | 79 | cause?: Cause; 80 | } 81 | 82 | /** 83 | * Revision describes a vcs revision. 84 | */ 85 | export class Revision { 86 | /** 87 | * commit is the upstream VCS commit ID (revision). 88 | * 89 | * If it is not provided, it may be interpreted as `master`, or the head 90 | * of the main branch. 91 | * 92 | * The default value is not guaranteed to be `master` in future versions. 93 | */ 94 | commit?: string; 95 | /* 96 | * Ref is the symbolic ref name. (refs/heads/master, refs/pull/12/head, refs/tags/v0.1.0) 97 | */ 98 | ref?: string; 99 | } 100 | 101 | /** 102 | * A Cause is a wrapper around an event. It is used to indicate that this event 103 | * caused a condition to occur. 104 | * 105 | * Frequently this is used to capture a case where an event triggered an error. 106 | */ 107 | export class Cause { 108 | /** 109 | * The event that was the cause. 110 | */ 111 | event?: BrigadeEvent; 112 | /** 113 | * The reason this event has caused a condition. (Typically, an error object) 114 | */ 115 | reason?: any; 116 | /** 117 | * The mechanism that triggered this event. 118 | * 119 | * For example, an exception cather may report "unahndled exception" here. 120 | */ 121 | trigger?: string; 122 | } 123 | 124 | /** 125 | * Repository describes a source code repository (VCS) 126 | */ 127 | export interface Repository { 128 | /** 129 | * name of the repository. For GitHub, this is org/project 130 | */ 131 | name: string; 132 | /** 133 | * cloneURL is the URL at which the repository can be cloned. 134 | * Traditionally this is https, but with sshKey specified, this can be git+ssh or ssh. 135 | */ 136 | cloneURL: string; 137 | /** 138 | * sshKey the SSH key to use for ssh:// or git+ssh:// protocols 139 | */ 140 | sshKey?: string; 141 | /** 142 | * sshCert the SSH certificate to use for ssh:// or git+ssh:// protocols 143 | * more details could be found at https://github.blog/2019-08-14-ssh-certificate-authentication-for-github-enterprise-cloud/ 144 | */ 145 | sshCert?: string; 146 | /** 147 | * token is the OAuth2 token for Git interactions over HTTPS 148 | */ 149 | token?: string; 150 | 151 | /** 152 | * initGitSubmodules is a flag that controls if the cloned repository should also have it's submodules initialized (if any). 153 | */ 154 | initGitSubmodules: boolean; 155 | } 156 | 157 | /** 158 | * KubernetesConfig describes Kubernetes configuration for a Project 159 | */ 160 | export interface KubernetesConfig { 161 | /** 162 | * namespace is the Kubernetes namespace in which this project should operate. 163 | */ 164 | namespace: string; 165 | /** 166 | * vcsSidecare is the image name for the sidecar container that resolves VCS operations. 167 | */ 168 | vcsSidecar: string; 169 | 170 | /** 171 | * vcsSidecarResourcesLimitsCPU is the cpu limits name for the sidecar container. 172 | */ 173 | vcsSidecarResourcesLimitsCPU: string; 174 | 175 | /** 176 | * vcsSidecarResourcesLimitsMemory is the memory limits name for the sidecar container. 177 | */ 178 | vcsSidecarResourcesLimitsMemory: string; 179 | 180 | /** 181 | * vcsSidecarResourcesRequestsCPU is the cpu requests name for the sidecar container. 182 | */ 183 | vcsSidecarResourcesRequestsCPU: string; 184 | 185 | /** 186 | * vcsSidecarResourcesRequestsMemory is the memory requests name for the sidecar container. 187 | */ 188 | vcsSidecarResourcesRequestsMemory: string; 189 | 190 | /** 191 | * buildStorageSize is the size of the build shared storage space used by the jobs 192 | */ 193 | buildStorageSize: string; 194 | 195 | /** 196 | * cacheStorageClass is the storage class for job caches. 197 | */ 198 | cacheStorageClass: string; 199 | 200 | /** 201 | * buildStorageClass is the storage class for build storage. 202 | */ 203 | buildStorageClass: string; 204 | } 205 | 206 | /** 207 | * Project represents a Brigade project. 208 | */ 209 | export class Project { 210 | /** 211 | * id is the unique ID of the project 212 | */ 213 | id?: string; 214 | /** 215 | * name is the project name. 216 | */ 217 | name?: string; 218 | /** 219 | * repo describes the VCS where source for this project can be obtained. 220 | */ 221 | repo?: Repository; 222 | /** 223 | * kubernetes contains the kubernetes configuration for this project. 224 | */ 225 | kubernetes?: KubernetesConfig; 226 | /* 227 | * secrets is a map of secret names to secret values. 228 | */ 229 | secrets: { [key: string]: string } = {}; 230 | 231 | /** 232 | * allowPrivilegedJobs enables privileged mode. 233 | */ 234 | allowPrivilegedJobs: boolean = false; 235 | 236 | /* 237 | * allowHostMounts enables whether or not builds can mount in host volumes. 238 | */ 239 | allowHostMounts: boolean = false; 240 | } 241 | 242 | /** 243 | * EventHandler is an event handler function. 244 | * 245 | * An event handler will always receive an event and a project. 246 | * 247 | * The EventRegistry.on() method should be supplied a function conformant to EventHandler. 248 | */ 249 | export type EventHandler = (e: BrigadeEvent, proj?: Project) => void; 250 | 251 | /** 252 | * EventRegistry manages the registration and execution of events. 253 | */ 254 | export class EventRegistry extends EventEmitter { 255 | /** 256 | * Create a new event registry. 257 | */ 258 | constructor() { 259 | super(); 260 | this.on("ping", (e: BrigadeEvent, p?: Project) => { 261 | console.log("ping"); 262 | }); 263 | } 264 | 265 | public has(name: string) { 266 | return this.listenerCount(name) > 0; 267 | } 268 | 269 | /** 270 | * fire triggers an event. 271 | * This uses BrigadeEvent.name to fire an event. 272 | */ 273 | public fire(e: BrigadeEvent, proj: Project) { 274 | this.emit(e.type, e, proj); 275 | } 276 | 277 | /** 278 | * Handle a named event using the given EventHandler. 279 | * 280 | * While we cannot revise the type that the Node events library takes for callbacks, Brigade will always 281 | * supply two arguments to the callback, as described in the EventHandler type. 282 | * 283 | * @param eventName The name of the event 284 | * @param cb A callback of the format described in type EventHandler 285 | */ 286 | public on(eventName: string | symbol, cb: EventHandler): this { 287 | return super.on(eventName, cb); 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/group.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * group provides features for grouping jobs and managing them collectively. 3 | */ 4 | 5 | /** */ 6 | 7 | import * as jobImpl from "./job"; 8 | 9 | /** 10 | * Group describes a collection of associated jobs. 11 | */ 12 | export class Group { 13 | /** 14 | * runAll is a convenience for running jobs in parallel. 15 | * 16 | * This runs a series of jobs in parallel. It is equivalent to 17 | * `(new Group(jobs)).runAll()` 18 | */ 19 | public static runAll(jobs: jobImpl.Job[]): Promise { 20 | let g = new Group(jobs); 21 | return g.runAll(); 22 | } 23 | /** 24 | * runEach is a convenience of running jobs in a sequence. 25 | * 26 | * This runs a series of jobs in order, blocking on each until it completes. 27 | * It is equivalent to `(new Group(jobs)).runEach()` 28 | */ 29 | public static runEach(jobs: jobImpl.Job[]): Promise { 30 | let g = new Group(jobs); 31 | return g.runEach(); 32 | } 33 | 34 | protected jobs: jobImpl.Job[] = []; 35 | public constructor(jobs?: jobImpl.Job[]) { 36 | this.jobs = jobs || []; 37 | } 38 | /** 39 | * add adds one or more jobs to the group. 40 | */ 41 | public add(...j: jobImpl.Job[]): void { 42 | for (let jj of j) { 43 | this.jobs.push(jj); 44 | } 45 | } 46 | /** 47 | * length returns the number of items in the group 48 | */ 49 | public length(): number { 50 | return this.jobs.length; 51 | } 52 | /** 53 | * runEach runs each job in order and waits for every one to finish. 54 | * 55 | */ 56 | public runEach(): Promise { 57 | // TODO: Rewrite this using async/await, which will make it much cleaner. 58 | return this.jobs.reduce( 59 | (promise: Promise, job: jobImpl.Job) => { 60 | return promise.then((results: jobImpl.Result[]) => { 61 | return job.run().then(jobResult => { 62 | results.push(jobResult); 63 | return results; 64 | }); 65 | }); 66 | }, 67 | Promise.resolve([]) 68 | ); 69 | } 70 | /** 71 | * runAll runs all jobs in parallel and waits for them all to finish. 72 | */ 73 | public runAll(): Promise { 74 | let plist: Promise[] = []; 75 | for (let j of this.jobs) { 76 | plist.push(j.run()); 77 | } 78 | return Promise.all(plist); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * brigadier is the client-facing library for Brigade. 3 | * 4 | * Objects in this library are available to `brigade.js` scripts. 5 | */ 6 | 7 | /** */ 8 | 9 | import * as jobImpl from "./job"; 10 | import * as groupImpl from "./group"; 11 | import * as eventsImpl from "./events"; 12 | 13 | /** 14 | * events is the main event registry. 15 | * 16 | * New event handlers can be registered using `events.on(name: string, (e: BrigadeEvent, 17 | * p: Project) => {})`. 18 | * where the `name` is the event name, and the callback is the function to be 19 | * executed when the event is triggered. 20 | */ 21 | export let events = new eventsImpl.EventRegistry(); 22 | 23 | /** 24 | * fire triggers an event. 25 | * 26 | * The fire() function takes a BrigadeEvent (the event to be triggered) and a 27 | * Project (the owner project). If an event handler is found, it is executed. 28 | * If no event handler is found, nothing happens. 29 | */ 30 | export function fire(e: eventsImpl.BrigadeEvent, p: eventsImpl.Project) { 31 | events.fire(e, p); 32 | } 33 | 34 | /** 35 | * Job describes a particular job. 36 | * 37 | * A Job always has a name and an image. The name is used to reference this 38 | * job in relation to other jobs in the same event. The image corresponds to a 39 | * container image that will be executed as part of this job. 40 | * 41 | * A Job may also have one or more tasks associated with it. Tasks are run 42 | * (in order) inside of the image. When no tasks are supplied, the image is 43 | * executed as-is. 44 | * 45 | * The version of Job that ships with this package has no runtime. Jobs are 46 | */ 47 | export class Job extends jobImpl.Job { 48 | public runResponse: string = "skipped run" 49 | public logsResponse: string = "skipped logs" 50 | 51 | run(): Promise { 52 | return Promise.resolve(this.runResponse) 53 | } 54 | 55 | logs(): Promise { 56 | return Promise.resolve(this.logsResponse) 57 | } 58 | } 59 | 60 | /** 61 | * Group describes a collection of associated jobs. 62 | * 63 | * A group of jobs can be executed in two ways: 64 | * - In parallel as runAll() 65 | * - In serial as runEach() 66 | */ 67 | export class Group extends groupImpl.Group { 68 | // This seems to be how you expose an existing class as an export. 69 | } 70 | 71 | /** 72 | * ErrorReport describes an error in the runtime handling of a Brigade script. 73 | */ 74 | export class ErrorReport { 75 | /** 76 | * cause is the BrigadeEvent that caused the error. 77 | */ 78 | public cause?: eventsImpl.BrigadeEvent; 79 | /** 80 | * reason is the message that the error reporter received that describes the error. 81 | * 82 | * It may be empty if no error description was provided. 83 | */ 84 | public reason?: any; 85 | } 86 | -------------------------------------------------------------------------------- /src/job.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Package job provides support for jobs. 3 | * 4 | * A Job idescribes a particular unit of a build. A Job returns a Result. 5 | * A JobRunner is an implementation of the runtime logic for a Job. 6 | */ 7 | 8 | /** */ 9 | 10 | import { V1EnvVarSource, V1VolumeMount, V1Volume } from "@kubernetes/client-node/dist/api"; 11 | 12 | /** 13 | * The default shell for the job. 14 | */ 15 | const defaultShell: string = "/bin/sh"; 16 | /** 17 | * defaultTimeout is the default timeout for a job (15 minutes) 18 | */ 19 | const defaultTimeout: number = 1000 * 60 * 15; 20 | /** 21 | * The default image if `Job.image` is not set 22 | */ 23 | const brigadeImage: string = "debian:jessie-slim"; 24 | 25 | export const brigadeCachePath = "/mnt/brigade/cache"; 26 | export const brigadeStoragePath = "/mnt/brigade/share"; 27 | export const dockerSocketMountPath = "/var/run/docker.sock"; 28 | export const dockerSocketMountName = "docker-socket"; 29 | 30 | /** 31 | * JobRunner is capable of executing a job within a runtime. 32 | */ 33 | export interface JobRunner { 34 | // TODO: Should we add the constructor here? 35 | // Start runs a new job. It returns a JobRunner that can be waited upon. 36 | start(): Promise; 37 | // Wait waits unti the job being run has reached a success or failure state. 38 | wait(): Promise; 39 | } 40 | 41 | /** 42 | * Result is the result of a particular Job. 43 | * 44 | * Every Result can be converted to a String with the `toString()` function. The 45 | * string is human-readable. 46 | */ 47 | export interface Result { 48 | toString(): string; 49 | } 50 | 51 | /** 52 | * Cache controls the job's cache. 53 | * 54 | * A cache is a small storage space that is shared between different instances 55 | * if the same job. 56 | * 57 | * Cache is just a plain filesystem, and as such comes with no guarantees about 58 | * consistency, etc. It should be treated as volatile. 59 | */ 60 | export class JobCache { 61 | /** 62 | * If enabled=true, a storage cache will be attached. 63 | */ 64 | public enabled: boolean = false; 65 | /** 66 | * size is the amount of storage space assigned to the cache. The default is 67 | * 5Mi. 68 | * For sizing information, see https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resources.md 69 | */ 70 | public size: string = "5Mi"; 71 | 72 | // EXPERIMENTAL: Allow script authors to change this location. 73 | // Before Brigade 0.15, this used a getter to prevent scripters from setting 74 | // this path directly. 75 | public path: string = brigadeCachePath; 76 | } 77 | 78 | /** 79 | * JobStorage configures build-wide storage preferences for this job. 80 | * 81 | * Changes to this object only impact the job, not the entire build. 82 | */ 83 | export class JobStorage { 84 | public enabled: boolean = false; 85 | 86 | // EXPERIMENTAL: Allow setting the path. 87 | // Prior to Brigade 0.15, this was read-only. 88 | public path: string = brigadeStoragePath; 89 | } 90 | 91 | /** 92 | * JobHost expresses expectations about the host a job will run on. 93 | */ 94 | export class JobHost { 95 | constructor() { 96 | this.nodeSelector = new Map(); 97 | } 98 | 99 | /** 100 | * os is the name of the OS upon which the job's container must run. 101 | * 102 | * This allows users to indicate that the container _must_ run on 103 | * "windows" or "linux" hosts. It is primarily useful in a "mixed node" 104 | * environment where the brigade.js will be run on a cluster that has more than 105 | * one OS 106 | */ 107 | public os?: string; 108 | 109 | /** 110 | * name of the host to run on. 111 | * 112 | * If this is set, a job will ask to be run on this named host. Generally, this 113 | * should be used only if it is necessary to run the job on a particular host. 114 | * If not set, Brigade will let the scheduler decide, which is strongly preferred. 115 | * 116 | * Example usage: If you use a Kubernetes-ACI bridge, you may want to use this 117 | * to run jobs on the bridge. 118 | */ 119 | public name?: string; 120 | 121 | /** 122 | * nodeSelector labels are used as selectors when choosing a node on which to run this job. 123 | */ 124 | public nodeSelector: Map; 125 | } 126 | 127 | /** 128 | * JobDockerMount enables or disables mounting the host's docker socket for a job. 129 | */ 130 | export class JobDockerMount { 131 | /** 132 | * enabled configues whether or not the job will mount the host's docker socket. 133 | */ 134 | public enabled: boolean = false; 135 | } 136 | 137 | /** 138 | * JobResourceRequest represents request of the resources 139 | */ 140 | export class JobResourceRequest { 141 | /** cpu requests */ 142 | public cpu?: string; 143 | /** memory requests */ 144 | public memory?: string; 145 | } 146 | 147 | /** 148 | * JobResourceLimit represents limit of the resources 149 | */ 150 | export class JobResourceLimit { 151 | /** cpu limits */ 152 | public cpu?: string; 153 | /** memory limits */ 154 | public memory?: string; 155 | } 156 | 157 | /** 158 | * Job represents a single job, which is composed of several closely related sequential tasks. 159 | * Jobs must have names. Every job also has an associated image, which references 160 | * the Docker container to be run. 161 | * */ 162 | export abstract class Job { 163 | public static readonly MAX_JOB_NAME_LENGTH = 36; 164 | 165 | /** name of the job*/ 166 | public name: string; 167 | /** shell that will be used by default in this job*/ 168 | public shell: string = defaultShell; 169 | /** tasks is a list of tasks run inside of the shell*/ 170 | public tasks: string[]; 171 | /** args is a list of arguments that will be supplied to the container.*/ 172 | public args: string[]; 173 | /** env is the environment variables for the job*/ 174 | public env: { [key: string]: string | V1EnvVarSource }; 175 | /** image is the container image to be run*/ 176 | public image: string = brigadeImage; 177 | /** imageForcePull defines the container image pull policy: Always if true or IfNotPresent if false */ 178 | public imageForcePull: boolean = false; 179 | /** 180 | * imagePullSecrets names secrets that contain the credentials for pulling this 181 | * image or the sidecar image. 182 | */ 183 | public imagePullSecrets: string[] = []; 184 | 185 | /** Path to mount as the base path for executable code in the container.*/ 186 | public mountPath: string = "/src"; 187 | 188 | /** Set the max time in miliseconds to wait for this job to complete.*/ 189 | public timeout: number = defaultTimeout; 190 | 191 | /** Fetch the source repo. Default: true*/ 192 | public useSource: boolean = true; 193 | 194 | /** If true, the job will be run in privileged mode. 195 | * This is necessary for Docker engines running inside the Job, for example. 196 | */ 197 | public privileged: boolean = false; 198 | 199 | /** The account identity to be used when running this job. 200 | * This is an optional way to override the build-wide service account. If it is 201 | * not specified, the main worker service account will be used. 202 | * 203 | * Different Brigade worker implementations may choose to honor or ignore this 204 | * for security or configurability reasons. 205 | * 206 | * See https://github.com/brigadecore/brigade/issues/251 207 | */ 208 | public serviceAccount?: string; 209 | 210 | /** Set the resource requests for the containers */ 211 | public resourceRequests: JobResourceRequest; 212 | 213 | /** Set the resource limits for the containers */ 214 | public resourceLimits: JobResourceLimit; 215 | 216 | /** 217 | * host expresses expectations about the host the job will run on. 218 | */ 219 | public host: JobHost; 220 | 221 | /** 222 | * cache controls per-Job caching preferences. 223 | */ 224 | public cache: JobCache; 225 | /** 226 | * storage controls this job's preferences on the build-wide storage. 227 | */ 228 | public storage: JobStorage; 229 | 230 | /** 231 | * EXPERIMENTAL: define volumes for the job. 232 | * The property is defined as a list of Kubernetes volumes, and supports all Kubernetes volume types. 233 | * Use the job's volumeMounts property to mount a volume defined to a path in the job's container. 234 | * The names for the volume and the desired volume mount must match. 235 | * For more info, see https://kubernetes.io/docs/concepts/storage/volumes/ 236 | * 237 | * For a simple shared volume between all the containers of a job, use JobStorage. 238 | */ 239 | public volumes: V1Volume[]; 240 | 241 | /** 242 | * EXPERIMENTAL: define volume mounts for the job. 243 | * The property is defined as a list of Kubernetes volume mounts. 244 | * Use the job's volumes property to define volumes. 245 | * The names for the volume and the desired volume mount must match. 246 | * For more info, see https://kubernetes.io/docs/concepts/storage/volumes/ 247 | * 248 | * For a simple shared volume between all the containers of a job, use JobStorage. 249 | */ 250 | public volumeMounts: V1VolumeMount[]; 251 | 252 | /** 253 | * docker controls the job's preferences on mounting the host's docker daemon. 254 | */ 255 | public docker: JobDockerMount; 256 | 257 | /** 258 | * pod annotations for the job 259 | */ 260 | public annotations: { [key: string]: string } = {}; 261 | 262 | /** _podName is set by the runtime. It is the name of the pod.*/ 263 | protected _podName: string = ""; 264 | 265 | /** podName is the generated name of the pod.*/ 266 | get podName(): string { 267 | return this._podName; 268 | } 269 | 270 | /** streamLogs controls whether logs from the job Pod will be streamed to output 271 | * this is similar to using `kubectl logs PODNAME -f` 272 | */ 273 | public streamLogs: boolean = false; 274 | 275 | /** Create a new Job 276 | * name is the name of the job. 277 | * image is the container image to use 278 | * tasks is a list of commands to run. 279 | */ 280 | constructor( 281 | name: string, 282 | image?: string, 283 | tasks?: string[], 284 | imageForcePull: boolean = false 285 | ) { 286 | if (!jobNameIsValid(name)) { 287 | throw new Error( 288 | "job name must be lowercase letters, numbers, and '-', and must not start or end with '-', having max length " + 289 | Job.MAX_JOB_NAME_LENGTH 290 | ); 291 | } 292 | this.name = name.toLocaleLowerCase(); 293 | this.image = image || ""; 294 | this.imageForcePull = imageForcePull; 295 | this.tasks = tasks || []; 296 | this.args = []; 297 | this.env = {}; 298 | this.cache = new JobCache(); 299 | this.storage = new JobStorage(); 300 | this.docker = new JobDockerMount(); 301 | this.host = new JobHost(); 302 | this.resourceRequests = new JobResourceRequest(); 303 | this.resourceLimits = new JobResourceLimit(); 304 | this.volumes = []; 305 | this.volumeMounts = []; 306 | } 307 | 308 | /** run executes the job and then */ 309 | public abstract run(): Promise; 310 | 311 | /** logs retrieves the logs (so far) from the job run */ 312 | public abstract logs(): Promise; 313 | } 314 | 315 | /** 316 | * jobNameIsValid checks the validity of a job's name. 317 | */ 318 | export function jobNameIsValid(name: string): boolean { 319 | return ( 320 | name.length <= Job.MAX_JOB_NAME_LENGTH && 321 | /^(([a-z0-9][-a-z0-9.]*)?[a-z0-9])+$/.test(name) 322 | ); 323 | } 324 | -------------------------------------------------------------------------------- /src/logger.ts: -------------------------------------------------------------------------------- 1 | import * as PrettyError from "pretty-error"; 2 | import * as path from "path"; 3 | 4 | const rootPath = path.join(__dirname, ".."); 5 | const pe = new PrettyError() 6 | .skipNodeFiles() 7 | .skipPackage("ts-node") 8 | .skipPackage("bluebird") 9 | .alias(rootPath, "."); 10 | pe.start(); 11 | 12 | export enum LogLevel { 13 | ALL = 0, 14 | LOG, 15 | INFO, 16 | WARN, 17 | ERROR, 18 | NONE 19 | } 20 | 21 | export interface Logger { 22 | logLevel: LogLevel; 23 | error(message?: any, ...optionalParams: any[]): void; 24 | warn(message?: any, ...optionalParams: any[]): void; 25 | info(message?: any, ...optionalParams: any[]): void; 26 | log(message?: any, ...optionalParams: any[]): void; 27 | } 28 | 29 | export class ContextLogger implements Logger { 30 | context: string; 31 | logLevel: LogLevel; 32 | constructor(ctx: string[] | string = [], logLevel = LogLevel.LOG) { 33 | if (typeof ctx === "string") { 34 | ctx = [ctx]; 35 | } 36 | this.context = `[${new Array("brigade", ...ctx).join(":")}]`; 37 | this.logLevel = logLevel; 38 | } 39 | error(message?: any, ...optionalParams: any[]): void { 40 | if (LogLevel.ERROR >= this.logLevel) { 41 | console.error(this.context, message, ...optionalParams); 42 | } 43 | } 44 | warn(message?: any, ...optionalParams: any[]): void { 45 | if (LogLevel.WARN >= this.logLevel) { 46 | console.warn(this.context, message, ...optionalParams); 47 | } 48 | } 49 | info(message?: any, ...optionalParams: any[]): void { 50 | if (LogLevel.INFO >= this.logLevel) { 51 | console.info(this.context, message, ...optionalParams); 52 | } 53 | } 54 | log(message?: any, ...optionalParams: any[]): void { 55 | if (LogLevel.LOG >= this.logLevel) { 56 | console.log(this.context, message, ...optionalParams); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/brigadier.ts: -------------------------------------------------------------------------------- 1 | import "mocha"; 2 | import { assert } from "chai"; 3 | 4 | import * as brigade from "../src/index"; 5 | import * as jobImpl from "../src/job"; 6 | 7 | import * as mock from "./mock"; 8 | 9 | // These tests are largely designed to ensure that the objects a script is likely 10 | // to use are indeed exposed. Tests for the actual functionality of each are found 11 | // in their respective libraries. 12 | describe("brigadier", function() { 13 | it("has #fire", function() { 14 | assert.property(brigade, "fire"); 15 | }); 16 | it("has .Job", function() { 17 | assert.property(brigade, "Job"); 18 | }); 19 | it("has .Group", function() { 20 | assert.property(brigade, "Group"); 21 | }); 22 | it("has .events", function() { 23 | assert.property(brigade, "events"); 24 | }); 25 | 26 | // Events tests 27 | describe("events", function() { 28 | it("has #on", function() { 29 | assert.property(brigade.events, "on"); 30 | }); 31 | }); 32 | 33 | // Group tests 34 | describe("Group", function() { 35 | let g: brigade.Group; 36 | beforeEach(function() { 37 | g = new brigade.Group(); 38 | }); 39 | describe("#add", function() { 40 | it("adds a job", function() { 41 | assert.equal(g.length(), 0); 42 | let j = new mock.MockJob("hello"); 43 | let j2 = new mock.MockJob("goodbye"); 44 | g.add(j); 45 | g.add(j2); 46 | assert.equal(g.length(), 2); 47 | }); 48 | }); 49 | describe("#runEach", function() { 50 | it("runs each job in order", function(done) { 51 | let j1 = new mock.MockJob("first"); 52 | let j2 = new mock.MockJob("second"); 53 | let j3 = new mock.MockJob("third"); 54 | // This ensures that if the jobs were not executed in sequence, 55 | // 1 and 2 would finish before 3. 56 | j3.delay = 50; 57 | g.add(j1, j2, j3); 58 | g.runEach().then((rez: jobImpl.Result[]) => { 59 | assert.equal(rez[0], j1.name); 60 | assert.equal(rez[1], j2.name); 61 | assert.equal(rez[2], j3.name); 62 | done(); 63 | }); 64 | }); 65 | it("gathers the logs after the run", function(done) { 66 | let j1 = new mock.MockJob("first"); 67 | j1.fail = true; 68 | j1.run().catch((res: jobImpl.Result) => { 69 | j1.logs().then((output: string) => { 70 | assert.equal(output, "These are the logs showing failure."); 71 | done(); 72 | }); 73 | }); 74 | }); 75 | context("when job fails", function() { 76 | it("stops processing with an error", function(done) { 77 | let j1 = new mock.MockJob("first"); 78 | let j2 = new mock.MockJob("second"); 79 | j2.fail = true; 80 | let j3 = new mock.MockJob("third"); 81 | g.add(j1, j2, j3); 82 | g 83 | .runEach() 84 | .then((rez: jobImpl.Result) => { 85 | done("expected error on job 2"); 86 | }) 87 | .catch(msg => { 88 | assert.equal(msg, "Failed"); 89 | done(); 90 | }); 91 | }); 92 | }); 93 | }); 94 | describe("#runAll", function() { 95 | it("runs jobs asynchronously", function(done) { 96 | let j1 = new mock.MockJob("first"); 97 | let j2 = new mock.MockJob("second"); 98 | let j3 = new mock.MockJob("third"); 99 | g.add(j1, j2, j3); 100 | g.runAll().then((rez: jobImpl.Result[]) => { 101 | assert.equal(rez.length, 3); 102 | done(); 103 | }); 104 | }); 105 | context("when job fails", function() { 106 | it("stops processing with an error", function(done) { 107 | let j1 = new mock.MockJob("first"); 108 | let j2 = new mock.MockJob("second"); 109 | j2.fail = true; 110 | let j3 = new mock.MockJob("third"); 111 | g.add(j1, j2, j3); 112 | g 113 | .runAll() 114 | .then((rez: jobImpl.Result) => { 115 | done("expected error on job 2"); 116 | }) 117 | .catch(msg => { 118 | assert.equal(msg, "Failed"); 119 | done(); 120 | }); 121 | }); 122 | }); 123 | }); 124 | }); 125 | }); 126 | -------------------------------------------------------------------------------- /test/events.ts: -------------------------------------------------------------------------------- 1 | import "mocha"; 2 | import { assert } from "chai"; 3 | import * as mock from "./mock"; 4 | 5 | import * as events from "../src/events"; 6 | 7 | describe("events", function() { 8 | // Here, we just want to ensure that objects exported to brigadier are 9 | // available. 10 | it("has .BrigadeEvent", function() { 11 | assert.property(events, "BrigadeEvent"); 12 | }); 13 | it("has .Project", function() { 14 | assert.property(events, "Project"); 15 | }); 16 | it("has .EventRegistry", function() { 17 | assert.property(events, "EventRegistry"); 18 | }); 19 | describe("EventRegistry", function() { 20 | let er: events.EventRegistry; 21 | beforeEach(function() { 22 | er = new events.EventRegistry(); 23 | }); 24 | describe("#constructor", function() { 25 | it("registers 'ping' handler", function() { 26 | assert.isTrue(er.has("ping")); 27 | }); 28 | }); 29 | describe("#on", function() { 30 | it("registers an event handler", function() { 31 | er.on("my-event", (e: events.BrigadeEvent, p?: events.Project) => {}); 32 | assert.isTrue(er.has("my-event")); 33 | }); 34 | }); 35 | describe("#fire", function() { 36 | it("executes an event handler", function() { 37 | let fired = false; 38 | let ename = "my-event"; 39 | let myEvent = mock.mockEvent(); 40 | let myProj = mock.mockProject(); 41 | myEvent.type = ename; 42 | er.on(ename, (e: events.BrigadeEvent, p?: events.Project) => { 43 | fired = true; 44 | }); 45 | er.fire(myEvent, myProj); 46 | assert.isTrue(fired); 47 | }); 48 | context("when calling an event with no handler", function() { 49 | it("does not cause an error (does nothing)", function() { 50 | // We want this behavior because we don't want to force every brigade.js 51 | // to implement every possible event. 52 | let myEvent = mock.mockEvent(); 53 | let myProj = mock.mockProject(); 54 | myEvent.type = "no-such-event"; 55 | er.fire(myEvent, myProj); 56 | }); 57 | }); 58 | }); 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /test/group.ts: -------------------------------------------------------------------------------- 1 | import "mocha"; 2 | import { assert } from "chai"; 3 | 4 | import * as group from "../src/group"; 5 | import * as jobImpl from "../src/job"; 6 | 7 | import * as mock from "./mock"; 8 | describe("group", function() { 9 | // Group tests 10 | describe("Group", function() { 11 | let g: group.Group; 12 | beforeEach(function() { 13 | g = new group.Group(); 14 | }); 15 | describe("#add", function() { 16 | it("adds a job", function() { 17 | assert.equal(g.length(), 0); 18 | let j = new mock.MockJob("hello"); 19 | let j2 = new mock.MockJob("goodbye"); 20 | g.add(j); 21 | g.add(j2); 22 | assert.equal(g.length(), 2); 23 | }); 24 | }); 25 | describe("#runEach", function() { 26 | it("runs each job in order", function(done) { 27 | let j1 = new mock.MockJob("first"); 28 | let j2 = new mock.MockJob("second"); 29 | let j3 = new mock.MockJob("third"); 30 | // This ensures that if the jobs were not executed in sequence, 31 | // 1 and 2 would finish before 3. 32 | j3.delay = 50; 33 | g.add(j1, j2, j3); 34 | g.runEach().then((rez: jobImpl.Result[]) => { 35 | assert.equal(rez[0], j1.name); 36 | assert.equal(rez[1], j2.name); 37 | assert.equal(rez[2], j3.name); 38 | done(); 39 | }); 40 | }); 41 | context("when job fails", function() { 42 | it("stops processing with an error", function(done) { 43 | let j1 = new mock.MockJob("first"); 44 | let j2 = new mock.MockJob("second"); 45 | j2.fail = true; 46 | let j3 = new mock.MockJob("third"); 47 | g.add(j1, j2, j3); 48 | g 49 | .runEach() 50 | .then((rez: jobImpl.Result[]) => { 51 | done("expected error on job 2"); 52 | }) 53 | .catch(msg => { 54 | assert.equal(msg, "Failed"); 55 | done(); 56 | }); 57 | }); 58 | }); 59 | }); 60 | describe("#runAll", function() { 61 | it("runs jobs asynchronously", function(done) { 62 | let j1 = new mock.MockJob("first"); 63 | let j2 = new mock.MockJob("second"); 64 | let j3 = new mock.MockJob("third"); 65 | g.add(j1, j2, j3); 66 | g.runAll().then((rez: jobImpl.Result[]) => { 67 | assert.equal(rez.length, 3); 68 | done(); 69 | }); 70 | }); 71 | context("when job fails", function() { 72 | it("stops processing with an error", function(done) { 73 | let j1 = new mock.MockJob("first"); 74 | let j2 = new mock.MockJob("second"); 75 | j2.fail = true; 76 | let j3 = new mock.MockJob("third"); 77 | g.add(j1, j2, j3); 78 | g 79 | .runAll() 80 | .then((rez: jobImpl.Result) => { 81 | done("expected error on job 2"); 82 | }) 83 | .catch(msg => { 84 | assert.equal(msg, "Failed"); 85 | done(); 86 | }); 87 | }); 88 | }); 89 | }); 90 | describe("static #runEach", function() { 91 | it("runs each job in order", function(done) { 92 | let j1 = new mock.MockJob("first"); 93 | let j2 = new mock.MockJob("second"); 94 | let j3 = new mock.MockJob("third"); 95 | // This ensures that if the jobs were not executed in sequence, 96 | // 1 and 2 would finish before 3. 97 | j3.delay = 5; 98 | group.Group.runEach([j1, j2, j3]).then((rez: jobImpl.Result[]) => { 99 | assert.equal(rez[0], j1.name); 100 | assert.equal(rez[1], j2.name); 101 | assert.equal(rez[2], j3.name); 102 | done(); 103 | }); 104 | }); 105 | context("when job fails", function() { 106 | it("stops processing with an error", function(done) { 107 | let j1 = new mock.MockJob("first"); 108 | let j2 = new mock.MockJob("second"); 109 | j2.fail = true; 110 | let j3 = new mock.MockJob("third"); 111 | group.Group.runEach([j1, j2, j3]) 112 | .then((rez: jobImpl.Result) => { 113 | done("expected error on job 2"); 114 | }) 115 | .catch(msg => { 116 | assert.equal(msg, "Failed"); 117 | done(); 118 | }); 119 | }); 120 | }); 121 | }); 122 | describe("static #runAll", function() { 123 | it("runs jobs asynchronously", function(done) { 124 | let j1 = new mock.MockJob("first"); 125 | let j2 = new mock.MockJob("second"); 126 | let j3 = new mock.MockJob("third"); 127 | group.Group.runAll([j1, j2, j3]).then((rez: jobImpl.Result[]) => { 128 | assert.equal(rez.length, 3); 129 | done(); 130 | }); 131 | }); 132 | context("when job fails", function() { 133 | it("stops processing with an error", function(done) { 134 | let j1 = new mock.MockJob("first"); 135 | let j2 = new mock.MockJob("second"); 136 | j2.fail = true; 137 | let j3 = new mock.MockJob("third"); 138 | group.Group.runAll([j1, j2, j3]) 139 | .then((rez: jobImpl.Result[]) => { 140 | done("expected error on job 2"); 141 | }) 142 | .catch(msg => { 143 | assert.equal(msg, "Failed"); 144 | done(); 145 | }); 146 | }); 147 | }); 148 | }); 149 | }); 150 | }); 151 | -------------------------------------------------------------------------------- /test/job.ts: -------------------------------------------------------------------------------- 1 | import "mocha"; 2 | import { assert } from "chai"; 3 | import * as mock from "./mock"; 4 | 5 | import { 6 | JobHost, 7 | JobCache, 8 | JobStorage, 9 | brigadeCachePath, 10 | brigadeStoragePath, 11 | jobNameIsValid, 12 | } from "../src/job"; 13 | import { V1Volume, V1VolumeMount } from "@kubernetes/client-node/dist/api"; 14 | 15 | describe("job", function () { 16 | describe("jobNameIsValid", () => { 17 | it("allows DNS-like names", function () { 18 | let legal = ["abcdef", "ab", "a-b", "a-9", "a12345678b", "a.b"]; 19 | for (let n of legal) { 20 | assert.isTrue(jobNameIsValid(n), "tested " + n); 21 | } 22 | }); 23 | it("disallows non-DNS-like names", function () { 24 | let illegal = [ 25 | "ab-", // no trailing - 26 | "-ab", // no leading dash 27 | "a_b", // underscore is illegal 28 | "ab.", // trailing dot is illegal 29 | "A-B" // Capitals are illegal 30 | ]; 31 | for (let n of illegal) { 32 | assert.isFalse(jobNameIsValid(n), "tested " + n); 33 | } 34 | }); 35 | }); 36 | 37 | describe("JobCache", function () { 38 | describe("#constructor", function () { 39 | it("correctly sets default values", function () { 40 | let c = new JobCache(); 41 | assert.equal(c.path, brigadeCachePath, "Dir is /brigade/cache"); 42 | assert.isFalse(c.enabled, "disabled by default"); 43 | assert.equal(c.size, "5Mi", "size is 5mi"); 44 | }); 45 | }); 46 | describe("#setPath", function () { 47 | it("correctly sets and gets path", function () { 48 | let c = new JobCache(); 49 | assert.equal(c.path, brigadeCachePath, "Dir is /brigade/cache"); 50 | c.path = "/foo" 51 | assert.equal(c.path, "/foo", "Assert dir is /foo"); 52 | }); 53 | }); 54 | }); 55 | describe("JobStorage", function () { 56 | describe("#constructor", function () { 57 | it("correctly sets default values", function () { 58 | let c = new JobStorage(); 59 | assert.equal( 60 | c.path, 61 | brigadeStoragePath, 62 | "Dir is " + brigadeStoragePath 63 | ); 64 | assert.isFalse(c.enabled, "disabled by default"); 65 | }); 66 | }); 67 | describe("#setPath", function () { 68 | it("correctly sets and gets path", function () { 69 | let s = new JobStorage(); 70 | assert.equal(s.path, brigadeStoragePath, "Dir is /brigade/cache"); 71 | s.path = "/foo" 72 | assert.equal(s.path, "/foo", "Assert dir is /foo"); 73 | }); 74 | }); 75 | }); 76 | describe("JobHost", function () { 77 | describe("#constructor", function () { 78 | it("correctly sets default values", function () { 79 | let h = new JobHost(); 80 | assert.equal(0, h.nodeSelector.size, "had empty nodeSelector map"); 81 | // Validate that the nodeSelector structure works like a map. 82 | h.nodeSelector.set("callMe", "Ishmael"); 83 | assert.equal("Ishmael", h.nodeSelector.get("callMe")); 84 | }); 85 | }); 86 | }); 87 | describe("Job", function () { 88 | // MockJob extends Job, but overrides the empty run() and logs() calls 89 | let j: mock.MockJob; 90 | describe("#constructor", function () { 91 | it("creates a named job", function () { 92 | j = new mock.MockJob("my-name"); 93 | assert.equal(j.name, "my-name"); 94 | }); 95 | it("starts with initialized JobHost", function () { 96 | j = new mock.MockJob("name"); 97 | assert.equal(j.host.nodeSelector.size, 0); 98 | }); 99 | context("when image is supplied", function () { 100 | it("sets image property", function () { 101 | j = new mock.MockJob("my-name", "alpine:3.4"); 102 | assert.equal(j.image, "alpine:3.4"); 103 | }); 104 | }); 105 | context("when imageForcePull is supplied", function () { 106 | it("sets imageForcePull property", function () { 107 | j = new mock.MockJob("my-name", "alpine:3.4", [], true); 108 | assert.isTrue(j.imageForcePull); 109 | }); 110 | }); 111 | context("when tasks are supplied", function () { 112 | it("sets task list", function () { 113 | j = new mock.MockJob("my", "img", ["a", "b", "c"]); 114 | assert.deepEqual(j.tasks, ["a", "b", "c"]); 115 | }); 116 | }); 117 | context("when serviceAccount is supplied", function () { 118 | it("sets serviceAccount property", function () { 119 | j = new mock.MockJob("my-name", "alpine:3.4", [], true); 120 | j.serviceAccount = "svcAccount"; 121 | assert.equal(j.serviceAccount, "svcAccount"); 122 | }); 123 | }); 124 | }); 125 | describe("#podName", function () { 126 | beforeEach(function () { 127 | j = new mock.MockJob("my-job"); 128 | }); 129 | context("before run", function () { 130 | it("is empty", function () { 131 | assert.isEmpty(j.podName); 132 | }); 133 | }); 134 | context("after run", function () { 135 | it("is accessible", function (done) { 136 | j.run().then(rez => { 137 | assert.equal(j.podName, "generated-fake-job-name"); 138 | done(); 139 | }); 140 | }); 141 | }); 142 | }); 143 | describe("#cache", function () { 144 | it("is disabled by default", function () { 145 | assert.isFalse(j.cache.enabled); 146 | }); 147 | }); 148 | describe("#storage", function () { 149 | it("is disabled by default", function () { 150 | assert.isFalse(j.storage.enabled); 151 | }); 152 | }); 153 | describe("#annotations", function () { 154 | beforeEach(function () { 155 | j = new mock.MockJob("my-job"); 156 | }); 157 | it("is an empty list that can be written", function () { 158 | assert.deepEqual(j.annotations, {}); 159 | j.annotations['some_kubetoiam/thing'] = 'my/path'; 160 | assert.deepEqual(j.annotations, { 'some_kubetoiam/thing': 'my/path' }); 161 | }); 162 | }); 163 | describe("#volumes and #volumeMounts", function () { 164 | beforeEach(function () { 165 | j = new mock.MockJob("my-job"); 166 | var mount = new V1VolumeMount(); 167 | mount.name = "mock-volume" 168 | mount.mountPath = "/mock/volume"; 169 | 170 | var volume = new V1Volume(); 171 | volume.name = "mock-volume"; 172 | volume.hostPath = { 173 | path: "/some/path", 174 | type: "Directory" 175 | }; 176 | 177 | j.volumes.push(volume); 178 | j.volumeMounts.push(mount); 179 | }); 180 | it("are correctly set", function () { 181 | assert.equal(j.volumes.length, 1); 182 | assert.equal(j.volumes[0].name, "mock-volume"); 183 | assert.equal(j.volumes[0].hostPath!.path, "/some/path"); 184 | assert.equal(j.volumes[0].hostPath!.type, "Directory"); 185 | 186 | assert.equal(j.volumeMounts.length, 1); 187 | assert.equal(j.volumeMounts[0].name, "mock-volume"); 188 | assert.equal(j.volumeMounts[0].mountPath, "/mock/volume"); 189 | }); 190 | }); 191 | }); 192 | }); 193 | -------------------------------------------------------------------------------- /test/mock.ts: -------------------------------------------------------------------------------- 1 | import { Project, BrigadeEvent } from "../src/events"; 2 | import { Result, Job } from "../src/job"; 3 | 4 | // This package contains mocks of objects found elsewhere in Brigade. 5 | 6 | export function mockProject(): Project { 7 | return { 8 | id: "brigade-4897c99315be5d2a2403ea33bdcb24f8116dc69613d5917d879d5f", 9 | name: "brigadecore/empty-testbed", 10 | repo: { 11 | name: "brigadecore/empty-testbed", 12 | cloneURL: "https://github.com/brigadecore/empty-testbed.git", 13 | token: "supersecret", 14 | initGitSubmodules: false 15 | }, 16 | kubernetes: { 17 | namespace: "default", 18 | vcsSidecar: "brigadecore/git-sidecar:latest", 19 | buildStorageSize: "50Mi" 20 | }, 21 | allowPrivilegedJobs: true, 22 | allowHostMounts: false 23 | } as Project; 24 | } 25 | 26 | export function mockEvent() { 27 | return { 28 | buildID: "1234567890abcdef", 29 | workerID: "test-1234567890abcdef-12345678", 30 | type: "push", 31 | provider: "github", 32 | revision: { 33 | commit: "c0ffee" 34 | }, 35 | payload: "{}" 36 | } as BrigadeEvent; 37 | } 38 | 39 | export class MockResult implements Result { 40 | protected msg: string = "uninitialized"; 41 | constructor(msg: string) { 42 | this.msg = msg; 43 | } 44 | public toString(): string { 45 | return this.msg; 46 | } 47 | } 48 | 49 | // MockJob implements the run() method on Job with a resolved Promise. 50 | // 51 | // If 'MockJob.fail = true', the job will return a failure instead of a success. 52 | // 53 | // The MockJob.run method will sleep for one nanosecond (that is, give up at least 54 | // one scheduler run). To set a longer delay, set MockJob.delay. 55 | export class MockJob extends Job { 56 | public fail: boolean = false; 57 | public delay: number = 1; // Just enough to cause the event loop to sleep it. 58 | public run(): Promise { 59 | let fail = this.fail; 60 | let delay = this.delay; 61 | this._podName = "generated-fake-job-name"; 62 | return new Promise((resolve, reject) => { 63 | if (fail) { 64 | setTimeout(() => { 65 | reject("Failed"); 66 | }, delay); 67 | return; 68 | } 69 | setTimeout(() => {resolve(new MockResult(this.name))}, delay); 70 | }); 71 | } 72 | public logs(): Promise { 73 | let fail = this.fail; 74 | let delay = this.delay; 75 | this._podName = "generated-fake-job-name-2"; 76 | return new Promise((resolve, reject) => { 77 | if (fail) { 78 | setTimeout(() => { 79 | resolve(`These are the logs showing failure.`); 80 | }, delay); 81 | return; 82 | } 83 | setTimeout(() => { 84 | resolve(`These are the logs showing successful completion.`); 85 | }, delay); 86 | }); 87 | } 88 | } 89 | 90 | export class MockBuildStorage { 91 | public create( 92 | e: BrigadeEvent, 93 | project: Project, 94 | size?: string 95 | ): Promise { 96 | return Promise.resolve(e.workerID || "unknown"); 97 | } 98 | public destroy(): Promise { 99 | return Promise.resolve(true); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "declaration": true, 10 | "sourceMap": true, 11 | "rootDir": "src", 12 | /* Strict Type-Checking Option */ 13 | "strict": true, /* enable all strict type-checking options */ 14 | /* Additional Checks */ 15 | "noUnusedLocals": true, /* Report errors on unused locals. */ 16 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 17 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 18 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 19 | "typeRoots": [ 20 | "node_modules/@types" 21 | ] 22 | }, 23 | "include": [ 24 | "./src/**/*" 25 | ], 26 | "exclude": [ 27 | "node_modules/**/*" 28 | //, "test" 29 | ] 30 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-string-throw": true, 4 | "no-unused-expression": true, 5 | "no-duplicate-variable": true, 6 | "curly": true, 7 | "class-name": true, 8 | "semicolon": [ 9 | true, 10 | "always" 11 | ], 12 | "triple-equals": true 13 | }, 14 | "defaultSeverity": "warning" 15 | } -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@kubernetes/client-node@^0.10.1": 6 | version "0.10.2" 7 | resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.10.2.tgz#9ca9d605148774c7fd77346d73743e5869f9205b" 8 | integrity sha512-JvsmxbTwiMqsh9LyuXMzT5HjoENFbB3a/JroJsobuAzkxN162UqAOvg++/AA+ccIMWRR2Qln4FyaOJ0a4eKyXg== 9 | dependencies: 10 | "@types/js-yaml" "^3.12.1" 11 | "@types/node" "^10.12.0" 12 | "@types/request" "^2.47.1" 13 | "@types/underscore" "^1.8.9" 14 | "@types/ws" "^6.0.1" 15 | isomorphic-ws "^4.0.1" 16 | js-yaml "^3.13.1" 17 | json-stream "^1.0.0" 18 | jsonpath-plus "^0.19.0" 19 | request "^2.88.0" 20 | shelljs "^0.8.2" 21 | tslib "^1.9.3" 22 | underscore "^1.9.1" 23 | ws "^6.1.0" 24 | 25 | "@types/caseless@*": 26 | version "0.12.2" 27 | resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" 28 | integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== 29 | 30 | "@types/chai@^4.0.1": 31 | version "4.1.4" 32 | resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.4.tgz#5ca073b330d90b4066d6ce18f60d57f2084ce8ca" 33 | 34 | "@types/events@*": 35 | version "3.0.0" 36 | resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" 37 | integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== 38 | 39 | "@types/js-yaml@^3.12.1": 40 | version "3.12.1" 41 | resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.1.tgz#5c6f4a1eabca84792fbd916f0cb40847f123c656" 42 | integrity sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA== 43 | 44 | "@types/mocha@^2.2.41": 45 | version "2.2.48" 46 | resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab" 47 | 48 | "@types/node@*": 49 | version "12.6.8" 50 | resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" 51 | integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== 52 | 53 | "@types/node@^10.12.0": 54 | version "10.14.13" 55 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" 56 | integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ== 57 | 58 | "@types/node@^12.20.37": 59 | version "12.20.37" 60 | resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed" 61 | integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA== 62 | 63 | "@types/request@^2.47.1": 64 | version "2.48.2" 65 | resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.2.tgz#936374cbe1179d7ed529fc02543deb4597450fed" 66 | integrity sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA== 67 | dependencies: 68 | "@types/caseless" "*" 69 | "@types/node" "*" 70 | "@types/tough-cookie" "*" 71 | form-data "^2.5.0" 72 | 73 | "@types/tough-cookie@*": 74 | version "2.3.5" 75 | resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" 76 | integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg== 77 | 78 | "@types/underscore@^1.8.9": 79 | version "1.9.2" 80 | resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.9.2.tgz#2c4f7743287218f5c2d9a83db3806672aa48530d" 81 | integrity sha512-KgOKTAD+9X+qvZnB5S1+onqKc4E+PZ+T6CM/NA5ohRPLHJXb+yCJMVf8pWOnvuBuKFNUAJW8N97IA6lba6mZGg== 82 | 83 | "@types/ws@^6.0.1": 84 | version "6.0.1" 85 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" 86 | integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== 87 | dependencies: 88 | "@types/events" "*" 89 | "@types/node" "*" 90 | 91 | "@ungap/promise-all-settled@1.1.2": 92 | version "1.1.2" 93 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 94 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 95 | 96 | ajv@^6.5.5: 97 | version "6.12.6" 98 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 99 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 100 | dependencies: 101 | fast-deep-equal "^3.1.1" 102 | fast-json-stable-stringify "^2.0.0" 103 | json-schema-traverse "^0.4.1" 104 | uri-js "^4.2.2" 105 | 106 | ansi-colors@4.1.1: 107 | version "4.1.1" 108 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 109 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 110 | 111 | ansi-regex@^2.0.0: 112 | version "2.1.1" 113 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 114 | 115 | ansi-regex@^5.0.1: 116 | version "5.0.1" 117 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 118 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 119 | 120 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 121 | version "4.3.0" 122 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 123 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 124 | dependencies: 125 | color-convert "^2.0.1" 126 | 127 | anymatch@~3.1.2: 128 | version "3.1.2" 129 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 130 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 131 | dependencies: 132 | normalize-path "^3.0.0" 133 | picomatch "^2.0.4" 134 | 135 | argparse@^1.0.7: 136 | version "1.0.10" 137 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 138 | dependencies: 139 | sprintf-js "~1.0.2" 140 | 141 | argparse@^2.0.1: 142 | version "2.0.1" 143 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 144 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 145 | 146 | arrify@^1.0.0: 147 | version "1.0.1" 148 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 149 | 150 | asn1@~0.2.3: 151 | version "0.2.4" 152 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 153 | dependencies: 154 | safer-buffer "~2.1.0" 155 | 156 | assert-plus@1.0.0, assert-plus@^1.0.0: 157 | version "1.0.0" 158 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 159 | 160 | assertion-error@^1.0.1: 161 | version "1.1.0" 162 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 163 | 164 | async-limiter@~1.0.0: 165 | version "1.0.1" 166 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" 167 | integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== 168 | 169 | asynckit@^0.4.0: 170 | version "0.4.0" 171 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 172 | 173 | aws-sign2@~0.7.0: 174 | version "0.7.0" 175 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 176 | 177 | aws4@^1.8.0: 178 | version "1.8.0" 179 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" 180 | 181 | balanced-match@^1.0.0: 182 | version "1.0.2" 183 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 184 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 185 | 186 | bcrypt-pbkdf@^1.0.0: 187 | version "1.0.2" 188 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" 189 | dependencies: 190 | tweetnacl "^0.14.3" 191 | 192 | binary-extensions@^2.0.0: 193 | version "2.2.0" 194 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 195 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 196 | 197 | boolbase@^1.0.0: 198 | version "1.0.0" 199 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 200 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= 201 | 202 | brace-expansion@^1.1.7: 203 | version "1.1.11" 204 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 205 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 206 | dependencies: 207 | balanced-match "^1.0.0" 208 | concat-map "0.0.1" 209 | 210 | braces@~3.0.2: 211 | version "3.0.2" 212 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 213 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 214 | dependencies: 215 | fill-range "^7.0.1" 216 | 217 | browser-stdout@1.3.1: 218 | version "1.3.1" 219 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 220 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 221 | 222 | buffer-from@^1.0.0, buffer-from@^1.1.0: 223 | version "1.1.1" 224 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 225 | 226 | camelcase@^6.0.0: 227 | version "6.2.1" 228 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" 229 | integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== 230 | 231 | caseless@~0.12.0: 232 | version "0.12.0" 233 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 234 | 235 | chai@^4.1.0: 236 | version "4.1.2" 237 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" 238 | dependencies: 239 | assertion-error "^1.0.1" 240 | check-error "^1.0.1" 241 | deep-eql "^3.0.0" 242 | get-func-name "^2.0.0" 243 | pathval "^1.0.0" 244 | type-detect "^4.0.0" 245 | 246 | chalk@^4.1.0: 247 | version "4.1.2" 248 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 249 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 250 | dependencies: 251 | ansi-styles "^4.1.0" 252 | supports-color "^7.1.0" 253 | 254 | check-error@^1.0.1: 255 | version "1.0.2" 256 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 257 | 258 | child-process-promise@^2.2.1: 259 | version "2.2.1" 260 | resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" 261 | dependencies: 262 | cross-spawn "^4.0.2" 263 | node-version "^1.0.0" 264 | promise-polyfill "^6.0.1" 265 | 266 | chokidar@3.5.2: 267 | version "3.5.2" 268 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" 269 | integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== 270 | dependencies: 271 | anymatch "~3.1.2" 272 | braces "~3.0.2" 273 | glob-parent "~5.1.2" 274 | is-binary-path "~2.1.0" 275 | is-glob "~4.0.1" 276 | normalize-path "~3.0.0" 277 | readdirp "~3.6.0" 278 | optionalDependencies: 279 | fsevents "~2.3.2" 280 | 281 | cliui@^7.0.2: 282 | version "7.0.4" 283 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 284 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 285 | dependencies: 286 | string-width "^4.2.0" 287 | strip-ansi "^6.0.0" 288 | wrap-ansi "^7.0.0" 289 | 290 | color-convert@^2.0.1: 291 | version "2.0.1" 292 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 293 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 294 | dependencies: 295 | color-name "~1.1.4" 296 | 297 | color-name@~1.1.4: 298 | version "1.1.4" 299 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 300 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 301 | 302 | combined-stream@^1.0.6, combined-stream@~1.0.6: 303 | version "1.0.7" 304 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" 305 | dependencies: 306 | delayed-stream "~1.0.0" 307 | 308 | concat-map@0.0.1: 309 | version "0.0.1" 310 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 311 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 312 | 313 | core-util-is@1.0.2: 314 | version "1.0.2" 315 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 316 | 317 | cross-spawn@^4.0.2: 318 | version "4.0.2" 319 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" 320 | dependencies: 321 | lru-cache "^4.0.1" 322 | which "^1.2.9" 323 | 324 | css-select@^4.1.3: 325 | version "4.1.3" 326 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" 327 | integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== 328 | dependencies: 329 | boolbase "^1.0.0" 330 | css-what "^5.0.0" 331 | domhandler "^4.2.0" 332 | domutils "^2.6.0" 333 | nth-check "^2.0.0" 334 | 335 | css-what@^5.0.0: 336 | version "5.0.1" 337 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" 338 | integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg== 339 | 340 | dashdash@^1.12.0: 341 | version "1.14.1" 342 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 343 | dependencies: 344 | assert-plus "^1.0.0" 345 | 346 | debug@4.3.2: 347 | version "4.3.2" 348 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" 349 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 350 | dependencies: 351 | ms "2.1.2" 352 | 353 | decamelize@^4.0.0: 354 | version "4.0.0" 355 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 356 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 357 | 358 | deep-eql@^3.0.0: 359 | version "3.0.1" 360 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 361 | dependencies: 362 | type-detect "^4.0.0" 363 | 364 | delayed-stream@~1.0.0: 365 | version "1.0.0" 366 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 367 | 368 | diff@5.0.0: 369 | version "5.0.0" 370 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 371 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 372 | 373 | diff@^3.1.0: 374 | version "3.5.0" 375 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 376 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 377 | 378 | dom-converter@^0.2.0: 379 | version "0.2.0" 380 | resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" 381 | integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== 382 | dependencies: 383 | utila "~0.4" 384 | 385 | dom-serializer@^1.0.1: 386 | version "1.3.2" 387 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" 388 | integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== 389 | dependencies: 390 | domelementtype "^2.0.1" 391 | domhandler "^4.2.0" 392 | entities "^2.0.0" 393 | 394 | domelementtype@^2.0.1, domelementtype@^2.2.0: 395 | version "2.2.0" 396 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" 397 | integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== 398 | 399 | domhandler@^4.0.0, domhandler@^4.2.0: 400 | version "4.2.0" 401 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" 402 | integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== 403 | dependencies: 404 | domelementtype "^2.2.0" 405 | 406 | domutils@^2.5.2, domutils@^2.6.0: 407 | version "2.7.0" 408 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442" 409 | integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg== 410 | dependencies: 411 | dom-serializer "^1.0.1" 412 | domelementtype "^2.2.0" 413 | domhandler "^4.2.0" 414 | 415 | ecc-jsbn@~0.1.1: 416 | version "0.1.2" 417 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" 418 | dependencies: 419 | jsbn "~0.1.0" 420 | safer-buffer "^2.1.0" 421 | 422 | emoji-regex@^8.0.0: 423 | version "8.0.0" 424 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 425 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 426 | 427 | entities@^2.0.0: 428 | version "2.2.0" 429 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" 430 | integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== 431 | 432 | escalade@^3.1.1: 433 | version "3.1.1" 434 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 435 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 436 | 437 | escape-string-regexp@4.0.0: 438 | version "4.0.0" 439 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 440 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 441 | 442 | esprima@^4.0.0: 443 | version "4.0.1" 444 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 445 | 446 | extend@~3.0.2: 447 | version "3.0.2" 448 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 449 | 450 | extsprintf@1.3.0: 451 | version "1.3.0" 452 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 453 | 454 | extsprintf@^1.2.0: 455 | version "1.4.0" 456 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 457 | 458 | fast-deep-equal@^3.1.1: 459 | version "3.1.3" 460 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 461 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 462 | 463 | fast-json-stable-stringify@^2.0.0: 464 | version "2.1.0" 465 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 466 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 467 | 468 | fill-range@^7.0.1: 469 | version "7.0.1" 470 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 471 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 472 | dependencies: 473 | to-regex-range "^5.0.1" 474 | 475 | find-up@5.0.0: 476 | version "5.0.0" 477 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 478 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 479 | dependencies: 480 | locate-path "^6.0.0" 481 | path-exists "^4.0.0" 482 | 483 | flat@^5.0.2: 484 | version "5.0.2" 485 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 486 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 487 | 488 | forever-agent@~0.6.1: 489 | version "0.6.1" 490 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 491 | 492 | form-data@^2.5.0: 493 | version "2.5.0" 494 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" 495 | integrity sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA== 496 | dependencies: 497 | asynckit "^0.4.0" 498 | combined-stream "^1.0.6" 499 | mime-types "^2.1.12" 500 | 501 | form-data@~2.3.2: 502 | version "2.3.3" 503 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 504 | dependencies: 505 | asynckit "^0.4.0" 506 | combined-stream "^1.0.6" 507 | mime-types "^2.1.12" 508 | 509 | fs-extra@^8.1.0: 510 | version "8.1.0" 511 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" 512 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== 513 | dependencies: 514 | graceful-fs "^4.2.0" 515 | jsonfile "^4.0.0" 516 | universalify "^0.1.0" 517 | 518 | fs.realpath@^1.0.0: 519 | version "1.0.0" 520 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 521 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 522 | 523 | fsevents@~2.3.2: 524 | version "2.3.2" 525 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 526 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 527 | 528 | function-bind@^1.1.1: 529 | version "1.1.1" 530 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 531 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 532 | 533 | get-caller-file@^2.0.5: 534 | version "2.0.5" 535 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 536 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 537 | 538 | get-func-name@^2.0.0: 539 | version "2.0.0" 540 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 541 | 542 | getpass@^0.1.1: 543 | version "0.1.7" 544 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 545 | dependencies: 546 | assert-plus "^1.0.0" 547 | 548 | glob-parent@~5.1.2: 549 | version "5.1.2" 550 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 551 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 552 | dependencies: 553 | is-glob "^4.0.1" 554 | 555 | glob@7.1.7: 556 | version "7.1.7" 557 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" 558 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== 559 | dependencies: 560 | fs.realpath "^1.0.0" 561 | inflight "^1.0.4" 562 | inherits "2" 563 | minimatch "^3.0.4" 564 | once "^1.3.0" 565 | path-is-absolute "^1.0.0" 566 | 567 | glob@^7.0.0, glob@^7.0.5: 568 | version "7.2.0" 569 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 570 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 571 | dependencies: 572 | fs.realpath "^1.0.0" 573 | inflight "^1.0.4" 574 | inherits "2" 575 | minimatch "^3.0.4" 576 | once "^1.3.0" 577 | path-is-absolute "^1.0.0" 578 | 579 | graceful-fs@^4.1.6: 580 | version "4.1.11" 581 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 582 | 583 | graceful-fs@^4.2.0: 584 | version "4.2.0" 585 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" 586 | integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== 587 | 588 | growl@1.10.5: 589 | version "1.10.5" 590 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 591 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 592 | 593 | handlebars@^4.3.0, handlebars@^4.7.6: 594 | version "4.7.7" 595 | resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" 596 | integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== 597 | dependencies: 598 | minimist "^1.2.5" 599 | neo-async "^2.6.0" 600 | source-map "^0.6.1" 601 | wordwrap "^1.0.0" 602 | optionalDependencies: 603 | uglify-js "^3.1.4" 604 | 605 | har-schema@^2.0.0: 606 | version "2.0.0" 607 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 608 | 609 | har-validator@~5.1.0: 610 | version "5.1.3" 611 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" 612 | dependencies: 613 | ajv "^6.5.5" 614 | har-schema "^2.0.0" 615 | 616 | has-flag@^4.0.0: 617 | version "4.0.0" 618 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 619 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 620 | 621 | has@^1.0.3: 622 | version "1.0.3" 623 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 624 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 625 | dependencies: 626 | function-bind "^1.1.1" 627 | 628 | he@1.2.0: 629 | version "1.2.0" 630 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 631 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 632 | 633 | highlight.js@^10.0.0: 634 | version "10.7.3" 635 | resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" 636 | integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== 637 | 638 | htmlparser2@^6.1.0: 639 | version "6.1.0" 640 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" 641 | integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== 642 | dependencies: 643 | domelementtype "^2.0.1" 644 | domhandler "^4.0.0" 645 | domutils "^2.5.2" 646 | entities "^2.0.0" 647 | 648 | http-signature@~1.2.0: 649 | version "1.2.0" 650 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 651 | dependencies: 652 | assert-plus "^1.0.0" 653 | jsprim "^1.2.2" 654 | sshpk "^1.7.0" 655 | 656 | inflight@^1.0.4: 657 | version "1.0.6" 658 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 659 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 660 | dependencies: 661 | once "^1.3.0" 662 | wrappy "1" 663 | 664 | inherits@2: 665 | version "2.0.4" 666 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 667 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 668 | 669 | interpret@^1.0.0: 670 | version "1.4.0" 671 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" 672 | integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== 673 | 674 | is-binary-path@~2.1.0: 675 | version "2.1.0" 676 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 677 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 678 | dependencies: 679 | binary-extensions "^2.0.0" 680 | 681 | is-core-module@^2.8.0: 682 | version "2.8.1" 683 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" 684 | integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== 685 | dependencies: 686 | has "^1.0.3" 687 | 688 | is-extglob@^2.1.1: 689 | version "2.1.1" 690 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 691 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 692 | 693 | is-fullwidth-code-point@^3.0.0: 694 | version "3.0.0" 695 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 696 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 697 | 698 | is-glob@^4.0.1, is-glob@~4.0.1: 699 | version "4.0.3" 700 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 701 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 702 | dependencies: 703 | is-extglob "^2.1.1" 704 | 705 | is-number@^7.0.0: 706 | version "7.0.0" 707 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 708 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 709 | 710 | is-plain-obj@^2.1.0: 711 | version "2.1.0" 712 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 713 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 714 | 715 | is-typedarray@~1.0.0: 716 | version "1.0.0" 717 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 718 | 719 | is-unicode-supported@^0.1.0: 720 | version "0.1.0" 721 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 722 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 723 | 724 | isexe@^2.0.0: 725 | version "2.0.0" 726 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 727 | 728 | isomorphic-ws@^4.0.1: 729 | version "4.0.1" 730 | resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" 731 | 732 | isstream@~0.1.2: 733 | version "0.1.2" 734 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 735 | 736 | js-yaml@4.1.0: 737 | version "4.1.0" 738 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 739 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 740 | dependencies: 741 | argparse "^2.0.1" 742 | 743 | js-yaml@^3.13.1: 744 | version "3.13.1" 745 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" 746 | integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== 747 | dependencies: 748 | argparse "^1.0.7" 749 | esprima "^4.0.0" 750 | 751 | jsbn@~0.1.0: 752 | version "0.1.1" 753 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 754 | 755 | json-schema-traverse@^0.4.1: 756 | version "0.4.1" 757 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 758 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 759 | 760 | json-schema@0.2.3: 761 | version "0.2.3" 762 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 763 | 764 | json-stream@^1.0.0: 765 | version "1.0.0" 766 | resolved "https://registry.yarnpkg.com/json-stream/-/json-stream-1.0.0.tgz#1a3854e28d2bbeeab31cc7ddf683d2ddc5652708" 767 | integrity sha1-GjhU4o0rvuqzHMfd9oPS3cVlJwg= 768 | 769 | json-stringify-safe@~5.0.1: 770 | version "5.0.1" 771 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 772 | 773 | jsonfile@^4.0.0: 774 | version "4.0.0" 775 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 776 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 777 | optionalDependencies: 778 | graceful-fs "^4.1.6" 779 | 780 | jsonpath-plus@^0.19.0: 781 | version "0.19.0" 782 | resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz#b901e57607055933dc9a8bef0cc25160ee9dd64c" 783 | integrity sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg== 784 | 785 | jsprim@^1.2.2: 786 | version "1.4.1" 787 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 788 | dependencies: 789 | assert-plus "1.0.0" 790 | extsprintf "1.3.0" 791 | json-schema "0.2.3" 792 | verror "1.10.0" 793 | 794 | locate-path@^6.0.0: 795 | version "6.0.0" 796 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 797 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 798 | dependencies: 799 | p-locate "^5.0.0" 800 | 801 | lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: 802 | version "4.17.21" 803 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 804 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 805 | 806 | log-symbols@4.1.0: 807 | version "4.1.0" 808 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 809 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 810 | dependencies: 811 | chalk "^4.1.0" 812 | is-unicode-supported "^0.1.0" 813 | 814 | lru-cache@^4.0.1: 815 | version "4.1.3" 816 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" 817 | dependencies: 818 | pseudomap "^1.0.2" 819 | yallist "^2.1.2" 820 | 821 | lunr@^2.3.8: 822 | version "2.3.9" 823 | resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" 824 | integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== 825 | 826 | make-error@^1.1.1: 827 | version "1.3.4" 828 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535" 829 | 830 | marked@1.0.0: 831 | version "1.0.0" 832 | resolved "https://registry.yarnpkg.com/marked/-/marked-1.0.0.tgz#d35784245a04871e5988a491e28867362e941693" 833 | integrity sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng== 834 | 835 | mime-db@~1.35.0: 836 | version "1.35.0" 837 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" 838 | 839 | mime-db@~1.37.0: 840 | version "1.37.0" 841 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" 842 | 843 | mime-types@^2.1.12: 844 | version "2.1.19" 845 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0" 846 | dependencies: 847 | mime-db "~1.35.0" 848 | 849 | mime-types@~2.1.19: 850 | version "2.1.21" 851 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" 852 | dependencies: 853 | mime-db "~1.37.0" 854 | 855 | minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4: 856 | version "3.0.4" 857 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 858 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 859 | dependencies: 860 | brace-expansion "^1.1.7" 861 | 862 | minimist@0.0.8, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: 863 | version "1.2.6" 864 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" 865 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== 866 | 867 | mkdirp@^0.5.1: 868 | version "0.5.1" 869 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 870 | dependencies: 871 | minimist "0.0.8" 872 | 873 | mocha@^9.1.3: 874 | version "9.1.3" 875 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.3.tgz#8a623be6b323810493d8c8f6f7667440fa469fdb" 876 | integrity sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw== 877 | dependencies: 878 | "@ungap/promise-all-settled" "1.1.2" 879 | ansi-colors "4.1.1" 880 | browser-stdout "1.3.1" 881 | chokidar "3.5.2" 882 | debug "4.3.2" 883 | diff "5.0.0" 884 | escape-string-regexp "4.0.0" 885 | find-up "5.0.0" 886 | glob "7.1.7" 887 | growl "1.10.5" 888 | he "1.2.0" 889 | js-yaml "4.1.0" 890 | log-symbols "4.1.0" 891 | minimatch "3.0.4" 892 | ms "2.1.3" 893 | nanoid "3.1.25" 894 | serialize-javascript "6.0.0" 895 | strip-json-comments "3.1.1" 896 | supports-color "8.1.1" 897 | which "2.0.2" 898 | workerpool "6.1.5" 899 | yargs "16.2.0" 900 | yargs-parser "20.2.4" 901 | yargs-unparser "2.0.0" 902 | 903 | ms@2.1.2: 904 | version "2.1.2" 905 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 906 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 907 | 908 | ms@2.1.3: 909 | version "2.1.3" 910 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 911 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 912 | 913 | nanoid@3.1.25: 914 | version "3.1.25" 915 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" 916 | integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== 917 | 918 | neo-async@^2.6.0: 919 | version "2.6.2" 920 | resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" 921 | integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== 922 | 923 | node-version@^1.0.0: 924 | version "1.2.0" 925 | resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" 926 | 927 | normalize-path@^3.0.0, normalize-path@~3.0.0: 928 | version "3.0.0" 929 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 930 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 931 | 932 | nth-check@^2.0.0: 933 | version "2.0.1" 934 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" 935 | integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== 936 | dependencies: 937 | boolbase "^1.0.0" 938 | 939 | oauth-sign@~0.9.0: 940 | version "0.9.0" 941 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 942 | 943 | once@^1.3.0: 944 | version "1.4.0" 945 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 946 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 947 | dependencies: 948 | wrappy "1" 949 | 950 | p-limit@^3.0.2: 951 | version "3.1.0" 952 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 953 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 954 | dependencies: 955 | yocto-queue "^0.1.0" 956 | 957 | p-locate@^5.0.0: 958 | version "5.0.0" 959 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 960 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 961 | dependencies: 962 | p-limit "^3.0.2" 963 | 964 | path-exists@^4.0.0: 965 | version "4.0.0" 966 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 967 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 968 | 969 | path-is-absolute@^1.0.0: 970 | version "1.0.1" 971 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 972 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 973 | 974 | path-parse@^1.0.7: 975 | version "1.0.7" 976 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 977 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 978 | 979 | pathval@^1.0.0: 980 | version "1.1.1" 981 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 982 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 983 | 984 | performance-now@^2.1.0: 985 | version "2.1.0" 986 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 987 | 988 | picomatch@^2.0.4, picomatch@^2.2.1: 989 | version "2.3.0" 990 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" 991 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== 992 | 993 | prettier@^1.9.1: 994 | version "1.14.0" 995 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.0.tgz#847c235522035fd988100f1f43cf20a7d24f9372" 996 | 997 | pretty-error@^3.0.4: 998 | version "3.0.4" 999 | resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-3.0.4.tgz#94b1d54f76c1ed95b9c604b9de2194838e5b574e" 1000 | integrity sha512-ytLFLfv1So4AO1UkoBF6GXQgJRaKbiSiGFICaOPNwQ3CMvBvXpLRubeQWyPGnsbV/t9ml9qto6IeCsho0aEvwQ== 1001 | dependencies: 1002 | lodash "^4.17.20" 1003 | renderkid "^2.0.6" 1004 | 1005 | progress@^2.0.3: 1006 | version "2.0.3" 1007 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 1008 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 1009 | 1010 | promise-polyfill@^6.0.1: 1011 | version "6.1.0" 1012 | resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" 1013 | 1014 | pseudomap@^1.0.2: 1015 | version "1.0.2" 1016 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 1017 | 1018 | psl@^1.1.24: 1019 | version "1.1.31" 1020 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" 1021 | 1022 | punycode@^1.4.1: 1023 | version "1.4.1" 1024 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 1025 | 1026 | punycode@^2.1.0: 1027 | version "2.1.1" 1028 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 1029 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1030 | 1031 | qs@~6.5.2: 1032 | version "6.5.2" 1033 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 1034 | 1035 | randombytes@^2.1.0: 1036 | version "2.1.0" 1037 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 1038 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 1039 | dependencies: 1040 | safe-buffer "^5.1.0" 1041 | 1042 | readdirp@~3.6.0: 1043 | version "3.6.0" 1044 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1045 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1046 | dependencies: 1047 | picomatch "^2.2.1" 1048 | 1049 | rechoir@^0.6.2: 1050 | version "0.6.2" 1051 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 1052 | integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= 1053 | dependencies: 1054 | resolve "^1.1.6" 1055 | 1056 | renderkid@^2.0.6: 1057 | version "2.0.7" 1058 | resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" 1059 | integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== 1060 | dependencies: 1061 | css-select "^4.1.3" 1062 | dom-converter "^0.2.0" 1063 | htmlparser2 "^6.1.0" 1064 | lodash "^4.17.21" 1065 | strip-ansi "^3.0.1" 1066 | 1067 | request@^2.88.0: 1068 | version "2.88.0" 1069 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" 1070 | dependencies: 1071 | aws-sign2 "~0.7.0" 1072 | aws4 "^1.8.0" 1073 | caseless "~0.12.0" 1074 | combined-stream "~1.0.6" 1075 | extend "~3.0.2" 1076 | forever-agent "~0.6.1" 1077 | form-data "~2.3.2" 1078 | har-validator "~5.1.0" 1079 | http-signature "~1.2.0" 1080 | is-typedarray "~1.0.0" 1081 | isstream "~0.1.2" 1082 | json-stringify-safe "~5.0.1" 1083 | mime-types "~2.1.19" 1084 | oauth-sign "~0.9.0" 1085 | performance-now "^2.1.0" 1086 | qs "~6.5.2" 1087 | safe-buffer "^5.1.2" 1088 | tough-cookie "~2.4.3" 1089 | tunnel-agent "^0.6.0" 1090 | uuid "^3.3.2" 1091 | 1092 | require-directory@^2.1.1: 1093 | version "2.1.1" 1094 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1095 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 1096 | 1097 | resolve@^1.1.6: 1098 | version "1.21.0" 1099 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" 1100 | integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA== 1101 | dependencies: 1102 | is-core-module "^2.8.0" 1103 | path-parse "^1.0.7" 1104 | supports-preserve-symlinks-flag "^1.0.0" 1105 | 1106 | rimraf@^2.6.2: 1107 | version "2.6.2" 1108 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 1109 | dependencies: 1110 | glob "^7.0.5" 1111 | 1112 | safe-buffer@^5.0.1, safe-buffer@^5.1.2: 1113 | version "5.1.2" 1114 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1115 | 1116 | safe-buffer@^5.1.0: 1117 | version "5.2.1" 1118 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1119 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1120 | 1121 | safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 1122 | version "2.1.2" 1123 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1124 | 1125 | serialize-javascript@6.0.0: 1126 | version "6.0.0" 1127 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 1128 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 1129 | dependencies: 1130 | randombytes "^2.1.0" 1131 | 1132 | shelljs@^0.8.2, shelljs@^0.8.4: 1133 | version "0.8.5" 1134 | resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" 1135 | integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== 1136 | dependencies: 1137 | glob "^7.0.0" 1138 | interpret "^1.0.0" 1139 | rechoir "^0.6.2" 1140 | 1141 | source-map-support@^0.5.6: 1142 | version "0.5.6" 1143 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" 1144 | dependencies: 1145 | buffer-from "^1.0.0" 1146 | source-map "^0.6.0" 1147 | 1148 | source-map@^0.6.0, source-map@^0.6.1: 1149 | version "0.6.1" 1150 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1151 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1152 | 1153 | sprintf-js@~1.0.2: 1154 | version "1.0.3" 1155 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1156 | 1157 | sshpk@^1.7.0: 1158 | version "1.14.2" 1159 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98" 1160 | dependencies: 1161 | asn1 "~0.2.3" 1162 | assert-plus "^1.0.0" 1163 | dashdash "^1.12.0" 1164 | getpass "^0.1.1" 1165 | safer-buffer "^2.0.2" 1166 | optionalDependencies: 1167 | bcrypt-pbkdf "^1.0.0" 1168 | ecc-jsbn "~0.1.1" 1169 | jsbn "~0.1.0" 1170 | tweetnacl "~0.14.0" 1171 | 1172 | string-width@^4.1.0, string-width@^4.2.0: 1173 | version "4.2.3" 1174 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1175 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1176 | dependencies: 1177 | emoji-regex "^8.0.0" 1178 | is-fullwidth-code-point "^3.0.0" 1179 | strip-ansi "^6.0.1" 1180 | 1181 | strip-ansi@^3.0.1: 1182 | version "3.0.1" 1183 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1184 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 1185 | dependencies: 1186 | ansi-regex "^2.0.0" 1187 | 1188 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1189 | version "6.0.1" 1190 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1191 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1192 | dependencies: 1193 | ansi-regex "^5.0.1" 1194 | 1195 | strip-json-comments@3.1.1: 1196 | version "3.1.1" 1197 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1198 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1199 | 1200 | supports-color@8.1.1: 1201 | version "8.1.1" 1202 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1203 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1204 | dependencies: 1205 | has-flag "^4.0.0" 1206 | 1207 | supports-color@^7.1.0: 1208 | version "7.2.0" 1209 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1210 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1211 | dependencies: 1212 | has-flag "^4.0.0" 1213 | 1214 | supports-preserve-symlinks-flag@^1.0.0: 1215 | version "1.0.0" 1216 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1217 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1218 | 1219 | to-regex-range@^5.0.1: 1220 | version "5.0.1" 1221 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1222 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1223 | dependencies: 1224 | is-number "^7.0.0" 1225 | 1226 | tough-cookie@~2.4.3: 1227 | version "2.4.3" 1228 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" 1229 | dependencies: 1230 | psl "^1.1.24" 1231 | punycode "^1.4.1" 1232 | 1233 | ts-node@^7.0.0: 1234 | version "7.0.0" 1235 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.0.tgz#a94a13c75e5e1aa6b82814b84c68deb339ba7bff" 1236 | dependencies: 1237 | arrify "^1.0.0" 1238 | buffer-from "^1.1.0" 1239 | diff "^3.1.0" 1240 | make-error "^1.1.1" 1241 | minimist "^1.2.0" 1242 | mkdirp "^0.5.1" 1243 | source-map-support "^0.5.6" 1244 | yn "^2.0.0" 1245 | 1246 | tslib@^1.9.3: 1247 | version "1.9.3" 1248 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" 1249 | 1250 | tunnel-agent@^0.6.0: 1251 | version "0.6.0" 1252 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 1253 | dependencies: 1254 | safe-buffer "^5.0.1" 1255 | 1256 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 1257 | version "0.14.5" 1258 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 1259 | 1260 | type-detect@^4.0.0: 1261 | version "4.0.8" 1262 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 1263 | 1264 | typedoc-default-themes@^0.10.2: 1265 | version "0.10.2" 1266 | resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz#743380a80afe62c5ef92ca1bd4abe2ac596be4d2" 1267 | integrity sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg== 1268 | dependencies: 1269 | lunr "^2.3.8" 1270 | 1271 | typedoc@^0.17.8: 1272 | version "0.17.8" 1273 | resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.17.8.tgz#96b67e9454aa7853bfc4dc9a55c8a07adfd5478e" 1274 | integrity sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w== 1275 | dependencies: 1276 | fs-extra "^8.1.0" 1277 | handlebars "^4.7.6" 1278 | highlight.js "^10.0.0" 1279 | lodash "^4.17.15" 1280 | lunr "^2.3.8" 1281 | marked "1.0.0" 1282 | minimatch "^3.0.0" 1283 | progress "^2.0.3" 1284 | shelljs "^0.8.4" 1285 | typedoc-default-themes "^0.10.2" 1286 | 1287 | typescript@^3.8.3: 1288 | version "3.9.10" 1289 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" 1290 | integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== 1291 | 1292 | uglify-js@^3.1.4: 1293 | version "3.13.5" 1294 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.5.tgz#5d71d6dbba64cf441f32929b1efce7365bb4f113" 1295 | integrity sha512-xtB8yEqIkn7zmOyS2zUNBsYCBRhDkvlNxMMY2smuJ/qA8NCHeQvKCF3i9Z4k8FJH4+PJvZRtMrPynfZ75+CSZw== 1296 | 1297 | ulid@^0.2.0: 1298 | version "0.2.0" 1299 | resolved "https://registry.yarnpkg.com/ulid/-/ulid-0.2.0.tgz#f43cf55c7807aec30d6695cb3bfe93b2e30b61a4" 1300 | 1301 | underscore@^1.9.1: 1302 | version "1.13.1" 1303 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" 1304 | integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g== 1305 | 1306 | universalify@^0.1.0: 1307 | version "0.1.2" 1308 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" 1309 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 1310 | 1311 | uri-js@^4.2.2: 1312 | version "4.4.1" 1313 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1314 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1315 | dependencies: 1316 | punycode "^2.1.0" 1317 | 1318 | utila@~0.4: 1319 | version "0.4.0" 1320 | resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" 1321 | 1322 | uuid@^3.3.2: 1323 | version "3.3.2" 1324 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" 1325 | 1326 | verror@1.10.0: 1327 | version "1.10.0" 1328 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 1329 | dependencies: 1330 | assert-plus "^1.0.0" 1331 | core-util-is "1.0.2" 1332 | extsprintf "^1.2.0" 1333 | 1334 | which@2.0.2: 1335 | version "2.0.2" 1336 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1337 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1338 | dependencies: 1339 | isexe "^2.0.0" 1340 | 1341 | which@^1.2.9: 1342 | version "1.3.1" 1343 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 1344 | dependencies: 1345 | isexe "^2.0.0" 1346 | 1347 | wordwrap@^1.0.0: 1348 | version "1.0.0" 1349 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 1350 | integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= 1351 | 1352 | workerpool@6.1.5: 1353 | version "6.1.5" 1354 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" 1355 | integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== 1356 | 1357 | wrap-ansi@^7.0.0: 1358 | version "7.0.0" 1359 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1360 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1361 | dependencies: 1362 | ansi-styles "^4.0.0" 1363 | string-width "^4.1.0" 1364 | strip-ansi "^6.0.0" 1365 | 1366 | wrappy@1: 1367 | version "1.0.2" 1368 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1369 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1370 | 1371 | ws@^6.1.0: 1372 | version "6.2.2" 1373 | resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" 1374 | integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== 1375 | dependencies: 1376 | async-limiter "~1.0.0" 1377 | 1378 | y18n@^5.0.5: 1379 | version "5.0.8" 1380 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1381 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1382 | 1383 | yallist@^2.1.2: 1384 | version "2.1.2" 1385 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 1386 | 1387 | yargs-parser@20.2.4: 1388 | version "20.2.4" 1389 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1390 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1391 | 1392 | yargs-parser@^20.2.2: 1393 | version "20.2.9" 1394 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1395 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1396 | 1397 | yargs-unparser@2.0.0: 1398 | version "2.0.0" 1399 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 1400 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1401 | dependencies: 1402 | camelcase "^6.0.0" 1403 | decamelize "^4.0.0" 1404 | flat "^5.0.2" 1405 | is-plain-obj "^2.1.0" 1406 | 1407 | yargs@16.2.0: 1408 | version "16.2.0" 1409 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1410 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1411 | dependencies: 1412 | cliui "^7.0.2" 1413 | escalade "^3.1.1" 1414 | get-caller-file "^2.0.5" 1415 | require-directory "^2.1.1" 1416 | string-width "^4.2.0" 1417 | y18n "^5.0.5" 1418 | yargs-parser "^20.2.2" 1419 | 1420 | yn@^2.0.0: 1421 | version "2.0.0" 1422 | resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" 1423 | 1424 | yocto-queue@^0.1.0: 1425 | version "0.1.0" 1426 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1427 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1428 | --------------------------------------------------------------------------------