diff --git a/aio/README.md b/aio/README.md index efb501a948..baab409b53 100644 --- a/aio/README.md +++ b/aio/README.md @@ -36,8 +36,9 @@ Here are the most important tasks you might need to use: * `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. * `yarn boilerplate:add:viewengine` - same as `boilerplate:add` but also turns on `ViewEngine` (pre-Ivy) mode. - * `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`. +* `yarn create-example` - create a new example directory containing initial source files. + * `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs. * `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs. diff --git a/aio/content/examples/.gitignore b/aio/content/examples/.gitignore index 368b596848..6d98f0cc41 100644 --- a/aio/content/examples/.gitignore +++ b/aio/content/examples/.gitignore @@ -32,6 +32,8 @@ **/karma-test-shim.js **/browser-test-shim.js **/node_modules +**/yarn.lock +**/package-lock.json # built files *.map diff --git a/aio/package.json b/aio/package.json index 5112241125..d09f70cb10 100644 --- a/aio/package.json +++ b/aio/package.json @@ -71,6 +71,7 @@ "boilerplate:test": "node tools/examples/test.js", "generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz", "generate-zips": "node ./tools/example-zipper/generateZips", + "create-example": "node ./tools/examples/create-example.js", "build-404-page": "node scripts/build-404-page", "update-webdriver": "node ../scripts/webdriver-manager-update.js", "~~audit-web-app": "node scripts/audit-web-app", @@ -172,6 +173,6 @@ "unist-util-visit-parents": "^1.1.1", "watchr": "^3.0.1", "xregexp": "^4.0.0", - "yargs": "^7.0.2" + "yargs": "^16.1.0" } } diff --git a/aio/tools/README.md b/aio/tools/README.md index cde00b3d03..1a949daea4 100644 --- a/aio/tools/README.md +++ b/aio/tools/README.md @@ -29,11 +29,12 @@ sub-folder. Also there are a number of common boilerplate files that are needed example's project. We maintain these common boilerplate files centrally to reduce the amount of effort if one of them needs to change. -This `examples` tool folder contains two utilities: +This `examples` tool folder contains three utilities: * example-boilerplate.js - install/remove the npm dependencies and boilerplate files into/from each of the examples' subfolders. * run-example-e2e.js - run the e2e tests for one or more examples +* create-example.js - create a new example from the `example-scaffold/` directory or by importing files from a CLI project. See the [README.md](examples/README.md) for more details. diff --git a/aio/tools/examples/README.md b/aio/tools/examples/README.md index 896b49a7bb..12bf0830ab 100644 --- a/aio/tools/examples/README.md +++ b/aio/tools/examples/README.md @@ -150,6 +150,14 @@ See [aio/README.md](../../README.md#developer-tasks) for the available command-l Running the script will create an `aio/protractor-results.txt` file with the results of the tests. +### `create-example.js` + +The [create-example.js](./create-example.js) script creates a new example under the `aio/content/examples` directory. + +You must provide a new name for the example. +By default the script will place basic scaffold files into the new example (from [shared/example-scaffold](./shared/example-scaffold)). +But you can also specify the path to a separate CLI project, from which the script will copy files that would not be considered "boilerplate". +See the [Boilerplate overview](#boilerplate-overview) for more information. ### Updating example dependencies diff --git a/aio/tools/examples/UPDATING.md b/aio/tools/examples/UPDATING.md index 65c7f1d6e8..2c823e7422 100644 --- a/aio/tools/examples/UPDATING.md +++ b/aio/tools/examples/UPDATING.md @@ -7,9 +7,9 @@ Follow these steps to update the examples to the latest versions of Angular (and > NOTE: > The [angular-cli-diff](https://github.com/cexbrayat/angular-cli-diff) repo can be a useful resource for discovering what dependency versions are used for a basic CLI app at a specific CLI version. -- In the [shared/](./shared) folder, run `yarn` to update the dependencies in the [shared/node_modules/](./shared/node_modules) folder and the [shared/yarn.lock](./shared/yarn.lock) file. +- In the [shared/](./shared) directory, run `yarn` to update the dependencies in the [shared/node_modules/](./shared/node_modules) directory and the [shared/yarn.lock](./shared/yarn.lock) file. -- In the [shared/](./shared) folder, run `yarn sync-deps` to update the dependency versions of the `package.json` files in each sub-folder of [shared/boilerplate/](./shared/boilerplate) to match the ones in [shared/package.json](./shared/package.json). +- In the [shared/](./shared) directory, run `yarn sync-deps` to update the dependency versions of the `package.json` files in each sub-folder of [shared/boilerplate/](./shared/boilerplate) to match the ones in [shared/package.json](./shared/package.json). - Follow the steps in the following section to update the rest of the boilerplate files. @@ -24,7 +24,7 @@ Any necessary changes to boilerplate files will be done automatically through mi > You have to make these changes (if any) manually. > Again, the [angular-cli-diff](https://github.com/cexbrayat/angular-cli-diff) repo can be a useful resource for discovering changes between versions. -- In the [shared/boilerplate/cli/](./shared/boilerplate/cli) folder, run the following commands to migrate the the project to the current versions of Angular CLI and the Angular framework (updated in previous steps): +- In the [shared/boilerplate/cli/](./shared/boilerplate/cli) directory, run the following commands to migrate the the project to the current versions of Angular CLI and the Angular framework (updated in previous steps): ```sh # Ensure dependencies are installed. yarn install @@ -38,8 +38,11 @@ Any necessary changes to boilerplate files will be done automatically through mi > In order for `ng update` to work, there must be a `node_modules/` directory with installed dependencies inside the [shared/boilerplate/cli/](./shared/boilerplate/cli) directory. > This `node_modules/` directory is only needed during the update operation and is otherwise ignored (both by git and by the [example-boilerplate.js](./example-boilerplate.js) script) by means of the [shared/boilerplate/.gitignore](./shared/boilerplate/.gitignore) file. -- The previous command made any necessary changes to boilerplate files inside the `cli/` folder, but the same changes need to be applied to the other CLI-based boilerplate folders. - Inspect the changes in `cli/` and manually apply the necessary ones to other CLI-based boilerplate folders. +- The previous command made any necessary changes to boilerplate files inside the `cli/` directory, but the same changes need to be applied to the other CLI-based boilerplate directories. + Inspect the changes in `cli/` and manually apply the necessary ones to other CLI-based boilerplate directories. + +- Also ensure that any relevant changes in the [shared/boilerplate/cli/](./shared/boilerplate/cli) directory are copied to the [shared/example-scaffold/](./shared/example-scaffold) directory, which is used when creating new examples (via `yarn create-example ...`). + Only files that would not be considered boilerplate should be added to the `example-scaffold/` directory. - Ensure any changes to [cli/tslint.json](./shared/boilerplate/cli/tslint.json) are ported over to [systemjs/tslint.json](./shared/boilerplate/systemjs/tslint.json) and also [aio/content/examples/tslint.json](../../content/examples/tslint.json). This last part is important, since this file is used to lint example code on CI. diff --git a/aio/tools/examples/constants.js b/aio/tools/examples/constants.js new file mode 100644 index 0000000000..c7d590d9d9 --- /dev/null +++ b/aio/tools/examples/constants.js @@ -0,0 +1,6 @@ +const path = require('canonical-path'); + +exports.EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples'); +exports.EXAMPLE_CONFIG_FILENAME = 'example-config.json'; +exports.SHARED_PATH = path.resolve(__dirname, 'shared'); +exports.STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json'; diff --git a/aio/tools/examples/create-example.js b/aio/tools/examples/create-example.js new file mode 100644 index 0000000000..7db729e1f5 --- /dev/null +++ b/aio/tools/examples/create-example.js @@ -0,0 +1,140 @@ +const fs = require('fs-extra'); +const glob = require('glob'); +const ignore = require('ignore'); +const path = require('canonical-path'); +const shelljs = require('shelljs'); +const yargs = require('yargs'); + +const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH, STACKBLITZ_CONFIG_FILENAME} = + require('./constants'); +const BASIC_SOURCE_PATH = path.resolve(SHARED_PATH, 'example-scaffold'); + +shelljs.set('-e'); + +if (require.main === module) { + const options = + yargs(process.argv.slice(2)) + .command( + '$0 [source]', + [ + 'Create a new example.', + '', + 'If [source] is provided then the relevant files from the CLI project at that path are copied into the example.', + ].join('\n')) + .strict() + .version(false) + .argv; + + const exampleName = options.name; + const examplePath = path.resolve(EXAMPLES_BASE_PATH, exampleName); + + console.log('Creating new example at', examplePath); + createEmptyExample(exampleName, examplePath); + + const sourcePath = + options.source !== undefined ? path.resolve(options.source) : BASIC_SOURCE_PATH; + console.log('Copying files from', sourcePath); + copyExampleFiles(sourcePath, examplePath, exampleName); + + console.log(`The new "${exampleName}" example has been created.`); + console.log('Now run "yarn boilerplate:add" to set it up for development.'); + console.log( + 'You can find more info on working with docs examples in aio/tools/examples/README.md.') +} + +/** + * Create the directory and marker files for the new example. + */ +function createEmptyExample(exampleName, examplePath) { + ensureExamplePath(examplePath); + writeExampleConfigFile(examplePath); + writeStackBlitzFile(exampleName, examplePath); +} + +/** + * Ensure that the new example directory exists. + */ +function ensureExamplePath(examplePath) { + if (fs.existsSync(examplePath)) { + throw new Error( + `Unable to create example. The path to the new example already exists: ${examplePath}`); + } + fs.ensureDirSync(examplePath); +} + +/** + * Write the `example-config.json` file to the new example. + */ +function writeExampleConfigFile(examplePath) { + fs.writeFileSync(path.resolve(examplePath, EXAMPLE_CONFIG_FILENAME), ''); +} + +/** + * Write the `stackblitz.json` file into the new example. + */ +function writeStackBlitzFile(exampleName, examplePath) { + const config = { + description: titleize(exampleName), + files: ['!**/*.d.ts', '!**/*.js', '!**/*.[1,2].*'], + tags: [exampleName.split('-')] + }; + fs.writeFileSync( + path.resolve(examplePath, STACKBLITZ_CONFIG_FILENAME), + JSON.stringify(config, null, 2) + '\n'); +} + +/** + * Copy all the files from the `sourcePath`, which are not ignored by the `.gitignore` file in the + * `EXAMPLES_BASE_PATH`, to the `examplePath`. + */ +function copyExampleFiles(sourcePath, examplePath, exampleName) { + const gitIgnoreSource = getGitIgnore(sourcePath); + const gitIgnoreExamples = getGitIgnore(EXAMPLES_BASE_PATH); + + // Grab the files in the source folder and filter them based on the gitignore rules. + const sourceFiles = + glob.sync('**/*', { + cwd: sourcePath, + dot: true, + ignore: ['**/node_modules/**', '.git/**', '.gitignore'], + mark: true + }) + // Filter out the directories, leaving only files + .filter(filePath => !/\/$/.test(filePath)) + // Filter out files that match the source directory .gitignore rules + .filter(filePath => !gitIgnoreSource.ignores(filePath)) + // Filter out files that match the examples directory .gitignore rules + .filter(filePath => !gitIgnoreExamples.ignores(path.join(exampleName, filePath))); + + for (const sourceFile of sourceFiles) { + console.log(' - ', sourceFile); + const destPath = path.resolve(examplePath, sourceFile) + fs.ensureDirSync(path.dirname(destPath)); + fs.copySync(path.resolve(sourcePath, sourceFile), destPath); + } +} + +function getGitIgnore(directory) { + const gitIgnoreMatcher = ignore(); + const gitignoreFilePath = path.resolve(directory, '.gitignore'); + if (fs.existsSync(gitignoreFilePath)) { + const gitignoreFile = fs.readFileSync(gitignoreFilePath, 'utf8'); + gitIgnoreMatcher.add(gitignoreFile); + } + return gitIgnoreMatcher; +} + +/** + * Convert a kebab-case string to space separated Title Case string. + */ +function titleize(input) { + return input.replace( + /(-|^)(.)/g, (_, pre, char) => `${pre === '-' ? ' ' : ''}${char.toUpperCase()}`); +} + +exports.createEmptyExample = createEmptyExample; +exports.ensureExamplePath = ensureExamplePath; +exports.writeExampleConfigFile = writeExampleConfigFile; +exports.writeStackBlitzFile = writeStackBlitzFile; +exports.copyExampleFiles = copyExampleFiles; +exports.titleize = titleize; \ No newline at end of file diff --git a/aio/tools/examples/create-example.spec.js b/aio/tools/examples/create-example.spec.js new file mode 100644 index 0000000000..79b1992449 --- /dev/null +++ b/aio/tools/examples/create-example.spec.js @@ -0,0 +1,130 @@ +const path = require('canonical-path'); +const fs = require('fs-extra'); +const {glob} = require('glob'); + +const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH, STACKBLITZ_CONFIG_FILENAME} = + require('./constants'); + +const { + copyExampleFiles, + createEmptyExample, + ensureExamplePath, + titleize, + writeExampleConfigFile, + writeStackBlitzFile +} = require('./create-example'); + +describe('create-example tool', () => { + describe('createEmptyExample', () => { + it('should create an empty example with marker files', () => { + spyOn(fs, 'existsSync').and.returnValue(false); + spyOn(fs, 'ensureDirSync'); + const writeFileSpy = spyOn(fs, 'writeFileSync'); + + createEmptyExample('foo-bar', '/path/to/foo-bar'); + expect(writeFileSpy).toHaveBeenCalledTimes(2); + expect(writeFileSpy) + .toHaveBeenCalledWith(`/path/to/foo-bar/${EXAMPLE_CONFIG_FILENAME}`, jasmine.any(String)); + expect(writeFileSpy) + .toHaveBeenCalledWith( + `/path/to/foo-bar/${STACKBLITZ_CONFIG_FILENAME}`, jasmine.any(String)); + }); + }); + + describe('ensureExamplePath', () => { + it('should error if the path already exists', () => { + spyOn(fs, 'existsSync').and.returnValue(true); + expect(() => ensureExamplePath('foo/bar')) + .toThrowError( + `Unable to create example. The path to the new example already exists: foo/bar`); + }); + + it('should create the directory on disk', () => { + spyOn(fs, 'existsSync').and.returnValue(false); + const spy = spyOn(fs, 'ensureDirSync'); + ensureExamplePath('foo/bar'); + expect(spy).toHaveBeenCalledWith('foo/bar'); + }); + }); + + describe('writeExampleConfigFile', () => { + it('should write a JSON file to disk', () => { + const spy = spyOn(fs, 'writeFileSync'); + writeExampleConfigFile('/foo/bar'); + expect(spy).toHaveBeenCalledWith(`/foo/bar/${EXAMPLE_CONFIG_FILENAME}`, ''); + }); + }); + + describe('writeStackBlitzFile', () => { + it('should write a JSON file to disk', () => { + const spy = spyOn(fs, 'writeFileSync'); + writeStackBlitzFile('bar-bar', '/foo/bar-bar'); + expect(spy).toHaveBeenCalledWith(`/foo/bar-bar/${STACKBLITZ_CONFIG_FILENAME}`, [ + '{', + ' "description": "Bar Bar",', + ' "files": [', + ' "!**/*.d.ts",', + ' "!**/*.js",', + ' "!**/*.[1,2].*"', + ' ],', + ' "tags": [', + ' [', + ' "bar",', + ' "bar"', + ' ]', + ' ]', + '}', + '', + ].join('\n')); + }); + }); + + describe('copyExampleFiles', () => { + it('should copy over files that are not ignored by git', () => { + const examplesGitIgnorePath = path.resolve(EXAMPLES_BASE_PATH, '.gitignore'); + const sourceGitIgnorePath = path.resolve('/source/path', '.gitignore'); + + spyOn(console, 'log'); + spyOn(fs, 'existsSync').and.returnValue(true); + const readFileSyncSpy = spyOn(fs, 'readFileSync').and.callFake(p => { + switch (p) { + case examplesGitIgnorePath: + return '**/a/b/**'; + case sourceGitIgnorePath: + return '**/*.bad'; + default: + throw new Error('Unexpected path'); + } + }); + spyOn(glob, 'sync').and.returnValue([ + 'a/', 'a/b/', 'a/c', 'x.ts', 'x.bad', 'a/b/y.ts', 'a/b/y.bad' + ]); + const ensureDirSyncSpy = spyOn(fs, 'ensureDirSync'); + const copySyncSpy = spyOn(fs, 'copySync'); + + copyExampleFiles('/source/path', '/path/to/test-example', 'test-example'); + + expect(readFileSyncSpy).toHaveBeenCalledWith(examplesGitIgnorePath, 'utf8'); + expect(readFileSyncSpy).toHaveBeenCalledWith(sourceGitIgnorePath, 'utf8'); + + expect(ensureDirSyncSpy.calls.allArgs()).toEqual([ + ['/path/to/test-example/a'], + ['/path/to/test-example'], + ]); + + expect(copySyncSpy.calls.allArgs()).toEqual([ + ['/source/path/a/c', '/path/to/test-example/a/c'], + ['/source/path/x.ts', '/path/to/test-example/x.ts'], + ]); + }); + }); + + describe('titleize', () => { + it('should convert a kebab-case string to title-case', () => { + expect(titleize('abc')).toEqual('Abc'); + expect(titleize('abc-def')).toEqual('Abc Def'); + expect(titleize('123')).toEqual('123'); + expect(titleize('abc---def')).toEqual('Abc - Def'); + }); + }); +}); diff --git a/aio/tools/examples/example-boilerplate.js b/aio/tools/examples/example-boilerplate.js index a77ac0dd88..5a2909f0ec 100644 --- a/aio/tools/examples/example-boilerplate.js +++ b/aio/tools/examples/example-boilerplate.js @@ -4,8 +4,8 @@ const ignore = require('ignore'); const path = require('canonical-path'); const shelljs = require('shelljs'); const yargs = require('yargs'); +const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH} = require('./constants'); -const SHARED_PATH = path.resolve(__dirname, 'shared'); const SHARED_NODE_MODULES_PATH = path.resolve(SHARED_PATH, 'node_modules'); const BOILERPLATE_BASE_PATH = path.resolve(SHARED_PATH, 'boilerplate'); @@ -13,9 +13,6 @@ const BOILERPLATE_CLI_PATH = path.resolve(BOILERPLATE_BASE_PATH, 'cli'); const BOILERPLATE_COMMON_PATH = path.resolve(BOILERPLATE_BASE_PATH, 'common'); const BOILERPLATE_VIEWENGINE_PATH = path.resolve(BOILERPLATE_BASE_PATH, 'viewengine'); -const EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples'); -const EXAMPLE_CONFIG_FILENAME = 'example-config.json'; - class ExampleBoilerPlate { /** * Add boilerplate files to all the examples diff --git a/aio/tools/examples/shared/example-scaffold/e2e/src/app.e2e-spec.ts b/aio/tools/examples/shared/example-scaffold/e2e/src/app.e2e-spec.ts new file mode 100644 index 0000000000..bd99243f89 --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/e2e/src/app.e2e-spec.ts @@ -0,0 +1,20 @@ +import { AppPage } from './app.po'; +import { browser, logging } from 'protractor'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + // Add your e2e tests here + + afterEach(async () => { + // Assert that there are no errors emitted from the browser + const logs = await browser.manage().logs().get(logging.Type.BROWSER); + expect(logs).not.toContain(jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry)); + }); +}); diff --git a/aio/tools/examples/shared/example-scaffold/src/app/app.component.css b/aio/tools/examples/shared/example-scaffold/src/app/app.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/aio/tools/examples/shared/example-scaffold/src/app/app.component.html b/aio/tools/examples/shared/example-scaffold/src/app/app.component.html new file mode 100644 index 0000000000..60dbe3a500 --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/src/app/app.component.html @@ -0,0 +1 @@ +

