├── .appveyor.yml ├── .editorconfig ├── .gitignore ├── .travis.yml ├── codecov.yml ├── license.md ├── logo.svg ├── package.json ├── packages ├── cli │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── index.js │ │ └── lib.ts │ └── test │ │ └── lib.ts ├── plugin-assert │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-copy │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-env │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-find-git-staged │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-find │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-input-files │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-babel │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-codecov │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-eslint │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-esm-loader │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── esm-loader.js │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-flow-check │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-flow-generate │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-istanbul │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── hooks.ts │ │ ├── index.ts │ │ ├── instrument.ts │ │ ├── report.ts │ │ ├── thresholds.ts │ │ └── variable.ts │ └── test │ │ └── index.ts ├── plugin-lib-jest │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-karma │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-npm-publish │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-npm-version │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-postcss │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-prettier-eslint │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-rollup │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-tape │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-typescript-check │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-typescript-generate │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-webpack-dev-server │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-webpack-serve │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-lib-webpack │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-overwrite │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-parallel │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-read │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-remove │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-rename │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-sequence │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-spawn │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-unpack │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ ├── fixtures │ │ ├── file.tar │ │ ├── file.tar.bz2 │ │ ├── file.tar.gz │ │ └── file.zip │ │ └── index.ts ├── plugin-watch │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-write │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin-xargs │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts ├── plugin │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ └── test │ │ └── index.ts └── reporter-verbose │ ├── package.json │ ├── readme.md │ ├── src │ └── index.ts │ └── test │ └── index.ts ├── readme.md ├── tasks ├── config │ ├── auto.ts │ └── babel.ts └── index.ts ├── tsconfig.json └── yarn.lock /.appveyor.yml: -------------------------------------------------------------------------------- 1 | # https://www.appveyor.com/docs/appveyor-yml 2 | 3 | version: "{build}" 4 | environment: 5 | matrix: 6 | - nodejs_version: "8" 7 | - nodejs_version: "10" 8 | branches: 9 | only: 10 | - master 11 | cache: 12 | - node_modules 13 | - '%LOCALAPPDATA%/Yarn' 14 | skip_tags: true 15 | matrix: 16 | fast_finish: true 17 | build: off 18 | install: 19 | - ps: Install-Product node $env:nodejs_version 20 | - yarn 21 | - yarn install --cwd node_modules/@auto/start-plugin --pure-lockfile 22 | test_script: 23 | - yarn start ci 24 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | coverage/ 4 | tmp/ 5 | .npmrc 6 | .DS_Store 7 | *.log 8 | .idea/ 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://docs.travis-ci.com/user/customizing-the-build/ 2 | 3 | sudo: false 4 | language: node_js 5 | node_js: 6 | - 8 7 | - 10 8 | env: 9 | global: 10 | - PATH=$HOME/.yarn/bin:$PATH 11 | before_install: 12 | - curl -o- -L https://yarnpkg.com/install.sh | bash 13 | cache: 14 | yarn: true 15 | directories: 16 | - node_modules 17 | branches: 18 | only: 19 | - master 20 | matrix: 21 | fast_finish: true 22 | before_script: 23 | - yarn install --cwd node_modules/@auto/start-plugin --pure-lockfile 24 | script: yarn start ciCoverage 25 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | parsers: 3 | javascript: 4 | enable_partials: yes 5 | status: 6 | project: off 7 | patch: off 8 | comment: off 9 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2015–present Kir "deepsweet" Belevich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "description": "🔴 Functional task runner for Node.js", 4 | "workspaces": [ 5 | "packages/*" 6 | ], 7 | "devDependencies": { 8 | "@auto/start-plugin": "^0.3.0", 9 | "@babel/core": "^7.4.0", 10 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 11 | "@babel/plugin-syntax-typescript": "^7.3.3", 12 | "@babel/plugin-transform-runtime": "^7.4.0", 13 | "@babel/preset-env": "^7.4.2", 14 | "@babel/preset-typescript": "^7.3.3", 15 | "@babel/register": "^7.4.0", 16 | "@types/blue-tape": "^0.1.32", 17 | "@types/node": "^11.13.4", 18 | "@types/prompts": "^1.2.0", 19 | "@typescript-eslint/parser": "^1.6.0", 20 | "babel-plugin-dynamic-import-node": "^2.2.0", 21 | "babel-plugin-dynamic-import-node-babel-7": "^2.0.7", 22 | "babel-plugin-module-resolver": "^3.2.0", 23 | "blue-tape": "^1.0.0", 24 | "eslint": "^5.16.0", 25 | "eslint-config-standard": "^12.0.0", 26 | "eslint-plugin-import": "^2.16.0", 27 | "eslint-plugin-node": "^8.0.1", 28 | "eslint-plugin-promise": "^4.0.0", 29 | "eslint-plugin-standard": "^4.0.0", 30 | "mocku": "^0.5.0", 31 | "spyfn": "^0.2.0", 32 | "tap-diff": "^0.1.1", 33 | "typescript": "^3.4.3" 34 | }, 35 | "scripts": { 36 | "start": "node packages/cli/src/index.js", 37 | "debug": "node --inspect-brk packages/cli/src/index.js" 38 | }, 39 | "start": { 40 | "require": [ 41 | [ 42 | "@babel/register", 43 | { 44 | "presets": [ 45 | [ 46 | "@babel/preset-env", 47 | { 48 | "targets": { 49 | "node": "current" 50 | } 51 | } 52 | ], 53 | "@babel/preset-typescript" 54 | ], 55 | "plugins": [ 56 | "@babel/plugin-syntax-dynamic-import", 57 | "babel-plugin-dynamic-import-node" 58 | ], 59 | "extensions": [ 60 | ".ts", 61 | ".js" 62 | ] 63 | } 64 | ] 65 | ], 66 | "reporter": "@start/reporter-verbose/src/" 67 | }, 68 | "eslintConfig": { 69 | "parser": "@typescript-eslint/parser", 70 | "plugins": [ 71 | "standard", 72 | "node", 73 | "promise", 74 | "import" 75 | ], 76 | "extends": [ 77 | "standard", 78 | "plugin:node/recommended", 79 | "plugin:promise/recommended", 80 | "plugin:import/recommended" 81 | ], 82 | "env": { 83 | "node": true 84 | }, 85 | "rules": { 86 | "no-undef": "off", 87 | "no-unused-vars": "off", 88 | "import/no-unresolved": "off", 89 | "import/named": "off", 90 | "node/no-unsupported-features/es-syntax": [ 91 | "error", 92 | { 93 | "ignores": [ 94 | "asyncFunctions", 95 | "modules", 96 | "restSpreadProperties" 97 | ] 98 | } 99 | ], 100 | "node/shebang": "off", 101 | "node/no-missing-import": [ 102 | "error", 103 | { 104 | "tryExtensions": [ 105 | ".ts", 106 | ".js" 107 | ] 108 | } 109 | ], 110 | "node/no-missing-require": [ 111 | "error", 112 | { 113 | "tryExtensions": [ 114 | ".ts", 115 | ".js" 116 | ] 117 | } 118 | ], 119 | "promise/avoid-new": "off", 120 | "promise/always-return": "off", 121 | "promise/no-nesting": "off", 122 | "promise/no-callback-in-promise": "off", 123 | "prefer-promise-reject-errors": "off", 124 | "no-throw-literal": "off", 125 | "no-debugger": "off" 126 | } 127 | }, 128 | "eslintIgnore": [ 129 | "build/", 130 | "coverage/", 131 | "node_modules/" 132 | ], 133 | "engines": { 134 | "node": ">=8.6.0" 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/cli", 3 | "version": "0.5.0", 4 | "description": "⬛️ CLI entry point", 5 | "keywords": "tasks, runner, start, cli", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/cli", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "bin": { 11 | "start": "build/index.js" 12 | }, 13 | "files": [ 14 | "build/" 15 | ], 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "engines": { 20 | "node": ">=8.6.0" 21 | }, 22 | "dependencies": { 23 | "@babel/runtime": "^7.4.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/cli/readme.md: -------------------------------------------------------------------------------- 1 | # ⬛️ cli 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/cli.svg?style=flat-square)](https://www.npmjs.com/package/@start/cli) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/cli&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/cli) 4 | 5 | CLI entry point, [ESM](https://github.com/standard-things/esm) included. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/cli 11 | # or 12 | $ npm install --save-dev @start/cli 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Example 18 | 19 | ```js 20 | // package.json 21 | 22 | "start": { 23 | // `./tasks` by default if there is no `preset` option 24 | "file": "./my-tasks-file", 25 | // module name as a preset, overrides `file` option 26 | "preset": "my-awesome-start-preset", 27 | // modules to require before anything else, kinda `node -r` 28 | "require": [ 29 | // module name 30 | "whatever-require-hook-lib", 31 | // or a tuple with settings, just like in Babel 32 | [ 33 | "@babel/register", 34 | { 35 | "extensions": [ 36 | ".ts", 37 | ".js" 38 | ] 39 | } 40 | ] 41 | ], 42 | // reporter module name 43 | "reporter": "@start/reporter-verbose" 44 | } 45 | ``` 46 | 47 | ```sh 48 | $ yarn start 49 | 50 | One of the following task names is required: 51 | * foo 52 | * bar 53 | * baz 54 | ``` 55 | 56 | ```sh 57 | $ yarn start foo 58 | $ yarn start bar arg 59 | $ yarn start baz arg1 arg2 60 | ``` 61 | -------------------------------------------------------------------------------- /packages/cli/src/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint-disable no-global-assign */ 4 | /* eslint-disable no-process-exit */ 5 | const { resolve } = require('path') 6 | const { start: options } = require(resolve('./package.json')) 7 | 8 | const isEsmLoader = (required) => required[Symbol.for('esm:package')] || required[Symbol.for('esm\u200D:package')] 9 | 10 | if (Array.isArray(options.require)) { 11 | options.require.forEach((pkg) => { 12 | if (typeof pkg === 'string') { 13 | const required = require(pkg) 14 | 15 | if (isEsmLoader(required)) { 16 | require = required(module) 17 | } 18 | } else if (Array.isArray(pkg)) { 19 | const required = require(pkg[0]) 20 | 21 | if (isEsmLoader(required)) { 22 | require = required(module, pkg[1]) 23 | } else { 24 | required(pkg[1]) 25 | } 26 | } 27 | }) 28 | } 29 | 30 | const { default: cliLib } = require('./lib') 31 | 32 | cliLib(process.argv, options).catch((error) => { 33 | if (error !== null) { 34 | console.log(error) 35 | } 36 | 37 | process.exit(1) 38 | }) 39 | -------------------------------------------------------------------------------- /packages/cli/src/lib.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | 3 | type Options = { 4 | file?: string, 5 | preset?: string, 6 | reporter?: string, 7 | // TODO: harden me 8 | require?: Array 9 | } 10 | 11 | export default async (argv: string[], options: Options) => { 12 | if (!options.reporter) { 13 | throw '`reporter` option is missing in your `package.json` → `start`' 14 | } 15 | 16 | const tasksFile = options.file || './tasks' 17 | const tasksToRequire = options.preset || resolve(tasksFile) 18 | const tasks = await import(tasksToRequire) 19 | const taskName = argv[2] 20 | const task = tasks[taskName] 21 | 22 | if (typeof taskName === 'undefined' || typeof task === 'undefined') { 23 | throw `One of the following task names is required:\n* ${Object.keys(tasks).join('\n* ')}` 24 | } 25 | 26 | const taskArgs = argv.slice(3) 27 | const taskRunner = await task(...taskArgs) 28 | const { default: reporter } = await import(options.reporter) 29 | 30 | return taskRunner(reporter(taskName))() 31 | } 32 | -------------------------------------------------------------------------------- /packages/cli/test/lib.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import test from 'blue-tape' 3 | import { mock, unmock } from 'mocku' 4 | import { createSpy, getSpyCalls } from 'spyfn' 5 | 6 | test('cli: export', async (t) => { 7 | const { default: cliLib } = await import('../src/lib') 8 | 9 | t.equals( 10 | typeof cliLib, 11 | 'function', 12 | 'must be a function' 13 | ) 14 | }) 15 | 16 | test('cli: throw without reporter', async (t) => { 17 | const { default: cliLib } = await import('../src/lib') 18 | 19 | const argv = [] as string[] 20 | const options = {} 21 | 22 | return cliLib(argv, options).catch((error) => { 23 | t.equals( 24 | error, 25 | '`reporter` option is missing in your `package.json` → `start`', 26 | 'should throw' 27 | ) 28 | }) 29 | }) 30 | 31 | test('cli: throw without task name', async (t) => { 32 | mock('../src/lib', { 33 | preset: { 34 | a: 1, 35 | b: 2 36 | } 37 | }) 38 | 39 | const { default: cliLib } = await import('../src/lib') 40 | 41 | const argv = ['foo', 'bar'] 42 | const options = { 43 | preset: 'preset', 44 | reporter: 'reporter' 45 | } 46 | 47 | return cliLib(argv, options).catch((error) => { 48 | t.equals( 49 | error, 50 | 'One of the following task names is required:\n* a\n* b', 51 | 'should throw' 52 | ) 53 | 54 | unmock('../src/lib') 55 | }) 56 | }) 57 | 58 | test('cli: throw with unknown task name', async (t) => { 59 | mock('../src/lib', { 60 | preset: { 61 | a: 1, 62 | b: 2 63 | } 64 | }) 65 | 66 | const { default: cliLib } = await import('../src/lib') 67 | 68 | const argv = ['foo', 'bar', 'c'] 69 | const options = { 70 | preset: 'preset', 71 | reporter: 'reporter' 72 | } 73 | 74 | return cliLib(argv, options).catch((error) => { 75 | t.equals( 76 | error, 77 | 'One of the following task names is required:\n* a\n* b', 78 | 'should throw' 79 | ) 80 | 81 | unmock('../src/lib') 82 | }) 83 | }) 84 | 85 | test('cli: default file', async (t) => { 86 | const taskRunnerSpy = createSpy(() => () => {}) 87 | const taskSpy = createSpy(() => taskRunnerSpy) 88 | const reporterSpy = createSpy(() => 'reporter') 89 | mock('../src/lib', { 90 | [resolve('./tasks')]: { 91 | task: taskSpy 92 | }, 93 | reporter: { 94 | default: reporterSpy 95 | } 96 | }) 97 | 98 | const { default: cliLib } = await import('../src/lib') 99 | 100 | const argv = ['foo', 'bar', 'task', 'arg1', 'arg2'] 101 | const options = { 102 | reporter: 'reporter' 103 | } 104 | 105 | await cliLib(argv, options) 106 | 107 | t.deepEquals( 108 | getSpyCalls(taskSpy), 109 | [['arg1', 'arg2']], 110 | 'should call task with args' 111 | ) 112 | 113 | t.deepEquals( 114 | getSpyCalls(taskRunnerSpy), 115 | [['reporter']], 116 | 'should call taskRunner with props' 117 | ) 118 | 119 | t.deepEquals( 120 | getSpyCalls(reporterSpy), 121 | [['task']], 122 | 'should call reporter with task name' 123 | ) 124 | 125 | unmock('../src/lib') 126 | }) 127 | 128 | test('cli: custom file', async (t) => { 129 | const taskRunnerSpy = createSpy(() => () => {}) 130 | const taskSpy = createSpy(() => taskRunnerSpy) 131 | const reporterSpy = createSpy(() => 'reporter') 132 | mock('../src/lib', { 133 | [resolve('./my-tasks')]: { 134 | task: taskSpy 135 | }, 136 | reporter: { 137 | default: reporterSpy 138 | } 139 | }) 140 | 141 | const { default: cliLib } = await import('../src/lib') 142 | 143 | const argv = ['foo', 'bar', 'task', 'arg1', 'arg2'] 144 | const options = { 145 | file: './my-tasks', 146 | reporter: 'reporter' 147 | } 148 | 149 | await cliLib(argv, options) 150 | 151 | t.deepEquals( 152 | getSpyCalls(taskSpy), 153 | [['arg1', 'arg2']], 154 | 'should call task with args' 155 | ) 156 | 157 | t.deepEquals( 158 | getSpyCalls(taskRunnerSpy), 159 | [['reporter']], 160 | 'should call taskRunner with props' 161 | ) 162 | 163 | t.deepEquals( 164 | getSpyCalls(reporterSpy), 165 | [['task']], 166 | 'should call reporter with task name' 167 | ) 168 | 169 | unmock('../src/lib') 170 | }) 171 | 172 | test('cli: preset', async (t) => { 173 | const taskRunnerSpy = createSpy(() => () => {}) 174 | const taskSpy = createSpy(() => taskRunnerSpy) 175 | const reporterSpy = createSpy(() => 'reporter') 176 | mock('../src/lib', { 177 | preset: { 178 | task: taskSpy 179 | }, 180 | reporter: { 181 | default: reporterSpy 182 | } 183 | }) 184 | 185 | const { default: cliLib } = await import('../src/lib') 186 | 187 | const argv = ['foo', 'bar', 'task', 'arg1', 'arg2'] 188 | const options = { 189 | preset: 'preset', 190 | reporter: 'reporter' 191 | } 192 | 193 | await cliLib(argv, options) 194 | 195 | t.deepEquals( 196 | getSpyCalls(taskSpy), 197 | [['arg1', 'arg2']], 198 | 'should call task with args' 199 | ) 200 | 201 | t.deepEquals( 202 | getSpyCalls(taskRunnerSpy), 203 | [['reporter']], 204 | 'should call taskRunner with props' 205 | ) 206 | 207 | t.deepEquals( 208 | getSpyCalls(reporterSpy), 209 | [['task']], 210 | 'should call reporter with task name' 211 | ) 212 | 213 | unmock('../src/lib') 214 | }) 215 | -------------------------------------------------------------------------------- /packages/plugin-assert/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-assert", 3 | "version": "0.3.1", 4 | "description": "❓ Node.js assert()", 5 | "keywords": "tasks, runner, start, start-plugin, assert", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-assert", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/plugin-assert/readme.md: -------------------------------------------------------------------------------- 1 | # ❓ plugin-assert 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-assert.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-assert) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-assert&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-assert) 4 | 5 | Node.js [`assert()`](https://nodejs.org/docs/latest-v8.x/api/all.html#assert_assert_value_message). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-assert 11 | # or 12 | $ npm install --save-dev @start/plugin-assert 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | assert(arg: any, message?: string) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | export const task = (arg) => assert(arg, 'arg is required') 27 | ``` 28 | -------------------------------------------------------------------------------- /packages/plugin-assert/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | export default (value: any, message?: string) => 4 | plugin('assert', () => async () => { 5 | const { default: assertLib } = await import('assert') 6 | 7 | assertLib(value, message) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/plugin-assert/test/index.ts: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events' 2 | import test from 'blue-tape' 3 | import { createSpy, getSpyCalls } from 'spyfn' 4 | 5 | import assert from '../src' 6 | 7 | test('plugin-assert: export', async (t) => { 8 | t.equals( 9 | typeof assert, 10 | 'function', 11 | 'must be a function' 12 | ) 13 | }) 14 | 15 | test('plugin-assert: throw with default message', async (t) => { 16 | const reporter = new EventEmitter() 17 | const onErrorSpy = createSpy(() => {}) 18 | const assertRunner = await assert(false) 19 | 20 | reporter.on('error', onErrorSpy) 21 | 22 | try { 23 | await assertRunner(reporter)() 24 | } catch (error) { 25 | t.equals( 26 | getSpyCalls(onErrorSpy).length, 27 | 1, 28 | 'should throw assert error only once' 29 | ) 30 | 31 | t.equals( 32 | getSpyCalls(onErrorSpy).length, 33 | 1, 34 | 'should throw assert error' 35 | ) 36 | } 37 | }) 38 | 39 | test('plugin-assert: throw with custom message', async (t) => { 40 | const reporter = new EventEmitter() 41 | const onErrorSpy = createSpy(() => {}) 42 | const assertRunner = await assert(false, 'should be true!') 43 | 44 | reporter.on('error', onErrorSpy) 45 | 46 | try { 47 | await assertRunner(reporter)() 48 | } catch (error) { 49 | t.equals( 50 | getSpyCalls(onErrorSpy).length, 51 | 1, 52 | 'should throw assert error only once' 53 | ) 54 | 55 | t.equals( 56 | getSpyCalls(onErrorSpy).length, 57 | 1, 58 | 'should throw assert error' 59 | ) 60 | } 61 | }) 62 | -------------------------------------------------------------------------------- /packages/plugin-copy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-copy", 3 | "version": "0.3.2", 4 | "description": "👯 Copy files to relative destination using streams and keeping folders structure", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-copy", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "copie": "^0.3.0", 25 | "make-dir": "^3.0.0", 26 | "move-path": "^0.2.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugin-copy/readme.md: -------------------------------------------------------------------------------- 1 | # 👯 plugin-copy 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-copy.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-copy) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-copy&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-copy) 4 | 5 | Copy files to relative destination using streams and keeping folders structure. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-copy 11 | # or 12 | $ npm install --save-dev @start/plugin-copy 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | copy(outDirRelative: string) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import sequence from '@start/plugin-sequence' 27 | import find from '@start/plugin-find' 28 | import copy from '@start/plugin-copy' 29 | 30 | export const task = () => 31 | sequence( 32 | find('src/**/*.json'), 33 | copy('build/') 34 | ) 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/plugin-copy/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFilesProps } from '@start/plugin/src/' 2 | 3 | export default (outDirRelative: string) => 4 | plugin('copy', ({ logPath }) => async ({ files }: StartFilesProps) => { 5 | const path = await import('path') 6 | const { default: movePath } = await import('move-path') 7 | const { default: makeDir } = await import('make-dir') 8 | const { default: copie } = await import('copie') 9 | 10 | return { 11 | files: await Promise.all( 12 | files.map(async (file) => { 13 | const outFile = movePath(file.path, outDirRelative) 14 | const outDir = path.dirname(outFile) 15 | 16 | await makeDir(outDir) 17 | await copie(file.path, outFile) 18 | 19 | logPath(outFile) 20 | 21 | return file 22 | }) 23 | ) 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /packages/plugin-copy/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import copy from '../src' 4 | 5 | test('plugin-copy: export', async (t) => { 6 | t.equals( 7 | typeof copy, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-env/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-env", 3 | "version": "0.5.2", 4 | "description": "👔 Set environment variable using process.env", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-env", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin-env/readme.md: -------------------------------------------------------------------------------- 1 | # 👔 plugin-env 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-env.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-env) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-env&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-env) 4 | 5 | Set environment variable using [`process.env`](https://nodejs.org/api/all.html#process_process_env). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-env 11 | # or 12 | $ npm install --save-dev @start/plugin-env 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | env(vars: { [key: string]: any }) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import sequence from '@start/plugin-sequence' 27 | import env from '@start/plugin-env' 28 | import webpack from '@start/plugin-webpack' 29 | 30 | export task = async () => { 31 | const { default: webpackConfig } = await import('./webpack-config') 32 | 33 | return sequence( 34 | env({ NODE_ENV: 'production' }), 35 | webpack(webpackConfig) 36 | ) 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /packages/plugin-env/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | export default (vars: NodeJS.ProcessEnv) => 4 | plugin('env', ({ logMessage }) => () => { 5 | Object.keys(vars).forEach((key) => { 6 | process.env[key] = vars[key] 7 | 8 | logMessage(`${key} = ${vars[key]}`) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/plugin-env/test/index.ts: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events' 2 | import test from 'blue-tape' 3 | import { createSpy, getSpyCalls } from 'spyfn' 4 | 5 | import env from '../src' 6 | 7 | const files = [{ 8 | path: 'test', 9 | data: null, 10 | map: null 11 | }] 12 | 13 | test('plugin-env: export', async (t) => { 14 | t.equals( 15 | typeof env, 16 | 'function', 17 | 'must be a function' 18 | ) 19 | }) 20 | 21 | test('plugin-env: process.env', async (t) => { 22 | const reporter = new EventEmitter() 23 | const envRunner = await env({ 24 | FOO: 'BAR', 25 | BEEP: 'BOOP' 26 | }) 27 | 28 | await envRunner(reporter)() 29 | 30 | t.equals( 31 | process.env.FOO, 32 | 'BAR', 33 | 'should set process.env' 34 | ) 35 | 36 | t.equals( 37 | process.env.BEEP, 38 | 'BOOP', 39 | 'should set process.env' 40 | ) 41 | }) 42 | 43 | test('plugin-env: message', async (t) => { 44 | const reporter = new EventEmitter() 45 | const onMessageSpy = createSpy(() => {}) 46 | 47 | reporter.on('message', onMessageSpy) 48 | 49 | const envRunner = await env({ 50 | FOO: 'BAR', 51 | BEEP: 'BOOP' 52 | }) 53 | 54 | await envRunner(reporter)({ files }) 55 | 56 | t.equals( 57 | getSpyCalls(onMessageSpy).length, 58 | 2, 59 | 'should log twice' 60 | ) 61 | 62 | t.deepEquals( 63 | getSpyCalls(onMessageSpy), 64 | [ 65 | ['env', 'FOO = BAR'], 66 | ['env', 'BEEP = BOOP'] 67 | ], 68 | 'should log first message' 69 | ) 70 | }) 71 | -------------------------------------------------------------------------------- /packages/plugin-find-git-staged/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-find-git-staged", 3 | "version": "0.3.1", 4 | "description": "🔍 Find Git staged files and filter them using glob patterns", 5 | "keywords": "tasks, runner, glob, git, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-find-git-staged", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0", 25 | "multimatch": "^3.0.0" 26 | }, 27 | "devDependencies": { 28 | "@types/execa": "^0.9.0", 29 | "@types/multimatch": "^2.1.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugin-find-git-staged/readme.md: -------------------------------------------------------------------------------- 1 | # 🔍 plugin-find-git-staged 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-find-git-staged.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-find-git-staged) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-find-git-staged&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-find-git-staged) 4 | 5 | Find Git staged files and filter them using glob patterns. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-find-git-staged 11 | # or 12 | $ npm install --save-dev @start/plugin-find-git-staged 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | findGitStaged(glob: string | string[]) 21 | ``` 22 | 23 | #### `glob` 24 | 25 | [minimatch patterns](https://github.com/isaacs/minimatch#usage) 26 | 27 | ### Example 28 | 29 | ```js 30 | import sequence from '@start/plugin-sequence' 31 | import findGitStaged from '@start/plugin-find-git-staged' 32 | import eslint from '@start/plugin-lib-eslint' 33 | 34 | export const task = () => 35 | sequence( 36 | findGitStaged('src/**/*.js'), 37 | eslint() 38 | ) 39 | ``` 40 | -------------------------------------------------------------------------------- /packages/plugin-find-git-staged/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFile } from '@start/plugin/src/' 2 | 3 | export default (glob: string | string[]) => 4 | plugin('findGitStaged', ({ logPath }) => async () => { 5 | const path = await import('path') 6 | const { EOL } = await import('os') 7 | const { default: execa } = await import('execa') 8 | const { default: multimatch } = await import('multimatch') 9 | 10 | const gitArgs = ['diff', '--cached', '--name-only', '--diff-filter=ACM'] 11 | const { stdout } = await execa('git', gitArgs) 12 | const gitFiles = stdout.split(EOL) 13 | const matchedFiles = multimatch(gitFiles, glob) 14 | 15 | return { 16 | files: matchedFiles 17 | .map((file) => path.resolve(file)) 18 | .map((file): StartFile => { 19 | logPath(file) 20 | 21 | return { 22 | path: file 23 | } 24 | }) 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /packages/plugin-find-git-staged/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import findGitStaged from '../src' 4 | 5 | test('plugin-findGitStaged: export', async (t) => { 6 | t.equals( 7 | typeof findGitStaged, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-find/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-find", 3 | "version": "0.3.1", 4 | "description": "🔍 Find files using glob patterns", 5 | "keywords": "tasks, runner, glob, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-find", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "globby": "^9.1.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-find/readme.md: -------------------------------------------------------------------------------- 1 | # 🔍 plugin-find 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-find.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-find) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-find&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-find) 4 | 5 | Find files using glob patterns. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-find 11 | # or 12 | $ npm install --save-dev @start/plugin-find 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | find(glob: string | string[], options?: {}) 21 | ``` 22 | 23 | #### `glob` 24 | 25 | [minimatch patterns](https://github.com/isaacs/minimatch#usage). 26 | 27 | #### `options` 28 | 29 | [fast-glob options](https://github.com/mrmlnc/fast-glob#options-1). 30 | 31 | Default: 32 | 33 | ```js 34 | { 35 | ignore: ['node_modules/**'] 36 | } 37 | ``` 38 | 39 | ### Example 40 | 41 | ```js 42 | import sequence from '@start/plugin-sequence' 43 | import find from '@start/plugin-find' 44 | import copy from '@start/plugin-copy' 45 | 46 | export const task = () => 47 | sequence( 48 | find('src/**/*.json'), 49 | copy('build/') 50 | ) 51 | ``` 52 | -------------------------------------------------------------------------------- /packages/plugin-find/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFile } from '@start/plugin/src/' 2 | 3 | export default (glob: string | string[], userOptions?: {}) => 4 | plugin('find', ({ logPath }) => async () => { 5 | const { default: globby } = await import('globby') 6 | 7 | const options = { 8 | ignore: ['node_modules/**'], 9 | deep: true, 10 | onlyFiles: false, 11 | expandDirectories: false, 12 | absolute: true, 13 | ...userOptions 14 | } 15 | const result = await globby(glob, options) 16 | 17 | result.forEach(logPath) 18 | 19 | return { 20 | files: result.map((file): StartFile => ({ 21 | path: file 22 | })) 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /packages/plugin-find/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import find from '../src' 4 | 5 | test('plugin-find: export', async (t) => { 6 | t.equals( 7 | typeof find, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-input-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-input-files", 3 | "version": "0.3.1", 4 | "description": "🔌 Inject arguments as files into Start flow files", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-input-files", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugin-input-files/readme.md: -------------------------------------------------------------------------------- 1 | # 🔌 plugin-input-files 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-input-files.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-input-files) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-input-files&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-input-files) 4 | 5 | Inject arguments as files into Start flow. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-input-files 11 | # or 12 | $ npm install --save-dev @start/plugin-input-files 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | inputFiles(target: StartPlugin): (...files: string[]) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import inputFiles from '@start/plugin-input-files' 27 | import eslint from '@start/plugin-lib-eslint' 28 | 29 | export task = inputFiles(eslint()) 30 | ``` 31 | -------------------------------------------------------------------------------- /packages/plugin-input-files/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFile, StartFilesProps, StartPlugin, MaybeObject } from '@start/plugin/src/' 2 | 3 | export default (target: StartPlugin) => (...files: string[]) => 4 | plugin('inputFiles', (utils) => async () => { 5 | const path = await import('path') 6 | 7 | const targetRunner = await target 8 | 9 | return targetRunner(utils.reporter)({ 10 | files: files.map((file): StartFile => ({ 11 | path: path.resolve(file) 12 | })) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /packages/plugin-input-files/test/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import EventEmitter from 'events' 3 | import test from 'blue-tape' 4 | import { createSpy, getSpyCalls } from 'spyfn' 5 | import { StartFile } from '@start/plugin/src' 6 | 7 | import inputFiles from '../src' 8 | 9 | test('plugin-input-files: export', async (t) => { 10 | t.equals( 11 | typeof inputFiles, 12 | 'function', 13 | 'must be a function' 14 | ) 15 | }) 16 | 17 | test('plugin-input-files: simple', async (t) => { 18 | const reporter = new EventEmitter() 19 | const pluginSpy = createSpy(() => ({ foo: true })) 20 | const targetPluginSpy = createSpy(() => pluginSpy) 21 | const files = [ 22 | '../src/index.ts', 23 | '../test/index.ts' 24 | ] 25 | 26 | const inputFilesRunner = await inputFiles<{ foo: boolean }>(targetPluginSpy)(...files) 27 | 28 | const result = await inputFilesRunner(reporter)({ files: [] }) 29 | 30 | t.deepEquals( 31 | getSpyCalls(targetPluginSpy), 32 | [[reporter]], 33 | 'shoudl be called with reporter' 34 | ) 35 | 36 | t.deepEquals( 37 | getSpyCalls(pluginSpy), 38 | [[{ 39 | files: files.map((file): StartFile => ({ 40 | path: resolve(file) 41 | })) 42 | }]], 43 | 'should call plugin with files and props' 44 | ) 45 | 46 | t.ok( 47 | result && result.foo, 48 | 'should return called plugin result' 49 | ) 50 | }) 51 | 52 | test('plugin-input-files: async plugin', async (t) => { 53 | const reporter = new EventEmitter() 54 | const targetSpy = createSpy(() => ({ foo: true })) 55 | const targetPluginSpy = createSpy(() => targetSpy) 56 | const targetPluginPromise = Promise.resolve(targetPluginSpy) 57 | const files = [ 58 | '../src/index.ts', 59 | '../test/index.ts' 60 | ] 61 | const inputFilesRunner = await inputFiles<{ foo: boolean }>(targetPluginPromise)(...files) 62 | 63 | const result = await inputFilesRunner(reporter)({ files: [] }) 64 | 65 | t.deepEquals( 66 | getSpyCalls(targetPluginSpy), 67 | [[reporter]], 68 | 'shoudl be called with reporter' 69 | ) 70 | 71 | t.deepEquals( 72 | getSpyCalls(targetSpy), 73 | [[{ 74 | files: files.map((file): StartFile => ({ 75 | path: resolve(file) 76 | })) 77 | }]], 78 | 'should call plugin with files and props' 79 | ) 80 | 81 | t.ok( 82 | result && result.foo, 83 | 'should return called plugin result' 84 | ) 85 | }) 86 | -------------------------------------------------------------------------------- /packages/plugin-lib-babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-babel", 3 | "version": "0.4.1", 4 | "description": "🏭 Transform files using Babel", 5 | "keywords": "tasks, runner, start, start-plugin, babel", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-babel", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/core": "^7.4.0", 23 | "@babel/runtime": "^7.4.2", 24 | "@start/plugin": "^0.3.1", 25 | "@types/babel__core": "^7.1.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/plugin-lib-babel/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-babel 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-babel.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-babel) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-babel&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-babel) 4 | 5 | Transform files using [Babel](https://babeljs.io/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-babel 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-babel 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | babel(options?: TransformOptions) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [Babel options](https://babeljs.io/docs/usage/api/#options). 26 | 27 | ### Example 28 | 29 | ```js 30 | import sequence from '@start/plugin-sequence' 31 | import find from '@start/plugin-find' 32 | import read from '@start/plugin-read' 33 | import babel from '@start/plugin-lib-babel' 34 | import write from '@start/plugin-write' 35 | 36 | const babelConfig = { 37 | // … 38 | babelrc: false, 39 | sourceMaps: true, 40 | } 41 | 42 | export const task = () => 43 | sequence( 44 | find('src/**/*.js'), 45 | read, 46 | babel(babelConfig), 47 | write('build/') 48 | ) 49 | ``` 50 | -------------------------------------------------------------------------------- /packages/plugin-lib-babel/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFile, StartDataFilesProps } from '@start/plugin/src/' 2 | import { TransformOptions } from '@babel/core' 3 | 4 | export default (userOptions?: TransformOptions) => 5 | plugin('babel', ({ logPath }) => async ({ files }: StartDataFilesProps) => { 6 | const { transform } = await import('@babel/core') 7 | 8 | return { 9 | files: await Promise.all( 10 | files.reduce((result, file): StartDataFile[] => { 11 | const options: TransformOptions = { 12 | ...userOptions, 13 | ast: false, 14 | inputSourceMap: file.map != null ? file.map : false, 15 | filename: file.path 16 | } 17 | const transformed = transform(file.data, options) 18 | 19 | if (transformed !== null) { 20 | if (typeof transformed.code !== 'string') { 21 | return result 22 | } 23 | 24 | const dataFile: StartDataFile = { 25 | path: file.path, 26 | data: transformed.code 27 | } 28 | 29 | if (options.sourceMaps && transformed.map) { 30 | dataFile.map = transformed.map 31 | } 32 | 33 | logPath(file.path) 34 | 35 | result.push(dataFile) 36 | } 37 | 38 | return result 39 | }, [] as StartDataFile[]) 40 | ) 41 | } 42 | }) 43 | -------------------------------------------------------------------------------- /packages/plugin-lib-babel/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import babel from '../src' 4 | 5 | test('plugin-lib-babel: export', async (t) => { 6 | t.equals( 7 | typeof babel, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-codecov/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-codecov", 3 | "version": "0.4.0", 4 | "description": "💯 Send code coverage report to codecov.io", 5 | "keywords": "tasks, runner, start, start-plugin, coverage, codecov", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-codecov", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "codecov-lite": "^0.2.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-lib-codecov/readme.md: -------------------------------------------------------------------------------- 1 | # 💯 plugin-lib-codecov 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-codecov.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-codecov) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-codecov&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-codecov) 4 | 5 | Send code coverage report to [codecov.io](https://codecov.io/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-codecov 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-codecov 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Example 18 | 19 | ```js 20 | import sequence from '@start/plugin-sequence' 21 | import find from '@start/plugin-find' 22 | import read from '@start/plugin-read' 23 | import codecov from '@start/plugin-lib-codecov' 24 | 25 | export task = () => 26 | sequence( 27 | find('coverage/lcov.info'), 28 | read, 29 | codecov 30 | ) 31 | ``` 32 | -------------------------------------------------------------------------------- /packages/plugin-lib-codecov/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFilesProps } from '@start/plugin/src/' 2 | 3 | export default plugin('codecov', ({ logMessage }) => async ({ files }: StartDataFilesProps) => { 4 | const { default: codecovLite } = await import('codecov-lite') 5 | 6 | await Promise.all( 7 | files.map(async (file) => { 8 | const { reportURL } = await codecovLite(process.env, file.data) 9 | 10 | logMessage(reportURL) 11 | }) 12 | ) 13 | 14 | return files 15 | }) 16 | -------------------------------------------------------------------------------- /packages/plugin-lib-codecov/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import codecov from '../src' 4 | 5 | test('plugin-lib-codecov: export', async (t) => { 6 | t.equals( 7 | typeof codecov, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-eslint", 3 | "version": "0.4.3", 4 | "description": "🚷 Lint and/or fix code using ESLint", 5 | "keywords": "tasks, runner, start, start-plugin, eslint", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-eslint", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "eslint": "^5.16.0" 25 | }, 26 | "devDependencies": { 27 | "@types/eslint": "^4.16.6" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-eslint/readme.md: -------------------------------------------------------------------------------- 1 | # 🚷 plugin-lib-eslint 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-eslint.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-eslint) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-eslint&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-eslint) 4 | 5 | Lint and/or fix code using [ESLint](https://eslint.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-eslint 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-eslint 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | eslint(options?: {}, formatter?: string) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [ESLint CLIEngine options](https://eslint.org/docs/developer-guide/nodejs-api#cliengine). 26 | 27 | Default: 28 | 29 | ```js 30 | { 31 | cache: true, 32 | cacheLocation: 'node_modules/.cache/eslint' 33 | } 34 | ``` 35 | 36 | #### `formatter` 37 | 38 | [ESLint formatter](https://eslint.org/docs/developer-guide/nodejs-api#clienginegetformatter). 39 | 40 | ### Example 41 | 42 | ```js 43 | import sequence from '@start/plugin-sequence' 44 | import findGitStaged from '@start/plugin-find-git-staged' 45 | import read from '@start/plugin-read' 46 | import eslint from '@start/plugin-lib-eslint' 47 | 48 | export const task = () => 49 | sequence( 50 | findGitStaged('src/**/*.js'), 51 | read, 52 | eslint({ 53 | rules: { 54 | 'no-undef': 'error' 55 | } 56 | }) 57 | ) 58 | ``` 59 | 60 | ```js 61 | import sequence from '@start/plugin-sequence' 62 | import find from '@start/plugin-find' 63 | import read from '@start/plugin-read' 64 | import eslint from '@start/plugin-lib-eslint' 65 | import overwrite from '@start/plugin-overwrite' 66 | 67 | export const task = () => 68 | sequence( 69 | find('src/**/*.js'), 70 | read, 71 | eslint({ fix: true }), 72 | overwrite 73 | ) 74 | ``` 75 | -------------------------------------------------------------------------------- /packages/plugin-lib-eslint/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFilesProps, StartDataFile } from '@start/plugin/src/' 2 | import { CLIEngine } from 'eslint' 3 | 4 | export default (userOptions?: CLIEngine.Options, formatter = '') => 5 | plugin('eslint', ({ logMessage, logPath }) => async ({ files }: StartDataFilesProps) => { 6 | const { CLIEngine } = await import('eslint') 7 | const options: CLIEngine.Options = { 8 | cache: true, 9 | cacheLocation: 'node_modules/.cache/eslint', 10 | ...userOptions 11 | } 12 | 13 | const cli = new CLIEngine(options) 14 | const filesToCheck = files.filter((file) => !cli.isPathIgnored(file.path)) 15 | 16 | const report: CLIEngine.LintReport = filesToCheck.reduce((acc, file) => { 17 | const [result] = cli.executeOnText(file.data, file.path).results 18 | 19 | acc.results.push(result) 20 | acc.errorCount += result.errorCount 21 | acc.warningCount += result.warningCount 22 | acc.fixableErrorCount += result.fixableErrorCount 23 | acc.fixableWarningCount += result.fixableWarningCount 24 | 25 | return acc 26 | }, { 27 | results: [] as CLIEngine.LintResult[], 28 | errorCount: 0, 29 | warningCount: 0, 30 | fixableErrorCount: 0, 31 | fixableWarningCount: 0 32 | }) 33 | 34 | const format = cli.getFormatter(formatter) 35 | 36 | if (report.errorCount > 0 || report.warningCount > 0) { 37 | console.log(format(report.results)) 38 | } 39 | 40 | if (!options.fix && report.errorCount > 0) { 41 | throw null 42 | } 43 | 44 | if (options.fix && report.results.length > 0) { 45 | const fixedFiles = report.results 46 | .filter(({ output }) => typeof output === 'string') 47 | .map((result): StartDataFile => { 48 | logPath(result.filePath) 49 | 50 | return ({ 51 | path: result.filePath, 52 | data: result.output! 53 | }) 54 | }) 55 | 56 | if (fixedFiles.length === 0) { 57 | logMessage('¯\\_(ツ)_/¯') 58 | } 59 | 60 | return { 61 | files: fixedFiles 62 | } 63 | } 64 | 65 | if (report.errorCount === 0 && report.warningCount === 0) { 66 | logMessage('¯\\_(ツ)_/¯') 67 | } 68 | }) 69 | -------------------------------------------------------------------------------- /packages/plugin-lib-eslint/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import eslint from '../src' 4 | 5 | test('plugin-lib-eslint: export', async (t) => { 6 | t.equals( 7 | typeof eslint, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-esm-loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-esm-loader", 3 | "version": "0.2.1", 4 | "description": "🏭 Copy a predefined ESM loader file to a directory", 5 | "keywords": "tasks, runner, start, start-plugin, esm", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-esm-loader", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@start/plugin": "^0.3.1", 23 | "copie": "^0.3.0" 24 | }, 25 | "devDependencies": { 26 | "esm": "^3.2.22" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugin-lib-esm-loader/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-esm-loader 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-esm-loader.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-esm-loader) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-esm-loader&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-esm-loader) 4 | 5 | Copy a predefined [ESM loader](https://github.com/standard-things/esm) file to a directory. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-esm-loader 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-esm-loader 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | copyEsmLoader(outDir: string, filename: string = 'esm-loader.js') 21 | ``` 22 | 23 | ### Example 24 | 25 | ```json 26 | { 27 | "name": "my-package", 28 | "version": "1.0.0", 29 | "main": "build/esm-loader.js", 30 | "module": "build/index.js", 31 | "dependencies": { 32 | "esm": "^3.0.75" 33 | } 34 | } 35 | ``` 36 | 37 | ```js 38 | import sequence from '@start/plugin-sequence' 39 | import find from '@start/plugin-find' 40 | import read from '@start/plugin-read' 41 | import babel from '@start/plugin-lib-babel' 42 | import write from '@start/plugin-write' 43 | import copyEsmLoader from '@start/plugin-lib-esm-loader' 44 | 45 | const babelConfig = { 46 | // … 47 | babelrc: false, 48 | sourceMaps: true, 49 | presets: [ 50 | ['@babel/preset-env', { 51 | targets: { node: 6 }, 52 | modules: false 53 | }] 54 | ] 55 | } 56 | 57 | export const task = () => 58 | sequence( 59 | find('src/**/*.js'), 60 | read, 61 | babel(babelConfig), 62 | write('build/'), 63 | copyEsmLoader('build/') 64 | ) 65 | ``` 66 | -------------------------------------------------------------------------------- /packages/plugin-lib-esm-loader/src/esm-loader.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require = require('esm')(module) 3 | module.exports = require('./index.js') 4 | -------------------------------------------------------------------------------- /packages/plugin-lib-esm-loader/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | export default (outDir: string, filename: string = 'esm-loader.js') => 4 | plugin('esm-loader', ({ logPath }) => async () => { 5 | const path = await import('path') 6 | const { default: copie } = await import('copie') 7 | 8 | const loaderFilePath = require.resolve('./esm-loader.js') 9 | const outFile = path.resolve(outDir, filename) 10 | 11 | await copie(loaderFilePath, outFile) 12 | 13 | logPath(outFile) 14 | }) 15 | -------------------------------------------------------------------------------- /packages/plugin-lib-esm-loader/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import esm from '../src' 4 | 5 | test('plugin-lib-esm: export', async (t) => { 6 | t.equals( 7 | typeof esm, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-check/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-flow-check", 3 | "version": "0.3.1", 4 | "description": "🚷 Check types using Flow", 5 | "keywords": "tasks, runner, start, start-plugin, flow, flowtype", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-flow-check", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0" 25 | }, 26 | "devDependencies": { 27 | "@types/execa": "^0.9.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-check/readme.md: -------------------------------------------------------------------------------- 1 | # 🚷 plugin-lib-flow-check 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-flow-check.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-flow-check) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-flow-check&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-flow-check) 4 | 5 | Check types using [Flow](https://flow.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-flow-check 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-flow-check 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | flowGenerate(outDirRelative: string, ...flowArgs: string[]) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import sequence from '@start/plugin-sequence' 27 | import find from '@start/plugin-find' 28 | import flowGenerate from '@start/plugin-lib-flow-generate' 29 | 30 | export task = () => 31 | sequence( 32 | find('src/**/*.js'), 33 | flowGenerate('build/') 34 | ) 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-check/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | export default (...flowArgs: string[]) => 4 | plugin('flowCheck', () => async (props) => { 5 | const path = await import('path') 6 | const { default: execa } = await import('execa') 7 | 8 | const flowBinPath = path.resolve('node_modules/.bin/flow') 9 | 10 | const spawnOptions = { 11 | stdout: process.stdout, 12 | stderr: process.stderr, 13 | stripEof: false, 14 | env: { 15 | FORCE_COLOR: '1' 16 | } 17 | } 18 | 19 | try { 20 | await execa('node', [flowBinPath, 'check', ...flowArgs], spawnOptions) 21 | } catch (e) { 22 | throw null 23 | } 24 | 25 | return props 26 | }) 27 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-check/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import flowCheck from '../src' 4 | 5 | test('plugin-lib-flow-check: export', async (t) => { 6 | t.equals( 7 | typeof flowCheck, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-generate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-flow-generate", 3 | "version": "0.3.1", 4 | "description": "🏭 Generate `.js.flow` files using Flow", 5 | "keywords": "tasks, runner, start, start-plugin, flow, flowtype", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-flow-generate", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0" 25 | }, 26 | "devDependencies": { 27 | "@types/execa": "^0.9.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-generate/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-flow-generate 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-flow-generate.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-flow-generate) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-flow-generate&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-flow-generate) 4 | 5 | Generate `.js.flow` files using [Flow](https://flow.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-flow-generate 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-flow-generate 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | flowCheck(...flowArgs: string[]) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import flowGenerate from '@start/plugin-lib-flow-generate' 27 | 28 | export task = () => flowCheck() 29 | ``` 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-generate/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFile, StartFilesProps } from '@start/plugin/src/' 2 | 3 | export default (outDirRelative: string, ...flowArgs: string[]) => 4 | plugin('flowGenerate', ({ logPath }) => async ({ files }: StartFilesProps) => { 5 | const path = await import('path') 6 | const { default: execa } = await import('execa') 7 | 8 | const outDir = path.resolve(outDirRelative) 9 | const flowBinPath = path.resolve('node_modules/.bin/flow') 10 | 11 | const spawnOptions = { 12 | stripEof: false, 13 | env: { 14 | FORCE_COLOR: '1' 15 | } 16 | } 17 | 18 | return { 19 | files: await Promise.all( 20 | files.map(async (file): Promise => { 21 | try { 22 | await execa( 23 | 'node', 24 | [flowBinPath, 'gen-flow-files', file.path, '--out-dir', outDir, ...flowArgs], 25 | spawnOptions 26 | ) 27 | } catch (e) { 28 | throw null 29 | } 30 | 31 | const flowFilePath = path.join(outDir, `${path.basename(file.path)}.flow`) 32 | 33 | logPath(flowFilePath) 34 | 35 | return { 36 | path: flowFilePath 37 | } 38 | }) 39 | ) 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /packages/plugin-lib-flow-generate/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import flowGenerate from '../src' 4 | 5 | test('plugin-lib-flow-generate: export', async (t) => { 6 | t.equals( 7 | typeof flowGenerate, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-istanbul", 3 | "version": "0.6.0", 4 | "description": "💯 Collect, report and check code coverage using Istanbul", 5 | "keywords": "tasks, runner, start, start-plugin, coverage, istanbul", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-istanbul", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "@types/istanbul-lib-instrument": "^1.7.2", 25 | "convert-source-map": "^1.6.0", 26 | "istanbul-api": "^2.1.1", 27 | "istanbul-lib-coverage": "^2.0.3", 28 | "istanbul-lib-hook": "^2.0.3", 29 | "istanbul-lib-instrument": "^3.1.0", 30 | "istanbul-lib-report": "^2.0.4", 31 | "istanbul-lib-source-maps": "^3.0.2", 32 | "tsfn": "^0.1.1" 33 | }, 34 | "devDependencies": { 35 | "@types/convert-source-map": "^1.5.1", 36 | "@types/istanbul-lib-coverage": "^2.0.0", 37 | "@types/istanbul-lib-hook": "^1.0.0", 38 | "@types/istanbul-lib-report": "^1.1.0", 39 | "@types/istanbul-lib-source-maps": "^1.2.1" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/readme.md: -------------------------------------------------------------------------------- 1 | # 💯 plugin-lib-istanbul 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-istanbul.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-istanbul) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-istanbul&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-istanbul) 4 | 5 | Collect, report and check code coverage using [Istanbul](https://istanbul.js.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-istanbul 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-istanbul 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | istanbulInstrument(options?: InstrumenterOptions, extensions?: string[]) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [Istanbul instrumenter options](https://github.com/istanbuljs/istanbuljs/blob/9f8aebf1f08159df20358d77fe98c809d2027c5f/packages/istanbul-lib-instrument/src/instrumenter.js#L11-L42) 26 | 27 | #### `extensions` 28 | 29 | File extensions to instrument, for example `['.ts']` 30 | 31 | ```ts 32 | istanbulReports(formats: string[] = ['lcovonly', 'text-summary']) 33 | ``` 34 | 35 | ```ts 36 | istanbulThresholds(options: { 37 | branches?: number, 38 | functions?: number, 39 | lines?: number, 40 | statements?: number 41 | }) 42 | ``` 43 | 44 | ### Example 45 | 46 | ```js 47 | import sequence from '@start/plugin-sequence' 48 | import find from '@start/plugin-find' 49 | import { 50 | istanbulInstrument, 51 | istanbulReport, 52 | istanbulThresholds 53 | } from '@start/plugin-lib-istanbul' 54 | import tape from '@start/plugin-lib-tape' 55 | 56 | export const task = () => 57 | sequence( 58 | find('src/**/*.js'), 59 | istanbulInstrument({ esModules: true }), 60 | find('test/**/*.js'), 61 | tape(), 62 | istanbulReport(['lcovonly', 'html', 'text-summary']), 63 | istanbulThresholds({ functions: 100 }) 64 | ) 65 | ``` 66 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/src/hooks.ts: -------------------------------------------------------------------------------- 1 | let hooks: (() => void)[] = [] 2 | 3 | export const add = (hook: () => void) => { 4 | hooks.push(hook) 5 | } 6 | 7 | export const clearAll = () => { 8 | hooks = hooks.filter((hook) => { 9 | hook() 10 | 11 | return false 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as istanbulInstrument } from './instrument' 2 | export { default as istanbulReport } from './report' 3 | export { default as istanbulThresholds } from './thresholds' 4 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/src/instrument.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFilesProps } from '@start/plugin/src/' 2 | import { InstrumenterOptions } from 'istanbul-lib-instrument' 3 | 4 | export default (options?: Partial, extensions?: string[]) => 5 | plugin('istanbulInstrument', ({ logMessage }) => async ({ files }: StartFilesProps) => { 6 | const Module = await import('module') 7 | const { fromSource: getSourceMapFromSource } = await import('convert-source-map') 8 | const { createInstrumenter } = await import('istanbul-lib-instrument') 9 | const { hookRequire } = await import('istanbul-lib-hook') 10 | const hooks = await import('./hooks') 11 | const { default: coverageVariable } = await import('./variable') 12 | 13 | const instrumenter = createInstrumenter({ 14 | ...options, 15 | coverageVariable 16 | }) 17 | 18 | hooks.clearAll() 19 | 20 | // clear require cache 21 | files.forEach((file) => { 22 | // @ts-ignore 23 | delete Module._cache[file.path] 24 | }) 25 | 26 | const hook = hookRequire( 27 | // hook requires matches files files 28 | (file) => files.findIndex(({ path }) => file === path) !== -1, 29 | // and instrument that sources 30 | (source, options) => { 31 | const sourceMapRaw = getSourceMapFromSource(source) 32 | let sourceMapObject = null 33 | 34 | if (sourceMapRaw) { 35 | sourceMapObject = sourceMapRaw.toObject() 36 | } 37 | 38 | // @ts-ignore 39 | // TODO: update @types/istanbul-lib-hook 40 | return instrumenter.instrumentSync(source, options.file, sourceMapObject) 41 | }, 42 | { extensions } 43 | ) 44 | 45 | hooks.add(hook) 46 | 47 | logMessage('imports has been hooked') 48 | }) 49 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/src/report.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { CoverageMapData } from 'istanbul-lib-coverage' 3 | 4 | export default (formats: string[] = ['lcovonly', 'text-summary']) => 5 | plugin('istanbulReport', ({ logMessage }) => async () => { 6 | const { createCoverageMap } = await import('istanbul-lib-coverage') 7 | const { createSourceMapStore } = await import('istanbul-lib-source-maps') 8 | // @ts-ignore 9 | const { createReporter } = await import('istanbul-api') 10 | const hooks = await import('./hooks') 11 | const { default: coverageVariable } = await import('./variable') 12 | 13 | hooks.clearAll() 14 | 15 | const coverageMapData = (global as any)[coverageVariable] as CoverageMapData 16 | 17 | if (!coverageMapData) { 18 | logMessage('no coverage information was collected') 19 | 20 | return 21 | } 22 | 23 | const coverageMap = createCoverageMap(coverageMapData) 24 | const sourceMapStore = createSourceMapStore() 25 | const remappedCoverageMap = sourceMapStore.transformCoverage(coverageMap).map 26 | const reporter = createReporter() 27 | 28 | logMessage(formats.join(', ')) 29 | 30 | formats.forEach((format) => { 31 | reporter.add(format) 32 | reporter.write(remappedCoverageMap, {}) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/src/thresholds.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { CoverageMapData } from 'istanbul-lib-coverage' 3 | 4 | export type TOptions = { 5 | branches?: number, 6 | functions?: number, 7 | lines?: number, 8 | statements?: number, 9 | } 10 | 11 | export default (options: TOptions) => 12 | plugin('istanbulThresholds', ({ logMessage }) => async () => { 13 | const { createCoverageMap } = await import('istanbul-lib-coverage') 14 | const { createSourceMapStore } = await import('istanbul-lib-source-maps') 15 | const { summarizers } = await import('istanbul-lib-report') 16 | const { getObjectKeys } = await import('tsfn') 17 | const hooks = await import('./hooks') 18 | const { default: coverageVariable } = await import('./variable') 19 | 20 | hooks.clearAll() 21 | 22 | const coverageMapData = (global as any)[coverageVariable] as CoverageMapData 23 | 24 | if (!coverageMapData) { 25 | logMessage('no coverage information was collected') 26 | 27 | return 28 | } 29 | 30 | const coverageMap = createCoverageMap(coverageMapData) 31 | const sourceMapStore = createSourceMapStore() 32 | const remappedCoverageMap = sourceMapStore.transformCoverage(coverageMap).map 33 | 34 | const coverageSummary = summarizers 35 | .flat(remappedCoverageMap) 36 | .getRoot() 37 | .getCoverageSummary(true) 38 | 39 | const result = getObjectKeys(options).reduce((errors, key) => { 40 | const threshold = options[key] as number 41 | const summary = coverageSummary[key] 42 | 43 | // check percentage threshold 44 | if (threshold > 0) { 45 | if (summary.pct < threshold) { 46 | return errors.concat(`${key} percentage: ${summary.pct}% < ${threshold}%`) 47 | } 48 | } 49 | 50 | // check gap threshold 51 | if (threshold < 0) { 52 | if (summary.covered - summary.total < threshold) { 53 | return errors.concat(`${key} gap: ${summary.covered} - ${summary.total} < ${threshold}`) 54 | } 55 | } 56 | 57 | return errors 58 | }, [] as string[]) 59 | 60 | if (result.length > 0) { 61 | throw result 62 | } 63 | }) 64 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/src/variable.ts: -------------------------------------------------------------------------------- 1 | export default '__start_istanbul__' 2 | -------------------------------------------------------------------------------- /packages/plugin-lib-istanbul/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import { 4 | istanbulInstrument, 5 | istanbulReport, 6 | istanbulThresholds 7 | } from '../src' 8 | 9 | test('plugin-lib-istanbul: export', async (t) => { 10 | t.equals( 11 | typeof istanbulInstrument, 12 | 'function', 13 | 'must be a function' 14 | ) 15 | 16 | t.equals( 17 | typeof istanbulReport, 18 | 'function', 19 | 'must be a function' 20 | ) 21 | 22 | t.equals( 23 | typeof istanbulThresholds, 24 | 'function', 25 | 'must be a function' 26 | ) 27 | }) 28 | -------------------------------------------------------------------------------- /packages/plugin-lib-jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-jest", 3 | "version": "0.5.0", 4 | "description": "✅ Run tests using Jest", 5 | "keywords": "tasks, runner, start, start-plugin, jest", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-jest", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@jest/types": "^24.7.0", 24 | "@start/plugin": "^0.3.1", 25 | "jest-cli": "^24.7.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/plugin-lib-jest/readme.md: -------------------------------------------------------------------------------- 1 | # ✅ plugin-lib-jest 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-jest.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-jest) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-jest&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-jest) 4 | 5 | Run tests using [Jest](https://facebook.github.io/jest/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-jest 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-jest 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | jest(argv?: ArgvOptions) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [Jest "argv" options](https://github.com/facebook/jest/blob/ac8c345f5318016d0789974fbc815d857fd70d99/packages/jest-types/src/Config.ts#L417-L504). 26 | 27 | ### Example 28 | 29 | ```js 30 | import jest from '@start/plugin-lib-jest' 31 | 32 | export task () => jest({ 33 | browser: true 34 | }) 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/plugin-lib-jest/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { Config } from '@jest/types' 3 | 4 | export default (userArgv?: Config.Argv) => 5 | plugin('jest', () => async () => { 6 | const { runCLI } = await import('jest-cli') 7 | const { buildArgv } = await import('jest-cli/build/cli') 8 | const argv: Config.Argv = { 9 | ...buildArgv(), 10 | ...userArgv 11 | } 12 | const projects = argv.projects || [argv.rootDir || process.cwd()] 13 | const result = await runCLI(argv, projects) 14 | 15 | if ( 16 | result.results.numFailedTests > 0 || 17 | result.results.numFailedTestSuites > 0 || 18 | result.results.numTotalTests === 0 19 | ) { 20 | throw null 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /packages/plugin-lib-jest/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import jest from '../src' 4 | 5 | test('plugin-lib-jest: export', async (t) => { 6 | t.equals( 7 | typeof jest, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-karma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-karma", 3 | "version": "0.3.1", 4 | "description": "✅ Run tests using Karma", 5 | "keywords": "tasks, runner, start, start-plugin, karma", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-karma", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "karma": "^2.0.2" 25 | }, 26 | "devDependencies": { 27 | "@types/karma": "^3.0.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-karma/readme.md: -------------------------------------------------------------------------------- 1 | # ✅ plugin-lib-karma 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-karma.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-karma) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-karma&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-karma) 4 | 5 | Run tests using [Karma](https://github.com/karma-runner/karma). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-karma 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-karma 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | karma(options: {}) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [Karma config options](https://karma-runner.github.io/2.0/config/configuration-file.html). 26 | 27 | ### Example 28 | 29 | ```js 30 | import karma from '@start/plugin-lib-karma' 31 | 32 | export const task = () => karma({ 33 | browsers: [ 'Chrome', 'Firefox' ], 34 | files: [ 35 | 'test/index.js' 36 | ], 37 | singleRun: true 38 | }) 39 | ``` 40 | -------------------------------------------------------------------------------- /packages/plugin-lib-karma/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { ConfigOptions } from 'karma' 3 | 4 | export default (options: ConfigOptions) => 5 | plugin('karma', () => async () => { 6 | const { Server } = await import('karma') 7 | 8 | await new Promise((resolve, reject) => { 9 | const karmaServer = new Server(options) 10 | 11 | karmaServer.on('run_complete', (browsers, results) => { 12 | if (results.exitCode !== 0) { 13 | reject(null) 14 | } else { 15 | resolve() 16 | } 17 | }) 18 | 19 | karmaServer.start() 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /packages/plugin-lib-karma/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import karma from '../src' 4 | 5 | test('plugin-lib-karma: export', async (t) => { 6 | t.equals( 7 | typeof karma, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-publish/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-npm-publish", 3 | "version": "0.3.1", 4 | "description": "📦 Publish package to NPM", 5 | "keywords": "tasks, runner, start, start-plugin, npm", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-npm-publish", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0" 25 | }, 26 | "devDependencies": { 27 | "@types/execa": "^0.9.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-publish/readme.md: -------------------------------------------------------------------------------- 1 | # 📦 plugin-lib-npm-publish 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-npm-publish.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-npm-publish) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-npm-publish&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-npm-publish) 4 | 5 | Publish package to NPM. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-npm-publish 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-npm-publish 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | npmPublish(packagePath: string, options?: {}) 21 | ``` 22 | 23 | #### `packagePath` 24 | 25 | Relative path to package, `.` by default. 26 | 27 | #### `options` 28 | 29 | [NPM publish options](https://docs.npmjs.com/cli/publish) 30 | 31 | Default: 32 | 33 | ```js 34 | { 35 | registry: 'https://registry.npmjs.org/' 36 | } 37 | ``` 38 | 39 | ### Example 40 | 41 | ```js 42 | import npmPublish from '@start/plugin-npm-plugin-lib-npm-publish' 43 | 44 | export task = (packageName) => npmPublish(`packages/${packageName}`) 45 | ``` 46 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-publish/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | type Options = { 4 | [key: string]: boolean | string 5 | } 6 | 7 | // https://docs.npmjs.com/cli/publish 8 | export default (packagePath: string = '.', userOptions?: Options) => 9 | plugin('npmPublish', () => async () => { 10 | const { default: execa } = await import('execa') 11 | 12 | const options: Options = { 13 | registry: 'https://registry.npmjs.org/', 14 | ...userOptions 15 | } 16 | const cliArgs = Object.keys(options).reduce((result, key) => { 17 | const value = options[key] 18 | 19 | if (typeof value === 'boolean') { 20 | return result.concat(`--${key}`) 21 | } 22 | 23 | if (typeof value === 'string') { 24 | return result.concat(`--${key}`, `${value}`) 25 | } 26 | 27 | return result 28 | }, [] as string[]) 29 | 30 | try { 31 | await execa('npm', ['publish', ...cliArgs, packagePath], { 32 | stdout: process.stdout, 33 | stderr: process.stderr, 34 | stripEof: false, 35 | env: { 36 | FORCE_COLOR: '1' 37 | } 38 | }) 39 | } catch (e) { 40 | throw null 41 | } 42 | }) 43 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-publish/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import npmPublish from '../src' 4 | 5 | test('plugin-lib-npm-publish: export', async (t) => { 6 | t.equals( 7 | typeof npmPublish, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-version/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-npm-version", 3 | "version": "0.3.1", 4 | "description": "🔢 Bump package version", 5 | "keywords": "tasks, runner, start, start-plugin, npm", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-npm-version", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0" 25 | }, 26 | "devDependencies": { 27 | "@types/execa": "^0.9.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-version/readme.md: -------------------------------------------------------------------------------- 1 | # 🔢 plugin-lib-npm-version 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-npm-version.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-npm-version) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-npm-version&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-npm-version) 4 | 5 | Bump package version. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-npm-version 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-npm-version 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | npmVersion(version: string, options?: {) 21 | ``` 22 | 23 | #### `version` 24 | 25 | ` | major | minor | patch | premajor | premin 26 | or | prepatch | prerelease | from-git` 27 | 28 | #### `options` 29 | 30 | [NPM version options](https://docs.npmjs.com/cli/version). 31 | 32 | ### Example 33 | 34 | ```js 35 | import npmVersion from '@start/plugin-npm-plugin-lib-npm-version' 36 | 37 | export task = (version) => npmVersion(version, { message: '📦 v%s' }) 38 | ``` 39 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-version/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | type Options = { 4 | packagePath?: string, 5 | [key: string]: boolean | string | undefined 6 | } 7 | 8 | // https://docs.npmjs.com/cli/version 9 | export default (version: string, userOptions?: Options) => 10 | plugin('npmVersion', () => async () => { 11 | const { default: execa } = await import('execa') 12 | 13 | const { packagePath, ...options } = { 14 | packagePath: '.', 15 | ...userOptions 16 | } as Options 17 | const cliArgs = Object.keys(options).reduce((result, key) => { 18 | const value = options[key] 19 | 20 | if (typeof value === 'boolean') { 21 | return result.concat(`--${key}`) 22 | } 23 | 24 | if (typeof value === 'string') { 25 | return result.concat(`--${key}`, `${value}`) 26 | } 27 | 28 | return result 29 | }, [] as string[]) 30 | 31 | try { 32 | await execa('npm', ['version', ...cliArgs, version], { 33 | cwd: packagePath, 34 | stdout: process.stdout, 35 | stderr: process.stderr, 36 | stripEof: false, 37 | env: { 38 | FORCE_COLOR: '1' 39 | } 40 | }) 41 | } catch (e) { 42 | throw null 43 | } 44 | }) 45 | -------------------------------------------------------------------------------- /packages/plugin-lib-npm-version/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import npmVersion from '../src' 4 | 5 | test('plugin-lib-npm-version: export', async (t) => { 6 | t.equals( 7 | typeof npmVersion, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-postcss/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-postcss", 3 | "version": "0.2.1", 4 | "description": "🏭 Transform files using PostCSS", 5 | "keywords": "tasks, runner, start, start-plugin, postcss", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-postcss", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "postcss": "^6.0.23" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-lib-postcss/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-postcss 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-postcss.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-postcss) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-postcss&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-postcss) 4 | 5 | Transform files using [PostCSS](https://postcss.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-postcss 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-postcss 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | postcss(options?: {}) 21 | ``` 22 | 23 | #### `options` 24 | 25 | * `plugins` – an array of [PostCSS plugins](https://github.com/postcss/postcss#plugins) 26 | * `sourceMaps` – boolean whether to process source maps or not 27 | * `parser`, `stringifier`, `syntax` – [PostCSS options](https://github.com/postcss/postcss#options) 28 | 29 | ### Example 30 | 31 | ```js 32 | import sequence from '@start/plugin-sequence' 33 | import find from '@start/plugin-find' 34 | import read from '@start/plugin-read' 35 | import postcss from '@start/plugin-lib-postcss' 36 | import write from '@start/plugin-write' 37 | 38 | import autoprefixer from 'autoprefixer' 39 | 40 | export const task = () => 41 | sequence( 42 | find('src/**/*.css'), 43 | read, 44 | postcss({ 45 | plugins: [autoprefixer], 46 | sourceMaps: true 47 | }), 48 | write('build/') 49 | ) 50 | ``` 51 | -------------------------------------------------------------------------------- /packages/plugin-lib-postcss/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFilesProps } from '@start/plugin/src/' 2 | import { AcceptedPlugin, ProcessOptions } from 'postcss' 3 | 4 | export type Options = { 5 | plugins?: AcceptedPlugin[], 6 | sourceMaps?: boolean, 7 | parser?: ProcessOptions['parser'], 8 | stringifier?: ProcessOptions['stringifier'], 9 | syntax?: ProcessOptions['syntax'] 10 | } 11 | 12 | export default (options?: Options) => 13 | plugin('postcss', ({ logMessage, logPath }) => async ({ files }: StartDataFilesProps) => { 14 | const { default: postcss } = await import('postcss') 15 | 16 | return { 17 | files: await Promise.all( 18 | files.map((file) => { 19 | const realOptions: ProcessOptions = { 20 | from: file.path, 21 | to: file.path 22 | } 23 | 24 | if (options && options.sourceMaps) { 25 | realOptions.map = { 26 | inline: false, 27 | annotation: false 28 | } 29 | } 30 | 31 | if (file.map !== null) { 32 | realOptions.map = { 33 | ...realOptions.map, 34 | prev: file.map 35 | } 36 | } 37 | 38 | const plugins = options && options.plugins 39 | const result = postcss(plugins).process(file.data, realOptions) 40 | 41 | logPath(file.path) 42 | 43 | return { 44 | path: file.path, 45 | data: result.css, 46 | map: result.map 47 | } 48 | }) 49 | ) 50 | } 51 | }) 52 | -------------------------------------------------------------------------------- /packages/plugin-lib-postcss/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import postcss from '../src' 4 | 5 | test('plugin-lib-postcss: export', async (t) => { 6 | t.equals( 7 | typeof postcss, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-prettier-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-prettier-eslint", 3 | "version": "0.3.1", 4 | "description": "🚷 Fix code(style) using Prettier + ESLint", 5 | "keywords": "tasks, runner, start, start-plugin, prettier, eslint", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-prettier-eslint", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "prettier-eslint": "^8.8.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-lib-prettier-eslint/readme.md: -------------------------------------------------------------------------------- 1 | # 🚷 plugin-lib-prettier-eslint 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-prettier-eslint.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-prettier-eslint) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-prettier-eslint&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-prettier-eslint) 4 | 5 | Fix code(style) using [Prettier + ESLint](https://github.com/prettier/prettier-eslint). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-prettier-eslint 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-prettier-eslint 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | prettierEslint(options?: {}) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [prettier-eslint options](https://github.com/prettier/prettier-eslint#options). 26 | 27 | ### Example 28 | 29 | ```js 30 | import sequence from '@start/plugin-sequence' 31 | import find from '@start/plugin-find' 32 | import read from '@start/plugin-read' 33 | import prettierEslint from '@start/plugin-lib-prettier-eslint' 34 | import overwrite from '@start/plugin-overwrite' 35 | 36 | export const task = () => 37 | sequence( 38 | find('src/**/*.js'), 39 | read, 40 | prettierEslint(), 41 | overwrite 42 | ) 43 | ``` 44 | -------------------------------------------------------------------------------- /packages/plugin-lib-prettier-eslint/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFile, StartFilesProps } from '@start/plugin/src/' 2 | 3 | type Options = { 4 | [key: string]: any 5 | } 6 | 7 | export default (options?: Options) => 8 | plugin('prettierEslint', ({ logPath }) => async ({ files }: StartFilesProps) => { 9 | // @ts-ignore 10 | const { default: format } = await import('prettier-eslint') 11 | 12 | return { 13 | files: await Promise.all( 14 | files.map((file) => 15 | new Promise((resolve, reject) => { 16 | const formatted: string = format({ ...options, filePath: file.path, text: file.data }) 17 | 18 | if (file.data !== formatted) { 19 | logPath(file.path) 20 | } 21 | 22 | resolve({ 23 | ...file, 24 | data: formatted 25 | }) 26 | }) 27 | ) 28 | ) 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /packages/plugin-lib-prettier-eslint/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import prettierEslint from '../src' 4 | 5 | test('plugin-lib-prettier-eslint: export', async (t) => { 6 | t.equals( 7 | typeof prettierEslint, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-rollup", 3 | "version": "0.2.1", 4 | "description": "🏭 Bundle files using Rollup", 5 | "keywords": "tasks, runner, start, start-plugin, rollup", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-rollup", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "rollup": "^0.62.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-lib-rollup/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-rollup 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-rollup.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-rollup) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-rollup&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-rollup) 4 | 5 | Bundle files using [Rollup](https://rollupjs.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-rollup 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-rollup 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | rollup(config: {}) 21 | ``` 22 | 23 | #### `config` 24 | 25 | [Rollup configuration](https://rollupjs.org/guide/en#configuration-files). 26 | 27 | ### Example 28 | 29 | ```js 30 | import sequence from '@start/plugin-sequence' 31 | import env from '@start/plugin-env' 32 | import rollup from '@start/plugin-lib-rollup' 33 | 34 | export const task = async () => { 35 | const { default: rollupConfig } = await import('./rollup.config') 36 | 37 | return sequence( 38 | env('NODE_ENV', 'production'), 39 | rollup(rollupConfig) 40 | ) 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /packages/plugin-lib-rollup/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { RollupFileOptions } from 'rollup' 3 | 4 | export default (config: RollupFileOptions) => 5 | plugin('rollup', () => async () => { 6 | const { rollup } = await import('rollup') 7 | 8 | const bundle = await rollup(config) 9 | 10 | if (typeof config.output === 'undefined') { 11 | throw new Error('config output is not defined') 12 | } 13 | 14 | await bundle.write(config.output) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/plugin-lib-rollup/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import rollup from '../src' 4 | 5 | test('plugin-lib-rollup: export', async (t) => { 6 | t.equals( 7 | typeof rollup, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-tape/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-tape", 3 | "version": "0.3.2", 4 | "description": "✅ Run tests using Tape", 5 | "keywords": "tasks, runner, start, start-plugin, tap", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-tape", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "tape": "^4.10.1", 25 | "through": "^2.3.8" 26 | }, 27 | "devDependencies": { 28 | "@types/tape": "^4.2.33", 29 | "@types/through": "^0.0.29" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugin-lib-tape/readme.md: -------------------------------------------------------------------------------- 1 | # ✅ plugin-lib-tape 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-tape.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-tape) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-tape&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-tape) 4 | 5 | Run tests using [Tape](https://github.com/substack/tape). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-tape 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-tape 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | tape(reporter?: () => NodeJS.ReadWriteStream) 21 | ``` 22 | 23 | #### `reporter` 24 | 25 | [TAP compatible reporter](https://github.com/substack/tape#pretty-reporters). 26 | 27 | ### Example 28 | 29 | ```js 30 | import sequence from '@start/plugin-sequence' 31 | import find from '@start/plugin-find' 32 | import tape from '@start/plugin-lib-tape' 33 | import tapDiff from 'tap-diff' 34 | 35 | export const task = () => 36 | sequence( 37 | find('test/**/*.js'), 38 | tape(tapDiff) 39 | ) 40 | ``` 41 | -------------------------------------------------------------------------------- /packages/plugin-lib-tape/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFilesProps } from '@start/plugin/src/' 2 | 3 | export default (reporter?: () => NodeJS.ReadWriteStream) => 4 | plugin('tape', () => async ({ files }: StartFilesProps) => { 5 | const path = await import('path') 6 | const { default: test } = await import('tape') 7 | const { default: through } = await import('through') 8 | 9 | return new Promise((resolve, reject) => { 10 | const stream = test.createStream() 11 | // @ts-ignore 12 | const results = test.getHarness()._results 13 | 14 | if (typeof reporter === 'function') { 15 | stream.pipe(reporter()).pipe(process.stdout) 16 | } else { 17 | stream.pipe(process.stdout) 18 | } 19 | 20 | results.once('done', function (this: any) { 21 | this._stream.queue(`\n1..${this.count}\n`) 22 | this._stream.queue(`# tests ${this.count}\n`) 23 | this._stream.queue(`# pass ${this.pass}`) 24 | 25 | if (this.fail > 0) { 26 | this._stream.queue(`# fail ${this.fail}\n`) 27 | } else { 28 | this._stream.queue('\n# ok\n') 29 | } 30 | 31 | this._stream.once('end', () => { 32 | const hasFailed = this.fail > 0 33 | 34 | this.count = 0 35 | this.fail = 0 36 | this.pass = 0 37 | this.tests = [] 38 | this._stream = through() 39 | 40 | if (hasFailed) { 41 | reject(null) 42 | } else { 43 | resolve() 44 | } 45 | }) 46 | this._stream.queue(null) 47 | }) 48 | 49 | files.forEach((file) => require(path.resolve(file.path))) 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /packages/plugin-lib-tape/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import tape from '../src' 4 | 5 | test('plugin-lib-tape: export', async (t) => { 6 | t.equals( 7 | typeof tape, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-check/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-typescript-check", 3 | "version": "0.3.1", 4 | "description": "🚷 Check types using TypeScript", 5 | "keywords": "tasks, runner, start, start-plugin, typescript", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-typescript-check", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0" 25 | }, 26 | "devDependencies": { 27 | "@types/execa": "^0.9.0" 28 | }, 29 | "peerDependencies": { 30 | "typescript": "*" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-check/readme.md: -------------------------------------------------------------------------------- 1 | # 🚷 plugin-lib-typescript-check 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-typescript-check.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-typescript-check) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-typescript-check&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-typescript-check) 4 | 5 | Check types using [TypeScript](https://www.typescriptlang.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-typescript-check 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-typescript-check 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | typescriptCheck(options?: {}) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [TypeScript Compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html). 26 | 27 | Default: 28 | 29 | ```js 30 | { 31 | allowSyntheticDefaultImports: true, 32 | lib: 'esnext', 33 | moduleResolution: 'node', 34 | pretty: true 35 | } 36 | ``` 37 | 38 | ### Example 39 | 40 | ```js 41 | import typescriptCheck from '@start/plugin-lib-typescript-check' 42 | 43 | export const task = () => typescriptCheck() 44 | ``` 45 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-check/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | export type Options = { 4 | [key: string]: boolean | string | string[] 5 | } 6 | 7 | export default (userOptions?: Options) => 8 | plugin('typescriptCheck', () => async () => { 9 | const path = await import('path') 10 | const { default: execa } = await import('execa') 11 | 12 | const tscBinPath = path.resolve('node_modules/.bin/tsc') 13 | const spawnOptions = { 14 | stripEof: false, 15 | env: { 16 | FORCE_COLOR: '1' 17 | } 18 | } 19 | const options: Options = { 20 | allowSyntheticDefaultImports: true, 21 | lib: 'esnext', 22 | moduleResolution: 'node', 23 | pretty: true, 24 | ...userOptions, 25 | noEmit: true 26 | } 27 | const tscArgs = Object.keys(options).reduce((result, key) => { 28 | const value = options[key] 29 | 30 | if (typeof value === 'boolean') { 31 | return result.concat(`--${key}`) 32 | } 33 | 34 | if (typeof value === 'string') { 35 | return result.concat(`--${key}`, `${value}`) 36 | } 37 | 38 | if (Array.isArray(value)) { 39 | return result.concat(`--${key}`, `${value.join(',')}`) 40 | } 41 | 42 | return result 43 | }, [] as string[]) 44 | 45 | await execa(tscBinPath, tscArgs, spawnOptions) 46 | }) 47 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-check/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import typescriptCheck from '../src' 4 | 5 | test('plugin-lib-typescript-check: export', async (t) => { 6 | t.equals( 7 | typeof typescriptCheck, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-generate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-typescript-generate", 3 | "version": "0.4.1", 4 | "description": "🏭 Generate `.d.ts` files using TypeScript", 5 | "keywords": "tasks, runner, start, start-plugin, typescript", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-typescript-generate", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1" 24 | }, 25 | "peerDependencies": { 26 | "typescript": "*" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-generate/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-typescript-generate 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-typescript-generate.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-typescript-generate) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-typescript-generate&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-typescript-generate) 4 | 5 | Generate `.d.ts` files using [TypeScript](https://www.typescriptlang.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-typescript-generate 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-typescript-generate 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | typescriptGenerate(outDir: string, options?: CompilerOptions) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [TypeScript Compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html). 26 | 27 | Default: 28 | 29 | ```js 30 | { 31 | allowSyntheticDefaultImports: true, 32 | lib: 'esnext', 33 | moduleResolution: 'node' 34 | } 35 | ``` 36 | 37 | ### Example 38 | 39 | ```js 40 | import sequence from '@start/plugin-sequence' 41 | import find from '@start/plugin-find' 42 | import typescriptGenerate from '@start/plugin-lib-typescript-generate' 43 | 44 | export const task = () => 45 | sequence( 46 | find('src/index.ts'), 47 | typescriptGenerate('build/') 48 | ) 49 | ``` 50 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-generate/src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ScriptTarget, 3 | ModuleResolutionKind, 4 | getPreEmitDiagnostics, 5 | flattenDiagnosticMessageText, 6 | CompilerOptions, 7 | ModuleKind 8 | } from 'typescript' 9 | import plugin, { StartFile, StartFilesProps } from '@start/plugin/src/' 10 | 11 | // https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API 12 | export default (outDirRelative: string, userOptions?: CompilerOptions) => 13 | plugin('typescriptGenerate', ({ logPath }) => async ({ files }: StartFilesProps) => { 14 | const { createProgram } = await import('typescript') 15 | const path = await import('path') 16 | const options = { 17 | allowSyntheticDefaultImports: true, 18 | esModuleInterop: true, 19 | moduleResolution: ModuleResolutionKind.NodeJs, 20 | target: ScriptTarget.ESNext, 21 | module: ModuleKind.ESNext, 22 | ...userOptions, 23 | declarationDir: path.resolve(outDirRelative), 24 | declaration: true, 25 | emitDeclarationOnly: true 26 | } 27 | const filePaths = files.map((file: StartFile) => file.path) 28 | 29 | filePaths.forEach(logPath) 30 | 31 | const program = createProgram(filePaths, options) 32 | const emitResult = program.emit() 33 | const allDiagnostics = getPreEmitDiagnostics(program).concat(emitResult.diagnostics) 34 | 35 | allDiagnostics.forEach((diagnostic) => { 36 | if (diagnostic.file) { 37 | const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!) 38 | const message = flattenDiagnosticMessageText(diagnostic.messageText, '\n') 39 | 40 | console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`) 41 | } else { 42 | console.log(`${flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`) 43 | } 44 | }) 45 | 46 | return { files } 47 | }) 48 | -------------------------------------------------------------------------------- /packages/plugin-lib-typescript-generate/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import typescriptGenerate from '../src' 4 | 5 | test('plugin-lib-typescript-generate: export', async (t) => { 6 | t.equals( 7 | typeof typescriptGenerate, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-dev-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-webpack-dev-server", 3 | "version": "0.1.1", 4 | "description": "🏭 Run Webpack development server", 5 | "keywords": "tasks, runner, start, start-plugin, webpack", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-webpack-dev-server", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "webpack-dev-server": "^3.2.1" 25 | }, 26 | "devDependencies": { 27 | "@types/webpack": "^4.4.27", 28 | "@types/webpack-dev-server": "^3.1.5", 29 | "webpack": "^4.29.6" 30 | }, 31 | "peerDependencies": { 32 | "webpack": "^4.29.6" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-dev-server/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-webpack-dev-server 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-webpack-dev-server.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-webpack-dev-server) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-webpack-dev-server&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-webpack-dev-server) 4 | 5 | Run [Webpack development server](https://github.com/webpack/webpack-dev-server). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-webpack-dev-server 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-webpack-dev-server 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | webpackServe(config: WebpackConfig, devServerConfig?: WebpackDevServerConfig) 21 | ``` 22 | 23 | #### `config` 24 | 25 | [webpack config](https://webpack.js.org/configuration#options). 26 | 27 | #### `devServerConfig` 28 | 29 | [webpack `devServer` config](https://webpack.js.org/configuration/dev-server). 30 | 31 | Default: 32 | 33 | ```js 34 | { 35 | host: '127.0.0.1', 36 | port: 8080 37 | } 38 | ``` 39 | 40 | ### Example 41 | 42 | ```js 43 | import sequence from '@start/plugin-sequence' 44 | import env from '@start/plugin-env' 45 | import webpackDevServer from '@start/plugin-lib-webpack-dev-server' 46 | 47 | export const task = async () => { 48 | const { default: webpackDevConfig } = await import('./webpack.dev') 49 | 50 | return sequence( 51 | env({ NODE_ENV: 'development' }), 52 | webpackDevServer( 53 | webpackConfig, 54 | { 55 | hot: true, 56 | port: 3000 57 | } 58 | ) 59 | ) 60 | } 61 | ``` 62 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-dev-server/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { Configuration as WebpackConfig } from 'webpack' 3 | import { Configuration as TWebpackDevServerConfig } from 'webpack-dev-server' 4 | 5 | export type TWebpackConfig = WebpackConfig & { 6 | devServer?: TWebpackDevServerConfig 7 | } 8 | 9 | export default (config: TWebpackConfig, devServerConfig?: TWebpackDevServerConfig) => 10 | plugin('webpackDevServer', ({ logMessage }) => async () => { 11 | const { default: Webpack } = await import('webpack') 12 | const { default: WebpackDevServer } = await import('webpack-dev-server') 13 | 14 | const compiler = Webpack(config) 15 | const { host, port, ...options }: TWebpackDevServerConfig = { 16 | host: '127.0.0.1', 17 | port: 8080, 18 | ...config.devServer, 19 | ...devServerConfig 20 | } 21 | const server = new WebpackDevServer(compiler, options) 22 | let isDone = false 23 | 24 | await new Promise((resolve, reject) => { 25 | compiler.hooks.done.tap('done', () => { 26 | if (!isDone) { 27 | logMessage(`http://${host}:${port}/`) 28 | } 29 | 30 | isDone = true 31 | 32 | resolve() 33 | }) 34 | 35 | server 36 | .listen(port, host, (error) => { 37 | if (error) { 38 | reject(error) 39 | } 40 | }) 41 | .on('error', reject) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-dev-server/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import webpackDevServer from '../src' 4 | 5 | test('plugin-lib-webpack-dev-server: export', async (t) => { 6 | t.equals( 7 | typeof webpackDevServer, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-serve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-webpack-serve", 3 | "version": "0.4.1", 4 | "description": "🏭 Run Webpack development server", 5 | "keywords": "tasks, runner, start, start-plugin, webpack", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-webpack-serve", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "webpack-serve": "^2.0.3" 25 | }, 26 | "devDependencies": { 27 | "@types/webpack-serve": "^2.0.1", 28 | "webpack": "^4.29.6" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-serve/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-webpack-serve 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-webpack-serve.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-webpack-serve) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-webpack-serve&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-webpack-serve) 4 | 5 | Run [Webpack development server](https://github.com/webpack-contrib/webpack-serve). 6 | 7 | **⚠️ Deprecated in favor of [plugin-webpack-dev-server](https://github.com/deepsweet/start/tree/master/packages/plugin-lib-webpack-dev-server)** 8 | 9 | ## Install 10 | 11 | ```sh 12 | $ yarn add --dev @start/plugin-lib-webpack-serve 13 | # or 14 | $ npm install --save-dev @start/plugin-lib-webpack-serve 15 | ``` 16 | 17 | ## Usage 18 | 19 | ### Signature 20 | 21 | ```ts 22 | webpackServe(options: {}, argv?: {}, ) 23 | ``` 24 | 25 | #### `options` 26 | 27 | [webpack-serve options](https://github.com/webpack-contrib/webpack-serve#serveoptions). 28 | 29 | #### `argv` 30 | 31 | [webpack-serve argv](https://github.com/webpack-contrib/webpack-serve#argv). 32 | 33 | ### Example 34 | 35 | ```js 36 | import sequence from '@start/plugin-sequence' 37 | import env from '@start/plugin-env' 38 | import webpackServe from '@start/plugin-lib-webpack-serve' 39 | 40 | export const task = async () => { 41 | const { default: webpackConfig } = await import('./webpack.config') 42 | 43 | return sequence( 44 | env({ NODE_ENV: 'development' }), 45 | webpackServe({ config: webpackConfig }) 46 | ) 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-serve/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { Options as TOptions } from 'webpack-serve' 3 | 4 | export default (options: TOptions, argv: {} = {}) => 5 | plugin('webpackServe', () => async () => { 6 | const { default: serve } = await import('webpack-serve') 7 | 8 | await serve(argv, options) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack-serve/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import webpackServe from '../src' 4 | 5 | test('plugin-lib-webpack-serve: export', async (t) => { 6 | t.equals( 7 | typeof webpackServe, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-lib-webpack", 3 | "version": "0.3.2", 4 | "description": "🏭 Bundle files using Webpack", 5 | "keywords": "tasks, runner, start, start-plugin, webpack", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-lib-webpack", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "makethen": "^0.3.0", 25 | "webpack": "^4.29.6" 26 | }, 27 | "devDependencies": { 28 | "@types/webpack": "^4.4.26" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack/readme.md: -------------------------------------------------------------------------------- 1 | # 🏭 plugin-lib-webpack 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-lib-webpack.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-lib-webpack) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-lib-webpack&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-lib-webpack) 4 | 5 | Bundle files using [Webpack](https://webpack.js.org/). 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-lib-webpack 11 | # or 12 | $ npm install --save-dev @start/plugin-lib-webpack 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | webpack(config: Configuration, statsOptions?: StatsOptions) 21 | ``` 22 | 23 | #### `config` 24 | 25 | [webpack configuration](https://webpack.js.org/configuration/). 26 | 27 | #### `statsOptions` 28 | 29 | [webpack stats options](https://webpack.js.org/configuration/stats/#stats). 30 | 31 | Default: 32 | 33 | ```js 34 | { 35 | colors: true 36 | } 37 | ``` 38 | 39 | ### Example 40 | 41 | ```js 42 | import sequence from '@start/plugin-sequence' 43 | import env from '@start/plugin-env' 44 | import webpack from '@start/plugin-lib-webpack' 45 | 46 | export const task = async () => { 47 | const { default: webpackConfig } = await import('./webpack.config') 48 | 49 | return sequence( 50 | env('NODE_ENV', 'production'), 51 | webpack(webpackConfig) 52 | ) 53 | } 54 | ``` 55 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { Configuration, Stats } from 'webpack' 3 | 4 | type Webpack = (options: Configuration, cb: (err: any, stats: Stats) => void) => void 5 | 6 | export default (config: Configuration, userStatsOptions?: Stats.ToStringOptionsObject) => 7 | plugin('webpack', () => async () => { 8 | const { default: makethen } = await import('makethen') 9 | const { default: webpackLib } = await import('webpack') 10 | const compiler = makethen(webpackLib as Webpack) 11 | 12 | const statsOptions: Stats.ToStringOptionsObject = { 13 | colors: true, 14 | ...userStatsOptions 15 | } 16 | const stats = await compiler(config) 17 | 18 | console.log(stats.toString(statsOptions)) 19 | 20 | if (stats.hasErrors()) { 21 | throw null 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /packages/plugin-lib-webpack/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import webpack from '../src' 4 | 5 | test('plugin-lib-webpack: export', async (t) => { 6 | t.equals( 7 | typeof webpack, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-overwrite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-overwrite", 3 | "version": "0.3.1", 4 | "description": "✏️ Overwrite files", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-overwrite", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "graceful-fs": "^4.1.15" 25 | }, 26 | "devDependencies": { 27 | "@types/graceful-fs": "^4.1.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-overwrite/readme.md: -------------------------------------------------------------------------------- 1 | # ✏️ plugin-overwrite 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-overwrite.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-overwrite) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-overwrite&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-overwrite) 4 | 5 | Overwrite files. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-overwrite 11 | # or 12 | $ npm install --save-dev @start/plugin-overwrite 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Example 18 | 19 | ```js 20 | import sequence from '@start/plugin-sequence' 21 | import find from '@start/plugin-find' 22 | import eslint from '@start/plugin-lib-eslint' 23 | import overwrite from '@start/plugin-overwrite' 24 | 25 | export const task = () => 26 | sequence( 27 | find('src/**/*.js'), 28 | eslint({ fix: true }), 29 | overwrite 30 | ) 31 | ``` 32 | -------------------------------------------------------------------------------- /packages/plugin-overwrite/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFilesProps } from '@start/plugin/src/' 2 | 3 | export default plugin('overwrite', ({ logPath }) => async ({ files }: StartDataFilesProps) => { 4 | const { promisify } = await import('util') 5 | const { writeFile } = await import('graceful-fs') 6 | 7 | const pWriteFile = promisify(writeFile) 8 | 9 | return { 10 | files: await Promise.all( 11 | files.map(async (file) => { 12 | await pWriteFile(file.path, file.data, 'utf8') 13 | 14 | logPath(file.path) 15 | 16 | return file 17 | }) 18 | ) 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /packages/plugin-overwrite/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import overwrite from '../src' 4 | 5 | test('plugin-overwrite: export', async (t) => { 6 | t.equals( 7 | typeof overwrite, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-parallel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-parallel", 3 | "version": "0.3.1", 4 | "description": "🔀 Run tasks as parallel child processes with same agruments", 5 | "keywords": "tasks, runner, start, start-plugin, parallelism, parallel", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-parallel", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0", 25 | "p-all": "^2.0.0" 26 | }, 27 | "devDependencies": { 28 | "@types/execa": "^0.9.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/plugin-parallel/readme.md: -------------------------------------------------------------------------------- 1 | # 🔀 plugin-parallel 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-parallel.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-parallel) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-parallel&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-parallel) 4 | 5 | Run tasks as parallel child processes with same agruments. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-parallel 11 | # or 12 | $ npm install --save-dev @start/plugin-parallel 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | parallel(taskNames: string[], options?: {}): (...args: string[]) 21 | ``` 22 | 23 | #### `taskNames` 24 | 25 | Array of exported task names. 26 | 27 | #### `options` 28 | 29 | * `maxProcesses` – `Infinity` by default 30 | 31 | ### Example 32 | 33 | ```js 34 | import sequence from '@start/plugin-sequence' 35 | import find from '@start/plugin-find' 36 | import remove from '@start/plugin-remove' 37 | import parallel from '@start/plugin-parallel' 38 | 39 | export const buildCJS = (...args) => { 40 | // … 41 | } 42 | 43 | export const buildESM = (...args) => { 44 | // … 45 | } 46 | 47 | export const task = (...args) => 48 | sequence( 49 | find('build/'), 50 | remove, 51 | parallel(['buildCJS', 'buildESM'])(...args) 52 | ) 53 | ``` 54 | -------------------------------------------------------------------------------- /packages/plugin-parallel/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { Options as TExecaOptions } from 'execa' 3 | 4 | export type Options = { 5 | maxProcesses?: number 6 | } 7 | 8 | export default (taskNames: string[], options: Options = {}) => (...args: string[]) => 9 | plugin('parallel', () => async () => { 10 | const { default: execa } = await import('execa') 11 | const { default: pAll } = await import('p-all') 12 | 13 | const spawnOptions: TExecaOptions = { 14 | stdout: process.stdout, 15 | stderr: process.stderr, 16 | stripEof: false, 17 | env: { 18 | FORCE_COLOR: '1' 19 | } 20 | } 21 | const pAllOptions = { 22 | concurrency: options.maxProcesses || Infinity 23 | } 24 | 25 | await pAll( 26 | taskNames.map((taskName) => { 27 | const spawnCommand = process.argv[0] 28 | const spawnArgs = [process.argv[1], taskName, ...args] 29 | 30 | return async () => { 31 | try { 32 | await execa(spawnCommand, spawnArgs, spawnOptions) 33 | } catch (e) { 34 | throw null 35 | } 36 | } 37 | }), 38 | pAllOptions 39 | ) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/plugin-parallel/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import parallel from '../src' 4 | 5 | test('plugin-parallel: export', async (t) => { 6 | t.equals( 7 | typeof parallel, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-read/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-read", 3 | "version": "0.3.1", 4 | "description": "📖 Read files content", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-read", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "graceful-fs": "^4.1.15" 25 | }, 26 | "devDependencies": { 27 | "@types/graceful-fs": "^4.1.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-read/readme.md: -------------------------------------------------------------------------------- 1 | # 📖 plugin-read 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-read.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-read) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-read&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-read) 4 | 5 | Read files content. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-read 11 | # or 12 | $ npm install --save-dev @start/plugin-read 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Example 18 | 19 | ```js 20 | import sequence from '@start/plugin-sequence' 21 | import find from '@start/plugin-find' 22 | import read from '@start/plugin-read' 23 | import babel from '@start/plugin-lib-babel' 24 | import write from '@start/plugin-write' 25 | 26 | const babelConfig = { 27 | // … 28 | babelrc: false, 29 | sourceMap: true, 30 | } 31 | 32 | export const task = () => 33 | sequence( 34 | find('src/**/*.js'), 35 | read, 36 | babel(babelConfig), 37 | write('build/') 38 | ) 39 | ``` 40 | -------------------------------------------------------------------------------- /packages/plugin-read/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFile, StartFilesProps } from '@start/plugin/src/' 2 | 3 | export default plugin('read', ({ logPath }) => async ({ files }: StartFilesProps) => { 4 | const { promisify } = await import('util') 5 | const { readFile } = await import('graceful-fs') 6 | 7 | const pReadFile = promisify(readFile) 8 | 9 | return { 10 | files: await Promise.all( 11 | files.map(async (file): Promise => { 12 | const data = await pReadFile(file.path, 'utf8') 13 | 14 | logPath(file.path) 15 | 16 | return { 17 | path: file.path, 18 | data 19 | } 20 | }) 21 | ) 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /packages/plugin-read/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import read from '../src' 4 | 5 | test('plugin-read: export', async (t) => { 6 | t.equals( 7 | typeof read, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-remove/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-remove", 3 | "version": "0.3.1", 4 | "description": "❌ Remove files or directories", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-remove", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "dleet": "^0.3.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-remove/readme.md: -------------------------------------------------------------------------------- 1 | # ❌ plugin-remove 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-remove.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-remove) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-remove&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-remove) 4 | 5 | Remove files or directories. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-remove 11 | # or 12 | $ npm install --save-dev @start/plugin-remove 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Example 18 | 19 | ```js 20 | import sequence from '@start/plugin-sequence' 21 | import find from '@start/plugin-find' 22 | import remove from '@start/plugin-remove' 23 | 24 | export const task = () => 25 | sequence( 26 | find('build/'), 27 | remove, 28 | ) 29 | ``` 30 | -------------------------------------------------------------------------------- /packages/plugin-remove/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFilesProps } from '@start/plugin/src/' 2 | 3 | export default plugin('remove', ({ logPath }) => async ({ files }: StartFilesProps) => { 4 | const { default: dleet } = await import('dleet') 5 | 6 | await Promise.all( 7 | files.map(async (file) => { 8 | await dleet(file.path) 9 | 10 | logPath(file.path) 11 | }) 12 | ) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/plugin-remove/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import remove from '../src' 4 | 5 | test('plugin-remove: export', async (t) => { 6 | t.equals( 7 | typeof remove, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-rename/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-rename", 3 | "version": "0.3.2", 4 | "description": "🔠 Rename files", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-rename", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/plugin-rename/readme.md: -------------------------------------------------------------------------------- 1 | # 🔠 plugin-rename 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-rename.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-rename) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-rename&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-rename) 4 | 5 | Rename files. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-rename 11 | # or 12 | $ npm install --save-dev @start/plugin-rename 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | rename(callback: (file: string) => string) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import sequence from '@start/plugin-sequence' 27 | import find from '@start/plugin-find' 28 | import read from '@start/plugin-read' 29 | import babel from '@start/plugin-lib-babel' 30 | import rename from '@start/plugin-rename' 31 | import write from '@start/plugin-write' 32 | 33 | const babelConfig = { 34 | // … 35 | babelrc: false, 36 | sourceMap: true, 37 | } 38 | 39 | export const task = () => 40 | sequence( 41 | find('src/*.ts'), 42 | read, 43 | babel(babelConfig), 44 | rename((file) => file.replace(/\.ts$/, '.js')), 45 | write('build/') 46 | ) 47 | ``` 48 | -------------------------------------------------------------------------------- /packages/plugin-rename/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFile, StartDataFilesProps } from '@start/plugin/src/' 2 | 3 | export default (callback: (file: string) => string) => 4 | plugin('rename', ({ logPath }) => async ({ files }: StartDataFilesProps) => { 5 | const path = await import('path') 6 | 7 | return { 8 | files: files.map((file): StartDataFile => { 9 | const newPath = callback(file.path) 10 | 11 | if (file.path === newPath) { 12 | return file 13 | } 14 | 15 | logPath(newPath) 16 | 17 | if (file.map) { 18 | return { 19 | path: newPath, 20 | data: file.data, 21 | map: { 22 | ...file.map, 23 | file: path.basename(newPath) 24 | } 25 | } 26 | } 27 | 28 | return { 29 | path: newPath, 30 | data: file.data 31 | } 32 | }) 33 | } 34 | }) 35 | -------------------------------------------------------------------------------- /packages/plugin-rename/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import rename from '../src' 4 | 5 | test('plugin-rename: export', async (t) => { 6 | t.equals( 7 | typeof rename, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-sequence/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-sequence", 3 | "version": "0.4.0", 4 | "description": "⏩ Run plugins in sequence", 5 | "keywords": "tasks, runner, start, start-plugin, sequence", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-sequence", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/plugin-sequence/readme.md: -------------------------------------------------------------------------------- 1 | # ⏩ plugin-sequence 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-sequence.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-sequence) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-sequence&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-sequence) 4 | 5 | Run plugins in sequence. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-sequence 11 | # or 12 | $ npm install --save-dev @start/plugin-sequence 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | sequence(...plugins: StartPlugin[]) 21 | ``` 22 | 23 | See [@start/plugin](https://github.com/deepsweet/start/tree/master/packages/plugin) for more details. 24 | 25 | ### Example 26 | 27 | ```js 28 | import sequence from '@start/plugin-sequence' 29 | import find from '@start/plugin-find' 30 | import copy from '@start/plugin-copy' 31 | 32 | export const task = () => 33 | sequence( 34 | find('src/**/*.json'), 35 | copy('build/') 36 | ) 37 | ``` 38 | -------------------------------------------------------------------------------- /packages/plugin-sequence/test/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import EventEmitter from 'events' 3 | import test from 'blue-tape' 4 | import { createSpy, getSpyCalls } from 'spyfn' 5 | 6 | import sequence from '../src' 7 | 8 | test('plugin-sequence: export', async (t) => { 9 | t.equals( 10 | typeof sequence, 11 | 'function', 12 | 'must be a function' 13 | ) 14 | }) 15 | 16 | test('plugin-sequence: ok / sync plugin / sync return', async (t) => { 17 | const reporter = new EventEmitter() 18 | const plugin1CallbackSpy = createSpy(() => ({ bar: true })) 19 | const plugin1Spy = createSpy(() => plugin1CallbackSpy) 20 | const plugin1 = plugin('plugin1', plugin1Spy) 21 | const plugin2CallbackSpy = createSpy(() => {}) 22 | const plugin2Spy = createSpy(() => plugin2CallbackSpy) 23 | const plugin2 = plugin('plugin2', plugin2Spy) 24 | const plugin3CallbackSpy = createSpy(() => {}) 25 | const plugin3Spy = createSpy(() => plugin3CallbackSpy) 26 | const plugin3 = plugin('plugin3', plugin3Spy) 27 | 28 | const run = await sequence(plugin1, plugin2, plugin3) 29 | 30 | await run(reporter)({ foo: true }) 31 | 32 | t.equal( 33 | getSpyCalls(plugin1Spy)[0][0].reporter, 34 | reporter, 35 | 'should pass reporter through sequence to plugin 1' 36 | ) 37 | 38 | t.deepEqual( 39 | getSpyCalls(plugin1CallbackSpy), 40 | [[{ foo: true }]], 41 | 'should pass initial props to plugin 1' 42 | ) 43 | 44 | t.equal( 45 | getSpyCalls(plugin2Spy)[0][0].reporter, 46 | reporter, 47 | 'should pass reporter through sequence to plugin 2' 48 | ) 49 | 50 | t.deepEqual( 51 | getSpyCalls(plugin2CallbackSpy), 52 | [[{ foo: true, bar: true }]], 53 | 'should extend initial props with plugin 1 output and pass it to plugin 2' 54 | ) 55 | 56 | t.equal( 57 | getSpyCalls(plugin3Spy)[0][0].reporter, 58 | reporter, 59 | 'should pass reporter through sequence to plugin 3' 60 | ) 61 | 62 | t.deepEqual( 63 | getSpyCalls(plugin3CallbackSpy), 64 | [[{ foo: true, bar: true }]], 65 | 'should allow plugins to return nothing' 66 | ) 67 | }) 68 | 69 | test('plugin-sequence: ok / async plugin / async return', async (t) => { 70 | const reporter = new EventEmitter() 71 | const plugin1CallbackSpy = createSpy(() => Promise.resolve({ bar: true })) 72 | const plugin1Spy = createSpy(() => plugin1CallbackSpy) 73 | const plugin1 = Promise.resolve(plugin('plugin1', plugin1Spy)) 74 | const plugin2CallbackSpy = createSpy(() => Promise.resolve()) 75 | const plugin2Spy = createSpy(() => plugin2CallbackSpy) 76 | const plugin2 = Promise.resolve(plugin('plugin2', plugin2Spy)) 77 | const plugin3CallbackSpy = createSpy(() => Promise.resolve()) 78 | const plugin3Spy = createSpy(() => plugin3CallbackSpy) 79 | const plugin3 = Promise.resolve(plugin('plugin3', plugin3Spy)) 80 | 81 | const run = await sequence(plugin1, plugin2, plugin3) 82 | 83 | await run(reporter)({ foo: true }) 84 | 85 | t.equal( 86 | getSpyCalls(plugin1Spy)[0][0].reporter, 87 | reporter, 88 | 'should pass reporter through sequence to plugin 1' 89 | ) 90 | 91 | t.deepEqual( 92 | getSpyCalls(plugin1CallbackSpy), 93 | [[{ foo: true }]], 94 | 'should pass initial props to plugin 1' 95 | ) 96 | 97 | t.equal( 98 | getSpyCalls(plugin2Spy)[0][0].reporter, 99 | reporter, 100 | 'should pass reporter through sequence to plugin 2' 101 | ) 102 | 103 | t.deepEqual( 104 | getSpyCalls(plugin2CallbackSpy), 105 | [[{ foo: true, bar: true }]], 106 | 'should extend initial props with plugin 1 output and pass it to plugin 2' 107 | ) 108 | 109 | t.equal( 110 | getSpyCalls(plugin3Spy)[0][0].reporter, 111 | reporter, 112 | 'should pass reporter through sequence to plugin 3' 113 | ) 114 | 115 | t.deepEqual( 116 | getSpyCalls(plugin3CallbackSpy), 117 | [[{ foo: true, bar: true }]], 118 | 'should allow plugins to return nothing' 119 | ) 120 | }) 121 | 122 | test('plugin-sequence: error / throw', async (t) => { 123 | const reporter = new EventEmitter() 124 | const plugin1CallbackSpy = createSpy(() => { 125 | throw 'oops' 126 | }) 127 | const plugin1Spy = createSpy(() => plugin1CallbackSpy) 128 | const plugin1 = plugin('plugin1', plugin1Spy) 129 | const plugin2CallbackSpy = createSpy(() => {}) 130 | const plugin2Spy = createSpy(() => plugin2CallbackSpy) 131 | const plugin2 = plugin('plugin2', plugin2Spy) 132 | 133 | const run = await sequence(plugin1, plugin2) 134 | 135 | reporter.on('error', () => {}) 136 | 137 | try { 138 | await run(reporter)() 139 | 140 | t.fail('should not get here') 141 | } catch (e) { 142 | t.deepEqual( 143 | getSpyCalls(plugin2Spy), 144 | [], 145 | 'should stop running sequence after error' 146 | ) 147 | } 148 | }) 149 | 150 | test('plugin-sequence: error / reject', async (t) => { 151 | const reporter = new EventEmitter() 152 | const plugin1CallbackSpy = createSpy(() => Promise.reject()) 153 | const plugin1Spy = createSpy(() => plugin1CallbackSpy) 154 | const plugin1 = plugin('plugin1', plugin1Spy) 155 | const plugin2CallbackSpy = createSpy(() => {}) 156 | const plugin2Spy = createSpy(() => plugin2CallbackSpy) 157 | const plugin2 = plugin('plugin2', plugin2Spy) 158 | 159 | const run = await sequence(plugin1, plugin2) 160 | 161 | reporter.on('error', () => {}) 162 | 163 | try { 164 | await run(reporter)() 165 | 166 | t.fail('should not get here') 167 | } catch (e) { 168 | t.deepEqual( 169 | getSpyCalls(plugin2Spy), 170 | [], 171 | 'should stop running sequence after error' 172 | ) 173 | } 174 | }) 175 | 176 | test('plugin-sequence: `false` as a plugin', async (t) => { 177 | const reporter = new EventEmitter() 178 | const plugin1 = false 179 | const plugin2CallbackSpy = createSpy(() => {}) 180 | const plugin2Spy = createSpy(() => plugin2CallbackSpy) 181 | const plugin2 = plugin('plugin2', plugin2Spy) 182 | 183 | const run = await sequence(plugin1, plugin2) 184 | 185 | await run(reporter)({ foo: true }) 186 | 187 | t.deepEqual( 188 | getSpyCalls(plugin2CallbackSpy), 189 | [[{ foo: true }]], 190 | 'should allow plugins to return nothing' 191 | ) 192 | }) 193 | -------------------------------------------------------------------------------- /packages/plugin-spawn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-spawn", 3 | "version": "0.3.1", 4 | "description": "🐣 Spawn new child process", 5 | "keywords": "tasks, runner, start, start-plugin, spawn", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-spawn", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0" 25 | }, 26 | "devDependencies": { 27 | "@types/execa": "^0.9.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/plugin-spawn/readme.md: -------------------------------------------------------------------------------- 1 | # 🐣 plugin-spawn 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-spawn.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-spawn) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-spawn&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-spawn) 4 | 5 | Spawn new child process. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-spawn 11 | # or 12 | $ npm install --save-dev @start/plugin-spawn 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | spawn(cli: string[], options?: {}) 21 | ``` 22 | 23 | #### `cli` 24 | 25 | Array of CLI command and args, for example `['node', '--version']`. 26 | 27 | #### `options` 28 | 29 | [execa options](https://github.com/sindresorhus/execa#options). 30 | 31 | Default: 32 | 33 | ```js 34 | { 35 | stdout: process.stdout, 36 | stderr: process.stderr, 37 | stripEof: false, 38 | env: { 39 | FORCE_COLOR: '1' 40 | } 41 | } 42 | ``` 43 | 44 | If there is no `stderr` then error will be shown using Start reporter. 45 | 46 | ### Example 47 | 48 | ```js 49 | import spawn from '@start/plugin-spawn' 50 | 51 | export task = () => spawn(['node', '--version']) 52 | ``` 53 | -------------------------------------------------------------------------------- /packages/plugin-spawn/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | 3 | export default (cli: string[], userOptions?: {}) => 4 | plugin('spawn', () => async () => { 5 | const { default: execa } = await import('execa') 6 | 7 | const [ command, ...args ] = cli 8 | const options = { 9 | stdout: process.stdout, 10 | stderr: process.stderr, 11 | stripEof: false, 12 | env: { 13 | FORCE_COLOR: '1' 14 | }, 15 | ...userOptions 16 | } 17 | 18 | try { 19 | await execa(command, args, options) 20 | } catch (error) { 21 | if (options.stderr) { 22 | throw null 23 | } 24 | 25 | throw error 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /packages/plugin-spawn/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import spawn from '../src' 4 | 5 | test('plugin-spawn: export', async (t) => { 6 | t.equals( 7 | typeof spawn, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-unpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-unpack", 3 | "version": "0.3.1", 4 | "description": "🗜 Unpack .tar/.tar.bz2/.tar.gz/.zip archives", 5 | "keywords": "tasks, runner, start, start-plugin, unpack, tar, tarbz2, targz, zip", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-unpack", 8 | "contributors": [ 9 | "Philipp 'luii' Czarnetzk (https://github.com/luii)", 10 | "Kir Belevich (https://twitter.com/deepsweet)" 11 | ], 12 | "license": "MIT", 13 | "main": "build/index.js", 14 | "types": "build/index.d.ts", 15 | "files": [ 16 | "build/" 17 | ], 18 | "publishConfig": { 19 | "access": "public" 20 | }, 21 | "engines": { 22 | "node": ">=8.6.0" 23 | }, 24 | "dependencies": { 25 | "decompress": "^4.2.0" 26 | }, 27 | "devDependencies": { 28 | "@babel/runtime": "^7.4.2", 29 | "@types/decompress": "^4.2.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugin-unpack/readme.md: -------------------------------------------------------------------------------- 1 | # 🗜 plugin-unpack 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-unpack.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-unpack) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-unpack&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-unpack) 4 | 5 | Unpack .tar/.tar.bz2/.tar.gz/.zip archives archives. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-unpack 11 | # or 12 | $ npm install --save-dev @start/plugin-unpack 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | unpack(outDir: string) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import sequence from '@start/plugin-sequence' 27 | import find from '@start/plugin-find' 28 | import unpack from '@start/plugin-unpack' 29 | 30 | export const task = () => 31 | sequence( 32 | find('packed/*.tar'), 33 | unpack('unpacked/') 34 | ) 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/plugin-unpack/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartFile, StartFilesProps } from '@start/plugin/src/' 2 | 3 | export default (outDir: string) => 4 | plugin('unpack', ({ logPath }) => async ({ files }: StartFilesProps) => { 5 | const path = await import('path') 6 | const { default: unpack } = await import('decompress') 7 | 8 | return { 9 | files: ( 10 | await Promise.all( 11 | files.map(async (file) => { 12 | let unpackedFiles = await unpack(file.path, outDir) 13 | 14 | return unpackedFiles.map((unpackedFile): StartFile => { 15 | const fullPath = path.resolve(outDir, unpackedFile.path) 16 | 17 | logPath(fullPath) 18 | 19 | return { 20 | path: fullPath 21 | } 22 | }) 23 | }) 24 | ) 25 | ).reduce((result, next) => result.concat(next), [] as StartFile[]) 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /packages/plugin-unpack/test/fixtures/file.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deepsweet/start/8a7844d1943aa54fbc9a9ef6d5ec7a66f4b6a3bf/packages/plugin-unpack/test/fixtures/file.tar -------------------------------------------------------------------------------- /packages/plugin-unpack/test/fixtures/file.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deepsweet/start/8a7844d1943aa54fbc9a9ef6d5ec7a66f4b6a3bf/packages/plugin-unpack/test/fixtures/file.tar.bz2 -------------------------------------------------------------------------------- /packages/plugin-unpack/test/fixtures/file.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deepsweet/start/8a7844d1943aa54fbc9a9ef6d5ec7a66f4b6a3bf/packages/plugin-unpack/test/fixtures/file.tar.gz -------------------------------------------------------------------------------- /packages/plugin-unpack/test/fixtures/file.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deepsweet/start/8a7844d1943aa54fbc9a9ef6d5ec7a66f4b6a3bf/packages/plugin-unpack/test/fixtures/file.zip -------------------------------------------------------------------------------- /packages/plugin-unpack/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import decompress from '../src' 4 | 5 | test('plugin-decompress: export', async (t) => { 6 | t.equals( 7 | typeof decompress, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-watch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-watch", 3 | "version": "0.3.1", 4 | "description": "👀 Watch for new or changed files matched by glob patterns", 5 | "keywords": "tasks, runner, start, start-plugin, watch", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-watch", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "chokidar": "^2.1.5" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/plugin-watch/readme.md: -------------------------------------------------------------------------------- 1 | # 👀 plugin-watch 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-watch.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-watch) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-watch&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-watch) 4 | 5 | Watch for new or changed files matched by glob patterns. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-watch 11 | # or 12 | $ npm install --save-dev @start/plugin-watch 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | watch(glob: string | string[], options?: {}): (target: StartPlugin) 21 | ``` 22 | 23 | #### `options` 24 | 25 | [chokidar options](https://github.com/paulmillr/chokidar#api). 26 | 27 | ### Example 28 | 29 | ```js 30 | import sequence from '@start/plugin-sequence' 31 | import read from '@start/plugin-read' 32 | import babel from '@start/plugin-lib-babel' 33 | import write from '@start/plugin-write' 34 | import watch from '@start/plugin-watch' 35 | 36 | const babelConfig = { 37 | // … 38 | babelrc: false, 39 | sourceMap: true, 40 | } 41 | 42 | export const task = () => 43 | watch('src/**/*.js')( 44 | sequence( 45 | read, 46 | babel(babelConfig), 47 | write('build/') 48 | ) 49 | ) 50 | ``` 51 | -------------------------------------------------------------------------------- /packages/plugin-watch/src/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable standard/no-callback-literal */ 2 | /* eslint-disable promise/catch-or-return */ 3 | import plugin, { StartFile, StartFilesProps, StartPlugin } from '@start/plugin/src/' 4 | 5 | export default (glob: string | string[], userOptions?: {}) => (target: StartPlugin) => 6 | plugin('watch', (utils) => async () => { 7 | const chokidar = await import('chokidar') 8 | 9 | const targetRunner = await target 10 | const events = ['add', 'change'] 11 | const options = { 12 | cwd: process.cwd(), 13 | persistent: true, 14 | ...userOptions 15 | } 16 | 17 | await new Promise((resolve, reject) => { 18 | const initialFiles: StartFile[] = [] 19 | const initialListener = (file: string) => { 20 | initialFiles.push({ 21 | path: file 22 | }) 23 | } 24 | 25 | const watcher = chokidar.watch(glob, options) 26 | 27 | watcher.on('add', initialListener) 28 | watcher.once('error', reject) 29 | watcher.once('ready', async () => { 30 | watcher.removeListener('add', initialListener) 31 | 32 | const watchForChanges = () => { 33 | events.forEach((event) => { 34 | watcher.once(event, async (file) => { 35 | try { 36 | await targetRunner(utils.reporter)({ 37 | files: [{ 38 | path: file 39 | }] 40 | }) 41 | } finally { 42 | watchForChanges() 43 | } 44 | }) 45 | }) 46 | } 47 | 48 | try { 49 | await targetRunner(utils.reporter)({ 50 | files: initialFiles 51 | }) 52 | } finally { 53 | watchForChanges() 54 | utils.logMessage('watching for changes, press ctrl-c to exit') 55 | } 56 | }) 57 | }) 58 | }) 59 | -------------------------------------------------------------------------------- /packages/plugin-watch/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import watch from '../src' 4 | 5 | test('plugin-watch: export', async (t) => { 6 | t.equals( 7 | typeof watch, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-write/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-write", 3 | "version": "0.3.2", 4 | "description": "✏️ Write files with source maps to relative destination keeping folders structure", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-write", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "graceful-fs": "^4.1.15", 25 | "make-dir": "^3.0.0", 26 | "move-path": "^0.2.0" 27 | }, 28 | "devDependencies": { 29 | "@types/graceful-fs": "^4.1.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugin-write/readme.md: -------------------------------------------------------------------------------- 1 | # ✏️ plugin-write 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-write.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-write) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-write&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-write) 4 | 5 | Write files with source maps to relative destination keeping folders structure. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-write 11 | # or 12 | $ npm install --save-dev @start/plugin-write 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | write(outDirRelative: string) 21 | ``` 22 | 23 | ### Example 24 | 25 | ```js 26 | import sequence from '@start/plugin-sequence' 27 | import find from '@start/plugin-find' 28 | import read from '@start/plugin-read' 29 | import babel from '@start/plugin-lib-babel' 30 | import write from '@start/plugin-write' 31 | 32 | const babelConfig = { 33 | // … 34 | babelrc: false, 35 | sourceMap: true, 36 | } 37 | 38 | export const task = () => 39 | sequence( 40 | find('src/**/*.js'), 41 | read, 42 | babel(babelConfig), 43 | write('build/') 44 | ) 45 | ``` 46 | -------------------------------------------------------------------------------- /packages/plugin-write/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFilesProps, StartDataFile } from '@start/plugin/src/' 2 | 3 | export default (outDirRelative: string) => 4 | plugin('write', ({ logPath }) => async ({ files }: StartDataFilesProps) => { 5 | const path = await import('path') 6 | const { promisify } = await import('util') 7 | const { writeFile } = await import('graceful-fs') 8 | const { default: movePath } = await import('move-path') 9 | const { default: makeDir } = await import('make-dir') 10 | 11 | const pWriteFile = promisify(writeFile) 12 | 13 | return { 14 | files: await Promise.all( 15 | files.map(async (file): Promise => { 16 | const outFile = movePath(file.path, outDirRelative) 17 | const outDir = path.dirname(outFile) 18 | 19 | await makeDir(outDir) 20 | 21 | const writeFiles = [] 22 | let fileData = file.data 23 | 24 | // sourcemap 25 | if (file.map != null) { 26 | const inFile = path.basename(file.path) 27 | // /beep/boop/src/beep/index.js -> .js 28 | const inExtname = path.extname(file.path) 29 | // index.js -> index.js.map 30 | const sourcemapFile = inFile + '.map' 31 | // /beep/boop/build/beep/index.js -> /beep/boop/build/beep/index.js.map 32 | const sourcemapPath = path.join(outDir, sourcemapFile) 33 | const sourcemapData = JSON.stringify(file.map) 34 | 35 | // /*# sourceMappingURL=index.css.map */ 36 | if (inExtname === '.css') { 37 | fileData += '\n/*# sourceMappingURL=' 38 | fileData += sourcemapFile 39 | fileData += ' */' 40 | // //# sourceMappingURL=index.js.map 41 | } else { 42 | fileData += '\n//# sourceMappingURL=' 43 | fileData += sourcemapFile 44 | } 45 | 46 | writeFiles.push( 47 | pWriteFile(sourcemapPath, sourcemapData, 'utf8').then(() => { 48 | logPath(sourcemapPath) 49 | }) 50 | ) 51 | } 52 | 53 | writeFiles.push( 54 | pWriteFile(outFile, fileData, 'utf8').then(() => { 55 | logPath(outFile) 56 | }) 57 | ) 58 | 59 | await Promise.all(writeFiles) 60 | 61 | return { 62 | ...file, 63 | path: outFile 64 | } 65 | }) 66 | ) 67 | } 68 | }) 69 | -------------------------------------------------------------------------------- /packages/plugin-write/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import write from '../src' 4 | 5 | test('plugin-write: export', async (t) => { 6 | t.equals( 7 | typeof write, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin-xargs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin-xargs", 3 | "version": "0.3.1", 4 | "description": "🔂 Run task as parallel child process for each argument", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin-xargs", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "@start/plugin": "^0.3.1", 24 | "execa": "^1.0.0", 25 | "p-all": "^2.0.0" 26 | }, 27 | "devDependencies": { 28 | "@types/execa": "^0.9.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/plugin-xargs/readme.md: -------------------------------------------------------------------------------- 1 | # 🔂 plugin-xargs 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin-xargs.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin-xargs) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin-xargs&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin-xargs) 4 | 5 | Run task as parallel child process for each argument. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/plugin-xargs 11 | # or 12 | $ npm install --save-dev @start/plugin-xargs 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Signature 18 | 19 | ```ts 20 | xargs(taskName: string, options?: {}): (...args: string[]) 21 | ``` 22 | 23 | #### `taskName` 24 | 25 | Exported task name. 26 | 27 | #### `options` 28 | 29 | * `maxProcesses` – `Infinity` by default 30 | 31 | ### Example 32 | 33 | ```js 34 | import sequence from '@start/plugin-sequence' 35 | import find from '@start/plugin-find' 36 | import read from '@start/plugin-read' 37 | import babel from '@start/plugin-lib-babel' 38 | import write from '@start/plugin-write' 39 | 40 | const babelConfig = { 41 | // … 42 | babelrc: false, 43 | sourceMap: true, 44 | } 45 | 46 | export const task1 = (packageName) => 47 | sequence( 48 | find(`${packageName}/src/**/*.js`), 49 | read, 50 | babel(babelConfig), 51 | write(`${packageName}/build/`) 52 | ) 53 | 54 | export const task2 => (...packageNames) = xargs('task1')(...packageNames) 55 | // export const task2 = xargs('task1') 56 | ``` 57 | -------------------------------------------------------------------------------- /packages/plugin-xargs/src/index.ts: -------------------------------------------------------------------------------- 1 | import plugin from '@start/plugin/src/' 2 | import { Options as TExecaOptions } from 'execa' 3 | 4 | export type Options = { 5 | maxProcesses?: number 6 | } 7 | 8 | export default (taskName: string, options: Options = {}) => (...args: string[]) => 9 | plugin('xargs', () => async () => { 10 | const { default: execa } = await import('execa') 11 | const { default: pAll } = await import('p-all') 12 | 13 | const spawnOptions: TExecaOptions = { 14 | stdout: process.stdout, 15 | stderr: process.stderr, 16 | stripEof: false, 17 | env: { 18 | FORCE_COLOR: '1' 19 | } 20 | } 21 | const pAllOptions = { 22 | concurrency: options.maxProcesses || Infinity 23 | } 24 | 25 | await pAll( 26 | args.map((arg) => { 27 | const spawnCommand = process.argv[0] 28 | const spawnArgs = [process.argv[1], taskName, arg] 29 | 30 | return async () => { 31 | try { 32 | await execa(spawnCommand, spawnArgs, spawnOptions) 33 | } catch (e) { 34 | throw null 35 | } 36 | } 37 | }), 38 | pAllOptions 39 | ) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/plugin-xargs/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import xargs from '../src' 4 | 5 | test('plugin-xargs: export', async (t) => { 6 | t.equals( 7 | typeof xargs, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /packages/plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/plugin", 3 | "version": "0.3.1", 4 | "description": "⚙️ Plugin creator", 5 | "keywords": "tasks, runner, start, start-plugin", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/plugin", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/plugin/readme.md: -------------------------------------------------------------------------------- 1 | # ⚙️ plugin 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/plugin.svg?style=flat-square)](https://www.npmjs.com/package/@start/plugin) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/plugin&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/plugin) 4 | 5 | Plugin creator. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add @start/plugin 11 | # or 12 | $ npm install --save-dev @start/plugin 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Types 18 | 19 | See [`src/index.ts`](src/index.ts) for all the types. It's (usually) better than any words. 20 | 21 | ### Example 22 | 23 | ```js 24 | import plugin from '@start/plugin' 25 | 26 | export default plugin('noop', () => () => {}) 27 | ``` 28 | 29 | ```js 30 | import plugin from '@start/plugin' 31 | 32 | export default plugin('foo', ({ logPath }) => async ({ files }) => { 33 | const { default: fooTransform } = await import('foo-lib') 34 | 35 | return { 36 | files: await Promise.all( 37 | files.map(async (file) => 38 | const { transformedData, sourceMap } = fooTransform(file.path) 39 | 40 | logPath(file.path) 41 | 42 | return { 43 | path: file.path, 44 | data: transformedData, 45 | map: sourceMap 46 | } 47 | ) 48 | ) 49 | } 50 | }) 51 | ``` 52 | 53 | ```js 54 | import plugin from '@start/plugin' 55 | 56 | export default (barOptions) => 57 | plugin('bar', ({ logMessage }) => async () => { 58 | const { default: barCheck } = await import('bar-lib') 59 | 60 | const barResult = barCheck(files, barOptions) 61 | 62 | if (barResult.issues.length === 0) { 63 | logMessage('¯\\_(ツ)_/¯') 64 | } 65 | }) 66 | ``` 67 | 68 | ## Notes 69 | 70 | * Dynamic imports – [it's a good idea](https://github.com/gulpjs/gulp/issues/632) to "lazyload" dependencies inside of a plugin function instead of importing it on top of a file 71 | * Plugin can return whatever "props" object or just nothing, and that output will extend an input props as an overall plugin result 72 | * `files` – many plugins works with `files` structure: it's an array of `{ path, data, map }` objects, where: 73 | * `path` – absolute file path 74 | * `data` – file data as utf8 string, if any 75 | * `map` – [Source Map object](https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-anatomy), if any 76 | * `logMessage` – any random message from plugin 77 | * `logPath` – current file path to indicate some kind of progress 78 | * `reporter` – advanced prop which should be passed through if plugin operates other plugins, like [sequence](../plugin-sequence) or [watch](../plugin-watch) 79 | -------------------------------------------------------------------------------- /packages/plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable space-infix-ops */ 2 | export type MaybeObject = void | {} 3 | 4 | export type StartReporter = NodeJS.EventEmitter 5 | 6 | export type StartFile = { 7 | path: string, 8 | data?: string, 9 | map?: {} 10 | } 11 | 12 | export type StartDataFile = StartFile & { 13 | data: string 14 | } 15 | 16 | export type StartFilesProps = { 17 | files: StartFile[] 18 | } 19 | 20 | export type StartDataFilesProps = { 21 | files: StartDataFile[] 22 | } 23 | 24 | export type StartPluginUtils = { 25 | reporter: StartReporter, 26 | logPath: (path: string) => void, 27 | logMessage: (message: string) => void, 28 | } 29 | 30 | export type StartPluginCallback

