diff --git a/package.json b/package.json index 8bff93d06c..1dee05f3c5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "scripts": { "prettier": "prettier --write .", "lint": "eslint --cache --fix --ext .js,.ts,.tsx --max-warnings 0 .", - "test": "jest" + "test": "jest", + "build": "yarn workspace create-modular-app build && yarn workspace modular-scripts build && yarn workspace esm-dependency-checker build" }, "devDependencies": { "@babel/core": "^7.9.6", diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts deleted file mode 100755 index c306573213..0000000000 --- a/packages/cli/src/cli.ts +++ /dev/null @@ -1,347 +0,0 @@ -#!/usr/bin/env node - -import meow from 'meow'; -import execa from 'execa'; -import findUp from 'find-up'; -import * as fs from 'fs-extra'; -import * as path from 'path'; -import chalk from 'chalk'; -import { - pascalCase as toPascalCase, - paramCase as toParamCase, -} from 'change-case'; -import resolveAsBin from 'resolve-as-bin'; -import generateComponentImports from './generateComponentImports'; - -// Makes the script crash on unhandled rejections instead of silently -// ignoring them. In the future, promise rejections that are not handled will -// terminate the Node.js process with a non-zero exit code. -// See https://github.com/facebook/create-react-app/blob/f36d61a/packages/react-scripts/bin/react-scripts.js#L11-L16 -process.on('unhandledRejection', (err) => { - throw err; -}); - -const cracoBin = resolveAsBin('craco'); -const cracoConfig = path.join(__dirname, '..', 'craco.config.js'); - -function execSync( - file: string, - args: string[], - options: { log?: boolean } & execa.SyncOptions = { log: true }, -) { - const { log, ...opts } = options; - if (log) { - console.log(chalk.grey(`$ ${file} ${args.join(' ')}`)); - } - return execa.sync(file, args, { - stdin: process.stdin, - stderr: process.stderr, - stdout: process.stdout, - ...opts, - }); -} - -function run() { - const cli = meow({ - description: 'Dashboards for a new generation', - help: ` - Usage: - $ modular app - $ modular new - $ modular start - $ modular build - $ modular test - $ modular map -`, - }); - - if (isYarnInstalled() === false) { - console.error('Please install `yarn` before attempting to run `modular`.'); - process.exit(1); - } - - const command = cli.input[0]; - switch (command) { - case 'app': - return app(cli.input[1]); - case 'new': - return widget(cli.input[1]); - case 'test': { - return test(process.argv.slice(3)); - } - case 'start': - return start(); - case 'build': - return build(); - case 'map': - return map(); - default: - console.log(cli.help); - process.exit(1); - } -} - -function app(name: string) { - const modularRoot = findUpModularRoot(); - if (modularRoot !== undefined) { - console.error( - 'It is not possible to create a new app within a modular repository.', - ); - process.exit(1); - } - - const newModularRoot = path.join(process.cwd(), name); - const widgetsPath = path.join(newModularRoot, 'widgets'); - const appPath = path.join(newModularRoot, 'app'); - - const projectPackageJsonPath = path.join(newModularRoot, 'package.json'); - const appPackageJsonPath = path.join(appPath, 'package.json'); - - const templatePath = path.join(__dirname, '..', 'template'); - - // Create a new CRA app, modify config for workspaces - fs.mkdirpSync(newModularRoot); - - execSync('yarn', ['init', '-y'], { - cwd: newModularRoot, - }); - - fs.writeJsonSync(projectPackageJsonPath, { - ...fs.readJsonSync(projectPackageJsonPath), - private: true, - workspaces: ['app', 'widgets/*'], - modular: {}, - scripts: { - start: 'modular start', - build: 'modular build', - test: 'modular test', - map: 'modular map', - lint: 'eslint .', - prettier: 'prettier --write .', - }, - eslintConfig: { - extends: 'modular', - }, - prettier: { - singleQuote: true, - trailingComma: 'all', - printWidth: 80, - proseWrap: 'always', - }, - }); - - execSync( - 'yarn', - ['add', '-W', '--dev', 'prettier', 'modular', 'eslint-config-modular'], - { cwd: newModularRoot }, - ); - - // TODO: We should be able to delete this once we have a published version of the tool. - execSync('yarn', ['add', '-W', '--dev', '@craco/craco'], { - cwd: newModularRoot, - }); - - fs.mkdirpSync(widgetsPath); - fs.copySync( - path.join(templatePath, 'widgets/README.md'), - path.join(widgetsPath, 'README.md'), - ); - - execSync('yarn', ['create', 'react-app', 'app'], { - cwd: newModularRoot, - }); - // TODO - this should use a ---template, which includes store.js - // and doesn't include a service worker? - fs.copySync( - path.join(templatePath, 'app/store.js'), - path.join(appPath, 'src/store.js'), - ); - - fs.moveSync( - path.join(appPath, '.gitignore'), - path.join(newModularRoot, '.gitignore'), - ); - fs.removeSync(path.join(appPath, '.git')); - fs.removeSync(path.join(appPath, 'yarn.lock')); - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const appPackageJson = fs.readJsonSync(appPackageJsonPath); - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - delete appPackageJson['scripts']; - delete appPackageJson['eslintConfig']; - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - fs.writeJsonSync(appPackageJsonPath, appPackageJson); - - map(newModularRoot); - - execSync('yarn', ['prettier'], { - cwd: newModularRoot, - }); - execSync('git', ['init'], { cwd: newModularRoot }); - - // TODO - make an initial commit? - execSync('git', ['add', '.'], { cwd: newModularRoot }); - execSync('git', ['commit', '-m', 'Initial commit'], { - cwd: newModularRoot, - }); -} - -function widget(name: string) { - const modularRoot = getModularRoot(); - - const newWidgetPackageName = toParamCase(name); - const newWidgetComponentName = toPascalCase(name); - - const newWidgetPath = path.join(modularRoot, 'widgets', newWidgetPackageName); - const templatePath = path.join(__dirname, '..', 'template'); - - // create a new widget source folder - if (fs.existsSync(newWidgetPath)) { - console.error(`The widget named ${name} already exists!`); - process.exit(1); - } - - fs.mkdirpSync(newWidgetPath); - fs.copySync(path.join(templatePath, 'widgets/starter'), newWidgetPath); - - const filePaths = fs - .readdirSync(newWidgetPath, { - withFileTypes: true, - }) - .filter((entry) => entry.isDirectory() === false) - .map((file) => path.join(newWidgetPath, file.name)); - - for (const filePath of filePaths) { - fs.writeFileSync( - filePath, - fs - .readFileSync(filePath, 'utf8') - .replace(/PackageName\$\$/g, newWidgetPackageName) - .replace(/ComponentName\$\$/g, newWidgetComponentName), - ); - } - - execSync('yarn', ['add', 'react', 'react-dom'], { cwd: newWidgetPath }); - - map(); - - execSync('yarn', ['prettier'], { - cwd: modularRoot, - }); -} - -function map(modularRoot = getModularRoot()) { - fs.writeFileSync( - path.join(modularRoot, 'app/src/widgets.js'), - generateComponentImports(path.join(modularRoot, 'widgets')), - ); -} - -function test(args: string[]) { - const modularRoot = getModularRoot(); - - map(); - - return execSync(cracoBin, ['test', '--config', cracoConfig, ...args], { - cwd: path.join(modularRoot, 'app'), - log: false, - }); -} - -function start() { - const modularRoot = getModularRoot(); - - map(); - - execSync(cracoBin, ['start', '--config', cracoConfig], { - cwd: path.join(modularRoot, 'app'), - log: false, - }); -} - -function build() { - const modularRoot = getModularRoot(); - - map(); - - execSync(cracoBin, ['build', '--config', cracoConfig], { - cwd: path.join(modularRoot, 'app'), - log: false, - }); -} - -function isModularRoot(packageJson: { modular?: Record }) { - return ( - typeof packageJson === 'object' && - packageJson.modular !== null && - typeof packageJson.modular === 'object' - ); -} - -function findUpModularRoot() { - return findUp.sync((directory: string) => { - const packageJsonPath = path.join(directory, 'package.json'); - if ( - findUp.sync.exists(packageJsonPath) && - isModularRoot(fs.readJsonSync(packageJsonPath)) - ) { - return packageJsonPath; - } - return; - }); -} - -function getModularRoot(): string { - try { - const modularRoot = findUpModularRoot(); - if (modularRoot === undefined) { - console.error('These commands must be run within a modular repository.'); - process.exit(1); - } - - return path.dirname(modularRoot); - } catch (err) { - console.error(err); - return process.exit(1); - } -} - -function isYarnInstalled(): boolean { - try { - execa.sync('yarn', ['-v']); - return true; - } catch (err) { - return false; - } -} - -try { - void run(); -} catch (err) { - console.error(err); -} - -// TODOS -// - remove craco, meow, etc -// - can components change their name? how to prevent -// that from happening? or if it does happen, how does one update -// their db/wherever they store this? -// - make sure react/react-dom have the same versions across the repo -// fix stdio coloring -// the components map has to be 'virtual' -// verify IDE integration -// how do you write tests for this??? -// sparse checkout helpers -// auto assign reviewers??? -// SOON -// - show an actual example working, with an app registry and everything -// - try to use module federation? will need to fork react-scripts and/or webpack - -// unanswered questions -// - global store/data flow? -// - drilldown pattern -// - filters -// etc etc - -// desktop / RN / custom renderers -// er, angular? diff --git a/packages/cli/.npmignore b/packages/create-modular-app/.npmignore similarity index 100% rename from packages/cli/.npmignore rename to packages/create-modular-app/.npmignore diff --git a/packages/create-modular-app/package.json b/packages/create-modular-app/package.json new file mode 100644 index 0000000000..26f0b2a93e --- /dev/null +++ b/packages/create-modular-app/package.json @@ -0,0 +1,26 @@ +{ + "name": "create-modular-app", + "version": "0.0.0", + "license": "Apache-2.0", + "bin": { + "create-modular-app": "build/cli.js" + }, + "engines": { + "node": ">=10" + }, + "scripts": { + "clean": "rimraf build", + "prebuild": "yarn clean", + "build": "babel --root-mode upward src --out-dir build --extensions .ts --ignore *.test.ts" + }, + "dependencies": { + "chalk": "^4.1.0", + "execa": "^4.0.2", + "fs-extra": "^9.0.1" + }, + "devDependencies": { + "@types/fs-extra": "^5.0.2", + "@types/node": "*", + "rimraf": "^3.0.2" + } +} diff --git a/packages/cli/src/cli.test.js b/packages/create-modular-app/src/cli.test.js similarity index 100% rename from packages/cli/src/cli.test.js rename to packages/create-modular-app/src/cli.test.js diff --git a/packages/create-modular-app/src/cli.ts b/packages/create-modular-app/src/cli.ts new file mode 100755 index 0000000000..a79f6fa907 --- /dev/null +++ b/packages/create-modular-app/src/cli.ts @@ -0,0 +1,188 @@ +#!/usr/bin/env node + +import execa from 'execa'; +import * as fs from 'fs-extra'; +import * as path from 'path'; +import chalk from 'chalk'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +// See https://github.com/facebook/create-react-app/blob/f36d61a/packages/react-scripts/bin/react-scripts.js#L11-L16 +process.on('unhandledRejection', (err) => { + throw err; +}); + +function execSync( + file: string, + args: string[], + options: { log?: boolean } & execa.SyncOptions = { log: true }, +) { + const { log, ...opts } = options; + if (log) { + console.log(chalk.grey(`$ ${file} ${args.join(' ')}`)); + } + return execa.sync(file, args, { + stdin: process.stdin, + stderr: process.stderr, + stdout: process.stdout, + ...opts, + }); +} + +function isYarnInstalled(): boolean { + try { + execa.sync('yarn', ['-v']); + return true; + } catch (err) { + return false; + } +} + +function createModularApp() { + if (isYarnInstalled() === false) { + console.error( + 'Please install `yarn` before attempting to run `create-modular-app`.', + ); + process.exit(1); + } + + const index = process.argv.findIndex((arg) => arg.endsWith('modular-app')); + const [name] = index !== -1 ? process.argv.slice(index + 1) : [undefined]; + if (!name) { + console.error('Please pass a name into `yarn create modular-app [name]`.'); + process.exit(1); + } + + const newModularRoot = path.join(process.cwd(), name); + const widgetsPath = path.join(newModularRoot, 'widgets'); + const appPath = path.join(newModularRoot, 'app'); + + const projectPackageJsonPath = path.join(newModularRoot, 'package.json'); + const appPackageJsonPath = path.join(appPath, 'package.json'); + + const templatePath = path.join(__dirname, '..', 'template'); + + // Create a new CRA app, modify config for workspaces + fs.mkdirpSync(newModularRoot); + + execSync('yarn', ['init', '-y'], { + cwd: newModularRoot, + }); + + fs.writeJsonSync(projectPackageJsonPath, { + ...fs.readJsonSync(projectPackageJsonPath), + private: true, + workspaces: ['app', 'widgets/*'], + modular: {}, + scripts: { + start: 'modular start', + build: 'modular build', + test: 'modular test', + lint: 'eslint .', + prettier: 'prettier --write .', + }, + eslintConfig: { + extends: 'modular', + }, + prettier: { + singleQuote: true, + trailingComma: 'all', + printWidth: 80, + proseWrap: 'always', + }, + }); + + execSync( + 'yarn', + [ + 'add', + '-W', + '--dev', + 'prettier', + // TODO: Enable these once published. + // 'modular-scripts', + // 'eslint-config-modular-app', + ], + { cwd: newModularRoot }, + ); + + fs.mkdirpSync(widgetsPath); + fs.copySync( + path.join(templatePath, 'widgets/README.md'), + path.join(widgetsPath, 'README.md'), + ); + + execSync('yarn', ['create', 'react-app', 'app'], { + cwd: newModularRoot, + }); + fs.removeSync(path.join(appPath, '.gitignore')); + fs.removeSync(path.join(appPath, '.git')); + fs.removeSync(path.join(appPath, 'yarn.lock')); + + fs.copySync( + path.join(templatePath, 'gitignore'), + path.join(newModularRoot, '.gitignore'), + ); + + // TODO: Rather than manually copying files across and installing dependencies this should use a `--template` + // that includes `store.js` and `widgets.js`, doesn't contain a service worker and installs the correct dependencies. + // See: https://github.com/facebook/create-react-app/tree/master/packages/cra-template + fs.copySync( + path.join(templatePath, 'app/store.js'), + path.join(appPath, 'src/store.js'), + ); + fs.copySync( + path.join(templatePath, 'app/widgets.js'), + path.join(appPath, 'src/widgets.js'), + ); + execSync('yarn', ['add', 'codegen.macro'], { cwd: appPath }); + // TODO: We should be able to delete this once we have a published version of modular-scripts. + execSync('yarn', ['add', '--dev', '@craco/craco'], { cwd: appPath }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const appPackageJson = fs.readJsonSync(appPackageJsonPath); + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + delete appPackageJson['scripts']; + delete appPackageJson['eslintConfig']; + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + fs.writeJsonSync(appPackageJsonPath, appPackageJson); + + execSync('yarn', ['prettier'], { + cwd: newModularRoot, + }); + execSync('git', ['init'], { + cwd: newModularRoot, + }); + + execSync('git', ['add', '.'], { + cwd: newModularRoot, + }); + execSync('git', ['commit', '-m', 'Initial commit'], { cwd: newModularRoot }); +} + +try { + void createModularApp(); +} catch (err) { + console.error(err); +} + +// TODOS +// - make sure react/react-dom have the same versions across the repo +// fix stdio coloring +// verify IDE integration +// how do you write tests for this??? +// sparse checkout helpers +// auto assign reviewers??? +// SOON +// - show an actual example working, with an app registry and everything +// - try to use module federation? will need to fork react-scripts and/or webpack + +// unanswered questions +// - global store/data flow? +// - drilldown pattern +// - filters +// etc etc + +// desktop / RN / custom renderers +// er, angular? diff --git a/packages/cli/template/app/store.js b/packages/create-modular-app/template/app/store.js similarity index 100% rename from packages/cli/template/app/store.js rename to packages/create-modular-app/template/app/store.js diff --git a/packages/create-modular-app/template/app/widgets.js b/packages/create-modular-app/template/app/widgets.js new file mode 100644 index 0000000000..236a8e4843 --- /dev/null +++ b/packages/create-modular-app/template/app/widgets.js @@ -0,0 +1,29 @@ +// DO NOT EDIT THIS FILE. +/* eslint-disable import/no-extraneous-dependencies, no-unused-vars */ +import { lazy } from 'react'; +import codegen from 'codegen.macro'; +/* eslint-enable import/no-extraneous-dependencies, no-unused-vars */ + +function getWidgetMap() { + // This defines the `widgetMap`. + codegen` + const path = require('path'); + const { getModularRoot, generateWidgetMap } = require('modular-scripts'); + + const widgetMap = generateWidgetMap( + path.join(getModularRoot(), 'widgets') + ); + + module.exports = 'const widgetMap = ' + widgetMap + ';'; + `; + + // eslint-disable-next-line no-undef + return widgetMap; +} + +// Given a directory of widgets, generate and export a widget map, like: +// +// export default { +// 'package-name': lazy(() => import('package-name')) +// } +export default getWidgetMap(); diff --git a/packages/create-modular-app/template/gitignore b/packages/create-modular-app/template/gitignore new file mode 100644 index 0000000000..04c5395eea --- /dev/null +++ b/packages/create-modular-app/template/gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/packages/cli/template/widgets/README.md b/packages/create-modular-app/template/widgets/README.md similarity index 100% rename from packages/cli/template/widgets/README.md rename to packages/create-modular-app/template/widgets/README.md diff --git a/packages/eslint-config-modular/index.js b/packages/eslint-config-modular-app/index.js similarity index 100% rename from packages/eslint-config-modular/index.js rename to packages/eslint-config-modular-app/index.js diff --git a/packages/eslint-config-modular/package.json b/packages/eslint-config-modular-app/package.json similarity index 88% rename from packages/eslint-config-modular/package.json rename to packages/eslint-config-modular-app/package.json index 913cb2ec6e..09d63e16b4 100644 --- a/packages/eslint-config-modular/package.json +++ b/packages/eslint-config-modular-app/package.json @@ -1,6 +1,6 @@ { - "name": "eslint-config-modular", - "version": "1.0.0", + "name": "eslint-config-modular-app", + "version": "0.0.0", "main": "index.js", "license": "MIT", "dependencies": { diff --git a/packages/modular-scripts/.npmignore b/packages/modular-scripts/.npmignore new file mode 100644 index 0000000000..85de9cf933 --- /dev/null +++ b/packages/modular-scripts/.npmignore @@ -0,0 +1 @@ +src diff --git a/packages/cli/craco.config.js b/packages/modular-scripts/craco.config.js similarity index 100% rename from packages/cli/craco.config.js rename to packages/modular-scripts/craco.config.js diff --git a/packages/cli/package.json b/packages/modular-scripts/package.json similarity index 88% rename from packages/cli/package.json rename to packages/modular-scripts/package.json index 3eafeb566e..566efa0b53 100644 --- a/packages/cli/package.json +++ b/packages/modular-scripts/package.json @@ -1,7 +1,8 @@ { - "name": "modular", + "name": "modular-scripts", "version": "0.0.0", "license": "Apache-2.0", + "main": "./build/index.js", "bin": { "modular": "build/cli.js" }, @@ -17,6 +18,7 @@ "@craco/craco": "^5.6.4", "chalk": "^4.1.0", "change-case": "^4.1.1", + "codegen.macro": "^4.0.0", "execa": "^4.0.2", "find-up": "^4.1.0", "fs-extra": "^9.0.1", diff --git a/packages/modular-scripts/src/cli.test.js b/packages/modular-scripts/src/cli.test.js new file mode 100644 index 0000000000..deaea6564d --- /dev/null +++ b/packages/modular-scripts/src/cli.test.js @@ -0,0 +1,3 @@ +test('tests work', () => { + expect(0.1 + 0.2).toEqual(0.30000000000000004); +}); diff --git a/packages/modular-scripts/src/cli.ts b/packages/modular-scripts/src/cli.ts new file mode 100755 index 0000000000..498d25e09f --- /dev/null +++ b/packages/modular-scripts/src/cli.ts @@ -0,0 +1,180 @@ +#!/usr/bin/env node + +import meow from 'meow'; +import execa from 'execa'; +import * as fs from 'fs-extra'; +import * as path from 'path'; +import chalk from 'chalk'; +import { + pascalCase as toPascalCase, + paramCase as toParamCase, +} from 'change-case'; +import resolveAsBin from 'resolve-as-bin'; + +import { getModularRoot } from './getModularRoot'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +// See https://github.com/facebook/create-react-app/blob/f36d61a/packages/react-scripts/bin/react-scripts.js#L11-L16 +process.on('unhandledRejection', (err) => { + throw err; +}); + +const cracoBin = resolveAsBin('craco'); +const cracoConfig = path.join(__dirname, '..', 'craco.config.js'); + +function execSync( + file: string, + args: string[], + options: { log?: boolean } & execa.SyncOptions = { log: true }, +) { + const { log, ...opts } = options; + if (log) { + console.log(chalk.grey(`$ ${file} ${args.join(' ')}`)); + } + return execa.sync(file, args, { + stdin: process.stdin, + stderr: process.stderr, + stdout: process.stdout, + ...opts, + }); +} + +function isYarnInstalled(): boolean { + try { + execa.sync('yarn', ['-v']); + return true; + } catch (err) { + return false; + } +} + +function run() { + const cli = meow({ + description: 'Dashboards for a new generation', + help: ` + Usage: + $ modular add + $ modular start + $ modular build + $ modular test +`, + }); + + if (isYarnInstalled() === false) { + console.error( + 'Please install `yarn` before attempting to run `modular-scripts`.', + ); + process.exit(1); + } + + const command = cli.input[0]; + switch (command) { + case 'add': + return addWidget(cli.input[1]); + case 'test': + return test(process.argv.slice(3)); + case 'start': + return start(); + case 'build': + return build(); + default: + console.log(cli.help); + process.exit(1); + } +} + +function addWidget(name: string) { + const modularRoot = getModularRoot(); + + const newWidgetPackageName = toParamCase(name); + const newWidgetComponentName = toPascalCase(name); + + const newWidgetPath = path.join(modularRoot, 'widgets', newWidgetPackageName); + const templatePath = path.join(__dirname, '..', 'template'); + + // create a new widget source folder + if (fs.existsSync(newWidgetPath)) { + console.error(`The widget named ${name} already exists!`); + process.exit(1); + } + + fs.mkdirpSync(newWidgetPath); + fs.copySync(path.join(templatePath, 'widgets/starter'), newWidgetPath); + + const widgetRootFilePaths = fs + .readdirSync(newWidgetPath, { withFileTypes: true }) + .filter((entry) => entry.isDirectory() === false) + .map((file) => path.join(newWidgetPath, file.name)); + + for (const widgetFilePath of widgetRootFilePaths) { + fs.writeFileSync( + widgetFilePath, + fs + .readFileSync(widgetFilePath, 'utf8') + .replace(/PackageName\$\$/g, newWidgetPackageName) + .replace(/ComponentName\$\$/g, newWidgetComponentName), + ); + } + + execSync('yarn', [], { cwd: newWidgetPath }); + + execSync('yarn', ['prettier'], { + cwd: modularRoot, + }); +} + +function test(args: string[]) { + const modularRoot = getModularRoot(); + + return execSync(cracoBin, ['test', '--config', cracoConfig, ...args], { + cwd: path.join(modularRoot, 'app'), + log: false, + }); +} + +function start() { + const modularRoot = getModularRoot(); + + execSync(cracoBin, ['start', '--config', cracoConfig], { + cwd: path.join(modularRoot, 'app'), + log: false, + }); +} + +function build() { + const modularRoot = getModularRoot(); + + execSync(cracoBin, ['build', '--config', cracoConfig], { + cwd: path.join(modularRoot, 'app'), + log: false, + }); +} + +try { + void run(); +} catch (err) { + console.error(err); +} + +// TODOS +// - remove craco, meow, etc +// - make sure react/react-dom have the same versions across the repo +// fix stdio coloring +// verify IDE integration +// how do you write tests for this??? +// sparse checkout helpers +// auto assign reviewers??? +// SOON +// - show an actual example working, with an app registry and everything +// - try to use module federation? will need to fork react-scripts and/or webpack + +// unanswered questions +// - global store/data flow? +// - drilldown pattern +// - filters +// etc etc + +// desktop / RN / custom renderers +// er, angular? diff --git a/packages/cli/src/generateComponentImports.ts b/packages/modular-scripts/src/generateWidgetMap.ts similarity index 81% rename from packages/cli/src/generateComponentImports.ts rename to packages/modular-scripts/src/generateWidgetMap.ts index d3f10e8525..f3a49c5546 100644 --- a/packages/cli/src/generateComponentImports.ts +++ b/packages/modular-scripts/src/generateWidgetMap.ts @@ -8,9 +8,7 @@ interface PackageJson { // Given a directory of widgets, generate a map like: // { 'package-name': lazy(() => import('package-name')) } -export default function generateComponentImports( - widgetsDirectoryPath: string, -): string { +export function generateWidgetMap(widgetsDirectoryPath: string): string { const packageNames = fs .readdirSync(widgetsDirectoryPath, { withFileTypes: true }) // Get individual widget directories. @@ -27,15 +25,11 @@ export default function generateComponentImports( // Get package names. .map((packageJson) => packageJson.name); - return `// DO NOT EDIT THIS FILE. -${packageNames.length > 0 ? `import { lazy } from 'react';` : ''} - -export default { + return `{ ${packageNames .map( (packageName) => `'${packageName}': lazy(() => import('${packageName}'))`, ) .join(',\n ')} -} -`; +}`; } diff --git a/packages/modular-scripts/src/getModularRoot.ts b/packages/modular-scripts/src/getModularRoot.ts new file mode 100644 index 0000000000..9c06af5fe3 --- /dev/null +++ b/packages/modular-scripts/src/getModularRoot.ts @@ -0,0 +1,39 @@ +import * as path from 'path'; +import * as fs from 'fs-extra'; +import findUp from 'find-up'; + +function isModularRoot(packageJson: { modular?: Record }) { + return ( + typeof packageJson === 'object' && + packageJson.modular !== null && + typeof packageJson.modular === 'object' + ); +} + +function findUpModularRoot() { + return findUp.sync((directory: string) => { + const packageJsonPath = path.join(directory, 'package.json'); + if ( + findUp.sync.exists(packageJsonPath) && + isModularRoot(fs.readJsonSync(packageJsonPath)) + ) { + return packageJsonPath; + } + return; + }); +} + +export function getModularRoot(): string { + try { + const modularRoot = findUpModularRoot(); + if (modularRoot === undefined) { + console.error('These commands must be run within a modular repository.'); + process.exit(1); + } + + return path.dirname(modularRoot); + } catch (err) { + console.error(err); + return process.exit(1); + } +} diff --git a/packages/modular-scripts/src/index.ts b/packages/modular-scripts/src/index.ts new file mode 100644 index 0000000000..e4742da4c1 --- /dev/null +++ b/packages/modular-scripts/src/index.ts @@ -0,0 +1,2 @@ +export * from './getModularRoot'; +export * from './generateWidgetMap'; diff --git a/packages/cli/template/widgets/starter/README.md b/packages/modular-scripts/template/widgets/starter/README.md similarity index 100% rename from packages/cli/template/widgets/starter/README.md rename to packages/modular-scripts/template/widgets/starter/README.md diff --git a/packages/cli/template/widgets/starter/index.js b/packages/modular-scripts/template/widgets/starter/index.js similarity index 100% rename from packages/cli/template/widgets/starter/index.js rename to packages/modular-scripts/template/widgets/starter/index.js diff --git a/packages/cli/template/widgets/starter/index.test.js b/packages/modular-scripts/template/widgets/starter/index.test.js similarity index 59% rename from packages/cli/template/widgets/starter/index.test.js rename to packages/modular-scripts/template/widgets/starter/index.test.js index 6c461b94a4..ce3824970b 100644 --- a/packages/cli/template/widgets/starter/index.test.js +++ b/packages/modular-scripts/template/widgets/starter/index.test.js @@ -1,8 +1,8 @@ import React from 'react'; import { render } from 'react-dom'; -import Component$$ from './'; +import ComponentName$$ from './'; test('it should render', () => { const el = document.createElement('div'); - expect(() => render(, el)).not.toThrow(); + expect(() => render(, el)).not.toThrow(); }); diff --git a/packages/cli/template/widgets/starter/package.json b/packages/modular-scripts/template/widgets/starter/package.json similarity index 55% rename from packages/cli/template/widgets/starter/package.json rename to packages/modular-scripts/template/widgets/starter/package.json index 87a3bc6f64..d28d4c764e 100644 --- a/packages/cli/template/widgets/starter/package.json +++ b/packages/modular-scripts/template/widgets/starter/package.json @@ -2,9 +2,9 @@ "name": "PackageName$$", "version": "1.0.0", "main": "index.js", - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "react": "*", - "react-dom": "*" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/yarn.lock b/yarn.lock index 8805f55295..5b8e743bd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -870,7 +870,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.2": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.7.2": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99" integrity sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw== @@ -922,6 +922,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@changesets/types@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@changesets/types/-/types-0.4.0.tgz#3413badb2c3904357a36268cb9f8c7e0afc3a804" + integrity sha512-TclHHKDVYQ8rJGZgVeWiF7c91yWzTTWdPagltgutelGu/Psup5PQlUq6svx7S8suj+jXcaE34yEEsfIvzXXB2Q== + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1131,6 +1136,14 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1144,6 +1157,11 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + "@nodelib/fs.walk@^1.2.3": version "1.2.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" @@ -1271,6 +1289,14 @@ dependencies: "@types/node" "*" +"@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + "@types/graceful-fs@^4.1.2": version "4.1.3" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.3.tgz#039af35fe26bec35003e8d86d2ee9c586354348f" @@ -1316,6 +1342,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + "@types/minimist@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" @@ -1571,7 +1602,7 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ== -aggregate-error@^3.0.0: +aggregate-error@^3.0.0, aggregate-error@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== @@ -1694,11 +1725,23 @@ array-includes@^3.0.3, array-includes@^3.1.1: es-abstract "^1.17.0" is-string "^1.0.5" +array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1820,6 +1863,15 @@ babel-jest@^26.0.1: graceful-fs "^4.2.4" slash "^3.0.0" +babel-plugin-codegen@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-codegen/-/babel-plugin-codegen-4.0.1.tgz#bf234c5fb31d8477bc1484f00d920bae163fa268" + integrity sha512-cehTkKAGgENw+ftEngX/zVfFqMxFFItsatwmLHfxVLJCnkJvREQhsCb5/WNrNdP7L3tbwGgd5JQt9dFth+p24g== + dependencies: + "@babel/runtime" "^7.9.2" + babel-plugin-macros "^2.8.0" + require-from-string "^2.0.2" + babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" @@ -1847,6 +1899,15 @@ babel-plugin-jest-hoist@^26.0.0: "@babel/types" "^7.3.3" "@types/babel__traverse" "^7.0.6" +babel-plugin-macros@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== + dependencies: + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" + babel-preset-current-node-syntax@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz#fb4a4c51fe38ca60fede1dc74ab35eb843cb41d6" @@ -1981,6 +2042,11 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2119,6 +2185,11 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" +chunkd@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/chunkd/-/chunkd-2.0.1.tgz#49cd1d7b06992dc4f7fccd962fe2a101ee7da920" + integrity sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -2178,6 +2249,13 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +codegen.macro@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/codegen.macro/-/codegen.macro-4.0.0.tgz#7f57a5c2d2c72e9c1c3dda71daba0e64c65a44ae" + integrity sha512-7K7BXVLmsO4shE/+2KhzCjP7uPbqwbkY4o5EJaJouncVY7IkZozpnbUex8xjWB9AzEV9aWpnXe0+oLbEuPj9Ew== + dependencies: + babel-plugin-codegen "^4.0.0" + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -2327,6 +2405,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + css.escape@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" @@ -2493,6 +2580,13 @@ diff-sequences@^26.0.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.0.0.tgz#0760059a5c287637b842bd7085311db7060e88a6" integrity sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg== +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -2542,6 +2636,13 @@ dot-case@^3.0.3: no-case "^3.0.3" tslib "^1.10.0" +duplexer2@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -3018,6 +3119,18 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + fast-glob@^3.1.1: version "3.2.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" @@ -3152,6 +3265,15 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -3239,6 +3361,15 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= +get-workspaces@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/get-workspaces/-/get-workspaces-0.5.2.tgz#4fb2031ec1bdd32d3c1f3de2589ce8af5c2e24ee" + integrity sha512-99x72taQ9OUHhCmBS0B2WI/zwOtBOBPoyVNGs9+B0ag2GGhCjl/EaU9VQ8Zorx64TyVj1Am7bO+0J1KwDqo7OA== + dependencies: + "@changesets/types" "^0.4.0" + fs-extra "^7.0.1" + globby "^9.2.0" + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -3261,6 +3392,11 @@ glob-parent@^5.0.0, glob-parent@^5.1.0: dependencies: is-glob "^4.0.1" +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -3297,6 +3433,20 @@ globby@^11.0.0: merge2 "^1.3.0" slash "^3.0.0" +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" @@ -3440,7 +3590,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ignore@^4.0.6: +ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== @@ -3484,7 +3634,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3745,6 +3895,11 @@ is-wsl@^2.1.1: dependencies: is-docker "^2.0.0" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -4297,6 +4452,13 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + jsonfile@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" @@ -4556,6 +4718,23 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +meow@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.1.tgz#1ad64c4b76b2a24dfb2f635fddcadf320d251467" + integrity sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "^4.0.2" + normalize-package-data "^2.5.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.13.1" + yargs-parser "^18.1.3" + meow@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/meow/-/meow-7.0.1.tgz#1ed4a0a50b3844b451369c48362eb0515f04c1dc" @@ -4580,6 +4759,11 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +merge2@^1.2.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + merge2@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" @@ -4822,6 +5006,11 @@ object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -4940,7 +5129,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.2.0: +p-limit@^2.2.0, p-limit@^2.2.1: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -5085,6 +5274,13 @@ path-type@^2.0.0: dependencies: pify "^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" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -5095,6 +5291,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +physical-cpu-count@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz#18de2f97e4bf7a9551ad7511942b5496f7aba660" + integrity sha1-GN4vl+S/epVRrXURlCtUlverpmA= + picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -5105,6 +5306,11 @@ pify@^2.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -5318,6 +5524,26 @@ readable-stream@^2.0.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@~1.0.17: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5467,6 +5693,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -5644,7 +5875,7 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2: +semver@^7.1.1, semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -5867,6 +6098,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split2@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/split2/-/split2-0.1.2.tgz#a4d560b91f04168f21cd9bdd569b6f78d5164593" + integrity sha1-pNVguR8EFo8hzZvdVptveNUWRZM= + dependencies: + through2 "~0.4.1" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -5989,6 +6227,11 @@ string.prototype.trimstart@^1.0.0: define-properties "^1.1.3" es-abstract "^1.17.5" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -6088,6 +6331,13 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" +task-graph-runner@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/task-graph-runner/-/task-graph-runner-1.0.3.tgz#73b2cd380cef6f51b8179b0d1da4bb7c356b03bf" + integrity sha512-aC70bepv1j9jXX70nzolNvnHJvD4A3WtU4lQ1HEjgTS8rgnRXoUUq+xl9hZ1hKYXxVwElZXmUUMxpzDC6R0mRg== + dependencies: + array-includes "^3.0.3" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -6115,6 +6365,22 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +through2@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" + integrity sha1-390BLrnHAOIyP9M084rGIqs3Lac= + dependencies: + readable-stream "~1.0.17" + xtend "~3.0.0" + +through2@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + integrity sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s= + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6323,6 +6589,11 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + universalify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" @@ -6513,6 +6784,27 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +workspaces-run@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/workspaces-run/-/workspaces-run-1.0.1.tgz#dace5df0d45f8770316d254e0cfe7a6c1a3df437" + integrity sha512-B7tZj/g4/1JCeNQ7+zVNVBC83hOJBKpOm/yYob3eqw0Aerp1Guecfdf0J6kO/I/EyA2X2uP1oCHWsh2QywXh0A== + dependencies: + aggregate-error "^3.0.1" + chalk "^3.0.0" + chunkd "^2.0.1" + cross-spawn "^7.0.1" + get-workspaces "^0.5.2" + meow "^6.0.0" + micromatch "^4.0.2" + p-limit "^2.2.1" + physical-cpu-count "^2.0.0" + redent "^3.0.0" + semver "^7.1.1" + signal-exit "^3.0.2" + task-graph-runner "^1.0.3" + trim-newlines "^3.0.0" + wrapline "^2.0.1" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -6522,6 +6814,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrapline@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wrapline/-/wrapline-2.0.1.tgz#c79908ac15f41d401da6607ff25661d4c91479bb" + integrity sha1-x5kIrBX0HUAdpmB/8lZh1MkUebs= + dependencies: + duplexer2 "~0.0.2" + split2 "^0.1.2" + through2 "^0.5.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -6566,6 +6867,18 @@ xregexp@^4.3.0: dependencies: "@babel/runtime-corejs3" "^7.8.3" +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= + dependencies: + object-keys "~0.4.0" + +xtend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" + integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= + y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"