Replace the src folder in this {{title}} with yours.

\ No newline at end of file diff --git a/aio/tools/examples/shared/example-scaffold/src/app/app.component.spec.ts b/aio/tools/examples/shared/example-scaffold/src/app/app.component.spec.ts new file mode 100644 index 0000000000..0509746ff0 --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/src/app/app.component.spec.ts @@ -0,0 +1,20 @@ +import { TestBed } from '@angular/core/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + // Add your unit tests here +}); diff --git a/aio/tools/examples/shared/example-scaffold/src/app/app.component.ts b/aio/tools/examples/shared/example-scaffold/src/app/app.component.ts new file mode 100644 index 0000000000..ea1aba85a9 --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/src/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], +}) +export class AppComponent { + title = 'example'; +} diff --git a/aio/tools/examples/shared/example-scaffold/src/app/app.module.ts b/aio/tools/examples/shared/example-scaffold/src/app/app.module.ts new file mode 100644 index 0000000000..f65716351a --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/src/app/app.module.ts @@ -0,0 +1,16 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; + +import { AppComponent } from './app.component'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/aio/tools/examples/shared/example-scaffold/src/index.html b/aio/tools/examples/shared/example-scaffold/src/index.html new file mode 100644 index 0000000000..3e64774523 --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/src/index.html @@ -0,0 +1,13 @@ + + + + + Ponyracer + + + + + + + + diff --git a/aio/tools/examples/shared/example-scaffold/src/main.ts b/aio/tools/examples/shared/example-scaffold/src/main.ts new file mode 100644 index 0000000000..c7b673cf44 --- /dev/null +++ b/aio/tools/examples/shared/example-scaffold/src/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/aio/yarn.lock b/aio/yarn.lock index 3ed1dd1189..c17cd21176 100644 --- a/aio/yarn.lock +++ b/aio/yarn.lock @@ -3075,11 +3075,6 @@ camelcase@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -3459,7 +3454,7 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== -cliui@^3.0.3, cliui@^3.2.0: +cliui@^3.0.3: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= @@ -3495,6 +3490,15 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +cliui@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.2.tgz#e3a412e1d5ec0ccbe50d1b4120fc8164e97881f4" + integrity sha512-lhpKkuUj67j5JgZIPZxLe7nSa4MQoojzRVWQyzMqBp2hBg6gwRjUDAwC1YDeBaC3APDBKNnjWbv2mlDF4XgOSA== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -4905,7 +4909,7 @@ errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -5017,6 +5021,11 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: es6-iterator "^2.0.3" es6-symbol "^3.1.1" +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -5583,14 +5592,6 @@ find-free-port@^2.0.0: resolved "https://registry.yarnpkg.com/find-free-port/-/find-free-port-2.0.0.tgz#4b22e5f6579eb1a38c41ac6bcb3efed1b6da9b1b" integrity sha1-SyLl9leesaOMQaxryz7+0bbamxs= -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -5925,7 +5926,7 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -7374,11 +7375,6 @@ is-url@^1.2.2: resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - is-whitespace-character@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" @@ -8137,17 +8133,6 @@ listenercount@~1.0.1: resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -9824,13 +9809,6 @@ parse-entities@^1.0.2, parse-entities@^1.1.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -9910,13 +9888,6 @@ path-dirname@^1.0.0: resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -9959,15 +9930,6 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -10872,23 +10834,6 @@ read-package-tree@5.3.1: readdir-scoped-modules "^1.0.0" util-promisify "^2.1.0" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -12381,7 +12326,7 @@ string-length@^1.0.0: dependencies: strip-ansi "^3.0.0" -string-width@^1.0.1, string-width@^1.0.2: +string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= @@ -12513,13 +12458,6 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -14010,11 +13948,6 @@ when@~3.6.x: resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -14114,6 +14047,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -14246,7 +14188,7 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -y18n@^3.2.0, y18n@^3.2.1: +y18n@^3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= @@ -14256,6 +14198,11 @@ y18n@^3.2.0, y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== +y18n@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.3.tgz#978115b82befe2b5c762bf55980b7b01a4a2d5d9" + integrity sha512-JeFbcHQ/7hVmMBXW6UB6Tg7apStHd/ztGz1JN78y3pFi/q0Ht1eA6PVkvw56gm7UA8fcJR/ziRlYEDMGoju0yQ== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -14295,12 +14242,10 @@ yargs-parser@^18.1.0, yargs-parser@^18.1.1, yargs-parser@^18.1.3: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= - dependencies: - camelcase "^3.0.0" +yargs-parser@^20.2.2: + version "20.2.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.2.tgz#84562c6b1c41ccec2f13d346c7dd83f8d1a0dc70" + integrity sha512-XmrpXaTl6noDsf1dKpBuUNCOHqjs0g3jRMXf/ztRxdOmb+er8kE5z5b55Lz3p5u2T8KJ59ENBnASS8/iapVJ5g== yargs@15.3.0: version "15.3.0" @@ -14383,24 +14328,18 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.1" -yargs@^7.0.2: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= +yargs@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a" + integrity sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g== dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" + string-width "^4.2.0" + y18n "^5.0.2" + yargs-parser "^20.2.2" yauzl@^2.10.0: version "2.10.0"