= (utils: StartPluginUtils) => (props: P) => R | Promise 31 | export type StartPluginWrapper

= (reporter: StartReporter) => (inProps?: P) => Promise 32 | export type StartPlugin

= StartPluginWrapper | Promise> 33 | 34 | export default

(name: string, pluginCallback: StartPluginCallback): StartPlugin => (reporter) => async (inProps?: P): Promise => { 35 | try { 36 | reporter.emit('start', name) 37 | 38 | const outProps = await pluginCallback({ 39 | reporter, 40 | logPath: (path) => reporter.emit('path', name, path), 41 | logMessage: (message) => reporter.emit('message', name, message) 42 | })(inProps as P) 43 | 44 | reporter.emit('done', name) 45 | 46 | return outProps 47 | } catch (error) { 48 | reporter.emit('error', name, error) 49 | 50 | throw null 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/plugin/test/index.ts: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events' 2 | import test from 'blue-tape' 3 | import { createSpy, getSpyCalls } from 'spyfn' 4 | 5 | import plugin from '../src' 6 | 7 | test('plugin: export', async (t) => { 8 | t.equals( 9 | typeof plugin, 10 | 'function', 11 | 'must be a function' 12 | ) 13 | }) 14 | 15 | test('plugin: utils and props', async (t) => { 16 | const reporter = new EventEmitter() 17 | const pluginCallbackSpy = createSpy(() => ({ bar: true })) 18 | const pluginSpy = createSpy(() => pluginCallbackSpy) 19 | const pluginRunner = await plugin('plugin', pluginSpy) 20 | const result = await pluginRunner(reporter)({ foo: true }) 21 | 22 | t.deepEqual( 23 | getSpyCalls(pluginSpy)[0][0].reporter, 24 | reporter, 25 | 'should pass reporter to plugin utils' 26 | ) 27 | 28 | t.deepEqual( 29 | getSpyCalls(pluginCallbackSpy), 30 | [[{ foo: true }]], 31 | 'should pass props to plugin' 32 | ) 33 | 34 | t.deepEqual( 35 | result, 36 | { bar: true }, 37 | 'should return output props' 38 | ) 39 | }) 40 | 41 | test('plugin: done', async (t) => { 42 | const reporter = new EventEmitter() 43 | const pluginRunner = await plugin('plugin', () => () => {}) 44 | const eventStartSpy = createSpy(() => {}) 45 | const eventDoneSpy = createSpy(() => {}) 46 | 47 | await pluginRunner(reporter)() 48 | 49 | reporter.on('start', eventStartSpy) 50 | reporter.on('done', eventDoneSpy) 51 | 52 | await pluginRunner(reporter)() 53 | 54 | t.deepEqual( 55 | getSpyCalls(eventStartSpy), 56 | [[ 'plugin' ]], 57 | 'should emit `start` event' 58 | ) 59 | 60 | t.deepEqual( 61 | getSpyCalls(eventDoneSpy), 62 | [[ 'plugin' ]], 63 | 'should emit `done` event' 64 | ) 65 | }) 66 | 67 | test('plugin: hard error', async (t) => { 68 | const reporter = new EventEmitter() 69 | const pluginRunner = await plugin('plugin', () => () => { 70 | throw 'oops' 71 | }) 72 | const eventStartSpy = createSpy(() => {}) 73 | const eventErrorSpy = createSpy(() => {}) 74 | 75 | reporter.on('start', eventStartSpy) 76 | reporter.on('error', eventErrorSpy) 77 | 78 | try { 79 | await pluginRunner(reporter)() 80 | 81 | t.fail('should not get here') 82 | } catch (e) { 83 | t.deepEqual( 84 | getSpyCalls(eventStartSpy), 85 | [[ 'plugin' ]], 86 | 'should emit `start` event' 87 | ) 88 | 89 | t.deepEqual( 90 | getSpyCalls(eventErrorSpy), 91 | [[ 'plugin', 'oops' ]], 92 | 'should emit `done` event' 93 | ) 94 | } 95 | }) 96 | 97 | test('plugin: reject', async (t) => { 98 | const reporter = new EventEmitter() 99 | const pluginRunner = await plugin('plugin', () => () => Promise.reject('oops')) 100 | const eventStartSpy = createSpy(() => {}) 101 | const eventErrorSpy = createSpy(() => {}) 102 | 103 | reporter.on('start', eventStartSpy) 104 | reporter.on('error', eventErrorSpy) 105 | 106 | try { 107 | await pluginRunner(reporter)() 108 | 109 | t.fail('should not get here') 110 | } catch (e) { 111 | t.deepEqual( 112 | getSpyCalls(eventStartSpy), 113 | [[ 'plugin' ]], 114 | 'should emit `start` event' 115 | ) 116 | 117 | t.deepEqual( 118 | getSpyCalls(eventErrorSpy), 119 | [[ 'plugin', 'oops' ]], 120 | 'should emit `done` event' 121 | ) 122 | } 123 | }) 124 | 125 | test('plugin: log message', async (t) => { 126 | const reporter = new EventEmitter() 127 | const pluginRunner = await plugin('plugin', ({ logMessage }) => () => { 128 | logMessage('hi') 129 | }) 130 | const eventMessageSpy = createSpy(() => {}) 131 | 132 | await pluginRunner(reporter)() 133 | 134 | reporter.on('message', eventMessageSpy) 135 | 136 | await pluginRunner(reporter)() 137 | 138 | t.deepEqual( 139 | getSpyCalls(eventMessageSpy), 140 | [[ 'plugin', 'hi' ]], 141 | 'should emit `message` event' 142 | ) 143 | }) 144 | 145 | test('plugin: log path', async (t) => { 146 | const reporter = new EventEmitter() 147 | const pluginRunner = await plugin('plugin', ({ logPath }) => () => { 148 | logPath('path/to/file') 149 | }) 150 | const eventPathSpy = createSpy(() => {}) 151 | 152 | await pluginRunner(reporter)() 153 | 154 | reporter.on('path', eventPathSpy) 155 | 156 | await pluginRunner(reporter)() 157 | 158 | t.deepEqual( 159 | getSpyCalls(eventPathSpy), 160 | [[ 'plugin', 'path/to/file' ]], 161 | 'should emit `path` event' 162 | ) 163 | }) 164 | -------------------------------------------------------------------------------- /packages/reporter-verbose/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@start/reporter-verbose", 3 | "version": "0.2.1", 4 | "description": "📃 Verbose reporter", 5 | "keywords": "tasks, runner, start, start-reporter", 6 | "repository": "deepsweet/start", 7 | "homepage": "https://github.com/deepsweet/start/tree/master/packages/reporter-verbose", 8 | "author": "Kir Belevich (https://twitter.com/deepsweet)", 9 | "license": "MIT", 10 | "main": "build/index.js", 11 | "types": "build/index.d.ts", 12 | "files": [ 13 | "build/" 14 | ], 15 | "publishConfig": { 16 | "access": "public" 17 | }, 18 | "engines": { 19 | "node": ">=8.6.0" 20 | }, 21 | "dependencies": { 22 | "@babel/runtime": "^7.4.2", 23 | "chalk": "^2.4.2", 24 | "stack-utils": "^1.0.2" 25 | }, 26 | "devDependencies": { 27 | "@types/stack-utils": "^1.0.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/reporter-verbose/readme.md: -------------------------------------------------------------------------------- 1 | # 📃 reporter-verbose 2 | 3 | [![npm](https://img.shields.io/npm/v/@start/reporter-verbose.svg?style=flat-square)](https://www.npmjs.com/package/@start/reporter-verbose) [![linux](https://img.shields.io/travis/deepsweet/start/master.svg?label=linux&style=flat-square)](https://travis-ci.org/deepsweet/start) [![windows](https://img.shields.io/appveyor/ci/deepsweet/start/master.svg?label=windows&style=flat-square)](https://ci.appveyor.com/project/deepsweet/start) [![coverage](https://img.shields.io/codecov/c/github/deepsweet/start/master.svg?style=flat-square)](https://codecov.io/github/deepsweet/start) [![deps](https://david-dm.org/deepsweet/start.svg?path=packages/reporter-verbose&style=flat-square)](https://david-dm.org/deepsweet/start?path=packages/reporter-verbose) 4 | 5 | Verbose reporter. 6 | 7 | ## Install 8 | 9 | ```sh 10 | $ yarn add --dev @start/reporter-verbose 11 | # or 12 | $ npm install --save-dev @start/reporter-verbose 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Example 18 | 19 | ```ts 20 | export default (taskName: string) => { 21 | const emitter = new EventEmitter() 22 | 23 | emitter.on('start', (pluginName: string) => {}) 24 | emitter.on('message', (pluginName: string, message: string) => {}) 25 | emitter.on('file', (pluginName: string, file: string) => {}) 26 | emitter.on('done', (pluginName: string) => {}) 27 | emitter.on('error', (pluginName: string, error: Error | string[] | string | null) => {}) 28 | 29 | return emitter 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /packages/reporter-verbose/src/index.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import EventEmitter from 'events' 3 | import chalk from 'chalk' 4 | import StackUtils from 'stack-utils' 5 | 6 | type StartError = Error | string[] | string | null 7 | 8 | export default (taskName: string) => { 9 | const emitter = new EventEmitter() 10 | 11 | emitter.on('start', (pluginName: string) => { 12 | console.log(`${chalk.yellow(`${taskName}.${pluginName}`)}: start`) 13 | }) 14 | 15 | emitter.on('message', (pluginName: string, message: string) => { 16 | console.log(`${chalk.cyan(`${taskName}.${pluginName}`)}: ${message}`) 17 | }) 18 | 19 | emitter.on('path', (pluginName: string, pathToLog: string) => { 20 | const relativeFile = path.relative(process.cwd(), pathToLog) 21 | 22 | console.log(`${chalk.blue(`${taskName}.${pluginName}`)}: ${relativeFile}`) 23 | }) 24 | 25 | emitter.on('done', (pluginName: string) => { 26 | console.log(`${chalk.green(`${taskName}.${pluginName}`)}: done`) 27 | }) 28 | 29 | emitter.on('error', (pluginName: string, error: StartError) => { 30 | // hard error 31 | if (error instanceof Error) { 32 | const stackUtils = new StackUtils({ 33 | cwd: process.cwd(), 34 | internals: StackUtils.nodeInternals() 35 | }) 36 | const stack = stackUtils.clean(error.stack!) 37 | 38 | console.error(`${chalk.red(`${taskName}.${pluginName}`)}: ${error.message}`) 39 | console.error(`\n${chalk.red(stack)}`) 40 | // array of "soft" errors 41 | } else if (Array.isArray(error)) { 42 | error.forEach((message) => { 43 | console.error(`${chalk.red(`${taskName}.${pluginName}`)}: ${message}`) 44 | }) 45 | // "soft" error 46 | } else if (typeof error === 'string') { 47 | console.error(`${chalk.red(`${taskName}.${pluginName}`)}: ${error}`) 48 | } 49 | 50 | console.error(`${chalk.red(`${taskName}.${pluginName}`)}: error`) 51 | }) 52 | 53 | return emitter 54 | } 55 | -------------------------------------------------------------------------------- /packages/reporter-verbose/test/index.ts: -------------------------------------------------------------------------------- 1 | import test from 'blue-tape' 2 | 3 | import reporterVerbose from '../src' 4 | 5 | test('reporter-verbose: export', async (t) => { 6 | t.equals( 7 | typeof reporterVerbose, 8 | 'function', 9 | 'must be a function' 10 | ) 11 | }) 12 | -------------------------------------------------------------------------------- /tasks/config/auto.ts: -------------------------------------------------------------------------------- 1 | import { TGitOptions } from '@auto/git' 2 | import { TBumpOptions } from '@auto/bump' 3 | import { TGithubOptions } from '@auto/log' 4 | import { TPrefixes, TWorkspacesOptions } from '@auto/utils' 5 | 6 | export const prefixes: TPrefixes = { 7 | required: { 8 | major: { 9 | title: 'Breaking change', 10 | value: '💥' 11 | }, 12 | minor: { 13 | title: 'New feature', 14 | value: '➕' 15 | }, 16 | patch: { 17 | title: 'Bugfix', 18 | value: '✔️' 19 | }, 20 | publish: { 21 | title: 'New version', 22 | value: '📦' 23 | }, 24 | dependencies: { 25 | title: 'Dependencies', 26 | value: '♻️' 27 | }, 28 | initial: { 29 | title: 'Initial', 30 | value: '🐣' 31 | } 32 | }, 33 | custom: [ 34 | { 35 | title: 'Dependencies', 36 | value: '♻️' 37 | }, 38 | { 39 | title: 'Lint', 40 | value: '🚷' 41 | }, 42 | { 43 | title: 'Test', 44 | value: '👾' 45 | }, 46 | { 47 | title: 'Docs', 48 | value: '📝' 49 | }, 50 | { 51 | title: 'Demo', 52 | value: '📺' 53 | }, 54 | { 55 | title: 'Refactor', 56 | value: '🛠' 57 | }, 58 | { 59 | title: 'WIP', 60 | value: '🚧' 61 | }, 62 | { 63 | title: 'Other', 64 | value: '🛠' 65 | } 66 | ] 67 | } 68 | 69 | export const gitOptions: TGitOptions = { initialType: 'minor' } 70 | 71 | export const bumpOptions: TBumpOptions = { 72 | zeroBreakingChangeType: 'minor', 73 | shouldAlwaysBumpDependents: true 74 | } 75 | 76 | export const githubOptions: TGithubOptions = { 77 | username: 'deepsweet', 78 | repo: 'start', 79 | token: process.env.GITHUB_RELEASE_TOKEN || '' 80 | } 81 | 82 | export const workspacesOptions: TWorkspacesOptions = { autoNamePrefix: '@start/' } 83 | -------------------------------------------------------------------------------- /tasks/config/babel.ts: -------------------------------------------------------------------------------- 1 | const babelConfigCommon = { 2 | babelrc: false, 3 | presets: [ 4 | [ 5 | '@babel/preset-env', 6 | { 7 | targets: { 8 | node: '8.6.0' 9 | } 10 | } 11 | ] 12 | ], 13 | plugins: [ 14 | [ 15 | '@babel/plugin-transform-runtime', 16 | { 17 | regenerator: false 18 | } 19 | ], 20 | '@babel/plugin-syntax-dynamic-import', 21 | 'babel-plugin-dynamic-import-node', 22 | [ 23 | 'module-resolver', { 24 | 'alias': { 25 | '@start/plugin/src/': '@start/plugin' 26 | } 27 | } 28 | ] 29 | ] 30 | } 31 | 32 | export const babelConfigBuild = { 33 | ...babelConfigCommon, 34 | presets: [ 35 | ...babelConfigCommon.presets, 36 | '@babel/preset-typescript' 37 | ] 38 | } 39 | 40 | export const babelConfigDts = { 41 | ...babelConfigCommon, 42 | plugins: [ 43 | ...babelConfigCommon.plugins, 44 | '@babel/plugin-syntax-typescript' 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /tasks/index.ts: -------------------------------------------------------------------------------- 1 | import plugin, { StartDataFilesProps, StartDataFile } from '@start/plugin/src' 2 | import sequence from '@start/plugin-sequence/src/' 3 | import parallel from '@start/plugin-parallel/src/' 4 | import xargs from '@start/plugin-xargs/src/' 5 | import assert from '@start/plugin-assert/src/' 6 | import env from '@start/plugin-env/src/' 7 | import find from '@start/plugin-find/src/' 8 | import findGitStaged from '@start/plugin-find-git-staged/src/' 9 | import remove from '@start/plugin-remove/src/' 10 | import read from '@start/plugin-read/src/' 11 | import babel from '@start/plugin-lib-babel/src/' 12 | import rename from '@start/plugin-rename/src/' 13 | import write from '@start/plugin-write/src/' 14 | import overwrite from '@start/plugin-overwrite/src/' 15 | import watch from '@start/plugin-watch/src/' 16 | import eslint from '@start/plugin-lib-eslint/src/' 17 | import { istanbulInstrument, istanbulReport } from '@start/plugin-lib-istanbul/src/' 18 | import tape from '@start/plugin-lib-tape/src/' 19 | import typescriptGenerate from '@start/plugin-lib-typescript-generate/src/' 20 | import typescriptCheck from '@start/plugin-lib-typescript-check/src/' 21 | import codecov from '@start/plugin-lib-codecov/src/' 22 | import { 23 | makeWorkspacesCommit, 24 | buildBumpedPackages, 25 | getWorkspacesPackagesBumps, 26 | publishWorkspacesPrompt, 27 | writeWorkspacesPackagesDependencies, 28 | writeWorkspacesDependenciesCommit, 29 | writeWorkspacesPackageVersions, 30 | writeWorkspacesPublishCommit, 31 | publishWorkspacesPackagesBumps, 32 | pushCommitsAndTags, 33 | writeWorkspacesPublishTags, 34 | makeWorkspacesGithubReleases 35 | } from '@auto/start-plugin' 36 | // @ts-ignore 37 | import tapDiff from 'tap-diff' 38 | 39 | export const build = async (packageName: string) => { 40 | const { babelConfigBuild } = await import('./config/babel') 41 | 42 | return sequence( 43 | find(`packages/${packageName}/src/**/*.+(js|ts)`), 44 | read, 45 | babel(babelConfigBuild), 46 | rename((file) => file.replace(/\.ts$/, '.js')), 47 | write(`packages/${packageName}/build/`) 48 | ) 49 | } 50 | 51 | export const dts = (packageName: string) => 52 | sequence( 53 | find(`packages/${packageName}/src/*.ts`), 54 | typescriptGenerate(`packages/${packageName}/build/`), 55 | find(`packages/${packageName}/build/**/*.d.ts`), 56 | read, 57 | // https://github.com/babel/babel/issues/7749 58 | // babel(babelConfigDts) 59 | plugin('modifyImports', () => ({ files }: StartDataFilesProps) => ({ 60 | files: files.map((file): StartDataFile => ({ 61 | ...file, 62 | data: file.data.replace(/(@.+?)\/src\/?/g, '$1') 63 | })) 64 | })), 65 | write(`packages/${packageName}/build/`) 66 | ) 67 | 68 | export const pack = (packageName: string) => 69 | sequence( 70 | assert(packageName, 'package name is required'), 71 | env({ NODE_ENV: 'production' }), 72 | find(`packages/${packageName}/build/`), 73 | remove, 74 | parallel(['build', 'dts'])(packageName) 75 | ) 76 | 77 | export const packs = xargs('pack') 78 | 79 | export const dev = async (packageName: string) => { 80 | const { babelConfigBuild } = await import('./config/babel') 81 | 82 | return watch(`packages/${packageName}/src/**/*.ts`)( 83 | sequence( 84 | read, 85 | babel(babelConfigBuild), 86 | rename((file) => file.replace(/\.ts$/, '.js')), 87 | write(`packages/${packageName}/build/`) 88 | ) 89 | ) 90 | } 91 | 92 | export const lint = () => 93 | sequence( 94 | findGitStaged(['packages/*/+(src|test)/**/*.ts', 'tasks/**/*.ts']), 95 | read, 96 | eslint(), 97 | typescriptCheck() 98 | ) 99 | 100 | export const lintAll = () => 101 | sequence( 102 | find(['packages/*/+(src|test)/**/*.+(ts|js)', 'tasks/**/*.ts']), 103 | read, 104 | eslint(), 105 | typescriptCheck() 106 | ) 107 | 108 | export const fix = () => 109 | sequence( 110 | find(['packages/*/+(src|test)/**/*.+(js|ts)', 'tasks/**/*.ts']), 111 | read, 112 | eslint({ fix: true }), 113 | overwrite 114 | ) 115 | 116 | export const test = (packageName: string = '*') => 117 | sequence( 118 | env({ NODE_ENV: 'test' }), 119 | find(`coverage/`), 120 | remove, 121 | find(`packages/${packageName}/src/**/*.ts`), 122 | istanbulInstrument({ esModules: true }, ['.ts']), 123 | find(`packages/${packageName}/test/**/*.ts`), 124 | tape(tapDiff), 125 | istanbulReport(['lcovonly', 'html', 'text-summary']) 126 | ) 127 | 128 | export const ci = () => 129 | sequence( 130 | lintAll(), 131 | test() 132 | ) 133 | 134 | export const ciCoverage = () => 135 | sequence( 136 | ci(), 137 | find('coverage/lcov.info'), 138 | read, 139 | codecov 140 | ) 141 | 142 | export const commit = async () => { 143 | const { prefixes, workspacesOptions } = await import('./config/auto') 144 | 145 | return makeWorkspacesCommit(prefixes, workspacesOptions) 146 | } 147 | 148 | export const publish = async () => { 149 | const { prefixes, workspacesOptions, gitOptions, bumpOptions, githubOptions } = await import('./config/auto') 150 | 151 | return sequence( 152 | getWorkspacesPackagesBumps(prefixes, gitOptions, bumpOptions, workspacesOptions), 153 | publishWorkspacesPrompt(prefixes), 154 | buildBumpedPackages(pack), 155 | writeWorkspacesPackagesDependencies, 156 | writeWorkspacesDependenciesCommit(prefixes), 157 | writeWorkspacesPackageVersions, 158 | writeWorkspacesPublishCommit(prefixes, workspacesOptions), 159 | writeWorkspacesPublishTags(workspacesOptions), 160 | publishWorkspacesPackagesBumps(), 161 | pushCommitsAndTags, 162 | makeWorkspacesGithubReleases(prefixes, workspacesOptions, githubOptions) 163 | ) 164 | } 165 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "allowSyntheticDefaultImports": true, 5 | "noEmit": true, 6 | "pretty": true, 7 | "lib": ["esnext"], 8 | "moduleResolution": "node", 9 | "skipLibCheck": true 10 | }, 11 | "include": [ 12 | "packages/*/src/", 13 | "packages/*/test/", 14 | "tasks/" 15 | ] 16 | } 17 | --------------------------------------------------------------------------------