├── .nvmrc
├── .eslintignore
├── .npmrc
├── NOTICE
├── packages
├── web-scripts-utils
│ ├── .eslintignore
│ ├── __fixtures__
│ │ └── demo-lib
│ │ │ ├── src
│ │ │ └── index.ts
│ │ │ ├── tsconfig.json
│ │ │ └── package.json
│ ├── tsconfig.json
│ ├── src
│ │ ├── index.ts
│ │ ├── get-consuming-root.ts
│ │ ├── has-key-in-obj.ts
│ │ ├── has-key-in-obj.test.ts
│ │ ├── has-config.ts
│ │ └── has-config.test.ts
│ ├── package.json
│ └── CHANGELOG.md
├── web-scripts
│ ├── .eslintignore
│ ├── __fixtures__
│ │ ├── index.js
│ │ ├── index.ts
│ │ ├── Component.jsx
│ │ ├── Component.tsx
│ │ ├── index.test.js
│ │ ├── index.test.ts
│ │ ├── Component.test.jsx
│ │ └── Component.test.tsx
│ ├── bin
│ │ └── web-scripts
│ ├── src
│ │ ├── Tasks
│ │ │ ├── FormatTask
│ │ │ │ ├── __fixtures__
│ │ │ │ │ └── poorly-formatted-file.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── index.test.ts
│ │ │ ├── AuditTasks
│ │ │ │ ├── __fixtures__
│ │ │ │ │ ├── 0
│ │ │ │ │ │ └── package.json
│ │ │ │ │ ├── 12
│ │ │ │ │ │ └── package.json
│ │ │ │ │ └── 30
│ │ │ │ │ │ └── package.json
│ │ │ │ ├── index.ts
│ │ │ │ └── index.test.ts
│ │ │ ├── TestTask.ts
│ │ │ ├── LintTask.ts
│ │ │ ├── BuildTask.ts
│ │ │ └── CommitTasks.ts
│ │ ├── Paths.test.ts
│ │ ├── @types
│ │ │ └── index.d.ts
│ │ ├── Paths.ts
│ │ ├── SharedTypes.ts
│ │ ├── integration.test.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── config
│ │ ├── README.md
│ │ ├── tsconfig.json
│ │ ├── eslintrc.js
│ │ ├── prettier.config.js
│ │ ├── jest.config.js
│ │ ├── commitlint.config.js
│ │ └── lint-staged.config.js
│ ├── package.json
│ └── README.md
├── create-web-scripts-library
│ ├── bin
│ │ └── create-web-scripts-library
│ ├── tsconfig.json
│ ├── .eslintignore
│ ├── README.md
│ ├── src
│ │ ├── get-install-cmd.ts
│ │ ├── cli.ts
│ │ ├── messages.ts
│ │ ├── index.ts
│ │ └── integration.test.ts
│ └── package.json
├── eslint-plugin
│ ├── tsconfig.json
│ ├── .eslintrc.json
│ ├── src
│ │ ├── rules
│ │ │ └── best-practices
│ │ │ │ ├── no-discouraged-words.md
│ │ │ │ ├── no-discouraged-words.ts
│ │ │ │ └── no-discouraged-words.test.ts
│ │ ├── util
│ │ │ ├── helpers.ts
│ │ │ └── testHelpers.ts
│ │ └── index.ts
│ ├── README.md
│ ├── package.json
│ └── CHANGELOG.md
├── eslint-config
│ ├── README.md
│ ├── package.json
│ └── index.js
├── prettier-config
│ ├── README.md
│ ├── package.json
│ ├── index.js
│ └── CHANGELOG.md
├── eslint-config-base
│ ├── package.json
│ ├── index.js
│ ├── README.md
│ ├── es6.js
│ └── CHANGELOG.md
├── eslint-config-react
│ ├── README.md
│ ├── package.json
│ ├── index.js
│ └── CHANGELOG.md
├── eslint-config-typescript
│ ├── README.md
│ ├── package.json
│ ├── index.js
│ └── CHANGELOG.md
└── tsconfig
│ ├── package.json
│ ├── tsconfig.json
│ ├── docs
│ ├── README.md
│ ├── guides
│ │ ├── cra.md
│ │ └── next.md
│ └── examples.md
│ ├── README.md
│ └── CHANGELOG.md
├── .prettierrc.js
├── .husky
├── commit-msg
└── pre-commit
├── catalog-info.yaml
├── .eslintrc.json
├── .gitmodules
├── postinstall.sh
├── lerna.json
├── .github
├── workflows
│ ├── test.yml
│ ├── rebase.yml
│ ├── publish.yml
│ ├── publish-develop.yml
│ └── publish-release.yml
└── dependabot.yaml
├── package.json
├── .gitignore
├── release.sh
└── README.md
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | .gitignore
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmjs.org
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | web-scripts
2 | Copyright 2019 Spotify AB
3 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/.eslintignore:
--------------------------------------------------------------------------------
1 | __fixtures__
--------------------------------------------------------------------------------
/packages/web-scripts/.eslintignore:
--------------------------------------------------------------------------------
1 | __fixtures__
2 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./packages/prettier-config');
2 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/index.js:
--------------------------------------------------------------------------------
1 | export const sum = (a, b) => a + b;
2 |
--------------------------------------------------------------------------------
/packages/web-scripts/bin/web-scripts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('../cjs');
3 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/__fixtures__/demo-lib/src/index.ts:
--------------------------------------------------------------------------------
1 | export const a = () => '';
2 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/index.ts:
--------------------------------------------------------------------------------
1 | export const sum = (a: number, b: number) => a + b;
2 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | yarn web-scripts commitmsg --edit="$1"
5 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/bin/create-web-scripts-library:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('../cjs/cli');
3 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | yarn web-scripts precommit --no-tests --no-typecheck
5 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/FormatTask/__fixtures__/poorly-formatted-file.ts:
--------------------------------------------------------------------------------
1 | // prettier-ignore
2 | export const FOO = "bar"
3 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/__fixtures__/demo-lib/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@spotify/tsconfig",
3 | "include": ["src"]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/Component.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | export const Component = () =>
hello, world.
;
3 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/Component.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | export const Component = () => hello, world.
;
3 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@spotify/web-scripts/config/tsconfig.json",
3 | "include": ["src"]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/index.test.js:
--------------------------------------------------------------------------------
1 | import { sum } from './';
2 | test('sum', () => {
3 | expect(sum(1, 1)).toEqual(2);
4 | });
5 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/index.test.ts:
--------------------------------------------------------------------------------
1 | import { sum } from './';
2 | test('sum', () => {
3 | expect(sum(1, 1)).toEqual(2);
4 | });
5 |
--------------------------------------------------------------------------------
/catalog-info.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: backstage.io/v1alpha1
2 | kind: Component
3 | metadata:
4 | name: web-scripts
5 | spec:
6 | type: library
7 | owner: web-infra
8 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/.eslintignore:
--------------------------------------------------------------------------------
1 | # coverage
2 | coverage/
3 |
4 | # web-scripts generated files
5 | cjs/
6 | esm/
7 | types/
8 |
9 | # ignore the template
10 | template/
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@spotify", "@spotify/eslint-config-oss"],
3 | "ignorePatterns": [
4 | "__fixtures__",
5 | "packages/create-web-scripts-library/template"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "packages/create-web-scripts-library/template"]
2 | path = packages/create-web-scripts-library/template
3 | url = https://github.com/spotify/web-scripts-library-template.git
4 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/AuditTasks/__fixtures__/0/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "audit-test",
3 | "description": "This test has no dependencies, so the audit dependency should return a status code of 0"
4 | }
5 |
--------------------------------------------------------------------------------
/packages/web-scripts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@spotify/tsconfig",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "isolatedModules": false,
6 | "noEmit": true,
7 | "jsx": "preserve"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/AuditTasks/__fixtures__/12/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "audit-test",
3 | "description": "Throws a high and moderate status. See => https://www.npmjs.com/advisories/10",
4 | "devDependencies": {
5 | "geddy": "13.0.7"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@spotify/tsconfig",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "isolatedModules": false,
6 | "noEmit": true,
7 | "declaration": false,
8 | "jsx": "preserve"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/Component.test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { Component } from './Component';
4 |
5 | describe('testing JSX in tests', () => {
6 | it('does not throw', () => {
7 | expect(() => ).not.toThrow();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/packages/web-scripts/__fixtures__/Component.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { Component } from './Component';
4 |
5 | describe('testing JSX in tests', () => {
6 | it('does not throw', () => {
7 | expect(() => ).not.toThrow();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@spotify/web-scripts/config/tsconfig.json",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "types": ["node", "jest"],
6 | "isolatedModules": false,
7 | "noEmit": true,
8 | "jsx": "preserve"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/README.md:
--------------------------------------------------------------------------------
1 | This folder contains the configuration files for consumers of this CLI. Right now, they are simply symlinks to what the CLI itself uses. In the future they could drift. Even if they do, this folder ensures that consumers will not have to change their paths.
2 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@spotify/tsconfig",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "declaration": true,
6 | "isolatedModules": false,
7 | "jsx": "react",
8 | "lib": ["es6", "dom"],
9 | "module": "commonjs",
10 | "sourceMap": true,
11 | "target": "es6"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/postinstall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | web-scripts audit --help &> /dev/null
3 |
4 | if ! [ $? -eq 0 ]; then
5 | echo "Bootstrapping web-scripts..."
6 | yarn lerna run bootstrap
7 | fi
8 |
9 | git submodule update --init --recursive
10 | # gotta remove threshold low until semantic-release gets their lives in order
11 | web-scripts audit # --threshold low
12 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "overrides": [
3 | {
4 | "files": [
5 | "src/rules/best-practices/no-discouraged-words.{md,ts}",
6 | "src/rules/best-practices/no-discouraged-words.test.ts"
7 | ],
8 | "rules": {
9 | "@spotify/best-practices/no-discouraged-words": "off"
10 | }
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/AuditTasks/__fixtures__/30/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "audit-test",
3 | "description": "Throws a high and moderate status. See => https://www.npmjs.com/advisories/10 + 48 + 1 ",
4 | "devDependencies": {
5 | "bassmaster": "1.5.1",
6 | "geddy": "13.0.7",
7 | "uglify-js": "2.5.0",
8 | "chokidar": "2.1.8"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/__fixtures__/demo-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "some-dummy-project",
3 | "jest": {
4 | "collectCoverageFrom": "src/**/*.ts"
5 | },
6 | "dependencies": {
7 | "react": "*"
8 | },
9 | "devDependencies": {
10 | "@testing-library/react": "*"
11 | },
12 | "peerDependencies": {
13 | "styled-components": "*"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": ["packages/*"],
3 | "npmClient": "yarn",
4 | "useWorkspaces": true,
5 | "version": "15.0.0",
6 | "command": {
7 | "publish": {
8 | "ignoreChanges": [
9 | "*.md",
10 | "__test__/**",
11 | "__fixtures__/**",
12 | "**/*.test.{j|t}s",
13 | "@(!(package)).json"
14 | ]
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/eslint-config/README.md:
--------------------------------------------------------------------------------
1 | # @spotify/eslint-config
2 |
3 | Spotify's TypeScript full ESLint config.
4 |
5 | ## Installation
6 |
7 | ```sh
8 | npm install --save-dev eslint @spotify/eslint-config
9 | ```
10 |
11 | ## Usage
12 |
13 | After installing, update your project's ESLint config:
14 |
15 | ```js
16 | {
17 | "extends" : ["@spotify"]
18 | }
19 | ```
20 |
21 | ---
22 |
23 | Read the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
24 | for more information.
25 |
--------------------------------------------------------------------------------
/packages/prettier-config/README.md:
--------------------------------------------------------------------------------
1 | # prettier-config
2 |
3 | Spotify's base Prettier config.
4 |
5 | ## Installation
6 |
7 | ```sh
8 | yarn add --dev @spotify/prettier-config
9 | ```
10 |
11 | ## Usage
12 |
13 | After installing, update your project's `prettier.config.js` file to import the rule sets you want:
14 |
15 | ```js
16 | module.exports = {
17 | ...require('@spotify/prettier-config'),
18 | // your overrides here
19 | };
20 | ```
21 |
22 | ---
23 |
24 | Read the [Prettier config docs](https://prettier.io) for more information.
25 |
--------------------------------------------------------------------------------
/packages/eslint-config-base/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/eslint-config-base",
3 | "version": "15.0.0",
4 | "license": "Apache-2.0",
5 | "description": "Spotify's base ESLint config",
6 | "main": "index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/spotify/web-scripts.git"
10 | },
11 | "scripts": {},
12 | "peerDependencies": {
13 | "eslint": ">=7.x"
14 | },
15 | "publishConfig": {
16 | "access": "public"
17 | },
18 | "engines": {
19 | "node": ">=18"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/prettier-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/prettier-config",
3 | "version": "15.0.0",
4 | "license": "Apache-2.0",
5 | "description": "Spotify's base Prettier config",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/spotify/web-scripts.git"
9 | },
10 | "main": "index.js",
11 | "scripts": {},
12 | "devDependencies": {
13 | "prettier": "^2.8.8"
14 | },
15 | "peerDependencies": {
16 | "prettier": "2.x"
17 | },
18 | "publishConfig": {
19 | "access": "public"
20 | },
21 | "engines": {
22 | "node": ">=18"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/eslint-config-react/README.md:
--------------------------------------------------------------------------------
1 | # eslint-config-react
2 |
3 | Spotify's ESLint config for react.
4 |
5 | ## Installation
6 |
7 | ```sh
8 | yarn add --dev @spotify/eslint-config-react eslint eslint-plugin-react eslint-plugin-jsx-a11y
9 | ```
10 |
11 | ## Usage
12 |
13 | After installing, update your project's `.eslintrc.json` file to import the rule sets you want:
14 |
15 | ```js
16 | {
17 | "extends" : [
18 | "@spotify/eslint-config-react"
19 | ]
20 | }
21 | ```
22 |
23 | ---
24 |
25 | Read the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
26 | for more information.
27 |
--------------------------------------------------------------------------------
/packages/eslint-config-typescript/README.md:
--------------------------------------------------------------------------------
1 | # eslint-config-typescript
2 |
3 | Spotify's TypeScript ESLint config extras.
4 |
5 | ## Installation
6 |
7 | ```sh
8 | npm install --save-dev @spotify/eslint-config-typescript
9 | ```
10 |
11 | ## Usage
12 |
13 | After installing, update your project's `.eslintrc.json` file to import the rule sets you want:
14 |
15 | ```js
16 | {
17 | "extends" : [
18 | "@spotify/eslint-config-base",
19 | "@spotify/eslint-config-typescript"
20 | ]
21 | }
22 | ```
23 |
24 | ---
25 |
26 | Read the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
27 | for more information.
28 |
--------------------------------------------------------------------------------
/packages/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/tsconfig",
3 | "version": "15.0.0",
4 | "license": "Apache-2.0",
5 | "description": "Common tsconfigs to be used as your base configurations",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/spotify/web-scripts.git"
9 | },
10 | "main": "tsconfig.json",
11 | "files": [
12 | "tsconfig.json"
13 | ],
14 | "scripts": {
15 | "test": "true"
16 | },
17 | "devDependencies": {
18 | "typescript": "^5.0.4"
19 | },
20 | "peerDependencies": {
21 | "typescript": ">=5"
22 | },
23 | "publishConfig": {
24 | "access": "public"
25 | },
26 | "engines": {
27 | "node": ">=18"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/eslintrc.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = {
17 | extends: ['@spotify'],
18 | };
19 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/prettier.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = require('@spotify/prettier-config');
17 |
--------------------------------------------------------------------------------
/packages/eslint-config-base/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = {
17 | extends: ['./es5.js', './es6.js'],
18 | };
19 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | export { getConsumingRoot } from './get-consuming-root';
17 | export { hasConfig } from './has-config';
18 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/README.md:
--------------------------------------------------------------------------------
1 | # `create-web-scripts-library`
2 |
3 | Scaffold a [@spotify/web-scripts](https://github.com/spotify/web-scripts) library quickly. Code was directly inspired by [create-next-app](https://github.com/zeit/create-next-app).
4 |
5 | ## Usage
6 |
7 | ### With `yarn create`
8 |
9 | ```sh
10 | yarn create @spotify/web-scripts-library my-cool-library
11 | ```
12 |
13 | ### With `npx`
14 |
15 | ```sh
16 | npx @spotify/create-web-scripts-library my-cool-library
17 | ```
18 |
19 | ### Programatically
20 |
21 | ```javascript
22 | const path = require('path');
23 | const createWebScriptsLibrary = require('@spotify/create-web-scripts-library');
24 |
25 | async function start() {
26 | await createWebScriptsLibrary(path.resolve('my-cool-library'));
27 | }
28 | ```
29 |
--------------------------------------------------------------------------------
/packages/eslint-config-typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/eslint-config-typescript",
3 | "version": "15.0.0",
4 | "license": "Apache-2.0",
5 | "description": "Spotify's ESLint config for TypeScript",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/spotify/web-scripts.git"
9 | },
10 | "main": "index.js",
11 | "scripts": {},
12 | "devDependencies": {
13 | "@typescript-eslint/eslint-plugin": "^5.59.6",
14 | "@typescript-eslint/parser": "^5.59.6",
15 | "eslint": "^8.40.0"
16 | },
17 | "peerDependencies": {
18 | "@typescript-eslint/eslint-plugin": ">=5",
19 | "@typescript-eslint/parser": ">=5",
20 | "eslint": ">=8.x"
21 | },
22 | "publishConfig": {
23 | "access": "public"
24 | },
25 | "engines": {
26 | "node": ">=18"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - '*'
10 |
11 | jobs:
12 | test:
13 | name: Test on node ${{ matrix.node-version }}
14 | runs-on: ubuntu-latest
15 |
16 | strategy:
17 | matrix:
18 | node-version: [18]
19 |
20 | steps:
21 | - uses: actions/checkout@v2
22 | with:
23 | fetch-depth: 0
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v2
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | - name: yarn install
29 | run: yarn install --frozen-lockfile
30 | - name: yarn build
31 | run: yarn build
32 | - name: lint
33 | run: yarn lint
34 | - name: test
35 | run: yarn test
36 |
--------------------------------------------------------------------------------
/packages/eslint-config-base/README.md:
--------------------------------------------------------------------------------
1 | # @spotify/eslint-config-base
2 |
3 | Spotify's base ESLint config.
4 |
5 | ## Installation
6 |
7 | ```sh
8 | yarn add --dev @spotify/eslint-config-base eslint
9 | ```
10 |
11 | ## Usage
12 |
13 | After installing, update your project's `.eslintrc.json` file to import the rule sets you want:
14 |
15 | ```js
16 | {
17 | "extends" : [
18 | "@spotify/eslint-config-base"
19 | ]
20 | }
21 | ```
22 |
23 | ### ES5 only
24 |
25 | ```js
26 | {
27 | "extends" : [
28 | "@spotify/eslint-config-base/es5"
29 | ]
30 | }
31 | ```
32 |
33 | ### ES6+ only
34 |
35 | ```js
36 | {
37 | "extends" : [
38 | "@spotify/eslint-config-base/es6"
39 | ]
40 | }
41 | ```
42 |
43 | ---
44 |
45 | Read the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
46 | for more information.
47 |
--------------------------------------------------------------------------------
/.github/workflows/rebase.yml:
--------------------------------------------------------------------------------
1 | on:
2 | issue_comment:
3 | types: [created]
4 | name: Automatic Rebase
5 | jobs:
6 | rebase:
7 | name: Rebase
8 | if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@master
12 | with:
13 | fetch-depth: 0
14 | - name: Automatic Rebase
15 | uses: cirrus-actions/rebase@1.2
16 | env:
17 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
18 | # https://github.community/t5/GitHub-Actions/Workflow-is-failing-if-no-job-can-be-ran-due-to-condition/m-p/38186#M3250
19 | always_job:
20 | name: Always run job
21 | runs-on: ubuntu-latest
22 | steps:
23 | - name: Always run
24 | run: echo "This job is used to prevent the workflow to fail when all other jobs are skipped."
25 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/src/rules/best-practices/no-discouraged-words.md:
--------------------------------------------------------------------------------
1 | # Prevents usage of discouraged words. (best-practices/no-discouraged-words)
2 |
3 | Use in order to prevent discouraged words in variable names and comments.
4 |
5 | ```js
6 | // .eslintrc.json
7 | {
8 | "plugins": ["@spotify/eslint-plugin"],
9 | "rules": {
10 | "@spotify/best-practices/no-discouraged-words": "error",
11 | }
12 | }
13 | ```
14 |
15 | ## Discouraged words
16 |
17 | ```js
18 | const discouragedWords = ['blacklist', 'whitelist'];
19 | ```
20 |
21 | To make a contribution to the list, see [this file](./no-discouraged-words.ts). PRs are most welcome!
22 |
23 | ## Rule details
24 |
25 | This rule will raise the following error whenever you refer to one of the discouraged words above:
26 |
27 | > Usage of the word "{word}" is strongly discouraged. Please use a different word.
28 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/src/util/helpers.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export const createDocsUrl = (pathname: string): string => {
18 | return `https://github.com/spotify/web-scripts/blob/master/packages/eslint-plugin/src/rules/${pathname}`;
19 | };
20 |
--------------------------------------------------------------------------------
/packages/eslint-config-react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/eslint-config-react",
3 | "version": "15.0.0",
4 | "license": "Apache-2.0",
5 | "description": "Spotify's ESLint config for React projects",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/spotify/web-scripts.git"
9 | },
10 | "main": "index.js",
11 | "scripts": {},
12 | "devDependencies": {
13 | "eslint": "^8.40.0",
14 | "eslint-plugin-jsx-a11y": "^6.4.1",
15 | "eslint-plugin-react": "^7.32.2",
16 | "eslint-plugin-react-hooks": "^4.2.0"
17 | },
18 | "peerDependencies": {
19 | "eslint": ">=8.x",
20 | "eslint-plugin-jsx-a11y": "6.x",
21 | "eslint-plugin-react": ">=7.7.0 <8",
22 | "eslint-plugin-react-hooks": "^4.0.0"
23 | },
24 | "publishConfig": {
25 | "access": "public"
26 | },
27 | "engines": {
28 | "node": ">=18"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/src/get-consuming-root.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { resolve } from 'path';
17 |
18 | // The ROOT folder of the consuming package,
19 | // aka where the user is using this package from.
20 | export const getConsumingRoot = () => resolve(process.cwd());
21 |
--------------------------------------------------------------------------------
/packages/tsconfig/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": false,
4 | "experimentalDecorators": false,
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "importHelpers": false,
8 | "incremental": true,
9 | "isolatedModules": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "noEmit": true,
13 | "noFallthroughCasesInSwitch": true,
14 | "noImplicitAny": true,
15 | "noImplicitReturns": true,
16 | "noImplicitThis": true,
17 | "noUnusedLocals": true,
18 | "noUnusedParameters": true,
19 | "pretty": true,
20 | "removeComments": true,
21 | "resolveJsonModule": true,
22 | "strict": true,
23 | "strictBindCallApply": true,
24 | "strictFunctionTypes": true,
25 | "strictNullChecks": true,
26 | "strictPropertyInitialization": true,
27 | "stripInternal": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/web-scripts-monorepo",
3 | "private": true,
4 | "license": "Apache-2.0",
5 | "repository": {
6 | "type": "git",
7 | "url": "git+https://github.com/spotify/web-scripts.git"
8 | },
9 | "scripts": {
10 | "postinstall": "./postinstall.sh",
11 | "test": "lerna run test --stream",
12 | "build": "lerna run build --stream",
13 | "lint": "web-scripts lint --no-typecheck",
14 | "format": "web-scripts format",
15 | "commit": "web-scripts commit",
16 | "bootstrap": "lerna bootstrap --use-workspaces",
17 | "release": "./release.sh",
18 | "prepare": "husky install"
19 | },
20 | "workspaces": [
21 | "packages/*"
22 | ],
23 | "devDependencies": {
24 | "@spotify/eslint-config-oss": "^1.0.0",
25 | "@spotify/eslint-plugin": "^14.1.6",
26 | "husky": "^8.0.1",
27 | "lerna": "^6.6.2",
28 | "typescript": "^5.0.4"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.github/dependabot.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: /
5 | schedule:
6 | interval: daily
7 | - package-ecosystem: npm
8 | directory: /packages/web-scripts/src/Tasks/AuditTasks/__fixtures__/12
9 | schedule:
10 | interval: daily
11 | ignore:
12 | # these dependencies are intentionally included in
13 | # the test fixtures to see if the audit task works as designed
14 | - dependency-name: geddy
15 | - package-ecosystem: npm
16 | directory: /packages/web-scripts/src/Tasks/AuditTasks/__fixtures__/30
17 | schedule:
18 | interval: daily
19 | ignore:
20 | # these dependencies are intentionally included in
21 | # the test fixtures to see if the audit task works as designed
22 | - dependency-name: bassmaster
23 | - dependency-name: chokidar
24 | - dependency-name: geddy
25 | - dependency-name: uglify-js
26 |
--------------------------------------------------------------------------------
/packages/tsconfig/docs/README.md:
--------------------------------------------------------------------------------
1 | # tsconfig
2 |
3 | A collection of different base `tsconfig.json` to be extended from in your project.
4 |
5 | This project aims to reduce per-project configuration as much as possible. With good defaults, we can focus on building, not configuration!
6 |
7 | ## Installation
8 |
9 | Add TypeScript to your project:
10 |
11 | ```sh
12 | yarn add typescript
13 | ```
14 |
15 | Using npm or yarn:
16 |
17 | ```sh
18 | yarn add --dev @spotify/tsconfig
19 | ```
20 |
21 | ## Examples
22 |
23 | See the [examples documentation](./examples.md) for detailed guidance on how to set up the Spotify TypeScript config for your any library or app.
24 |
25 | ## Getting Started with TypeScript
26 |
27 | Step-by-step guides for setting up TypeScript and the Spotify TypeScript config for Golden Path use cases are available in this repo as well.
28 |
29 | - [Create React App](./guides/cra.md)
30 | - [Next.js](./guides/next.md)
31 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/src/has-key-in-obj.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | export const hasKeyInObj = (
17 | key: string,
18 | obj: { [s: string]: any } = {},
19 | ): boolean => {
20 | const [k, ...restOfK] = key.split('.');
21 | if (restOfK.length === 0) {
22 | return Object.keys(obj).some(ok => ok === k);
23 | }
24 | const nextObj = obj[k];
25 | if (!(nextObj instanceof Object)) {
26 | return false;
27 | }
28 | return hasKeyInObj(restOfK.join('.'), nextObj);
29 | };
30 |
--------------------------------------------------------------------------------
/packages/tsconfig/README.md:
--------------------------------------------------------------------------------
1 | # tsconfig
2 |
3 | Check out our [docs on GitHub].
4 |
5 | A collection of different base `tsconfig.json` to be extended from in your project.
6 |
7 | This project aims to reduce per-project configuration as much as possible. With good defaults, we can focus on building, not configuration!
8 |
9 | ## Installation
10 |
11 | Using npm or yarn:
12 |
13 | ```sh
14 | yarn add --dev @spotify/tsconfig
15 | ```
16 |
17 | For more information, check out our [docs on GitHub].
18 |
19 | ## Contributing
20 |
21 | Try to optimize for the fewest specified options between the config specializations. For example, only `app` has `noEmit: true`, since the [default value][compiler options], `false`, is good for the `lib` config. Specifying it only in the `app` config means fewer overall entries!
22 |
23 | We want to keep maintenance low by only specifying what is necessary. If the option's [default value][compiler options] is good for every config, remove it from every config!
24 |
25 | [compiler options]: https://www.typescriptlang.org/docs/handbook/compiler-options.html
26 | [docs on github]: ./docs
27 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/src/util/testHelpers.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { RuleTester } from 'eslint';
18 |
19 | export const createRuleTester = (): RuleTester => {
20 | return new RuleTester({
21 | parser: require.resolve('@typescript-eslint/parser'),
22 | parserOptions: {
23 | ecmaVersion: 2018,
24 | ecmaFeatures: {
25 | experimentalObjectRestSpread: true,
26 | jsx: true,
27 | },
28 | sourceType: 'module',
29 | },
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/jest.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | const path = require('path');
17 |
18 | module.exports = {
19 | rootDir: path.join(process.cwd(), 'src'),
20 | coverageDirectory: path.join(process.cwd(), 'coverage'),
21 | collectCoverageFrom: ['**/*.{js,jsx,ts,tsx}', '!**/*.d.ts'],
22 | transform: {
23 | '^.+\\.[tj]sx?$': [
24 | 'ts-jest',
25 | {
26 | tsconfig: {
27 | allowJs: true,
28 | },
29 | },
30 | ],
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | publish:
10 | name: Publish
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | with:
16 | # pulls all commits (needed for lerna / semantic release to correctly version)
17 | fetch-depth: '0'
18 | # pulls all tags (needed for lerna / semantic release to correctly version)
19 | - name: fetch tags
20 | run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
21 | - uses: actions/setup-node@v2
22 | with:
23 | node-version: 18
24 | - name: yarn install
25 | run: yarn install --frozen-lockfile
26 | - name: yarn build
27 | run: yarn build
28 | - name: lint
29 | run: yarn lint
30 | - name: test
31 | run: yarn test
32 | - name: release
33 | run: yarn release
34 | env:
35 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36 | GH_TOKEN: ${{ secrets.GH_TOKEN }}
37 | GH_USERNAME: ${{ secrets.GH_USERNAME }}
38 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/src/get-install-cmd.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | // from https://github.com/zeit/create-next-app/blob/master/lib/utils/get-install-cmd.js
17 |
18 | import execa from 'execa';
19 |
20 | let cmd: string;
21 |
22 | export default function getInstallCmd() {
23 | if (cmd) {
24 | return cmd;
25 | }
26 |
27 | try {
28 | execa.commandSync('yarnpkg --version');
29 | cmd = 'yarn';
30 | } catch (e) {
31 | cmd = 'npm';
32 | }
33 |
34 | return cmd;
35 | }
36 |
--------------------------------------------------------------------------------
/packages/tsconfig/docs/guides/cra.md:
--------------------------------------------------------------------------------
1 | # Create React App
2 |
3 | **This assumes you are using `react-scripts` v2.1 or higher!**
4 |
5 | ## Install TypeScript
6 |
7 | Install TypeScript and configure it for use with Create React App by following their [brief tutorial](https://facebook.github.io/create-react-app/docs/adding-typescript).
8 |
9 | _Feel free to commit just that part as a first step._
10 |
11 | ## Install and use the Spotify TypeScript config
12 |
13 | Next, install the Spotify TypeScript config as a dev dependency:
14 |
15 | ```sh
16 | yarn add -D @spotify/tsconfig
17 | ```
18 |
19 | Create React App will have already created a `tsconfig.json` for you. In this file, add an `extends` configuration:
20 |
21 | ```json
22 | {
23 | "extends": "@spotify/tsconfig",
24 | "include": ["src"]
25 | }
26 | ```
27 |
28 | Start your server up. At this point, Create React App will probably update your tsconfig.json with some defaults they recommend. At the time of writing, these don't conflict with anything the Spotify config attempts to cover, so let Create React App do it.
29 |
30 | _Go ahead and create another commit here once your server runs successfully._
31 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/README.md:
--------------------------------------------------------------------------------
1 | # @spotify/eslint-plugin
2 |
3 | This contains all Spotify-specific eslint rules.
4 |
5 | ## Installation
6 |
7 | ```sh
8 | npm install --save-dev eslint @spotify/eslint-plugin
9 | ```
10 |
11 | ## Rules
12 |
13 | | Category | Name | Description |
14 | | -------------- | --------------------------------------- | ------------------------------------------------------------------------------------ |
15 | | Best Practices | [`best-practices/no-discouraged-words`] | Prevents usage of specific words. [See more][`best-practices/no-discouraged-words`]. |
16 |
17 | [`best-practices/no-discouraged-words`]: https://github.com/spotify/web-scripts/blob/master/packages/eslint-spotify/src/rules/best-practices/no-discouraged-words.md
18 |
19 | ## Usage
20 |
21 | After installing, update your project's `.eslintrc.json` config:
22 |
23 | ```js
24 | {
25 | "plugins": ["@spotify/eslint-plugin"],
26 | }
27 | ```
28 |
29 | ---
30 |
31 | Read the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information.
32 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Paths.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { stat as statFS } from 'fs';
17 | import { promisify } from 'util';
18 | const stat = promisify(statFS);
19 | import * as Paths from './Paths';
20 |
21 | test('Paths are exported and exist', async () => {
22 | expect(await stat(Paths.CONSUMING_ROOT)).toBeTruthy();
23 | expect(await stat(Paths.THIS_ROOT)).toBeTruthy();
24 | expect(await stat(Paths.ESLINT_CONFIG)).toBeTruthy();
25 | expect(await stat(Paths.PRETTIER_CONFIG)).toBeTruthy();
26 | expect(await stat(Paths.TSCONFIG)).toBeTruthy();
27 | });
28 |
--------------------------------------------------------------------------------
/packages/tsconfig/docs/guides/next.md:
--------------------------------------------------------------------------------
1 | # Next.js
2 |
3 | **This assumes you are using `next` v9 or higher!**
4 |
5 | ## Install TypeScript in your Next app
6 |
7 | Install TypeScript and configure it for use with Next by following their [brief tutorial](https://github.com/zeit/next.js#typescript).
8 |
9 | _Feel free to commit just that part as a first step._
10 |
11 | ## Install and use the Spotify TypeScript config
12 |
13 | Next, install the Spotify TypeScript config as a dev dependency:
14 |
15 | ```sh
16 | yarn add -D @spotify/tsconfig
17 | ```
18 |
19 | You will have already created a `tsconfig.json` in the tutorial, and it should contain some defaults from Next. In this file, add an `extends` configuration:
20 |
21 | ```json
22 | {
23 | "extends": "@spotify/tsconfig"
24 | }
25 | ```
26 |
27 | Start your server up. Be sure to test that TypeScript is all working by changing the file extension of something in `pages` from `.js` to `.tsx`.
28 |
29 | You can test that type failures break your build by doing some invalid TypeScript:
30 |
31 | ```ts
32 | let a = 1;
33 | console.log(a);
34 | a = 'foo';
35 | ```
36 |
37 | _Go ahead and create another commit here once your server runs successfully._
38 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import path from 'path';
18 | import { Rule } from 'eslint';
19 |
20 | type RulesInput = string[];
21 | type RulesOutput = { [key: string]: Rule.RuleModule };
22 |
23 | const exportRules = (rulesInput: RulesInput): RulesOutput => {
24 | return rulesInput.reduce(
25 | (rulesOutput, rule) => ({
26 | ...rulesOutput,
27 | [rule]: require(`./${path.join('./rules/', rule)}`).default,
28 | }),
29 | {} as RulesOutput,
30 | );
31 | };
32 |
33 | module.exports = {
34 | rules: exportRules(['best-practices/no-discouraged-words']),
35 | };
36 |
--------------------------------------------------------------------------------
/.github/workflows/publish-develop.yml:
--------------------------------------------------------------------------------
1 | name: Publish Develop Branch
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 |
8 | jobs:
9 | publish:
10 | name: Publish Develop Branch
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | with:
16 | # pulls all commits (needed for lerna / semantic release to correctly version)
17 | fetch-depth: '0'
18 | # pulls all tags (needed for lerna / semantic release to correctly version)
19 | - name: fetch tags
20 | run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
21 | - uses: actions/setup-node@v2
22 | with:
23 | node-version: 18
24 | - name: yarn install
25 | run: yarn install --frozen-lockfile
26 | - name: yarn build
27 | run: yarn build
28 | - name: lint
29 | run: yarn lint
30 | - name: test
31 | run: yarn test
32 | - name: copy token
33 | run: echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} >> ~/.npmrc
34 | env:
35 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36 | - name: publish
37 | run: npx lerna publish --yes --canary --preid dev --dist-tag dev --conventional-commits --registry=https://registry.npmjs.org
38 |
--------------------------------------------------------------------------------
/.github/workflows/publish-release.yml:
--------------------------------------------------------------------------------
1 | name: Publish Release Branch
2 |
3 | on:
4 | push:
5 | branches:
6 | - release
7 |
8 | jobs:
9 | publish:
10 | name: Publish Release Branch
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | with:
16 | # pulls all commits (needed for lerna / semantic release to correctly version)
17 | fetch-depth: '0'
18 | # pulls all tags (needed for lerna / semantic release to correctly version)
19 | - name: fetch tags
20 | run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
21 | - uses: actions/setup-node@v2
22 | with:
23 | node-version: 18
24 | - name: yarn install
25 | run: yarn install --frozen-lockfile
26 | - name: yarn build
27 | run: yarn build
28 | - name: lint
29 | run: yarn lint
30 | - name: test
31 | run: yarn test
32 | - name: copy token
33 | run: echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} >> ~/.npmrc
34 | env:
35 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36 | - name: publish
37 | run: npx lerna publish --yes --canary --preid rc --dist-tag prerelease --conventional-commits --registry=https://registry.npmjs.org
38 |
--------------------------------------------------------------------------------
/packages/prettier-config/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | // defaults have been commented out
17 | // https://prettier.io/docs/en/options.html
18 |
19 | module.exports = {
20 | // printWidth: 80,
21 | // tabWidth: 2,
22 | // useTabs: false,
23 | // semi: true,
24 | singleQuote: true,
25 | // jsxSingleQuote: false,
26 | trailingComma: 'all',
27 | // bracketSpacing: true,
28 | // jsxBracketSameLine: false,
29 | arrowParens: 'avoid',
30 | // rangeStart: 0,
31 | // rangeEnd: Infinity,
32 | // requirePragma: false,
33 | // insertPragma: false,
34 | // proseWrap: 'preserve',
35 | // htmlWhitespaceSensitivity: 'css',
36 | // endOfLine: 'auto',
37 | };
38 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/commitlint.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = {
17 | extends: ['@commitlint/config-conventional'],
18 | rules: {
19 | 'subject-case': [
20 | 1,
21 | 'never',
22 | ['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
23 | ],
24 | 'type-enum': [
25 | 1,
26 | 'always',
27 | [
28 | 'feat',
29 | 'fix',
30 | 'improvement',
31 | 'docs',
32 | 'style',
33 | 'refactor',
34 | 'perf',
35 | 'test',
36 | 'build',
37 | 'ci',
38 | 'chore',
39 | 'revert',
40 | ],
41 | ],
42 | },
43 | };
44 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/web-scripts-utils",
3 | "version": "15.0.0",
4 | "description": "Private package which contains re-used utils within web-scripts projects",
5 | "license": "Apache-2.0",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/spotify/web-scripts.git"
9 | },
10 | "main": "cjs/index.js",
11 | "module": "esm/index.js",
12 | "types": "types",
13 | "files": [
14 | "cjs",
15 | "esm",
16 | "types"
17 | ],
18 | "scripts": {
19 | "clean": "rm -rf cjs esm types",
20 | "build": "web-scripts build",
21 | "test": "web-scripts test",
22 | "lint": "web-scripts lint --stylecheck",
23 | "format": "web-scripts format",
24 | "bootstrap": "yarn run clean && tsc --allowJs --outDir cjs --noEmit false --module CommonJS && tsc --declaration --isolatedModules false --outDir types --emitDeclarationOnly --noEmit false",
25 | "prepublishOnly": "yarn run bootstrap && yarn run build"
26 | },
27 | "dependencies": {
28 | "@types/glob": "8.1.0",
29 | "glob": "8.1.0",
30 | "read-pkg-up": "^7.0.1"
31 | },
32 | "devDependencies": {
33 | "@spotify/tsconfig": "^15.0.0",
34 | "@types/jest": "^29.5.1"
35 | },
36 | "publishConfig": {
37 | "access": "public"
38 | },
39 | "engines": {
40 | "node": ">=18"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/@types/index.d.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | declare module 'object.fromentries' {
17 | export default function fromEntries(entries: Array<[string, T]>): {
18 | [s: string]: T;
19 | };
20 | }
21 |
22 | // /
23 |
24 | declare module 'cross-spawn-promise' {
25 | import { SpawnOptions } from 'child_process';
26 |
27 | interface CrossSpawnOptions extends SpawnOptions {
28 | encoding: string;
29 | }
30 |
31 | interface CrossSpawnError {
32 | exitStatus: number;
33 | message: string;
34 | stack: string;
35 | stderr: Uint8Array;
36 | stdout: Uint8Array | null;
37 | }
38 |
39 | export default function crossSpawnPromise(
40 | cmd: string,
41 | args?: any[],
42 | options?: Partial,
43 | ): Promise;
44 | }
45 |
--------------------------------------------------------------------------------
/packages/eslint-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/eslint-config",
3 | "version": "15.0.0",
4 | "description": "Combined ESLint config for Spotify",
5 | "author": "Paul Marbach ",
6 | "homepage": "https://github.com/spotify/web-scripts#readme",
7 | "license": "Apache-2.0",
8 | "main": "index.js",
9 | "files": [
10 | "index.js"
11 | ],
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/spotify/web-scripts.git"
15 | },
16 | "bugs": {
17 | "url": "https://github.com/spotify/web-scripts/issues"
18 | },
19 | "scripts": {},
20 | "dependencies": {
21 | "@spotify/eslint-config-base": "^15.0.0",
22 | "@spotify/eslint-config-react": "^15.0.0",
23 | "@spotify/eslint-config-typescript": "^15.0.0",
24 | "@spotify/eslint-plugin": "^15.0.0",
25 | "@spotify/web-scripts-utils": "^15.0.0",
26 | "@typescript-eslint/eslint-plugin": "^5.59.6",
27 | "@typescript-eslint/parser": "^5.59.6",
28 | "eslint-config-prettier": "^8.8.0",
29 | "eslint-plugin-jest": "^27.1.6",
30 | "eslint-plugin-jsx-a11y": "^6.4.1",
31 | "eslint-plugin-react": "^7.32.2",
32 | "eslint-plugin-react-hooks": "^4.2.0"
33 | },
34 | "devDependencies": {
35 | "eslint": "^8.40.0"
36 | },
37 | "peerDependencies": {
38 | "eslint": ">=8.x"
39 | },
40 | "publishConfig": {
41 | "access": "public"
42 | },
43 | "engines": {
44 | "node": ">=18"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Paths.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { join } from 'path';
17 | import { getConsumingRoot } from '@spotify/web-scripts-utils';
18 |
19 | // The ROOT folder of the consuming package, aka where the user is using this
20 | // package from.
21 | export const CONSUMING_ROOT = getConsumingRoot();
22 |
23 | // This tool's ROOT folder.
24 | export const THIS_ROOT = join(__dirname, '..');
25 |
26 | export const CONFIG_FOLDER = join(THIS_ROOT, 'config');
27 | export const ESLINT_CONFIG = join(CONFIG_FOLDER, 'eslintrc.js');
28 | export const PRETTIER_CONFIG = join(CONFIG_FOLDER, 'prettier.config.js');
29 | export const TSCONFIG = join(CONFIG_FOLDER, 'tsconfig.json');
30 | export const JEST_CONFIG = join(CONFIG_FOLDER, 'jest.config.js');
31 | export const COMMITLINT_CONIFG = join(CONFIG_FOLDER, 'commitlint.config.js');
32 | export const LINT_STAGED_CONFIG = join(CONFIG_FOLDER, 'lint-staged.config.js');
33 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/create-web-scripts-library",
3 | "version": "15.0.0",
4 | "description": "Project scaffolding script for @spotify/web-scripts libraries",
5 | "author": "Paul Marbach ",
6 | "homepage": "https://github.com/spotify/web-scripts#readme",
7 | "license": "Apache-2.0",
8 | "bin": {
9 | "create-web-scripts-library": "bin/create-web-scripts-library"
10 | },
11 | "main": "cjs/index.js",
12 | "module": "esm/index.js",
13 | "types": "types",
14 | "files": [
15 | "cjs",
16 | "esm",
17 | "bin",
18 | "types",
19 | "template",
20 | "package.json"
21 | ],
22 | "repository": {
23 | "type": "git",
24 | "url": "git+https://github.com/spotify/web-scripts.git"
25 | },
26 | "scripts": {
27 | "test": "web-scripts test",
28 | "build": "web-scripts build",
29 | "lint": "web-scripts lint --stylecheck",
30 | "format": "web-scripts format",
31 | "prepublishOnly": "yarn run build"
32 | },
33 | "bugs": {
34 | "url": "https://github.com/spotify/web-scripts/issues"
35 | },
36 | "dependencies": {
37 | "chalk": "^4.0.0",
38 | "commander": "^10.0.1",
39 | "execa": "^5.0.0",
40 | "fs-extra": "^11.1.1",
41 | "read-pkg-up": "^7.0.1"
42 | },
43 | "devDependencies": {
44 | "@spotify/web-scripts": "^15.0.0",
45 | "@types/fs-extra": "^11.0.1",
46 | "tempy": "^1.0.1"
47 | },
48 | "publishConfig": {
49 | "access": "public"
50 | },
51 | "engines": {
52 | "node": ">=18"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/eslint-plugin",
3 | "version": "15.0.0",
4 | "description": "Set of rules for Spotify's custom ESLint rules",
5 | "author": "Bilawal Hameed ",
6 | "homepage": "https://github.com/spotify/web-scripts/blob/master/packages/eslint-plugin#readme",
7 | "keywords": [
8 | "eslint",
9 | "eslint-plugin",
10 | "react",
11 | "typescript"
12 | ],
13 | "license": "Apache-2.0",
14 | "main": "cjs/index.js",
15 | "module": "esm/index.js",
16 | "types": "types",
17 | "files": [
18 | "cjs",
19 | "esm",
20 | "types"
21 | ],
22 | "repository": {
23 | "type": "git",
24 | "url": "git+https://github.com/spotify/web-scripts.git",
25 | "directory": "packages/eslint-plugin"
26 | },
27 | "bugs": {
28 | "url": "https://github.com/spotify/web-scripts/issues"
29 | },
30 | "scripts": {
31 | "build": "web-scripts build",
32 | "test": "web-scripts test",
33 | "lint": "web-scripts lint --stylecheck",
34 | "format": "web-scripts format"
35 | },
36 | "devDependencies": {
37 | "@spotify/web-scripts": "^15.0.0",
38 | "@types/eslint": "^8.37.0",
39 | "@types/jest": "^29.5.1",
40 | "@typescript-eslint/parser": "^5.59.6",
41 | "@typescript-eslint/types": "^5.59.6",
42 | "eslint": "^8.40.0",
43 | "typescript": "^5.0.4"
44 | },
45 | "peerDependencies": {
46 | "@typescript-eslint/parser": "^5.13.0",
47 | "eslint": ">=8.x"
48 | },
49 | "publishConfig": {
50 | "access": "public"
51 | },
52 | "engines": {
53 | "node": ">=18"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/src/cli.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { program } from 'commander';
17 | import chalk from 'chalk';
18 |
19 | import createWebScriptsLibrary from '.';
20 |
21 | // MUST require and not import this to avoid wrecking the
22 | // file structure in the build output.
23 | const pkg = require('../package.json');
24 |
25 | let projectName: string;
26 |
27 | program
28 | .version(pkg.version)
29 | .arguments('')
30 | .usage(`${chalk.green('')} [options]`)
31 | .action((name: string) => {
32 | projectName = name;
33 | })
34 | .allowUnknownOption()
35 | .parse(process.argv);
36 |
37 | async function run() {
38 | try {
39 | await createWebScriptsLibrary(projectName);
40 | } catch (err) {
41 | /* eslint-disable no-console */
42 | console.log(chalk.redBright('Failed to create your project!'));
43 | console.log((err as Error).message);
44 | /* eslint-enable no-console */
45 | process.exit(1);
46 | return;
47 | }
48 | }
49 |
50 | run();
51 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/src/has-key-in-obj.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { hasKeyInObj } from './has-key-in-obj';
17 |
18 | describe('hasKeyInObj', () => {
19 | it('works when the key is defined', () => {
20 | expect(hasKeyInObj('a', { a: 1, b: 2 })).toBe(true);
21 | });
22 |
23 | it('works when the key is not defined', () => {
24 | expect(hasKeyInObj('c', { a: 1, b: 2 })).toBe(false);
25 | });
26 |
27 | it('works when the key is nested and defined', () => {
28 | expect(hasKeyInObj('c.foo', { a: 1, b: 2, c: { foo: 'bar' } })).toBe(true);
29 | });
30 |
31 | it('works when the key is nested and undefined', () => {
32 | expect(hasKeyInObj('c.baz', { a: 1, b: 2, c: { foo: 'bar' } })).toBe(false);
33 | });
34 |
35 | it('works when the key is nested and undefined early', () => {
36 | expect(hasKeyInObj('d.baz', { a: 1, b: 2, c: { foo: 'bar' } })).toBe(false);
37 | });
38 |
39 | it('does not fail when the object is undefined', () => {
40 | expect(() => hasKeyInObj('foo', undefined)).not.toThrow();
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/src/messages.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { program } from 'commander';
17 | import chalk from 'chalk';
18 |
19 | export const missingProjectName = () => `
20 | Please specify the project directory:
21 | ${chalk.cyan(program.name())} ${chalk.green('')}
22 |
23 | For example:
24 | ${chalk.cyan(program.name())} ${chalk.green('my-library-name')}
25 | Run ${chalk.cyan(`${program.name()} --help`)} to see all options.
26 | `;
27 |
28 | export const alreadyExists = (projectName: string) => `
29 | It looks like there's already a directory called "${chalk.cyan(
30 | projectName,
31 | )}". Please try a different name or delete that folder.`;
32 |
33 | export const start = (projectName: string) => `
34 | Your project is now set up in "${chalk.cyan(projectName)}"! Try running
35 |
36 | ${chalk.green('yarn lint')}
37 | ${chalk.green('yarn test')}
38 | ${chalk.green('yarn build')}
39 |
40 | to see the web-scripts in action. When you're ready to publish your package, use ${chalk.green(
41 | 'yarn commit',
42 | )} and ${chalk.green('yarn release')} to use commitizen and semantic-release.`;
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Optional REPL history
57 | .node_repl_history
58 |
59 | # Output of 'npm pack'
60 | *.tgz
61 |
62 | # Yarn Integrity file
63 | .yarn-integrity
64 |
65 | # dotenv environment variables file
66 | .env
67 | .env.test
68 |
69 | # parcel-bundler cache (https://parceljs.org/)
70 | .cache
71 |
72 | # next.js build output
73 | .next
74 |
75 | # nuxt.js build output
76 | .nuxt
77 |
78 | # vuepress build output
79 | .vuepress/dist
80 |
81 | # Serverless directories
82 | .serverless/
83 |
84 | # FuseBox cache
85 | .fusebox/
86 |
87 | # DynamoDB Local files
88 | .dynamodb/
89 |
90 | # web-scripts generated files
91 | cjs/
92 | esm/
93 | types/
94 |
--------------------------------------------------------------------------------
/packages/web-scripts/config/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | const { getEslintConfig } = require('../cjs/Tasks/LintTask');
17 | const { getPrettierConfig } = require('../cjs/Tasks/FormatTask');
18 | const { getJestConfig } = require('../cjs/Tasks/TestTask');
19 |
20 | const tests = process.env.WEB_SCRIPTS_RUN_TESTS === 'true';
21 | const jestConfig = process.env.WEB_SCRIPTS_JEST_CONFIG || getJestConfig();
22 | const prettierConfig =
23 | process.env.WEB_SCRIPTS_PRETTIER_CONFIG || getPrettierConfig();
24 | const eslintConfig = process.env.WEB_SCRIPTS_ESLINT_CONFIG || getEslintConfig();
25 |
26 | const testRelatedChanges = `jest ${
27 | jestConfig ? `--config ${jestConfig} ` : ''
28 | }--bail --findRelatedTests --passWithNoTests`;
29 |
30 | const lintRelatedChanges = `eslint --fix ${
31 | eslintConfig ? `--config ${eslintConfig}` : ''
32 | }`.trim();
33 |
34 | const formatRelatedChanges = `prettier --write ${
35 | prettierConfig ? `--config ${prettierConfig}` : ''
36 | }`.trim();
37 |
38 | module.exports = {
39 | '*.{js,jsx,ts,tsx,json,md,yaml}': [formatRelatedChanges],
40 | '*.{js,jsx,ts,tsx}': [
41 | lintRelatedChanges,
42 | ...(tests ? [testRelatedChanges] : []),
43 | ],
44 | };
45 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/TestTask.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { default as spawn } from 'cross-spawn';
17 | import { default as Debug } from 'debug';
18 | import { SpawnSyncReturns } from 'child_process';
19 | import { hasConfig } from '@spotify/web-scripts-utils';
20 |
21 | import { TestTaskDesc } from '../SharedTypes';
22 | import { JEST_CONFIG } from '../Paths';
23 |
24 | const dbg = Debug('web-scripts:test'); // eslint-disable-line new-cap
25 |
26 | export function getJestConfig(): string | null {
27 | if (
28 | !hasConfig([
29 | { type: 'file', pattern: 'jest.config.js' },
30 | { type: 'package.json', property: 'jest' },
31 | ])
32 | ) {
33 | return JEST_CONFIG;
34 | }
35 |
36 | return null;
37 | }
38 |
39 | export function testTask(task: TestTaskDesc): SpawnSyncReturns {
40 | // `coverageDirectory` is necessary because the root is `src`
41 | const cmd = 'npx';
42 | const config = task.config || getJestConfig();
43 |
44 | const args = [
45 | '--no-install',
46 | 'jest',
47 | ...(config ? ['--config', config] : []),
48 | ...task.restOptions,
49 | ];
50 | dbg('npx args %o', args);
51 | return spawn.sync(cmd, args, { stdio: 'inherit' });
52 | }
53 |
--------------------------------------------------------------------------------
/release.sh:
--------------------------------------------------------------------------------
1 | # This release script determines if a publish should happen using a dry run of semantic release to determine if the
2 | # commits contain publishable changes (feat, bug, breaking change). If so, lerna will be used to perform the actual
3 | # publish, however, lerna also has its own logic for determining whether to publish. Specifically, it will run git diff
4 | # in each package, excluding markdown files, tests, etc. So any attempt to force a version bump with an empty commit or
5 | # readme tweak will fail. To get around this, we pass the `force-publish` option to lerna, skipping the git diff for
6 | # changed packages. This allows the semantic release dry run check to be the deciding factor for publishing.
7 |
8 | # this message is logged by semantic-release when one of the commits found by web-scripts should trigger a release
9 | expected_release_message="The release type for the commit is"
10 |
11 | echo "spotify/web-scripts: Running semantic-release in --dry-run to see if we should trigger a lerna release."
12 | yarn web-scripts release --dry-run | grep "${expected_release_message}"
13 |
14 | if [ $? -eq 0 ]
15 | then
16 | echo "spotify/web-scripts: A release will be triggered."
17 | echo "spotify/web-scripts: Configuring git for Github Actions Lerna publish..."
18 | git config --global user.email "no-reply@spotify.com"
19 | git config --global user.name "GitHub Action"
20 | git remote set-url origin "https://${GH_USERNAME}:${GH_TOKEN}@github.com/spotify/web-scripts.git"
21 | git checkout master
22 | echo "spotify/web-scripts: Configuring npm for publishing..."
23 | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
24 | echo "spotify/web-scripts: Attempting publish..."
25 | npx lerna publish --yes --force-publish --ignore-scripts --conventional-commits --create-release=github --registry=https://registry.npmjs.org
26 | exit $?
27 | else
28 | echo "spotify/web-scripts: No release will be triggered." >&2
29 | exit 0
30 | fi
31 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/FormatTask/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { default as Debug } from 'debug';
17 | import { default as spawn } from 'cross-spawn';
18 | import { SpawnSyncReturns } from 'child_process';
19 | import { hasConfig } from '@spotify/web-scripts-utils';
20 |
21 | import { FormatTaskDesc } from '../../SharedTypes';
22 | import { PRETTIER_CONFIG, CONSUMING_ROOT } from '../../Paths';
23 |
24 | const dbg = Debug('web-scripts:format'); // eslint-disable-line new-cap
25 |
26 | export function getPrettierConfig(): string | null {
27 | if (
28 | !hasConfig([
29 | { type: 'file', pattern: '.prettierrc' },
30 | { type: 'file', pattern: 'prettier.config.js' },
31 | { type: 'package.json', property: 'prettierrc' },
32 | ])
33 | ) {
34 | return PRETTIER_CONFIG;
35 | }
36 |
37 | return null;
38 | }
39 |
40 | export function formatTask(task: FormatTaskDesc): SpawnSyncReturns {
41 | const cmd = 'npx';
42 | const config = task.config || getPrettierConfig();
43 | const path = task.path || `${CONSUMING_ROOT}/**/src`;
44 |
45 | const args = [
46 | '--no-install',
47 | 'prettier',
48 | ...(config ? ['--config', config] : []),
49 | '--write',
50 | `${path}/**/*.{ts,tsx,js,jsx}`,
51 | ];
52 | dbg('npx args %o', args);
53 | return spawn.sync(cmd, args, { stdio: 'inherit' });
54 | }
55 |
--------------------------------------------------------------------------------
/packages/web-scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@spotify/web-scripts",
3 | "version": "15.0.0",
4 | "license": "Apache-2.0",
5 | "description": "Build, lint, test, format, and release your JS/TS library.",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/spotify/web-scripts.git"
9 | },
10 | "main": "cjs/index.js",
11 | "module": "esm/index.js",
12 | "types": "types",
13 | "bin": {
14 | "web-scripts": "./bin/web-scripts"
15 | },
16 | "files": [
17 | "bin",
18 | "cjs",
19 | "config",
20 | "esm",
21 | "types"
22 | ],
23 | "scripts": {
24 | "clean": "rm -rf cjs esm types",
25 | "build": "node ./bin/web-scripts build",
26 | "test": "node ./bin/web-scripts test",
27 | "lint": "node ./bin/web-scripts lint",
28 | "format": "node ./bin/web-scripts format",
29 | "bootstrap": "yarn run clean && tsc --allowJs --outDir cjs --noEmit false --module CommonJS",
30 | "prepublishOnly": "yarn run bootstrap && yarn run build"
31 | },
32 | "dependencies": {
33 | "@commitlint/cli": "^17.6.3",
34 | "@commitlint/config-conventional": "^17.6.3",
35 | "@spotify/eslint-config": "^15.0.0",
36 | "@spotify/prettier-config": "^15.0.0",
37 | "@spotify/tsconfig": "^15.0.0",
38 | "@spotify/web-scripts-utils": "^15.0.0",
39 | "@types/cross-spawn": "^6.0.0",
40 | "@types/debug": "^4.1.2",
41 | "@types/jest": "^29.5.1",
42 | "@types/react": "^18.2.6",
43 | "commander": "^10.0.1",
44 | "commitizen": "^4.2.6",
45 | "cross-spawn-promise": "^0.10.1",
46 | "cz-conventional-changelog": "^3.3.0",
47 | "debug": "^4.1.1",
48 | "eslint": "^8.40.0",
49 | "jest": "^29.5.0",
50 | "jest-junit": "^16.0.0",
51 | "lint-staged": "^13.2.2",
52 | "prettier": "^2.8.8",
53 | "semantic-release": "^21.0.2",
54 | "ts-jest": "^29.1.0",
55 | "typescript": "^5.0.4"
56 | },
57 | "devDependencies": {
58 | "@types/rimraf": "^3.0.0",
59 | "object.fromentries": "^2.0.0",
60 | "rimraf": "^3.0.0",
61 | "tempy": "^1.0.1"
62 | },
63 | "publishConfig": {
64 | "access": "public"
65 | },
66 | "engines": {
67 | "node": ">=18"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/packages/eslint-config/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | const { hasConfig } = require('@spotify/web-scripts-utils');
17 |
18 | const hasReact = hasConfig([
19 | { type: 'dependency', dependency: 'react' },
20 | { type: 'dependency', dependency: 'react', dependencyType: 'peer' },
21 | ]);
22 | const hasTypescript = hasConfig([
23 | { type: 'dependency', dependency: 'typescript' },
24 | { type: 'dependency', dependency: 'typescript', dependencyType: 'dev' },
25 | { type: 'file', pattern: 'tsconfig.json' },
26 | ]);
27 |
28 | // We explicitly set the Jest version because auto-detection doesn't work in the monorepo.
29 | // Ref: https://github.com/jest-community/eslint-plugin-jest/pull/564/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5
30 | const settings = {
31 | jest: {
32 | version: 24,
33 | },
34 | };
35 |
36 | if (hasReact) {
37 | settings.react = {
38 | version: 'detect',
39 | };
40 | }
41 |
42 | module.exports = {
43 | extends: [
44 | '@spotify/eslint-config-base',
45 | hasReact ? '@spotify/eslint-config-react' : null,
46 | hasTypescript ? '@spotify/eslint-config-typescript' : null,
47 | 'prettier',
48 | 'plugin:jest/recommended',
49 | ].filter(s => !!s),
50 | parser: '@typescript-eslint/parser',
51 | env: {
52 | jest: true,
53 | },
54 | parserOptions: {
55 | ecmaVersion: 2018,
56 | sourceType: 'module',
57 | },
58 | settings,
59 | plugins: ['@spotify/eslint-plugin'],
60 | rules: {
61 | // no discouraged words
62 | '@spotify/best-practices/no-discouraged-words': 'error',
63 | },
64 | };
65 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/SharedTypes.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | type ThresholdLimits =
17 | | 'info'
18 | | 'low'
19 | | 'moderate'
20 | | 'high'
21 | | 'critical'
22 | | 'none';
23 |
24 | export type TaskName =
25 | | 'init'
26 | | 'build'
27 | | 'test'
28 | | 'lint'
29 | | 'format'
30 | | 'commit'
31 | | 'commitmsg'
32 | | 'precommit'
33 | | 'release'
34 | | 'audit';
35 |
36 | export type TaskDesc = {
37 | name: TaskName;
38 | restOptions: string[];
39 | };
40 |
41 | export type BuildTaskDesc = {
42 | name: 'build';
43 | cjs: boolean;
44 | esm: boolean;
45 | types: boolean;
46 | } & TaskDesc;
47 |
48 | export type TestTaskDesc = {
49 | name: 'test';
50 | config?: string;
51 | } & TaskDesc;
52 |
53 | export type LintTaskDesc = {
54 | name: 'lint';
55 | config?: string;
56 | stylecheck: boolean;
57 | typecheck: boolean;
58 | } & TaskDesc;
59 |
60 | export type FormatTaskDesc = {
61 | name: 'format';
62 | config?: string;
63 | path?: string;
64 | } & TaskDesc;
65 |
66 | export type CommitTaskDesc = {
67 | name: 'commit';
68 | path: string;
69 | } & TaskDesc;
70 |
71 | export type CommitMsgTaskDesc = {
72 | name: 'commitmsg';
73 | config: string;
74 | edit?: string;
75 | } & TaskDesc;
76 |
77 | export type ReleaseTaskDesc = {
78 | name: 'release';
79 | } & TaskDesc;
80 |
81 | export type AuditTaskDesc = {
82 | name: 'audit';
83 | threshold: ThresholdLimits;
84 | } & TaskDesc;
85 |
86 | export type PrecommitTaskDesc = {
87 | name: 'precommit';
88 | tests: boolean;
89 | typecheck: boolean;
90 | eslintConfig: string;
91 | jestConfig: string;
92 | prettierConfig: string;
93 | } & TaskDesc;
94 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/FormatTask/index.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { join } from 'path';
17 |
18 | import { promisify } from 'util';
19 | import tempy from 'tempy';
20 | import {
21 | mkdir as mkdirFS,
22 | readFile as readFileFS,
23 | writeFile as writeFileFS,
24 | } from 'fs';
25 |
26 | import { formatTask } from '.';
27 |
28 | const writeFile = promisify(writeFileFS);
29 | const readFile = promisify(readFileFS);
30 | const mkdir = promisify(mkdirFS);
31 |
32 | // @ts-ignore
33 | jest.spyOn(process, 'exit').mockImplementation(c => c);
34 |
35 | describe('web-scripts format', () => {
36 | let pkgRoot: string;
37 | let testFile: string;
38 |
39 | beforeEach(async () => {
40 | jest.clearAllMocks();
41 | pkgRoot = tempy.directory();
42 |
43 | const fixtureFile = join(
44 | __dirname,
45 | '__fixtures__',
46 | 'poorly-formatted-file.ts',
47 | );
48 | testFile = join(pkgRoot, 'src', 'poorly-formatted-file.ts');
49 |
50 | await mkdir(join(pkgRoot, 'src'));
51 | const content = (await readFile(fixtureFile)).toString();
52 | await writeFile(testFile, content.replace(/\/\/ prettier-ignore[\n]+/, ''));
53 | });
54 |
55 | afterAll(() => jest.restoreAllMocks());
56 |
57 | it('formats files', async () => {
58 | const before = await readFile(
59 | join(pkgRoot, 'src', 'poorly-formatted-file.ts'),
60 | );
61 | expect(before.toString().trim()).toBe('export const FOO = "bar"');
62 |
63 | formatTask({ name: 'format', path: pkgRoot, restOptions: [] });
64 |
65 | const after = await readFile(
66 | join(pkgRoot, 'src', 'poorly-formatted-file.ts'),
67 | );
68 | expect(after.toString().trim()).toBe("export const FOO = 'bar';");
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/src/has-config.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import glob from 'glob';
17 | import readPkgUp from 'read-pkg-up';
18 |
19 | import { getConsumingRoot } from './get-consuming-root';
20 | import { hasKeyInObj } from './has-key-in-obj';
21 |
22 | const getDependencyTypePath = (
23 | dependency: string,
24 | type?: 'dev' | 'peer',
25 | ): string => {
26 | switch (type) {
27 | case 'dev':
28 | return `devDependencies.${dependency}`;
29 | case 'peer':
30 | return `peerDependencies.${dependency}`;
31 | default:
32 | return `dependencies.${dependency}`;
33 | }
34 | };
35 |
36 | // this function can be used to determine whether a config exists,
37 | // either in package.json or as a file.
38 | export const hasConfig = (
39 | sources: (
40 | | { type: 'file'; pattern: string }
41 | | { type: 'package.json'; property: string }
42 | | {
43 | type: 'dependency';
44 | dependency: string;
45 | dependencyType?: 'peer' | 'dev';
46 | }
47 | )[],
48 | ): boolean => {
49 | const { path: pkgPath, packageJson } = readPkgUp.sync({
50 | cwd: getConsumingRoot(),
51 | }) || { packageJson: {}, path: getConsumingRoot() };
52 | const root = pkgPath.slice(0, pkgPath.length - '/package.json'.length);
53 | return sources.some(source => {
54 | switch (source.type) {
55 | case 'file':
56 | return !!glob.sync(source.pattern, { cwd: root }).length;
57 | case 'package.json':
58 | return hasKeyInObj(source.property, packageJson);
59 | case 'dependency':
60 | return hasKeyInObj(
61 | getDependencyTypePath(source.dependency, source.dependencyType),
62 | packageJson,
63 | );
64 | default:
65 | return false;
66 | }
67 | });
68 | };
69 |
--------------------------------------------------------------------------------
/packages/eslint-config-typescript/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = {
17 | parser: '@typescript-eslint/parser',
18 | parserOptions: {
19 | sourceType: 'module',
20 | },
21 | plugins: ['@typescript-eslint/eslint-plugin'],
22 | // camelcase, indent, no-array-constructor, and no-unused-vars are all
23 | // busted when using TypeScript at the moment. When you use this plugin, you're
24 | // forced to turn off the base rules from ESLint and turn on the TypeScript-friendly
25 | // variant that comes with @typescript-eslint/eslint-plugin.
26 | rules: {
27 | // camelcase interference fix.
28 | camelcase: 'off',
29 | '@typescript-eslint/naming-convention': 'off',
30 | // indent interference fix.
31 | indent: 'off',
32 | '@typescript-eslint/indent': ['error', 2, { SwitchCase: 1 }],
33 | // no-array-constructor interference fix.
34 | 'no-array-constructor': 'off',
35 | '@typescript-eslint/no-array-constructor': 'error',
36 | // no-unused-vars interference fix.
37 | 'no-unused-vars': 'off',
38 | '@typescript-eslint/no-unused-vars': 'off',
39 | // no-useless-constructor interference fix.
40 | 'no-useless-constructor': 'off',
41 | '@typescript-eslint/no-useless-constructor': 'error',
42 | // semi interference fix.
43 | semi: 'off',
44 | '@typescript-eslint/semi': 'warn',
45 | // no-shadow interference fix.
46 | 'no-shadow': 'off',
47 | '@typescript-eslint/no-shadow': 'error',
48 | // no-redeclare interference fix.
49 | 'no-redeclare': 'off',
50 | '@typescript-eslint/no-redeclare': 'error',
51 | // no-use-before-define interference fix.
52 | // allow functions to be defined after they're used
53 | 'no-use-before-define': 'off',
54 | '@typescript-eslint/no-use-before-define': ['error', 'nofunc'],
55 | },
56 | };
57 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import path from 'path';
17 | import fs from 'fs-extra';
18 | import execa from 'execa';
19 | import chalk from 'chalk';
20 | import readPkgUp from 'read-pkg-up';
21 |
22 | import * as messages from './messages';
23 | import getInstallCmd from './get-install-cmd';
24 |
25 | // console.log is used here to make sure that logs make it to the user
26 | /* eslint-disable no-console */
27 | export default async function createWebScriptsLibrary(projectName?: string) {
28 | if (!projectName) {
29 | throw new Error(messages.missingProjectName());
30 | }
31 |
32 | if (fs.existsSync(projectName) && projectName !== '.') {
33 | throw new Error(messages.alreadyExists(projectName));
34 | }
35 |
36 | const { packageJson: cwslPkg } =
37 | readPkgUp.sync({
38 | cwd: __dirname,
39 | }) || {};
40 |
41 | const projectPath = path.resolve(process.cwd(), projectName);
42 | const templatePath = path.resolve(__dirname, '..', 'template');
43 |
44 | console.log(chalk.gray('Copying template...'));
45 | await fs.copy(templatePath, projectPath);
46 |
47 | console.log(chalk.gray('Writing over necessary files...'));
48 | process.chdir(projectPath);
49 | const newPkgPath = path.join(projectPath, 'package.json');
50 | const newPkg = require(newPkgPath);
51 | newPkg.name = projectName;
52 | newPkg.devDependencies['@spotify/web-scripts'] =
53 | (cwslPkg?.devDependencies || {})['@spotify/web-scripts'] ||
54 | newPkg.devDependencies['@spotify/web-scripts'];
55 | await fs.writeFile(newPkgPath, JSON.stringify(newPkg, null, 2));
56 |
57 | console.log(chalk.gray('Installing dependencies...'));
58 | process.chdir(projectPath);
59 | await execa(getInstallCmd(), ['install']);
60 |
61 | console.log(messages.start(projectName));
62 | }
63 | /* eslint-enable no-console */
64 |
--------------------------------------------------------------------------------
/packages/eslint-config-base/es6.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = {
17 | env: {
18 | es6: true,
19 | },
20 | parserOptions: {
21 | ecmaVersion: 2018,
22 | sourceType: 'module',
23 | ecmaFeatures: {
24 | jsx: true,
25 | },
26 | },
27 | rules: {
28 | // require parens in arrow function arguments
29 | 'arrow-parens': 0,
30 | // require space before/after arrow function's arrow
31 | 'arrow-spacing': 0,
32 | // verify super() callings in constructors
33 | 'constructor-super': 0,
34 | // enforce the spacing around the * in generator functions
35 | 'generator-star-spacing': 0,
36 | // disallow modifying variables of class declarations
37 | 'no-class-assign': 0,
38 | // disallow modifying variables that are declared using const
39 | 'no-const-assign': 2,
40 | // disallow to use this/super before super() calling in constructors.
41 | 'no-this-before-super': 0,
42 | // disallow empty constructors and constructors that only delegate into the parent class.
43 | 'no-useless-constructor': 2,
44 | // require let or const instead of var
45 | 'no-var': 2,
46 | // require method and property shorthand syntax for object literals
47 | 'object-shorthand': 0,
48 | // suggest using of const declaration for variables that are never modified after declared
49 | 'prefer-const': 2,
50 | // suggest using the spread operator instead of .apply()
51 | 'prefer-spread': 0,
52 | // suggest using Reflect methods where applicable
53 | 'prefer-reflect': 0,
54 | // suggest using template strings instead of concatenation or joining
55 | 'prefer-template': 2,
56 | // disallow generator functions that do not have yield
57 | 'require-yield': 0,
58 | // disallow trailing commas in object literals
59 | 'comma-dangle': [2, 'always-multiline'],
60 | },
61 | };
62 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/AuditTasks/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { default as spawn } from 'cross-spawn-promise';
17 | import { default as Debug } from 'debug';
18 |
19 | import { AuditTaskDesc } from '../../SharedTypes';
20 | import { CONSUMING_ROOT } from '../../Paths';
21 |
22 | const dbg = Debug('web-scripts:audit'); // eslint-disable-line new-cap
23 |
24 | enum ThresholdLimits {
25 | info = 1,
26 | low = 2,
27 | moderate = 4,
28 | high = 8,
29 | critical = 16,
30 | none = 32,
31 | }
32 |
33 | export async function auditTask(task: AuditTaskDesc): Promise {
34 | const fns = [yarnRun];
35 |
36 | return await Promise.all(
37 | fns.map(async fn => {
38 | dbg('Beginning %s task', fn.name);
39 | const stdout = await fn(task);
40 | dbg('Finished %s task', fn.name);
41 | return stdout;
42 | }),
43 | );
44 | }
45 |
46 | /**
47 | * This task will run yarn audit at the location from which it was called.
48 | * Yarn audit returns a status code which is the sum of the following masks:
49 | * 1 for INFO
50 | * 2 for LOW
51 | * 4 for MODERATE
52 | * 8 for HIGH
53 | * 16 for CRITICAL
54 | *
55 | * The threshold ceiling is therefore 31. The default value of the threshold
56 | * is 32, returning 0 exit status unless a threshold option is set.
57 | * @see https://yarnpkg.com/lang/en/docs/cli/audit/
58 | */
59 | async function yarnRun(task: AuditTaskDesc): Promise {
60 | const cmd = 'npx';
61 | const { threshold } = task;
62 |
63 | const args = [
64 | '--no-install',
65 | 'yarn',
66 | 'audit',
67 | '--cwd',
68 | CONSUMING_ROOT,
69 | ...task.restOptions,
70 | ];
71 | dbg('npx args %o', args);
72 |
73 | try {
74 | await spawn(cmd, args, { stdio: 'inherit' });
75 | } catch (err) {
76 | const thresholdReached =
77 | (err as any).exitStatus >= ThresholdLimits[threshold];
78 | if (thresholdReached) process.exit((err as any).exitStatus);
79 | }
80 |
81 | return '';
82 | }
83 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/src/rules/best-practices/no-discouraged-words.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Rule } from 'eslint';
18 | import { TSESTree } from '@typescript-eslint/types';
19 | import { createDocsUrl } from '../../util/helpers';
20 |
21 | /**
22 | * List of discouraged words in the form of RegEx (regular expressions).
23 | */
24 | const discouragedWords = ['blacklist', 'whitelist'];
25 |
26 | const rule: Rule.RuleModule = {
27 | meta: {
28 | docs: {
29 | category: 'Best Practices',
30 | description: 'Prevent use of discouraged words.',
31 | url: createDocsUrl('best-practices/no-discouraged-words.md'),
32 | },
33 | schema: [],
34 | fixable: 'code',
35 | type: 'suggestion',
36 | },
37 | create(context: Rule.RuleContext) {
38 | return {
39 | // This checks all the JS comments for use of discouraged word. This line is an example of a comment.
40 | Program(): void {
41 | const comments = context.getSourceCode().getAllComments();
42 | comments.forEach(comment => {
43 | const commentText = comment.value;
44 | const commentTextViolation = discouragedWords.find(word =>
45 | commentText.match(new RegExp(word, 'i')),
46 | );
47 |
48 | if (!commentTextViolation) {
49 | // There is no violation here.
50 | return;
51 | }
52 |
53 | context.report({
54 | // @ts-ignore
55 | node: comment,
56 | message: `Usage of the word "${commentTextViolation}" is strongly discouraged. Please use a different word.`,
57 | });
58 | });
59 | },
60 |
61 | // This checks all the JS syntax for use of discouraged words.
62 | Identifier(node: TSESTree.Identifier) {
63 | const variableName = node.name;
64 | const variableNameViolation = discouragedWords.find(word =>
65 | variableName.match(new RegExp(word, 'i')),
66 | );
67 |
68 | if (!variableNameViolation) {
69 | // There is no violation here
70 | return;
71 | }
72 |
73 | // Report it as an error to ESLint
74 | context.report({
75 | node,
76 | message: `Usage of the word "${variableNameViolation}" is strongly discouraged. Please use a different word.`,
77 | });
78 | },
79 | } as Rule.RuleListener;
80 | },
81 | };
82 |
83 | export default rule;
84 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/src/has-config.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | jest.mock('./get-consuming-root');
17 |
18 | import path from 'path';
19 | import { hasConfig } from './has-config';
20 |
21 | const { getConsumingRoot } = jest.requireMock('./get-consuming-root');
22 |
23 | describe('hasConfig', () => {
24 | beforeEach(() => {
25 | getConsumingRoot.mockReturnValue(
26 | path.join(__dirname, '..', '__fixtures__', 'demo-lib'),
27 | );
28 | });
29 | it('works for a file', () => {
30 | expect(hasConfig([{ type: 'file', pattern: 'tsconfig.json' }])).toBe(true);
31 | });
32 |
33 | it('works for a package.json property', () => {
34 | expect(hasConfig([{ type: 'package.json', property: 'name' }])).toBe(true);
35 | });
36 |
37 | it('works for a nested package.json property', () => {
38 | expect(
39 | hasConfig([
40 | { type: 'package.json', property: 'jest.collectCoverageFrom' },
41 | ]),
42 | ).toBe(true);
43 | });
44 |
45 | it('works for a dependency', () => {
46 | expect(hasConfig([{ type: 'dependency', dependency: 'react' }])).toBe(true);
47 | });
48 |
49 | it('works for a dev dependency', () => {
50 | expect(
51 | hasConfig([
52 | {
53 | type: 'dependency',
54 | dependency: '@testing-library/react',
55 | dependencyType: 'dev',
56 | },
57 | ]),
58 | ).toBe(true);
59 | });
60 |
61 | it('works for a peer dependency', () => {
62 | expect(
63 | hasConfig([
64 | {
65 | type: 'dependency',
66 | dependency: 'styled-components',
67 | dependencyType: 'peer',
68 | },
69 | ]),
70 | ).toBe(true);
71 | });
72 |
73 | it('works when some fail and some succeed', () => {
74 | expect(
75 | hasConfig([
76 | {
77 | type: 'dependency',
78 | dependency: 'react',
79 | },
80 | {
81 | type: 'dependency',
82 | dependency: 'react',
83 | dependencyType: 'peer',
84 | },
85 | ]),
86 | ).toBe(true);
87 | });
88 |
89 | it('fails when all fail', () => {
90 | expect(
91 | hasConfig([
92 | {
93 | type: 'dependency',
94 | dependency: 'angular',
95 | },
96 | {
97 | type: 'dependency',
98 | dependency: 'angular',
99 | dependencyType: 'peer',
100 | },
101 | ]),
102 | ).toBe(false);
103 | });
104 | });
105 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/LintTask.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { default as spawn } from 'cross-spawn-promise';
17 | import { default as Debug } from 'debug';
18 | import { hasConfig } from '@spotify/web-scripts-utils';
19 |
20 | import { LintTaskDesc } from '../SharedTypes';
21 | import { CONSUMING_ROOT, ESLINT_CONFIG } from '../Paths';
22 | import { getPrettierConfig } from './FormatTask';
23 |
24 | const dbg = Debug('web-scripts:lint'); // eslint-disable-line new-cap
25 |
26 | export function getEslintConfig(): string | null {
27 | if (
28 | !hasConfig([
29 | { type: 'file', pattern: '.eslintrc.*' },
30 | { type: 'package.json', property: 'eslintConfig' },
31 | ])
32 | ) {
33 | return ESLINT_CONFIG;
34 | }
35 |
36 | return null;
37 | }
38 |
39 | export async function lintTask(task: LintTaskDesc): Promise {
40 | const fns = [eslintRun];
41 | if (task.typecheck) fns.push(typeCheck);
42 | if (task.stylecheck) fns.push(styleCheck);
43 |
44 | return await Promise.all(
45 | fns.map(async fn => {
46 | dbg('Beginning %s task', fn.name);
47 | const stdout = await fn(task);
48 | dbg('Finished %s task', fn.name);
49 | return stdout;
50 | }),
51 | );
52 | }
53 |
54 | export async function eslintRun(task: LintTaskDesc): Promise {
55 | const cmd = 'npx';
56 | const config = task.config || getEslintConfig();
57 |
58 | const args = [
59 | '--no-install',
60 | 'eslint',
61 | '--ext',
62 | 'js,ts,jsx,tsx',
63 | CONSUMING_ROOT,
64 | '--ignore-pattern',
65 | 'types/',
66 | '--ignore-pattern',
67 | 'cjs/',
68 | '--ignore-pattern',
69 | 'esm/',
70 | ...(config ? ['--config', config] : []),
71 | ...task.restOptions,
72 | ];
73 | dbg('npx args %o', args);
74 |
75 | const stdout = await spawn(cmd, args, { stdio: 'inherit' });
76 | return (stdout || '').toString();
77 | }
78 |
79 | export async function typeCheck(): Promise {
80 | const cmd = 'npx';
81 | const args = ['tsc', '--noEmit'];
82 | const stdout = await spawn(cmd, args, { stdio: 'inherit' });
83 | return (stdout || '').toString();
84 | }
85 |
86 | export async function styleCheck(): Promise {
87 | const cmd = 'npx';
88 | const args = ['--no-install', 'prettier'];
89 |
90 | const config = getPrettierConfig();
91 | if (config) {
92 | args.push('--config', config);
93 | }
94 |
95 | args.push('--check', `${CONSUMING_ROOT}/**/src/**/*.{ts,tsx,js,jsx}`);
96 | const stdout = await spawn(cmd, args, { stdio: 'inherit' });
97 | return (stdout || '').toString();
98 | }
99 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/AuditTasks/index.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { join } from 'path';
17 |
18 | import { auditTask } from '.';
19 |
20 | // @ts-ignore
21 | jest.spyOn(process, 'exit').mockImplementation(c => c);
22 |
23 | jest.mock('cross-spawn-promise', () => jest.fn());
24 |
25 | const spawn: jest.Mock = jest.requireMock('cross-spawn-promise');
26 |
27 | class AuditError extends Error {
28 | public exitStatus: number;
29 | constructor(message: string, exitStatus: number) {
30 | super(message);
31 | this.exitStatus = exitStatus;
32 | }
33 | }
34 |
35 | /**
36 | * WARNING:
37 | * These tests have some issues with being potentially non-deterministic.
38 | * Due to a network dependency on npmjs.com this test could potentially fail
39 | * should there be any downtime with external services used by with yarn audit.
40 | *
41 | * Should these tests begin to fail suddenly, it might be worth trading test coverage
42 | * confidence for test reliability by mocking the network calls made by yarn audit.
43 | */
44 | describe('web-scripts audit', () => {
45 | beforeEach(() => jest.clearAllMocks());
46 | afterAll(() => jest.restoreAllMocks());
47 |
48 | test.each`
49 | violations | threshold | status
50 | ${0} | ${undefined} | ${0}
51 | ${0} | ${'none'} | ${0}
52 | ${12} | ${undefined} | ${0}
53 | ${12} | ${'none'} | ${0}
54 | ${12} | ${'low'} | ${12}
55 | ${12} | ${'moderate'} | ${12}
56 | ${12} | ${'high'} | ${12}
57 | ${12} | ${'critical'} | ${0}
58 | ${30} | ${undefined} | ${0}
59 | ${30} | ${'none'} | ${0}
60 | ${30} | ${'low'} | ${30}
61 | ${30} | ${'moderate'} | ${30}
62 | ${30} | ${'high'} | ${30}
63 | ${30} | ${'critical'} | ${30}
64 | `(
65 | 'return status code $status when audited dependencies have $violations violations and $threshold threshold',
66 | async ({ violations, threshold, status }) => {
67 | const source = join(__dirname, '__fixtures__', violations.toString());
68 |
69 | if (violations) {
70 | spawn.mockRejectedValueOnce(
71 | new AuditError('audit failure found', violations),
72 | );
73 | } else {
74 | spawn.mockResolvedValueOnce(null);
75 | }
76 |
77 | await auditTask({
78 | name: 'audit',
79 | threshold,
80 | // Overrides implementation logic for CWD
81 | restOptions: ['--cwd', source],
82 | });
83 |
84 | /* eslint jest/no-conditional-expect: off */
85 | if (status) expect(process.exit).toHaveBeenCalledWith(status);
86 | else expect(process.exit).not.toHaveBeenCalled();
87 | },
88 | );
89 | });
90 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/BuildTask.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { BuildTaskDesc } from '../SharedTypes';
17 |
18 | import { default as Debug } from 'debug';
19 | import { default as spawn } from 'cross-spawn-promise';
20 | const dbg = Debug('web-scripts:build'); // eslint-disable-line new-cap
21 |
22 | // Pretty sure I have to use the tsconfig in the root of the calling
23 | // project, since the "include" key resolves the folder relative to the
24 | // tsconfig location, not the process.cwd(). Manually specifying it would
25 | // force this CLI to have to build the config up manually as well. Something
26 | // I don't really want to do.
27 | export async function buildTask(task: BuildTaskDesc): Promise {
28 | const fns = [];
29 |
30 | if (!task.cjs && !task.esm && !task.types) {
31 | // default is all!
32 | fns.push(buildTypes, buildCJS, buildESM);
33 | } else {
34 | if (task.types) fns.push(buildTypes);
35 | if (task.esm) fns.push(buildESM);
36 | if (task.cjs) fns.push(buildCJS);
37 | }
38 |
39 | return Promise.all(
40 | fns.map(async fn => {
41 | dbg('Beginning %s task', fn.name);
42 | const result = await fn(task);
43 | dbg('Finished %s task', fn.name);
44 | return result;
45 | }),
46 | );
47 | }
48 |
49 | async function buildTypes(task: BuildTaskDesc): Promise {
50 | const cmd = 'npx';
51 | const args = [
52 | 'tsc',
53 | '--declaration',
54 | '--declarationMap',
55 | '--isolatedModules',
56 | 'false',
57 | '--outDir',
58 | 'types',
59 | '--emitDeclarationOnly',
60 | '--noEmit',
61 | 'false',
62 | '--module',
63 | 'CommonJS',
64 | ...task.restOptions,
65 | ];
66 | const stdout = await spawn(cmd, args, { stdio: 'inherit' });
67 | return (stdout || '').toString();
68 | }
69 |
70 | async function buildCJS(task: BuildTaskDesc): Promise {
71 | const cmd = 'npx';
72 | const args = [
73 | 'tsc',
74 | '--declaration',
75 | 'false',
76 | '--allowJs',
77 | '--outDir',
78 | 'cjs',
79 | '--noEmit',
80 | 'false',
81 | '--module',
82 | 'CommonJS',
83 | ...task.restOptions,
84 | ];
85 | const stdout = await spawn(cmd, args, { stdio: 'inherit' });
86 | return (stdout || '').toString();
87 | }
88 |
89 | async function buildESM(task: BuildTaskDesc): Promise {
90 | const cmd = 'npx';
91 | const args = [
92 | 'tsc',
93 | '--declaration',
94 | 'false',
95 | '--allowJs',
96 | '--outDir',
97 | 'esm',
98 | '--noEmit',
99 | 'false',
100 | '--module',
101 | 'ES2015',
102 | ...task.restOptions,
103 | ];
104 | const stdout = await spawn(cmd, args, { stdio: 'inherit' });
105 | return (stdout || '').toString();
106 | }
107 |
--------------------------------------------------------------------------------
/packages/create-web-scripts-library/src/integration.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import tempy from 'tempy';
17 | import path from 'path';
18 | import execa from 'execa';
19 | import fs from 'fs-extra';
20 |
21 | import createWebScriptsLibrary from '.';
22 | import getInstallCmd from './get-install-cmd';
23 |
24 | describe('integration test', () => {
25 | let PKG_ROOT: string;
26 | let LIBRARY_NAME: string;
27 | let LIBRARY_ROOT: string;
28 | let INSTALL_CMD: string;
29 |
30 | describe('succesful create', () => {
31 | // using a beforeAll instead of beforeEach for this test, which ensures that the tests run quickly
32 | // this IS a risky testing strategy. Inside this describe block, we need to avoid doing destructive operations.
33 | beforeAll(async () => {
34 | PKG_ROOT = tempy.directory();
35 | LIBRARY_NAME = 'my-cool-library';
36 | LIBRARY_ROOT = path.join(PKG_ROOT, LIBRARY_NAME);
37 | process.chdir(PKG_ROOT);
38 | INSTALL_CMD = getInstallCmd();
39 |
40 | // create a single library and then assert against it
41 | await createWebScriptsLibrary(LIBRARY_NAME);
42 | }, 60000);
43 |
44 | it('replace the package.json name with the correct name', async () => {
45 | // check the package.json name replacement
46 | const pkgPath = path.join(LIBRARY_ROOT, 'package.json');
47 | expect(fs.existsSync(pkgPath)).toBe(true);
48 | expect(require(pkgPath).name).toBe(LIBRARY_NAME);
49 | });
50 |
51 | // check that all the commands work
52 | [
53 | { cmd: 'lint', asyncTimeout: 20000 },
54 | { cmd: 'test', asyncTimeout: 30000 },
55 | { cmd: 'build', asyncTimeout: 60000 },
56 | ].forEach(
57 | ({
58 | cmd,
59 | asyncTimeout = 10000,
60 | }: {
61 | cmd: string;
62 | asyncTimeout?: number;
63 | }) => {
64 | it(
65 | `scaffolds such that "${cmd}" command runs successfully`,
66 | async () => {
67 | await expect(
68 | execa(INSTALL_CMD, ['run', cmd], { cwd: LIBRARY_ROOT }),
69 | ).resolves.toBeDefined();
70 | },
71 | asyncTimeout,
72 | );
73 | },
74 | );
75 | });
76 |
77 | describe('failure cases', () => {
78 | beforeEach(() => {
79 | PKG_ROOT = tempy.directory();
80 | LIBRARY_NAME = 'my-cool-library';
81 | LIBRARY_ROOT = path.join(PKG_ROOT, LIBRARY_NAME);
82 | process.chdir(PKG_ROOT);
83 | INSTALL_CMD = getInstallCmd();
84 | });
85 |
86 | it('fails when the library name is missing', async () => {
87 | await expect(createWebScriptsLibrary()).rejects.toEqual(
88 | expect.any(Error),
89 | );
90 | });
91 |
92 | it('fails when a directory already exists', async () => {
93 | await fs.mkdir(path.join(PKG_ROOT, LIBRARY_NAME));
94 | await expect(createWebScriptsLibrary()).rejects.toEqual(
95 | expect.any(Error),
96 | );
97 | });
98 | });
99 | });
100 |
--------------------------------------------------------------------------------
/packages/eslint-config-react/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | module.exports = {
17 | plugins: ['react', 'react-hooks', 'jsx-a11y'],
18 | parserOptions: {
19 | ecmaFeatures: {
20 | jsx: true,
21 | },
22 | },
23 | extends: ['plugin:jsx-a11y/recommended'],
24 | rules: {
25 | // Prevent missing displayName in a React component definition
26 | 'react/display-name': 0,
27 | // Enforce boolean attributes notation in JSX
28 | 'react/jsx-boolean-value': 2,
29 | // Enforce or disallow spaces inside of curly braces in JSX attributes
30 | 'react/jsx-curly-spacing': 0,
31 | // Enforce or disallow react string props to be wrapped in curly braces
32 | 'react/jsx-curly-brace-presence': 2,
33 | // Prevent duplicate props in JSX
34 | 'react/jsx-no-duplicate-props': 0,
35 | // Disallow undeclared variables in JSX
36 | 'react/jsx-no-undef': 0,
37 | // Enforce quote style for JSX attributes
38 | 'react/jsx-quotes': 0,
39 | // Enforce propTypes declarations alphabetical sorting
40 | 'react/jsx-sort-prop-types': 0,
41 | // Enforce props alphabetical sorting
42 | 'react/jsx-sort-props': 0,
43 | // Prevent React to be incorrectly marked as unused
44 | 'react/jsx-uses-react': 2,
45 | // Prevent variables used in JSX to be incorrectly marked as unused
46 | 'react/jsx-uses-vars': 2,
47 | // Prevent missing parentheses around multilines JSX
48 | 'react/jsx-wrap-multilines': 2,
49 | // Enforce react rules of hooks
50 | 'react-hooks/rules-of-hooks': 2,
51 | // Enforce the list of dependencies for hooks is correct
52 | 'react-hooks/exhaustive-deps': 2,
53 | // Prevent usage of dangerous JSX properties
54 | 'react/no-danger': 0,
55 | // Prevent usage of setState in componentDidMount
56 | 'react/no-did-mount-set-state': 0,
57 | // Prevent usage of setState in componentDidUpdate
58 | 'react/no-did-update-set-state': 2,
59 | // Prevent multiple component definition per file
60 | 'react/no-multi-comp': [2, { ignoreStateless: true }],
61 | // Prevent usage of unknown DOM property
62 | 'react/no-unknown-property': 2,
63 | // Prevent missing props validation in a React component definition
64 | 'react/prop-types': 0,
65 | // Prevent missing React when using JSX
66 | 'react/react-in-jsx-scope': 2,
67 | // Restrict file extensions that may be required
68 | 'react/require-extension': 0,
69 | // Prevent extra closing tags for components without children
70 | 'react/self-closing-comp': 2,
71 | // Enforce component methods order
72 | 'react/sort-comp': [
73 | 2,
74 | {
75 | order: [
76 | 'statics',
77 | 'static-variables',
78 | 'static-methods',
79 | 'instance-variables',
80 | 'constructor',
81 | 'getChildContext',
82 | 'componentDidMount',
83 | 'shouldComponentUpdate',
84 | 'getSnapshotBeforeUpdate',
85 | 'componentDidUpdate',
86 | 'componentWillUnmount',
87 | 'componentDidCatch',
88 | '/^handle.+$/',
89 | '/^on.+$/',
90 | 'everything-else',
91 | '/^render.+$/',
92 | 'render',
93 | ],
94 | },
95 | ],
96 | },
97 | };
98 |
--------------------------------------------------------------------------------
/packages/tsconfig/docs/examples.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | ## Getting started
4 |
5 | This project outputs a single tsconfig.json file for use. This file is configured to disable all output options (`declaration` is `false`, `noEmit` is true) and is set to strictly type check your code (for example, `noImplicitAny` and many other strict type checks). It is likely that you will need to import this file and do a little configuration additionally depending on whether you plan to use this configuration in conjunction with Webpack or Babel, or whether you plan to use `tsc` to output artifacts.
6 |
7 | ### Questions to answer
8 |
9 | 1. Do you have a full TypeScript project (e.g. is your project brand new or is it sufficiently small that you can convert the whole thing at once)?
10 | 2. Do you need to keep using Babel to transpile an existing project, or can you use `tsc` (the TypeScript compiler that is installed when you add `typescript` as a Node dependency) to keep your build simple?
11 | 3. Is your project a library, which means it needs to compile in a way that other TypeScript projects can use the types from it, or is it an app, which means it likely has JSX and that there is no need to export declarations?
12 |
13 | ### Overriding options
14 |
15 | Use the `"extends"` option in your tsconfig.json to extend the appropriate config.
16 |
17 | ## Apps
18 |
19 | This setup assumes that Create React App, Next, Webpack, and/or Babel will transpile your bundled assets (aka `tsc` is not used for emitting transpiled code, only for type-checking).
20 |
21 | Extend your `tsconfig.json`:
22 |
23 | ```json
24 | {
25 | "extends": "@spotify/tsconfig"
26 | }
27 | ```
28 |
29 | ### Create React App
30 |
31 | Use our [Create React App guide](./guides/cra.md).
32 |
33 | ### Next.js
34 |
35 | Use our [Next.js guide](./guides/next.md).
36 |
37 | ### Babel
38 |
39 | When using Babel, use [@babel/preset-typescript](https://babeljs.io/docs/en/babel-preset-typescript) to load TypeScript files. If you use the Babel CLI directly, make sure to include `--extensions ".js,.ts,.tsx"`.
40 |
41 | ### Webpack
42 |
43 | If using Babel with Webpack, use [@babel/preset-typescript](https://babeljs.io/docs/en/babel-preset-typescript) as described above. Then, in your Webpack config, be sure to update the `test` regular expression which `babel-loader` is using to include your `ts` and `tsx` files.
44 |
45 | If you don't use `babel-loader` or you prefer for it not to handle your TypeScript, you can use `ts-loader` instead.
46 |
47 | ```bash
48 | yarn add -D ts-loader
49 | ```
50 |
51 | Make sure to add the TypeScript filetypes and `ts-loader` to your Webpack config.
52 |
53 | ```js
54 | module.exports = {
55 | // ...
56 | resolve: {
57 | extensions: ['.ts', '.tsx', '.js'],
58 | },
59 | module: {
60 | rules: [{ test: /\.(ts|tsx)$/, loader: 'ts-loader' }],
61 | },
62 | // ...
63 | };
64 | ```
65 |
66 | **IMPORTANT** You will need to turn off `noEmit` when using `ts-loader` with `@spotify/tsconfig`:
67 |
68 | ```json
69 | {
70 | "extends": "@spotify/tsconfig",
71 | "compilerOptions": {
72 | "noEmit": false
73 | }
74 | }
75 | ```
76 |
77 | ## Libraries
78 |
79 | ### @spotify/web-scripts
80 |
81 | With one command, [`web-scripts build`](https://github.com/spotify/web-scripts/tree/master/packages/web-scripts#the-build-script) takes your TypeScript code and outputs types, esm, and cjs files ready for publishing. It's probably want you want!
82 |
83 | If you want or need to manually control how your library is built using our shared configs, read on.
84 |
85 | ### Manual builds
86 |
87 | Assumes the library will be consumed as a node module by an app that will provide, if needed, polyfills for platforms lacking in ES6/2015 support. For example, this config will not transpile `async`/`await`. It will assume the consuming platform either supports those features natively or provides transpilation / polyfills.
88 |
89 | This config also assumes that `tsc` (the TypeScript compiler) is responsible for emitting / transpiling the TS -> JS (and providing type declaration files).
90 |
91 | Essentially, this config takes the base config and extends it to output Common JS modules and the corresponding type definitions.
92 |
93 | ```json
94 | {
95 | "extends": "@spotify/tsconfig",
96 | "include": ["src"],
97 | "compilerOptions": {
98 | "noEmit": false,
99 | "outDir": "dist",
100 | "declaration": true,
101 | "declarationMap": true,
102 | "jsx": "react",
103 | "lib": ["es6", "dom"],
104 | "module": "commonjs",
105 | "sourceMap": true,
106 | "target": "es6"
107 | }
108 | }
109 | ```
110 |
111 | Run `tsc -p tsconfig.json` to see your output.
112 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/src/rules/best-practices/no-discouraged-words.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import rule from './no-discouraged-words';
18 | import { createRuleTester } from '../../util/testHelpers';
19 |
20 | const defaultErrorMessageWithWord = (word: string): string =>
21 | `Usage of the word "${word}" is strongly discouraged. Please use a different word.`;
22 |
23 | createRuleTester().run('best-practices/no-discouraged-words', rule, {
24 | valid: [
25 | {
26 | code: 'var foo = () => {};',
27 | },
28 | {
29 | code: 'var foo: String = () => {};',
30 | },
31 | {
32 | code: 'var foo: String = () => ({} as ExampleObject);',
33 | },
34 | {
35 | // We currently don't do "advanced" checking of the discouraged words. That's something we can add over time.
36 | code: 'var black_list = "";',
37 | },
38 | {
39 | // This plugin only covers variable naming. It's unclear if there are unexpected side effects if we flat out ban the words.
40 | // In the future, if we see there is not, let's check the entire codebase and avoid them.
41 | code: 'var foo = "blacklist";',
42 | },
43 | {
44 | code: "/* Hello world. I'm using no discouraged words. */",
45 | },
46 | ],
47 | invalid: [
48 | {
49 | code: 'var whitelist = "";',
50 | errors: [defaultErrorMessageWithWord('whitelist')],
51 | },
52 | {
53 | code: 'var blacklist = "";',
54 | errors: [defaultErrorMessageWithWord('blacklist')],
55 | },
56 | {
57 | code: 'var foo = blacklist => "";',
58 | errors: [defaultErrorMessageWithWord('blacklist')],
59 | },
60 | {
61 | code: 'var foo = _blacklist => "";',
62 | errors: [defaultErrorMessageWithWord('blacklist')],
63 | },
64 | {
65 | code: 'var foo = (bar: Blacklist) => "";',
66 | errors: [defaultErrorMessageWithWord('blacklist')],
67 | },
68 | {
69 | code: 'var foo = bar => "" as Blacklist;',
70 | errors: [defaultErrorMessageWithWord('blacklist')],
71 | },
72 | {
73 | code: 'var bLacKLisT = "";',
74 | errors: [defaultErrorMessageWithWord('blacklist')],
75 | },
76 | {
77 | code: 'var _blacklist = "";',
78 | errors: [defaultErrorMessageWithWord('blacklist')],
79 | },
80 | {
81 | code: 'var wordsWithBlacklistAndAfter = "";',
82 | errors: [defaultErrorMessageWithWord('blacklist')],
83 | },
84 | {
85 | code: 'var { blacklist } = {};',
86 | // Because this translates to '{ var blacklist: blacklist } = {}' the plugin reports the error twice
87 | errors: [
88 | defaultErrorMessageWithWord('blacklist'),
89 | defaultErrorMessageWithWord('blacklist'),
90 | ],
91 | },
92 | {
93 | code: 'var blacklist = {}; console.log(blacklist);',
94 | // Because we're using the word twice in the syntax, it'll report twice. Maybe we can clear this up later.
95 | errors: [
96 | defaultErrorMessageWithWord('blacklist'),
97 | defaultErrorMessageWithWord('blacklist'),
98 | ],
99 | },
100 | {
101 | code: 'var { blacklist: name } = {};',
102 | errors: [defaultErrorMessageWithWord('blacklist')],
103 | },
104 | {
105 | code: 'var { name: blacklist } = {};',
106 | errors: [defaultErrorMessageWithWord('blacklist')],
107 | },
108 | {
109 | code: 'var foo: Blacklist = "";',
110 | errors: [defaultErrorMessageWithWord('blacklist')],
111 | },
112 | {
113 | code: 'var foo = "" as Blacklist;',
114 | errors: [defaultErrorMessageWithWord('blacklist')],
115 | },
116 | {
117 | code: 'var foo = "" as Example.Blacklist;',
118 | errors: [defaultErrorMessageWithWord('blacklist')],
119 | },
120 | {
121 | code: 'var foo = "" as Blacklist.Example;',
122 | errors: [defaultErrorMessageWithWord('blacklist')],
123 | },
124 | {
125 | code: 'var foo = ""; // blacklist',
126 | errors: [defaultErrorMessageWithWord('blacklist')],
127 | },
128 | {
129 | code: 'enum Blacklist {}',
130 | errors: [defaultErrorMessageWithWord('blacklist')],
131 | },
132 | {
133 | code: 'class Blacklist {}',
134 | errors: [defaultErrorMessageWithWord('blacklist')],
135 | },
136 | {
137 | code: 'type Blacklist = {}',
138 | errors: [defaultErrorMessageWithWord('blacklist')],
139 | },
140 | {
141 | code: "/* Hello world. I'm using the discouraged word blacklist. */",
142 | errors: [defaultErrorMessageWithWord('blacklist')],
143 | },
144 | ],
145 | });
146 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/Tasks/CommitTasks.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { default as Debug } from 'debug';
17 | import { default as spawn } from 'cross-spawn';
18 | import { default as promiseSpawn } from 'cross-spawn-promise';
19 | import { SpawnSyncReturns } from 'child_process';
20 | // @ts-ignore
21 | import { bootstrap as czBootstrap } from 'commitizen/dist/cli/git-cz';
22 | import { hasConfig } from '@spotify/web-scripts-utils';
23 |
24 | import { typeCheck } from './LintTask';
25 | import {
26 | CommitTaskDesc,
27 | CommitMsgTaskDesc,
28 | ReleaseTaskDesc,
29 | PrecommitTaskDesc,
30 | } from '../SharedTypes';
31 | import { LINT_STAGED_CONFIG } from '../Paths';
32 |
33 | export function getLintStagedConfig(): string | null {
34 | if (
35 | !hasConfig([
36 | { type: 'file', pattern: 'lint-staged.config.js' },
37 | { type: 'file', pattern: '.lintstagedrc*' },
38 | { type: 'package.json', property: 'lint-staged' },
39 | ])
40 | ) {
41 | return LINT_STAGED_CONFIG;
42 | }
43 |
44 | return null;
45 | }
46 |
47 | const dbg = Debug('web-scripts:commit'); // eslint-disable-line new-cap
48 |
49 | export async function precommitTask(
50 | task: PrecommitTaskDesc,
51 | ): Promise {
52 | const fns: Array<(task?: PrecommitTaskDesc) => Promise> = [];
53 | if (task.typecheck) {
54 | fns.push(typeCheck);
55 | }
56 |
57 | const results = await Promise.all(
58 | fns.map(async fn => {
59 | dbg('Beginning %s task', fn.name);
60 | const stdout = await fn(task);
61 | dbg('Finished %s task', fn.name);
62 | return stdout;
63 | }),
64 | );
65 |
66 | // unfortunately, lint-staged cannot be parallelized alongside any other tasks because it takes over the output
67 | // completely, rendering the output unreadable if anything is run with it.
68 | results.push(await lintStaged(task));
69 |
70 | return results;
71 | }
72 |
73 | export async function lintStaged(task: PrecommitTaskDesc): Promise {
74 | const config = getLintStagedConfig();
75 | const cmd = 'npx';
76 | const args = [
77 | '--no-install',
78 | 'lint-staged',
79 | ...(config ? ['--config', config] : []),
80 | ...task.restOptions,
81 | ];
82 | dbg('npx args %o', args);
83 |
84 | const env: { [key: string]: string } = {
85 | ...process.env,
86 | WEB_SCRIPTS_RUN_TESTS: task.tests.toString(),
87 | };
88 |
89 | if (task.eslintConfig) {
90 | env.WEB_SCRIPTS_ESLINT_CONFIG = task.eslintConfig;
91 | }
92 | if (task.jestConfig) {
93 | env.WEB_SCRIPTS_JEST_CONFIG = task.jestConfig;
94 | }
95 | if (task.prettierConfig) {
96 | env.WEB_SCRIPTS_PRETTIER_CONFIG = task.prettierConfig;
97 | }
98 |
99 | const stdout = await promiseSpawn(cmd, args, {
100 | stdio: 'inherit',
101 | env,
102 | });
103 |
104 | return (stdout || '').toString();
105 | }
106 |
107 | export function commitTask(task: CommitTaskDesc): void {
108 | dbg('running commitizen commit', task.restOptions);
109 |
110 | // use this to get the resolved path to the root of the commitizen directory
111 | const cliPath = require
112 | .resolve('commitizen/package.json')
113 | .replace('package.json', '');
114 |
115 | // https://github.com/commitizen/cz-cli/issues/667
116 | Object.assign(process.env, {
117 | CZ_TYPE: process.env.CZ_TYPE || ' ',
118 | CZ_SCOPE: process.env.CZ_SCOPE || ' ',
119 | CZ_SUBJECT: process.env.CZ_SUBJECT || ' ',
120 | CZ_BODY: process.env.CZ_BODY || ' ',
121 | CZ_ISSUES: process.env.CZ_ISSUES || ' ',
122 | CZ_MAX_HEADER_WIDTH: process.env.CZ_MAX_HEADER_WIDTH || 100,
123 | CZ_MAX_LINE_WIDTH: process.env.CZ_MAX_LINE_WIDTH || 100,
124 | });
125 |
126 | return czBootstrap(
127 | {
128 | cliPath,
129 | config: {
130 | path: task.path,
131 | },
132 | },
133 | // this gets the arguments in the right positions to
134 | // satisfy commitizen, which strips the first two
135 | // (assumes that they're `['node', 'git-cz']`)
136 | [null, ...task.restOptions],
137 | );
138 | }
139 |
140 | export function commitMsgTask(
141 | task: CommitMsgTaskDesc,
142 | ): SpawnSyncReturns {
143 | const cmd = 'npx';
144 | const args = [
145 | '--no-install',
146 | 'commitlint',
147 | `--config=${task.config}`,
148 | `--edit=${task.edit || process.env.HUSKY_GIT_PARAMS}`,
149 | ...task.restOptions,
150 | ];
151 | dbg('npx args %o', args);
152 | return spawn.sync(cmd, args, { stdio: 'inherit' });
153 | }
154 |
155 | export function releaseTask(task: ReleaseTaskDesc): SpawnSyncReturns {
156 | const cmd = 'npx';
157 | const args = ['--no-install', 'semantic-release', ...task.restOptions];
158 | dbg('npx args %o', args);
159 | return spawn.sync(cmd, args, { stdio: 'inherit' });
160 | }
161 |
--------------------------------------------------------------------------------
/packages/eslint-plugin/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **deps:** upgrade dependencies ([ef060c7](https://github.com/spotify/web-scripts/commit/ef060c7da531060cc1d0f0fb60d3df8f355e418e))
11 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
12 |
13 | ### BREAKING CHANGES
14 |
15 | - **node:** Node bump from v14 to v18
16 | - **deps:** TypeScript bump from v4 to v5, Jest bump from v28 to v29
17 |
18 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
19 |
20 | **Note:** Version bump only for package @spotify/eslint-plugin
21 |
22 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
23 |
24 | **Note:** Version bump only for package @spotify/eslint-plugin
25 |
26 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
27 |
28 | **Note:** Version bump only for package @spotify/eslint-plugin
29 |
30 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
31 |
32 | **Note:** Version bump only for package @spotify/eslint-plugin
33 |
34 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
35 |
36 | **Note:** Version bump only for package @spotify/eslint-plugin
37 |
38 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
39 |
40 | **Note:** Version bump only for package @spotify/eslint-plugin
41 |
42 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
43 |
44 | **Note:** Version bump only for package @spotify/eslint-plugin
45 |
46 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
47 |
48 | **Note:** Version bump only for package @spotify/eslint-plugin
49 |
50 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
51 |
52 | **Note:** Version bump only for package @spotify/eslint-plugin
53 |
54 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
55 |
56 | ### Bug Fixes
57 |
58 | - fix peer dependency versioning for eslint ([46068c2](https://github.com/spotify/web-scripts/commit/46068c240faccb3ee8db2244541a6b1fbc0a6d90))
59 |
60 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
61 |
62 | ### chore
63 |
64 | - update [@typescript-eslint](https://github.com/typescript-eslint) from v4 to v5, eslint from v7 to v8 ([e284943](https://github.com/spotify/web-scripts/commit/e28494330a6dd9c2561370f56a4eed1ef152f23d))
65 | - update eslint from v7 to v8 ([725749c](https://github.com/spotify/web-scripts/commit/725749c6cf177de20b4011057198dd590cdbb742))
66 |
67 | ### BREAKING CHANGES
68 |
69 | - update @typescript-eslint from v4 to v5, eslint from v7 to v8
70 | - update eslint from v7 to v8
71 |
72 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
73 |
74 | ### Build System
75 |
76 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
77 |
78 | ### BREAKING CHANGES
79 |
80 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
81 |
82 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
83 |
84 | **Note:** Version bump only for package @spotify/eslint-plugin
85 |
86 | # [10.1.0](https://github.com/spotify/web-scripts/compare/v10.0.1...v10.1.0) (2021-06-30)
87 |
88 | **Note:** Version bump only for package @spotify/eslint-plugin
89 |
90 | ## [10.0.1](https://github.com/spotify/web-scripts/compare/v10.0.0...v10.0.1) (2021-04-27)
91 |
92 | **Note:** Version bump only for package @spotify/eslint-plugin
93 |
94 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
95 |
96 | ### Build System
97 |
98 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
99 |
100 | ### BREAKING CHANGES
101 |
102 | - drop support for NodeJS v10.x, which reaches EOL on
103 | April 30, 2021.
104 |
105 | ## [9.0.2](https://github.com/spotify/web-scripts/compare/v9.0.1...v9.0.2) (2021-02-26)
106 |
107 | **Note:** Version bump only for package @spotify/eslint-plugin
108 |
109 | ## [9.0.1](https://github.com/spotify/web-scripts/compare/v9.0.0...v9.0.1) (2021-02-21)
110 |
111 | **Note:** Version bump only for package @spotify/eslint-plugin
112 |
113 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
114 |
115 | ### Bug Fixes
116 |
117 | - sync [@typescript-eslint](https://github.com/typescript-eslint) versions across repo ([fb20119](https://github.com/spotify/web-scripts/commit/fb201196a551a3b942410b1e5a3b40c5f43bc721)), closes [#555](https://github.com/spotify/web-scripts/issues/555)
118 |
119 | ## [8.1.1](https://github.com/spotify/web-scripts/compare/v8.1.0...v8.1.1) (2020-09-22)
120 |
121 | ### Bug Fixes
122 |
123 | - update eslint-plugin to allow for @typescript-eslint/parser@4 ([0363558](https://github.com/spotify/web-scripts/commit/0363558716e39ec175e14375070206e97a418d39))
124 |
125 | # [8.1.0](https://github.com/spotify/web-scripts/compare/v8.0.4...v8.1.0) (2020-09-08)
126 |
127 | ### Features
128 |
129 | - **eslint-spotify:** added eslint-plugin package w/ best-practices/no-discouraged-words ([ddbbadc](https://github.com/spotify/web-scripts/commit/ddbbadcb810bc8f15f94f14fa5e9cc468c476131))
130 |
--------------------------------------------------------------------------------
/packages/web-scripts/README.md:
--------------------------------------------------------------------------------
1 | # web-scripts
2 |
3 | ## Description
4 |
5 | Build, lint, test, format, and release your JS/TS library. This CLI tool bundles all the necessary configuration and dependencies so you can focus on the code.
6 |
7 | ## Usage
8 |
9 | ```sh
10 | yarn add --dev @spotify/web-scripts husky
11 | ```
12 |
13 | Add the scripts and commit hooks to your package.json:
14 |
15 | ```json
16 | {
17 | "scripts": {
18 | "test": "web-scripts test",
19 | "lint": "web-scripts lint",
20 | "format": "web-scripts format",
21 | "build": "web-scripts build",
22 | "commit": "web-scripts commit",
23 | "release": "web-scripts release"
24 | },
25 | "husky": {
26 | "hooks": {
27 | "commit-msg": "web-scripts commitmsg",
28 | "pre-commit": "web-scripts precommit"
29 | }
30 | }
31 | }
32 | ```
33 |
34 | If you plan to use `web-scripts build` to build ESM, CommonJS, and types for your library with ease, update your package.json to define the locations where those will end up. [Read more about our the build script](#the-build-script).
35 |
36 | ```json
37 | {
38 | "main": "cjs/index.js",
39 | "module": "esm/index.js",
40 | "types": "types"
41 | }
42 | ```
43 |
44 | ### Editor support steps
45 |
46 | Add a root tsconfig.json:
47 |
48 | ```json
49 | {
50 | "extends": "@spotify/web-scripts/config/tsconfig.json",
51 | "include": ["src"]
52 | }
53 | ```
54 |
55 | Add a root prettier.config.js:
56 |
57 | ```js
58 | module.exports = require('@spotify/web-scripts/config/prettier.config.js');
59 | ```
60 |
61 | Add a root .eslintrc.js:
62 |
63 | ```js
64 | module.exports = require('@spotify/web-scripts/config/eslintrc.js');
65 | ```
66 |
67 | Add a root jest.config.js:
68 |
69 | ```js
70 | module.exports = require('@spotify/web-scripts/config/jest.config.js');
71 | ```
72 |
73 | ### Watchers
74 |
75 | Both `web-scripts build` and `web-scripts test` support a `--watch` flag which runs the underlying CLIs (tsc and jest) as watchers.
76 |
77 | ```sh
78 | # re-compile the cjs, esm, and types on each change to your src with tsc
79 | web-scripts build --watch
80 |
81 | # re-run the tests that are relevant to your file changes with jest
82 | web-scripts test --watch
83 | ```
84 |
85 | ### The `build` script
86 |
87 | `web-scripts build` runs three parallel calls to the TypeScript compiler.
88 |
89 | - One of them transpiles the files as CommonJS and outputs it to the `cjs` directory. Your repo should have `"cjs/index.js"` set as `main` in your package.json. You can turn this off using `--no-cjs` when running build.
90 | - Another does the exact same thing but only transpiles to [EcmaScript modules](https://github.com/standard-things/esm). This is super helpful if your consuming project is using Babel or TypeScript, and you'll end up avoiding playing games of transpilation telephone along the way. Your repo should have `"esm/index.js"` set as `module` in your package.json if using this. You can turn this off with the `--no-esm` flag when running build.
91 | - Finally, tsc will be run to output type definitions. Your repo should have the `"types"` directory set as `types` in your package.json if using this. You can turn this off with the `--no-types` flag when running build.
92 |
93 | These parallel builds are set up to share resources and work efficiently.
94 |
95 | If you need to use Babel for some reason, that's ok! Simply use babel directly instead of using `web-scripts build`. Teams inside Spotify mix and match which scripts they use to serve their needs. In many cases, `tsc` is all you need and is lighter and simpler to set up.
96 |
97 | ### Setting up CI publishing (Travis CI)
98 |
99 | The following steps should be from your local repository folder.
100 |
101 | (Optional but probably mandatory): Visit https://travis-ci.com/account/repositories and click "Sync Account" otherwise the Travis CLI may not be able to register your ENV vars later.
102 |
103 | 1. Add a basic .travis.yaml. You probably want something like:
104 |
105 | ```yml
106 | language: node_js
107 | node_js:
108 | - '14'
109 | branches:
110 | only:
111 | - master
112 | cache:
113 | yarn: true
114 | directories:
115 | - node_modules
116 | before_install:
117 | - curl -o- -L https://yarnpkg.com/install.sh | bash -s
118 | - export PATH="$HOME/.yarn/bin:$PATH"
119 | script:
120 | - yarn lint
121 | - yarn test
122 | ```
123 |
124 | 2. Append a "release" stage to the `jobs:` that invokes `web-scripts release`:
125 |
126 | ```
127 | jobs:
128 | include:
129 | - stage: release
130 | node_js: lts/*
131 | script: skip # do not run tests again
132 | deploy:
133 | provider: script
134 | skip_cleanup: true
135 | script:
136 | - yarn web-scripts release # or `yarn release` if you defined it in your package.json scripts
137 | ```
138 |
139 | 3. Install the travis CI CLI: `gem install travis`
140 | 4. Create an NPM token: `https://www.npmjs.com/settings/[NPM USERNAME]/tokens` (scope: Read and Publish)
141 | 5. Set the secure ENV var: `travis env set NPM_TOKEN YOUR-NPM-TOKEN`
142 | 6. Create a Github Token: `https://github.com/settings/tokens` (required scope: `public_repo` !)
143 | 7. Set the secure ENV var: `travis env set GH_TOKEN YOUR-GH-TOKEN`
144 | 8. Commit all your changes with `yarn commit`, and push.
145 |
146 | If you use a scoped public package, such as `@yourusername/packagename`, then you'll need explicitly set in your `package.json`:
147 |
148 | ```
149 | "publishConfig": {
150 | "access": "public"
151 | },
152 | ```
153 |
154 | Otherwise you'll receive an error during release like "You must sign up for private packages" or a missing flag `--access=public`.
155 |
156 | ## Contributing
157 |
158 | To start working in the repo:
159 |
160 | ```sh
161 | yarn
162 | yarn bootstrap
163 | ```
164 |
165 | This library provides shared scripts and configs for creating a library at Spotify. It tries to use as much of those scripts and configs for itself, which is why the `bootstrap` task is required above. Otherwise, you can run within this package itself:
166 |
167 | ```sh
168 | yarn lint
169 | yarn build
170 | yarn test
171 | ```
172 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @spotify/web-scripts
2 |
3 | [](https://github.com/spotify/web-scripts/actions)
4 | [](https://www.npmjs.com/package/@spotify/web-scripts)
5 |
6 | # ⚠️ DEPRECATION NOTICE
7 |
8 | 2023-12-15: This repository is now officially deprecated. This means that the repository is no longer actively maintained and will not receive any further updates or bug fixes.
9 |
10 | ---
11 |
12 | A monorepo of base configs and CLI wrappers used to speed up development @ Spotify.
13 |
14 | Want to use it? Check out the [CLI documentation](https://github.com/spotify/web-scripts/blob/master/packages/web-scripts) to get started!
15 |
16 | ## About this project
17 |
18 | ### web-scripts CLI
19 |
20 | [@spotify/web-scripts](./packages/web-scripts) is a CLI that combines shared configuration for building, linting, testing, formatting, and releasing libraries for Node and the browser. It is opinionated, but allows configuration to avoid lock-in. You can also pick and choose which scripts you use. It is inspired by other tooling bundles like [react-scripts](https://www.npmjs.com/package/react-scripts) and [kcd-scripts](https://www.npmjs.com/package/kcd-scripts).
21 |
22 | ```bash
23 | yarn add --dev @spotify/web-scripts husky
24 | ```
25 |
26 | It is intended to be used within a project as a series of npm scripts.
27 |
28 | ```json
29 | {
30 | "devDependencies": {
31 | "@spotify/web-scripts": "^12.0.0",
32 | "husky": "^7.0.0"
33 | },
34 | "scripts": {
35 | "build": "web-scripts build",
36 | "test": "web-scripts test",
37 | "format": "web-scripts format",
38 | "lint": "web-scripts lint",
39 | "commit": "web-scripts commit",
40 | "release": "web-scripts release",
41 | "prepare": "husky install && web-scripts audit"
42 | }
43 | }
44 | ```
45 |
46 | Additionally, you'll need to run the following two commands to create the commit and pre-commit hooks:
47 |
48 | ```shell
49 | npx husky set .husky/pre-commit 'yarn web-scripts precommit --no-tests --no-typecheck'
50 |
51 | npx husky set .husky/commit-msg 'yarn web-scripts commitmsg --edit="$1"' && \
52 | sed 's/edit=""/edit="$1"/g' .husky/commit-msg | tee .husky/commit-msg
53 | ```
54 |
55 | NOTE: the second command uses sed to hack around [this bug in husky](https://github.com/typicode/husky/issues/1019) that removes `$1`.
56 |
57 | You'll want to add and commit the `.husky` directory.
58 |
59 | View the [full CLI documentation](./packages/web-scripts) for more details on how to get started.
60 |
61 | ### Create a new library
62 |
63 | To quickly get started with a new `@spotify/web-scripts` library, you can build one with our [library scaffolding tool](https://github.com/spotify/web-scripts/tree/master/packages/create-web-scripts-library):
64 |
65 | ```sh
66 | yarn create @spotify/web-scripts-library my-library-name
67 | ```
68 |
69 | ### Spotify shared configurations
70 |
71 | The other projects in this repo are shared configurations for common tools we use for building, linting, and formatting our code. They can be installed separately and used by anyone should they opt to follow our standards. We have a [specialized point-of-view on what belongs in our configs](#methodology). They are all used by the web-scripts CLI by default.
72 |
73 | - [@spotify/eslint-config](./packages/eslint-config)
74 | - [@spotify/eslint-config-base](./packages/eslint-config-base)
75 | - [@spotify/eslint-config-react](./packages/eslint-config-react)
76 | - [@spotify/eslint-config-typescript](./packages/eslint-config-typescript)
77 | - [@spotify/eslint-plugin](./packages/eslint-plugin)
78 | - [@spotify/prettier-config](./packages/prettier-config)
79 | - [@spotify/tsconfig](./packages/tsconfig)
80 |
81 | ## Methodology
82 |
83 | We have a few guiding principles for this project.
84 |
85 | 1. Style rules should be auto-fixable and if you can, errors should be linted ahead of runtime.
86 | 2. Avoid enforcing code style in static analysis; search for bugs with static analysis, and let auto-formatting deal with code style.
87 | 3. Push "fast" checks as far left as you can. Optimize for code editors/IDEs fixing issues and enforcing things; write Git hooks that catch things as a failsafe; and use static analysis in CI to prevent bad things from getting into master.
88 | 4. `web-scripts` is meant to be configurable. We want to avoid the "eject" problem. You should be able to easily take the base configs and extend them in your project.
89 | 5. Fewer top-level scripts that encapsulate all behavior for that lifecycle are preferable to lots of smaller, composable scripts. For example, we do `yarn lint` which includes Prettier, ESLint, and TypeScript checks. We could have done `yarn lint`, `yarn typecheck`, and `yarn stylecheck`. That would have meant pushing "new" linting to all repos on new versions would be much harder, as we would need to communicate that you need to update your invocation in package.json.
90 |
91 | ## Related projects we use
92 |
93 | - [TypeScript]: a superset of JavaScript which we think helps make code readable and less bug-prone.
94 | - [ESLint]: used for static code analysis with some auto-fixing.
95 | - [Prettier]: use to format code pre-commit and automatically in your editor.
96 | - [Jest]: our preferred JavaScript test framework.
97 | - [husky]: allows us to hook into git events in a convenient way.
98 | - [lint-staged]: allows us to write pre-commit hooks which target specific paths and run a series of commands.
99 |
100 | ## Contributing
101 |
102 | This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code.
103 |
104 | This project is an opinionated approach to static analysis, code formatting, testing, and publishing. It's
105 | the result of consensus between many web engineers inside Spotify, and the default configs will mostly be
106 | written by Spotify employees. _We may reject PRs to the ESLint config if we don't agree that the rule
107 | makes sense as part of our baseline, for example._ Use it if it aligns with your needs!
108 |
109 | ### Running Tests locally
110 |
111 | If you get an error like `Cannot find module '../cjs'` when running `yarn test`, you need to bootstrap web-scripts.
112 |
113 | ```bash
114 | $ yarn lerna run bootstrap
115 | ```
116 |
117 | [eslint]: https://eslint.org/
118 | [typescript]: https://www.typescriptlang.org/
119 | [prettier]: https://prettier.io/
120 | [jest]: https://jestjs.io/
121 | [husky]: https://github.com/typicode/husky
122 | [lint-staged]: https://github.com/okonet/lint-staged
123 | [code-of-conduct]: https://github.com/spotify/code-of-conduct/blob/master/code-of-conduct.md
124 |
125 | ### Releasing
126 |
127 | The repo [releases automatically on merge to master](https://github.com/spotify/web-scripts/blob/master/release.sh) using `semantic-release` and `lerna` in a Github Action, if the commit message has the right [semantic-release format](https://github.com/semantic-release/semantic-release#commit-message-format)
128 |
--------------------------------------------------------------------------------
/packages/web-scripts-utils/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **deps:** upgrade dependencies ([ef060c7](https://github.com/spotify/web-scripts/commit/ef060c7da531060cc1d0f0fb60d3df8f355e418e))
11 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
12 |
13 | ### BREAKING CHANGES
14 |
15 | - **node:** Node bump from v14 to v18
16 | - **deps:** TypeScript bump from v4 to v5, Jest bump from v28 to v29
17 |
18 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
19 |
20 | **Note:** Version bump only for package @spotify/web-scripts-utils
21 |
22 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
23 |
24 | **Note:** Version bump only for package @spotify/web-scripts-utils
25 |
26 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
27 |
28 | **Note:** Version bump only for package @spotify/web-scripts-utils
29 |
30 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
31 |
32 | **Note:** Version bump only for package @spotify/web-scripts-utils
33 |
34 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
35 |
36 | **Note:** Version bump only for package @spotify/web-scripts-utils
37 |
38 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
39 |
40 | **Note:** Version bump only for package @spotify/web-scripts-utils
41 |
42 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
43 |
44 | **Note:** Version bump only for package @spotify/web-scripts-utils
45 |
46 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
47 |
48 | **Note:** Version bump only for package @spotify/web-scripts-utils
49 |
50 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
51 |
52 | **Note:** Version bump only for package @spotify/web-scripts-utils
53 |
54 | # [14.0.0](https://github.com/spotify/web-scripts/compare/v13.0.1...v14.0.0) (2022-07-11)
55 |
56 | ### chore
57 |
58 | - **deps:** upgrade deps; jest from v27 to v28 ([13aff23](https://github.com/spotify/web-scripts/commit/13aff23c90c7b23ca0a8bb27eb58695663d3f644))
59 |
60 | ### BREAKING CHANGES
61 |
62 | - **deps:** Jest bump from v27 to v28
63 |
64 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
65 |
66 | **Note:** Version bump only for package @spotify/web-scripts-utils
67 |
68 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
69 |
70 | **Note:** Version bump only for package @spotify/web-scripts-utils
71 |
72 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
73 |
74 | ### Build System
75 |
76 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
77 |
78 | ### BREAKING CHANGES
79 |
80 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
81 |
82 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
83 |
84 | **Note:** Version bump only for package @spotify/web-scripts-utils
85 |
86 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
87 |
88 | ### Build System
89 |
90 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
91 |
92 | ### BREAKING CHANGES
93 |
94 | - drop support for NodeJS v10.x, which reaches EOL on
95 | April 30, 2021.
96 |
97 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
98 |
99 | **Note:** Version bump only for package @spotify/web-scripts-utils
100 |
101 | # [8.0.0](https://github.com/spotify/web-scripts/compare/v7.0.2...v8.0.0) (2020-06-23)
102 |
103 | **Note:** Version bump only for package @spotify/web-scripts-utils
104 |
105 | # [7.0.0](https://github.com/spotify/web-scripts/compare/v6.2.0...v7.0.0) (2020-04-28)
106 |
107 | **Note:** Version bump only for package @spotify/web-scripts-utils
108 |
109 | ## [6.1.1](https://github.com/spotify/web-scripts/compare/v6.1.0...v6.1.1) (2020-04-03)
110 |
111 | **Note:** Version bump only for package @spotify/web-scripts-utils
112 |
113 | # [6.0.0](https://github.com/spotify/web-scripts/compare/v5.3.0...v6.0.0) (2020-01-29)
114 |
115 | ### Build System
116 |
117 | - bump node in engines to 10.18.0 ([08ea936](https://github.com/spotify/web-scripts/commit/08ea936faf879be18b97f8a4ba99aba5926ccff8))
118 |
119 | ### BREAKING CHANGES
120 |
121 | - increasing Node version in engines declaration
122 |
123 | # [5.3.0](https://github.com/spotify/web-scripts/compare/v5.2.1...v5.3.0) (2020-01-29)
124 |
125 | **Note:** Version bump only for package @spotify/web-scripts-utils
126 |
127 | # [5.1.0](https://github.com/spotify/web-scripts/compare/v5.0.2...v5.1.0) (2020-01-22)
128 |
129 | ### Features
130 |
131 | - **web-scripts:** rename postinstall to audit ([169f3c1](https://github.com/spotify/web-scripts/commit/169f3c18641d7a51c5319ba8e155cd5a7bd4b85e)), closes [#131](https://github.com/spotify/web-scripts/issues/131)
132 |
133 | ## [5.0.2](https://github.com/spotify/web-scripts/compare/v5.0.1...v5.0.2) (2020-01-21)
134 |
135 | **Note:** Version bump only for package @spotify/web-scripts-utils
136 |
137 | # [5.0.0](https://github.com/spotify/web-scripts/compare/v4.0.2...v5.0.0) (2020-01-06)
138 |
139 | ### Features
140 |
141 | - **tsconfig:** expose a single tsconfig ([5048d6a](https://github.com/spotify/web-scripts/commit/5048d6aea1e8949c11bfa8ed5bbdff3f177074b7)), closes [#21](https://github.com/spotify/web-scripts/issues/21)
142 |
143 | ### BREAKING CHANGES
144 |
145 | - **tsconfig:** deleted a number of exports from tsconfig
146 |
147 | # [4.0.0](https://github.com/spotify/web-scripts/compare/v3.3.1...v4.0.0) (2020-01-03)
148 |
149 | ### chore
150 |
151 | - bump engine to >=10.13.0 ([9527453](https://github.com/spotify/web-scripts/commit/9527453a03ea0a807e6f6964469bf8482a3e3cca))
152 |
153 | ### BREAKING CHANGES
154 |
155 | - Minimum Node version has been increased
156 |
157 | # [3.3.0](https://github.com/spotify/web-scripts/compare/v3.2.0...v3.3.0) (2020-01-03)
158 |
159 | ### Features
160 |
161 | - **deps:** yarn upgrade ([1b49fd8](https://github.com/spotify/web-scripts/commit/1b49fd84fcf23eb992dea9ac6cf08bf20b35270e))
162 |
163 | # [3.1.0](https://github.com/spotify/web-scripts/compare/v3.0.1...v3.1.0) (2020-01-02)
164 |
165 | ### Bug Fixes
166 |
167 | - stylecheck should use implicit config ([9c9a88c](https://github.com/spotify/web-scripts/commit/9c9a88c))
168 |
169 | # [3.0.0](https://github.com/spotify/web-scripts/compare/v2.1.0...v3.0.0) (2019-10-10)
170 |
171 | **Note:** Version bump only for package @spotify/web-scripts-utils
172 |
173 | # [2.1.0](https://github.com/spotify/web-scripts/compare/v2.0.1...v2.1.0) (2019-10-10)
174 |
175 | ### Features
176 |
177 | - use package attributes to determine lint preset ([f6151ed](https://github.com/spotify/web-scripts/commit/f6151ed)), closes [#56](https://github.com/spotify/web-scripts/issues/56)
178 |
--------------------------------------------------------------------------------
/packages/prettier-config/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **deps:** upgrade dependencies ([ef060c7](https://github.com/spotify/web-scripts/commit/ef060c7da531060cc1d0f0fb60d3df8f355e418e))
11 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
12 |
13 | ### BREAKING CHANGES
14 |
15 | - **node:** Node bump from v14 to v18
16 | - **deps:** TypeScript bump from v4 to v5, Jest bump from v28 to v29
17 |
18 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
19 |
20 | **Note:** Version bump only for package @spotify/prettier-config
21 |
22 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
23 |
24 | **Note:** Version bump only for package @spotify/prettier-config
25 |
26 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
27 |
28 | **Note:** Version bump only for package @spotify/prettier-config
29 |
30 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
31 |
32 | **Note:** Version bump only for package @spotify/prettier-config
33 |
34 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
35 |
36 | **Note:** Version bump only for package @spotify/prettier-config
37 |
38 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
39 |
40 | **Note:** Version bump only for package @spotify/prettier-config
41 |
42 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
43 |
44 | **Note:** Version bump only for package @spotify/prettier-config
45 |
46 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
47 |
48 | **Note:** Version bump only for package @spotify/prettier-config
49 |
50 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
51 |
52 | **Note:** Version bump only for package @spotify/prettier-config
53 |
54 | # [14.0.0](https://github.com/spotify/web-scripts/compare/v13.0.1...v14.0.0) (2022-07-11)
55 |
56 | **Note:** Version bump only for package @spotify/prettier-config
57 |
58 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
59 |
60 | **Note:** Version bump only for package @spotify/prettier-config
61 |
62 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
63 |
64 | **Note:** Version bump only for package @spotify/prettier-config
65 |
66 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
67 |
68 | ### Build System
69 |
70 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
71 |
72 | ### BREAKING CHANGES
73 |
74 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
75 |
76 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
77 |
78 | **Note:** Version bump only for package @spotify/prettier-config
79 |
80 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
81 |
82 | ### Build System
83 |
84 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
85 |
86 | ### BREAKING CHANGES
87 |
88 | - drop support for NodeJS v10.x, which reaches EOL on
89 | April 30, 2021.
90 |
91 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
92 |
93 | **Note:** Version bump only for package @spotify/prettier-config
94 |
95 | # [8.0.0](https://github.com/spotify/web-scripts/compare/v7.0.2...v8.0.0) (2020-06-23)
96 |
97 | **Note:** Version bump only for package @spotify/prettier-config
98 |
99 | # [7.0.0](https://github.com/spotify/web-scripts/compare/v6.2.0...v7.0.0) (2020-04-28)
100 |
101 | - major release- 7.0.0 (#318) ([29509b4](https://github.com/spotify/web-scripts/commit/29509b4a52325080b7a38f3aeb41ce8ed82f04f5)), closes [#318](https://github.com/spotify/web-scripts/issues/318) [#314](https://github.com/spotify/web-scripts/issues/314) [#312](https://github.com/spotify/web-scripts/issues/312) [#310](https://github.com/spotify/web-scripts/issues/310)
102 |
103 | ### BREAKING CHANGES
104 |
105 | - running web-scripts without arguments exits code 1 now instead of exiting 0
106 | - prettier 2.0 may introduce breaking changes
107 | - prettier 2.0 may introduce breaking changes
108 |
109 | - improvement(web-scripts): make stylecheck and typecheck default for lint
110 |
111 | the lint script will now default typechecking and stylechecking to true by default. You may shut
112 | these off with `--no-typecheck` and `--no-stylecheck`.
113 |
114 | - Users who have projects incompatible with TypeScript checks or with projects that
115 | do not user prettier will now fail yarn lint.
116 |
117 | # [6.2.0](https://github.com/spotify/web-scripts/compare/v6.1.1...v6.2.0) (2020-04-04)
118 |
119 | **Note:** Version bump only for package @spotify/prettier-config
120 |
121 | ## [6.1.1](https://github.com/spotify/web-scripts/compare/v6.1.0...v6.1.1) (2020-04-03)
122 |
123 | **Note:** Version bump only for package @spotify/prettier-config
124 |
125 | # [6.0.0](https://github.com/spotify/web-scripts/compare/v5.3.0...v6.0.0) (2020-01-29)
126 |
127 | ### Build System
128 |
129 | - bump node in engines to 10.18.0 ([08ea936](https://github.com/spotify/web-scripts/commit/08ea936faf879be18b97f8a4ba99aba5926ccff8))
130 |
131 | ### BREAKING CHANGES
132 |
133 | - increasing Node version in engines declaration
134 |
135 | # [5.0.0](https://github.com/spotify/web-scripts/compare/v4.0.2...v5.0.0) (2020-01-06)
136 |
137 | **Note:** Version bump only for package @spotify/prettier-config
138 |
139 | # [4.0.0](https://github.com/spotify/web-scripts/compare/v3.3.1...v4.0.0) (2020-01-03)
140 |
141 | ### chore
142 |
143 | - bump engine to >=10.13.0 ([9527453](https://github.com/spotify/web-scripts/commit/9527453a03ea0a807e6f6964469bf8482a3e3cca))
144 |
145 | ### BREAKING CHANGES
146 |
147 | - Minimum Node version has been increased
148 |
149 | # [3.0.0](https://github.com/spotify/web-scripts/compare/v2.1.0...v3.0.0) (2019-10-10)
150 |
151 | **Note:** Version bump only for package @spotify/prettier-config
152 |
153 | # [2.0.0](https://github.com/spotify/web-scripts/compare/v1.4.0...v2.0.0) (2019-09-23)
154 |
155 | **Note:** Version bump only for package @spotify/prettier-config
156 |
157 | ## [1.1.4](https://github.com/spotify/web-scripts/compare/v1.1.3...v1.1.4) (2019-07-17)
158 |
159 | ### Bug Fixes
160 |
161 | - Add repostiory field to package.json files ([fccd2db](https://github.com/spotify/web-scripts/commit/fccd2db))
162 |
163 | # [1.1.0](https://github.com/spotify/web-scripts/compare/v1.0.2...v1.1.0) (2019-07-01)
164 |
165 | ### Bug Fixes
166 |
167 | - Updates engines field to node >=10 ([b3b4f58](https://github.com/spotify/web-scripts/commit/b3b4f58))
168 |
169 | ## [1.0.2](https://github.com/spotify/web-scripts/compare/v1.0.1...v1.0.2) (2019-06-26)
170 |
171 | ### Bug Fixes
172 |
173 | - update dependencies for peerDependency warnings ([eceff7c](https://github.com/spotify/web-scripts/commit/eceff7c))
174 |
175 | ## [1.0.1](https://github.com/spotify/web-scripts/compare/v1.0.0...v1.0.1) (2019-06-24)
176 |
177 | **Note:** Version bump only for package @spotify/prettier-config
178 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/integration.test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { exec as execCP } from 'child_process';
17 | import { join } from 'path';
18 | import { promisify } from 'util';
19 | import {
20 | writeFile as writeFileFS,
21 | mkdir as mkdirFS,
22 | copyFile as copyFileFS,
23 | existsSync,
24 | } from 'fs';
25 | import fromEntries from 'object.fromentries';
26 | import * as tempy from 'tempy';
27 | import { default as Debug } from 'debug';
28 | import rimraf from 'rimraf';
29 |
30 | import { THIS_ROOT, TSCONFIG } from './Paths';
31 |
32 | const dbg = Debug('web-scripts:integration-test'); // eslint-disable-line new-cap
33 | const root = join(__dirname, '..');
34 | const CLI = join(root, 'bin/web-scripts');
35 | const MONOREPO_ROOT = join(root, '../..');
36 | const ESLINT_ROOT = join(MONOREPO_ROOT, 'packages/eslint-config');
37 |
38 | const execPromise = promisify(execCP);
39 | const writeFile = promisify(writeFileFS);
40 | const mkdir = promisify(mkdirFS);
41 | const copyFile = promisify(copyFileFS);
42 |
43 | // log output after the command finishes
44 | const exec = async (cmd: string, options?: object) => {
45 | function _log(resp: { stdout?: string | Buffer; stderr?: string | Buffer }) {
46 | if (resp.stdout) resp.stdout.toString().split('\n').forEach(dbg);
47 | if (resp.stderr) resp.stderr.toString().split('\n').forEach(dbg);
48 | }
49 | try {
50 | const resp = await execPromise(cmd, options);
51 | _log(resp);
52 | return resp;
53 | } catch (err) {
54 | _log(err as any);
55 | throw err;
56 | }
57 | };
58 |
59 | const SETUP_REPO_TIMEOUT = 30000;
60 | const TEST_SCRIPTS_TIMEOUT = 60000;
61 |
62 | // eslint-disable-next-line jest/no-disabled-tests
63 | describe.skip('integration tests', () => {
64 | let PKG_ROOT: string;
65 |
66 | beforeEach(() => {
67 | PKG_ROOT = tempy.directory();
68 | });
69 |
70 | describe('help', () => {
71 | const USAGE_MATCH = 'Usage: web-scripts [options] [command]';
72 |
73 | test('The CLI fails and offers help when invoked with no arguments', async () => {
74 | await expect(exec(`${CLI}`)).rejects.toMatchObject({
75 | stdout: expect.stringContaining(USAGE_MATCH),
76 | });
77 | });
78 |
79 | test('The CLI offers help when invoked with --help flag', async () => {
80 | const result = await exec(`${CLI} --help`);
81 | expect(result.stdout).toMatch(USAGE_MATCH);
82 | });
83 | });
84 |
85 | describe('TypeScript', () => {
86 | beforeEach(async () => {
87 | await setupRepo(
88 | 'index.ts',
89 | 'index.test.ts',
90 | 'Component.tsx',
91 | 'Component.test.tsx',
92 | );
93 | }, SETUP_REPO_TIMEOUT);
94 |
95 | // eslint-disable-next-line jest/expect-expect
96 | test(
97 | 'Full integration test',
98 | async () => await testScripts(),
99 | TEST_SCRIPTS_TIMEOUT,
100 | );
101 | });
102 |
103 | describe('JavaScript', () => {
104 | beforeEach(async () => {
105 | await setupRepo(
106 | 'index.js',
107 | 'index.test.js',
108 | 'Component.jsx',
109 | 'Component.test.jsx',
110 | );
111 | }, SETUP_REPO_TIMEOUT);
112 |
113 | // eslint-disable-next-line jest/expect-expect
114 | test(
115 | 'Full integration test',
116 | async () => await testScripts(['--no-types'], ['--no-typecheck']),
117 | TEST_SCRIPTS_TIMEOUT,
118 | );
119 | });
120 |
121 | async function setupRepo(...fileNames: string[]) {
122 | // we need to locally install some dependencies, but we want to avoid installing
123 | // all of them to prevent needlessly re-installing everything which significantly
124 | // slows this test down and often results in errors in CI. If one of these
125 | // dependencies is removed from package.json, this test will fail when the
126 | // commands are run at the end.
127 | const localDependencies: string[] = [
128 | 'eslint',
129 | 'ts-jest',
130 | 'typescript',
131 | '@types/jest',
132 | '@types/react',
133 | ];
134 |
135 | // as of ESLint 6, ESLint plugins need to be locally installed too.
136 | const eslintDependencies: string[] = [
137 | '@typescript-eslint/eslint-plugin',
138 | 'eslint-plugin-jest',
139 | 'eslint-plugin-jsx-a11y',
140 | 'eslint-plugin-react',
141 | 'eslint-plugin-react-hooks',
142 | ];
143 |
144 | const pkg = {
145 | name: 'test-pkg',
146 | scripts: {
147 | test: `${CLI} test`,
148 | build: `${CLI} build`,
149 | lint: `${CLI} lint`,
150 | commit: `${CLI} commit`,
151 | release: `${CLI} release`,
152 | },
153 | dependencies: fromEntries([
154 | ...Object.entries(
155 | require(`${THIS_ROOT}/package.json`).dependencies,
156 | ).filter(([k]) => localDependencies.includes(k)),
157 | ...Object.entries(
158 | require(`${ESLINT_ROOT}/package.json`).dependencies,
159 | ).filter(([k]) => eslintDependencies.includes(k)),
160 | // react isn't a local dependency so it needs to be directly specified
161 | ['react', '^17'],
162 | ]),
163 | };
164 |
165 | // extend the tsconfig from the web-scripts/config folder, using an absolute
166 | // path because we didn't link or install into the temp project
167 | const tsConfig = {
168 | extends: TSCONFIG,
169 | include: ['src'],
170 | };
171 |
172 | await writeFile(
173 | join(PKG_ROOT, 'package.json'),
174 | JSON.stringify(pkg, null, ' '),
175 | );
176 |
177 | await writeFile(
178 | join(PKG_ROOT, 'tsconfig.json'),
179 | JSON.stringify(tsConfig, null, 2),
180 | );
181 |
182 | await mkdir(join(PKG_ROOT, 'src'));
183 | fileNames.map(fileName =>
184 | copyFile(
185 | join(THIS_ROOT, '__fixtures__', fileName),
186 | join(PKG_ROOT, 'src', fileName),
187 | ),
188 | );
189 | await copyFile(
190 | join(MONOREPO_ROOT, '.gitignore'),
191 | join(PKG_ROOT, '.gitignore'),
192 | );
193 |
194 | // install the dependencies we specified above in pkg
195 | // this is what is making the tests fail
196 | // for some reason in docker it can't set the registry to the internal one
197 | await exec('yarn', { cwd: PKG_ROOT });
198 | // Required for the `commit` and `commitmsg` tasks.
199 | await exec('git init', { cwd: PKG_ROOT });
200 | }
201 |
202 | async function testScripts(
203 | buildArgs: string[] = [],
204 | lintArgs: string[] = ['--ignore-path=.gitignore', '--format=checkstyle'],
205 | ) {
206 | try {
207 | rimraf.sync(join(PKG_ROOT, 'cjs'));
208 | expect(existsSync(join(PKG_ROOT, 'cjs/index.js'))).toBe(false);
209 | await exec(['yarn build', ...buildArgs].join(' '), { cwd: PKG_ROOT });
210 | expect(existsSync(join(PKG_ROOT, 'cjs/index.js'))).toBe(true);
211 |
212 | await exec('yarn test', { cwd: PKG_ROOT });
213 | await exec('yarn test index.test', { cwd: PKG_ROOT });
214 | await exec(['yarn lint', ...lintArgs].join(' '), { cwd: PKG_ROOT });
215 | } catch (e) {
216 | // We are not capturing and printing stdout above, where TSC prints its errors. This makes sure it's printed.
217 | console.log((e as any).stdout); // eslint-disable-line no-console
218 | throw e;
219 | }
220 | }
221 | });
222 |
--------------------------------------------------------------------------------
/packages/tsconfig/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **deps:** upgrade dependencies ([ef060c7](https://github.com/spotify/web-scripts/commit/ef060c7da531060cc1d0f0fb60d3df8f355e418e))
11 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
12 |
13 | ### BREAKING CHANGES
14 |
15 | - **node:** Node bump from v14 to v18
16 | - **deps:** TypeScript bump from v4 to v5, Jest bump from v28 to v29
17 |
18 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
19 |
20 | **Note:** Version bump only for package @spotify/tsconfig
21 |
22 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
23 |
24 | **Note:** Version bump only for package @spotify/tsconfig
25 |
26 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
27 |
28 | **Note:** Version bump only for package @spotify/tsconfig
29 |
30 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
31 |
32 | **Note:** Version bump only for package @spotify/tsconfig
33 |
34 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
35 |
36 | **Note:** Version bump only for package @spotify/tsconfig
37 |
38 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
39 |
40 | **Note:** Version bump only for package @spotify/tsconfig
41 |
42 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
43 |
44 | **Note:** Version bump only for package @spotify/tsconfig
45 |
46 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
47 |
48 | **Note:** Version bump only for package @spotify/tsconfig
49 |
50 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
51 |
52 | **Note:** Version bump only for package @spotify/tsconfig
53 |
54 | # [14.0.0](https://github.com/spotify/web-scripts/compare/v13.0.1...v14.0.0) (2022-07-11)
55 |
56 | **Note:** Version bump only for package @spotify/tsconfig
57 |
58 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
59 |
60 | **Note:** Version bump only for package @spotify/tsconfig
61 |
62 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
63 |
64 | **Note:** Version bump only for package @spotify/tsconfig
65 |
66 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
67 |
68 | ### Build System
69 |
70 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
71 |
72 | ### BREAKING CHANGES
73 |
74 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
75 |
76 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
77 |
78 | **Note:** Version bump only for package @spotify/tsconfig
79 |
80 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
81 |
82 | ### Build System
83 |
84 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
85 |
86 | ### BREAKING CHANGES
87 |
88 | - drop support for NodeJS v10.x, which reaches EOL on
89 | April 30, 2021.
90 |
91 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
92 |
93 | ### Features
94 |
95 | - use TypeScript 4 ([bbf1164](https://github.com/spotify/web-scripts/commit/bbf1164c75c40457d6457274f83deb59d0de7c09)), closes [#487](https://github.com/spotify/web-scripts/issues/487) [#252](https://github.com/spotify/web-scripts/issues/252)
96 |
97 | ### BREAKING CHANGES
98 |
99 | - must upgrade to TypeScript 4 as a consumer; new tsconfig takes advantage of
100 | incremental + noEmit
101 |
102 | # [8.0.0](https://github.com/spotify/web-scripts/compare/v7.0.2...v8.0.0) (2020-06-23)
103 |
104 | **Note:** Version bump only for package @spotify/tsconfig
105 |
106 | # [7.0.0](https://github.com/spotify/web-scripts/compare/v6.2.0...v7.0.0) (2020-04-28)
107 |
108 | - major release- 7.0.0 (#318) ([29509b4](https://github.com/spotify/web-scripts/commit/29509b4a52325080b7a38f3aeb41ce8ed82f04f5)), closes [#318](https://github.com/spotify/web-scripts/issues/318) [#314](https://github.com/spotify/web-scripts/issues/314) [#312](https://github.com/spotify/web-scripts/issues/312) [#310](https://github.com/spotify/web-scripts/issues/310)
109 |
110 | ### BREAKING CHANGES
111 |
112 | - running web-scripts without arguments exits code 1 now instead of exiting 0
113 | - prettier 2.0 may introduce breaking changes
114 | - prettier 2.0 may introduce breaking changes
115 |
116 | - improvement(web-scripts): make stylecheck and typecheck default for lint
117 |
118 | the lint script will now default typechecking and stylechecking to true by default. You may shut
119 | these off with `--no-typecheck` and `--no-stylecheck`.
120 |
121 | - Users who have projects incompatible with TypeScript checks or with projects that
122 | do not user prettier will now fail yarn lint.
123 |
124 | # [6.2.0](https://github.com/spotify/web-scripts/compare/v6.1.1...v6.2.0) (2020-04-04)
125 |
126 | **Note:** Version bump only for package @spotify/tsconfig
127 |
128 | ## [6.1.1](https://github.com/spotify/web-scripts/compare/v6.1.0...v6.1.1) (2020-04-03)
129 |
130 | **Note:** Version bump only for package @spotify/tsconfig
131 |
132 | # [6.0.0](https://github.com/spotify/web-scripts/compare/v5.3.0...v6.0.0) (2020-01-29)
133 |
134 | ### Build System
135 |
136 | - bump node in engines to 10.18.0 ([08ea936](https://github.com/spotify/web-scripts/commit/08ea936faf879be18b97f8a4ba99aba5926ccff8))
137 |
138 | ### BREAKING CHANGES
139 |
140 | - increasing Node version in engines declaration
141 |
142 | # [5.0.0](https://github.com/spotify/web-scripts/compare/v4.0.2...v5.0.0) (2020-01-06)
143 |
144 | ### Features
145 |
146 | - **tsconfig:** expose a single tsconfig ([5048d6a](https://github.com/spotify/web-scripts/commit/5048d6aea1e8949c11bfa8ed5bbdff3f177074b7)), closes [#21](https://github.com/spotify/web-scripts/issues/21)
147 |
148 | ### BREAKING CHANGES
149 |
150 | - **tsconfig:** deleted a number of exports from tsconfig
151 |
152 | # [4.0.0](https://github.com/spotify/web-scripts/compare/v3.3.1...v4.0.0) (2020-01-03)
153 |
154 | ### chore
155 |
156 | - bump engine to >=10.13.0 ([9527453](https://github.com/spotify/web-scripts/commit/9527453a03ea0a807e6f6964469bf8482a3e3cca))
157 |
158 | ### BREAKING CHANGES
159 |
160 | - Minimum Node version has been increased
161 |
162 | # [3.3.0](https://github.com/spotify/web-scripts/compare/v3.2.0...v3.3.0) (2020-01-03)
163 |
164 | ### Features
165 |
166 | - **deps:** yarn upgrade ([1b49fd8](https://github.com/spotify/web-scripts/commit/1b49fd84fcf23eb992dea9ac6cf08bf20b35270e))
167 |
168 | # [3.0.0](https://github.com/spotify/web-scripts/compare/v2.1.0...v3.0.0) (2019-10-10)
169 |
170 | **Note:** Version bump only for package @spotify/tsconfig
171 |
172 | # [2.0.0](https://github.com/spotify/web-scripts/compare/v1.4.0...v2.0.0) (2019-09-23)
173 |
174 | **Note:** Version bump only for package @spotify/tsconfig
175 |
176 | ## [1.1.4](https://github.com/spotify/web-scripts/compare/v1.1.3...v1.1.4) (2019-07-17)
177 |
178 | ### Bug Fixes
179 |
180 | - Add repostiory field to package.json files ([fccd2db](https://github.com/spotify/web-scripts/commit/fccd2db))
181 |
182 | # [1.1.0](https://github.com/spotify/web-scripts/compare/v1.0.2...v1.1.0) (2019-07-01)
183 |
184 | ### Bug Fixes
185 |
186 | - Updates engines field to node >=10 ([b3b4f58](https://github.com/spotify/web-scripts/commit/b3b4f58))
187 |
188 | ## [1.0.2](https://github.com/spotify/web-scripts/compare/v1.0.1...v1.0.2) (2019-06-26)
189 |
190 | ### Bug Fixes
191 |
192 | - update dependencies for peerDependency warnings ([eceff7c](https://github.com/spotify/web-scripts/commit/eceff7c))
193 |
194 | ## [1.0.1](https://github.com/spotify/web-scripts/compare/v1.0.0...v1.0.1) (2019-06-24)
195 |
196 | **Note:** Version bump only for package @spotify/tsconfig
197 |
--------------------------------------------------------------------------------
/packages/eslint-config-base/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
11 |
12 | ### BREAKING CHANGES
13 |
14 | - **node:** Node bump from v14 to v18
15 |
16 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
17 |
18 | **Note:** Version bump only for package @spotify/eslint-config-base
19 |
20 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
21 |
22 | **Note:** Version bump only for package @spotify/eslint-config-base
23 |
24 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
25 |
26 | **Note:** Version bump only for package @spotify/eslint-config-base
27 |
28 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
29 |
30 | **Note:** Version bump only for package @spotify/eslint-config-base
31 |
32 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
33 |
34 | **Note:** Version bump only for package @spotify/eslint-config-base
35 |
36 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
37 |
38 | **Note:** Version bump only for package @spotify/eslint-config-base
39 |
40 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
41 |
42 | **Note:** Version bump only for package @spotify/eslint-config-base
43 |
44 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
45 |
46 | **Note:** Version bump only for package @spotify/eslint-config-base
47 |
48 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
49 |
50 | **Note:** Version bump only for package @spotify/eslint-config-base
51 |
52 | # [14.0.0](https://github.com/spotify/web-scripts/compare/v13.0.1...v14.0.0) (2022-07-11)
53 |
54 | **Note:** Version bump only for package @spotify/eslint-config-base
55 |
56 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
57 |
58 | **Note:** Version bump only for package @spotify/eslint-config-base
59 |
60 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
61 |
62 | **Note:** Version bump only for package @spotify/eslint-config-base
63 |
64 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
65 |
66 | ### Build System
67 |
68 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
69 |
70 | ### BREAKING CHANGES
71 |
72 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
73 |
74 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
75 |
76 | **Note:** Version bump only for package @spotify/eslint-config-base
77 |
78 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
79 |
80 | ### Build System
81 |
82 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
83 |
84 | ### BREAKING CHANGES
85 |
86 | - drop support for NodeJS v10.x, which reaches EOL on
87 | April 30, 2021.
88 |
89 | ## [9.0.2](https://github.com/spotify/web-scripts/compare/v9.0.1...v9.0.2) (2021-02-26)
90 |
91 | ### Bug Fixes
92 |
93 | - disable no-undef ([52926ad](https://github.com/spotify/web-scripts/commit/52926ad7b8d94170b0b2584afc14cdb666d47427))
94 |
95 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
96 |
97 | **Note:** Version bump only for package @spotify/eslint-config-base
98 |
99 | # [8.0.0](https://github.com/spotify/web-scripts/compare/v7.0.2...v8.0.0) (2020-06-23)
100 |
101 | ### Features
102 |
103 | - **eslint:** v7 ([55ebb7f](https://github.com/spotify/web-scripts/commit/55ebb7f402546e9c8d7c7372cafbd6f49f17790c))
104 |
105 | ### BREAKING CHANGES
106 |
107 | - **eslint:** see release notes for eslint v7
108 |
109 | # [7.0.0](https://github.com/spotify/web-scripts/compare/v6.2.0...v7.0.0) (2020-04-28)
110 |
111 | - major release- 7.0.0 (#318) ([29509b4](https://github.com/spotify/web-scripts/commit/29509b4a52325080b7a38f3aeb41ce8ed82f04f5)), closes [#318](https://github.com/spotify/web-scripts/issues/318) [#314](https://github.com/spotify/web-scripts/issues/314) [#312](https://github.com/spotify/web-scripts/issues/312) [#310](https://github.com/spotify/web-scripts/issues/310)
112 |
113 | ### BREAKING CHANGES
114 |
115 | - running web-scripts without arguments exits code 1 now instead of exiting 0
116 | - prettier 2.0 may introduce breaking changes
117 | - prettier 2.0 may introduce breaking changes
118 |
119 | - improvement(web-scripts): make stylecheck and typecheck default for lint
120 |
121 | the lint script will now default typechecking and stylechecking to true by default. You may shut
122 | these off with `--no-typecheck` and `--no-stylecheck`.
123 |
124 | - Users who have projects incompatible with TypeScript checks or with projects that
125 | do not user prettier will now fail yarn lint.
126 |
127 | # [6.2.0](https://github.com/spotify/web-scripts/compare/v6.1.1...v6.2.0) (2020-04-04)
128 |
129 | **Note:** Version bump only for package @spotify/eslint-config-base
130 |
131 | ## [6.1.1](https://github.com/spotify/web-scripts/compare/v6.1.0...v6.1.1) (2020-04-03)
132 |
133 | **Note:** Version bump only for package @spotify/eslint-config-base
134 |
135 | # [6.1.0](https://github.com/spotify/web-scripts/compare/v6.0.2...v6.1.0) (2020-03-12)
136 |
137 | ### Features
138 |
139 | - **eslint-config-base:** add rule for diabling unsafe finally blocks ([#230](https://github.com/spotify/web-scripts/issues/230)) ([5869bf9](https://github.com/spotify/web-scripts/commit/5869bf994038e918d3ae59c899d4bc2fbe465c6e))
140 |
141 | # [6.0.0](https://github.com/spotify/web-scripts/compare/v5.3.0...v6.0.0) (2020-01-29)
142 |
143 | ### Build System
144 |
145 | - bump node in engines to 10.18.0 ([08ea936](https://github.com/spotify/web-scripts/commit/08ea936faf879be18b97f8a4ba99aba5926ccff8))
146 |
147 | ### BREAKING CHANGES
148 |
149 | - increasing Node version in engines declaration
150 |
151 | ## [5.0.2](https://github.com/spotify/web-scripts/compare/v5.0.1...v5.0.2) (2020-01-21)
152 |
153 | ### Bug Fixes
154 |
155 | - **eslint-config-base:** allow triple slashes ([8ee981d](https://github.com/spotify/web-scripts/commit/8ee981dc6a2628fad0e62fb0d25938fd9dd0b4aa)), closes [#117](https://github.com/spotify/web-scripts/issues/117)
156 |
157 | # [5.0.0](https://github.com/spotify/web-scripts/compare/v4.0.2...v5.0.0) (2020-01-06)
158 |
159 | **Note:** Version bump only for package @spotify/eslint-config-base
160 |
161 | # [4.0.0](https://github.com/spotify/web-scripts/compare/v3.3.1...v4.0.0) (2020-01-03)
162 |
163 | ### chore
164 |
165 | - bump engine to >=10.13.0 ([9527453](https://github.com/spotify/web-scripts/commit/9527453a03ea0a807e6f6964469bf8482a3e3cca))
166 |
167 | ### BREAKING CHANGES
168 |
169 | - Minimum Node version has been increased
170 |
171 | # [3.0.0](https://github.com/spotify/web-scripts/compare/v2.1.0...v3.0.0) (2019-10-10)
172 |
173 | **Note:** Version bump only for package @spotify/eslint-config-base
174 |
175 | # [2.0.0](https://github.com/spotify/web-scripts/compare/v1.4.0...v2.0.0) (2019-09-23)
176 |
177 | ### Features
178 |
179 | - **eslint-config-base:** Add rule for disallowing useless constructors ([beab7ec](https://github.com/spotify/web-scripts/commit/beab7ec))
180 |
181 | ### BREAKING CHANGES
182 |
183 | - **eslint-config-base:** Adding a lint rule which doesn't have a fix, which means that upgrading could break
184 | builds due to the new rule.
185 |
186 | ## [1.1.4](https://github.com/spotify/web-scripts/compare/v1.1.3...v1.1.4) (2019-07-17)
187 |
188 | ### Bug Fixes
189 |
190 | - Add repostiory field to package.json files ([fccd2db](https://github.com/spotify/web-scripts/commit/fccd2db))
191 |
192 | # [1.1.0](https://github.com/spotify/web-scripts/compare/v1.0.2...v1.1.0) (2019-07-01)
193 |
194 | ### Bug Fixes
195 |
196 | - support ESLint 6 in our configs ([59341e3](https://github.com/spotify/web-scripts/commit/59341e3))
197 | - Updates engines field to node >=10 ([b3b4f58](https://github.com/spotify/web-scripts/commit/b3b4f58))
198 |
199 | ## [1.0.2](https://github.com/spotify/web-scripts/compare/v1.0.1...v1.0.2) (2019-06-26)
200 |
201 | ### Bug Fixes
202 |
203 | - update dependencies for peerDependency warnings ([eceff7c](https://github.com/spotify/web-scripts/commit/eceff7c))
204 |
205 | ## [1.0.1](https://github.com/spotify/web-scripts/compare/v1.0.0...v1.0.1) (2019-06-24)
206 |
207 | **Note:** Version bump only for package @spotify/eslint-config-base
208 |
--------------------------------------------------------------------------------
/packages/web-scripts/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Spotify AB
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | import { program, Command } from 'commander';
17 | import { SpawnSyncReturns } from 'child_process';
18 |
19 | import {
20 | AuditTaskDesc,
21 | BuildTaskDesc,
22 | CommitTaskDesc,
23 | CommitMsgTaskDesc,
24 | FormatTaskDesc,
25 | LintTaskDesc,
26 | PrecommitTaskDesc,
27 | ReleaseTaskDesc,
28 | TestTaskDesc,
29 | } from './SharedTypes';
30 | import { COMMITLINT_CONIFG } from './Paths';
31 | import { auditTask } from './Tasks/AuditTasks';
32 | import { testTask } from './Tasks/TestTask';
33 | import { buildTask } from './Tasks/BuildTask';
34 | import { lintTask } from './Tasks/LintTask';
35 | import { formatTask } from './Tasks/FormatTask';
36 | import {
37 | commitTask,
38 | commitMsgTask,
39 | releaseTask,
40 | precommitTask,
41 | } from './Tasks/CommitTasks';
42 |
43 | program
44 | .command('init')
45 | .description('initialize your package to use web-scripts')
46 | .action(() => {
47 | throw new Error('unimplemented');
48 | });
49 |
50 | program
51 | .command('build')
52 | .allowUnknownOption()
53 | .description('Build your project into esm, cjs, and types folders')
54 | .option('--no-esm', 'do not build esm target')
55 | .option('--no-cjs', 'do not build cjs target')
56 | .option('--no-types', 'do not build types target')
57 | .action((...args) => {
58 | const cmd = getCommand(args);
59 | const { esm, types, cjs } = getOpts(cmd);
60 | const t: BuildTaskDesc = {
61 | name: 'build',
62 | esm,
63 | types,
64 | cjs,
65 | restOptions: cmd.args,
66 | };
67 |
68 | handlePromiseResult(buildTask(t));
69 | });
70 |
71 | program
72 | .command('test')
73 | .allowUnknownOption()
74 | .description('Run tests via jest')
75 | .option('--config [path]', 'path to jest config')
76 | .action((...args) => {
77 | const cmd = getCommand(args);
78 | const { config } = getOpts(cmd);
79 | const t: TestTaskDesc = {
80 | name: 'test',
81 | config,
82 | restOptions: cmd.args,
83 | };
84 |
85 | const result = testTask(t);
86 | handleSpawnResult(result);
87 | });
88 |
89 | program
90 | .command('lint')
91 | .allowUnknownOption()
92 | .description('Run ESLint and TypeScript to statically analyze your code')
93 | .option('--config [path]', 'path to ESLint config')
94 | .option('--typecheck', 'run a TypeScript type check', true)
95 | .option('--no-typecheck', 'do not run a TypeScript type check')
96 | .option('--stylecheck', "run Prettier's style check", true)
97 | .option('--no-stylecheck', "do not run Prettier's style check")
98 | .action((...args) => {
99 | const cmd = getCommand(args);
100 | const { stylecheck, typecheck, config } = getOpts(cmd);
101 | const t: LintTaskDesc = {
102 | name: 'lint',
103 | config,
104 | stylecheck,
105 | typecheck,
106 | restOptions: cmd.args,
107 | };
108 |
109 | handlePromiseResult(lintTask(t));
110 | });
111 |
112 | program
113 | .command('format')
114 | .allowUnknownOption()
115 | .description('Run Prettier to format your code')
116 | .option('--config [path]', 'path to Prettier config')
117 | .option(
118 | '--path [path]',
119 | 'path to project folder to format. targets the `src` directory within this path only.',
120 | )
121 | .action((...args) => {
122 | const cmd = getCommand(args);
123 | const { config, path } = getOpts(cmd);
124 | const t: FormatTaskDesc = {
125 | name: 'format',
126 | config,
127 | path,
128 | restOptions: cmd.args,
129 | };
130 |
131 | handleSpawnResult(formatTask(t));
132 | });
133 |
134 | program
135 | .command('precommit')
136 | .allowUnknownOption()
137 | .description('Locally validate the repo before committing')
138 | .option('--jest-config [path]', 'path to jest config')
139 | .option('--prettier-config [path]', 'path to prettier config')
140 | .option('--eslint-config [path]', 'path to eslint config')
141 | .option('--no-tests', 'Do not run Jest tests')
142 | .option('--no-typecheck', 'Do not type check using TypeScript')
143 | .action((...args) => {
144 | const cmd = getCommand(args);
145 | const { tests, typecheck, jestConfig, eslintConfig, prettierConfig } =
146 | getOpts(cmd);
147 | const t: PrecommitTaskDesc = {
148 | name: 'precommit',
149 | tests,
150 | typecheck,
151 | jestConfig,
152 | eslintConfig,
153 | prettierConfig,
154 | restOptions: cmd.args,
155 | };
156 |
157 | handlePromiseResult(precommitTask(t));
158 | });
159 |
160 | function thresholdLimiter(value: string, defaultValue: string) {
161 | switch (value) {
162 | case 'info':
163 | case 'low':
164 | case 'moderate':
165 | case 'high':
166 | case 'critical':
167 | return value;
168 | default:
169 | return defaultValue;
170 | }
171 | }
172 |
173 | program
174 | .command('audit')
175 | .alias('postinstall')
176 | .allowUnknownOption()
177 | .description(
178 | `Run yarn audit and exit non-zero if the security vulnerability threshold is breached`,
179 | )
180 | .option(
181 | '--threshold [info|low|moderate|high|critical]',
182 | 'The amount of permissible vulnerabilities',
183 | thresholdLimiter,
184 | 'none',
185 | )
186 | .action((...args) => {
187 | const cmd = getCommand(args);
188 | const { threshold } = getOpts(cmd);
189 | const t: AuditTaskDesc = {
190 | name: 'audit',
191 | threshold,
192 | restOptions: cmd.args,
193 | };
194 |
195 | handlePromiseResult(auditTask(t));
196 | });
197 |
198 | program
199 | .command('commit')
200 | .allowUnknownOption()
201 | .description('Create Commitizen commit from staged files')
202 | .option(
203 | '--path [path]',
204 | 'path for commitizen adapter to use',
205 | 'cz-conventional-changelog',
206 | )
207 | .action((...args) => {
208 | const cmd = getCommand(args);
209 | const { path } = getOpts(cmd);
210 | const t: CommitTaskDesc = {
211 | name: 'commit',
212 | path,
213 | restOptions: cmd.args,
214 | };
215 |
216 | try {
217 | commitTask(t);
218 | } catch (err) {
219 | handleError(err as Error & { exitStatus?: number });
220 | }
221 | });
222 |
223 | program
224 | .command('commitmsg')
225 | .allowUnknownOption()
226 | .description('Run commitizen commit message validation hook')
227 | .option(
228 | '--config [path]',
229 | 'path to the commitlint config.',
230 | COMMITLINT_CONIFG,
231 | )
232 | .option(
233 | '--edit [path]',
234 | 'read last commit message from the specified file (only necessary when using Husky v6).',
235 | )
236 | .action((...args) => {
237 | const cmd = getCommand(args);
238 | const { config, edit } = getOpts(cmd);
239 | const t: CommitMsgTaskDesc = {
240 | name: 'commitmsg',
241 | config,
242 | edit,
243 | restOptions: cmd.args,
244 | };
245 |
246 | handleSpawnResult(commitMsgTask(t));
247 | });
248 |
249 | program
250 | .command('release')
251 | .allowUnknownOption()
252 | .description('Run semantic-release')
253 | .action((...args) => {
254 | const cmd = getCommand(args);
255 | const t: ReleaseTaskDesc = {
256 | name: 'release',
257 | restOptions: cmd.args,
258 | };
259 |
260 | handleSpawnResult(releaseTask(t));
261 | });
262 |
263 | function handlePromiseResult(result: Promise) {
264 | result.catch(handleError);
265 | }
266 |
267 | function handleError(error: Error & { exitStatus?: number }) {
268 | /* eslint-disable no-console */
269 | // only log if the error is useful (e.g. not the default message from non-zero status is in cross-spawn)
270 | if (error.message && error.message.indexOf('Error: Exited with status') < 0) {
271 | console.error(error);
272 | }
273 | /* eslint-enable no-console */
274 | process.exit(error.exitStatus || 1);
275 | }
276 |
277 | function handleSpawnResult(result: SpawnSyncReturns) {
278 | if (result.error) {
279 | throw result.error;
280 | }
281 |
282 | if (result.status !== 0) {
283 | process.exit(result.status === null ? 0 : result.status);
284 | }
285 | }
286 |
287 | function getCommand(args: any[]): Command {
288 | return args[1] as Command;
289 | }
290 |
291 | function getOpts(cmd: Command): { [key: string]: any } {
292 | return cmd.opts();
293 | }
294 |
295 | program.parse(process.argv);
296 |
297 | if (!process.argv.slice(2).length) {
298 | program.help();
299 | }
300 |
--------------------------------------------------------------------------------
/packages/eslint-config-react/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **deps:** upgrade dependencies ([ef060c7](https://github.com/spotify/web-scripts/commit/ef060c7da531060cc1d0f0fb60d3df8f355e418e))
11 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
12 |
13 | ### BREAKING CHANGES
14 |
15 | - **node:** Node bump from v14 to v18
16 | - **deps:** TypeScript bump from v4 to v5, Jest bump from v28 to v29
17 |
18 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
19 |
20 | **Note:** Version bump only for package @spotify/eslint-config-react
21 |
22 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
23 |
24 | **Note:** Version bump only for package @spotify/eslint-config-react
25 |
26 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
27 |
28 | **Note:** Version bump only for package @spotify/eslint-config-react
29 |
30 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
31 |
32 | **Note:** Version bump only for package @spotify/eslint-config-react
33 |
34 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
35 |
36 | **Note:** Version bump only for package @spotify/eslint-config-react
37 |
38 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
39 |
40 | **Note:** Version bump only for package @spotify/eslint-config-react
41 |
42 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
43 |
44 | **Note:** Version bump only for package @spotify/eslint-config-react
45 |
46 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
47 |
48 | **Note:** Version bump only for package @spotify/eslint-config-react
49 |
50 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
51 |
52 | **Note:** Version bump only for package @spotify/eslint-config-react
53 |
54 | # [14.0.0](https://github.com/spotify/web-scripts/compare/v13.0.1...v14.0.0) (2022-07-11)
55 |
56 | **Note:** Version bump only for package @spotify/eslint-config-react
57 |
58 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
59 |
60 | **Note:** Version bump only for package @spotify/eslint-config-react
61 |
62 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
63 |
64 | ### chore
65 |
66 | - update [@typescript-eslint](https://github.com/typescript-eslint) from v4 to v5, eslint from v7 to v8 ([e284943](https://github.com/spotify/web-scripts/commit/e28494330a6dd9c2561370f56a4eed1ef152f23d))
67 |
68 | ### BREAKING CHANGES
69 |
70 | - update @typescript-eslint from v4 to v5, eslint from v7 to v8
71 |
72 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
73 |
74 | ### Build System
75 |
76 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
77 |
78 | ### BREAKING CHANGES
79 |
80 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
81 |
82 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
83 |
84 | **Note:** Version bump only for package @spotify/eslint-config-react
85 |
86 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
87 |
88 | ### Build System
89 |
90 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
91 |
92 | ### Features
93 |
94 | - **eslint-config-react:** disable react/prop-types rule ([d445345](https://github.com/spotify/web-scripts/commit/d4453456e8d70accd5beede7c5adfd3a814afe35))
95 |
96 | ### BREAKING CHANGES
97 |
98 | - drop support for NodeJS v10.x, which reaches EOL on
99 | April 30, 2021.
100 |
101 | ## [9.0.2](https://github.com/spotify/web-scripts/compare/v9.0.1...v9.0.2) (2021-02-26)
102 |
103 | ### Bug Fixes
104 |
105 | - disable no-undef ([52926ad](https://github.com/spotify/web-scripts/commit/52926ad7b8d94170b0b2584afc14cdb666d47427))
106 |
107 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
108 |
109 | **Note:** Version bump only for package @spotify/eslint-config-react
110 |
111 | ## [8.0.2](https://github.com/spotify/web-scripts/compare/v8.0.1...v8.0.2) (2020-07-15)
112 |
113 | ### Bug Fixes
114 |
115 | - **eslint-config-react:** fix peer dependency on eslint-plugin-react-hooks ([8591423](https://github.com/spotify/web-scripts/commit/859142322212ed3ef5ac2140b831e4244487d91c))
116 |
117 | # [8.0.0](https://github.com/spotify/web-scripts/compare/v7.0.2...v8.0.0) (2020-06-23)
118 |
119 | ### Features
120 |
121 | - **eslint:** v7 ([55ebb7f](https://github.com/spotify/web-scripts/commit/55ebb7f402546e9c8d7c7372cafbd6f49f17790c))
122 |
123 | ### BREAKING CHANGES
124 |
125 | - **eslint:** see release notes for eslint v7
126 |
127 | ## [7.0.1](https://github.com/spotify/web-scripts/compare/v7.0.0...v7.0.1) (2020-05-15)
128 |
129 | **Note:** Version bump only for package @spotify/eslint-config-react
130 |
131 | # [7.0.0](https://github.com/spotify/web-scripts/compare/v6.2.0...v7.0.0) (2020-04-28)
132 |
133 | - major release- 7.0.0 (#318) ([29509b4](https://github.com/spotify/web-scripts/commit/29509b4a52325080b7a38f3aeb41ce8ed82f04f5)), closes [#318](https://github.com/spotify/web-scripts/issues/318) [#314](https://github.com/spotify/web-scripts/issues/314) [#312](https://github.com/spotify/web-scripts/issues/312) [#310](https://github.com/spotify/web-scripts/issues/310)
134 |
135 | ### BREAKING CHANGES
136 |
137 | - running web-scripts without arguments exits code 1 now instead of exiting 0
138 | - prettier 2.0 may introduce breaking changes
139 | - prettier 2.0 may introduce breaking changes
140 |
141 | - improvement(web-scripts): make stylecheck and typecheck default for lint
142 |
143 | the lint script will now default typechecking and stylechecking to true by default. You may shut
144 | these off with `--no-typecheck` and `--no-stylecheck`.
145 |
146 | - Users who have projects incompatible with TypeScript checks or with projects that
147 | do not user prettier will now fail yarn lint.
148 |
149 | # [6.2.0](https://github.com/spotify/web-scripts/compare/v6.1.1...v6.2.0) (2020-04-04)
150 |
151 | **Note:** Version bump only for package @spotify/eslint-config-react
152 |
153 | ## [6.1.1](https://github.com/spotify/web-scripts/compare/v6.1.0...v6.1.1) (2020-04-03)
154 |
155 | **Note:** Version bump only for package @spotify/eslint-config-react
156 |
157 | # [6.0.0](https://github.com/spotify/web-scripts/compare/v5.3.0...v6.0.0) (2020-01-29)
158 |
159 | ### Build System
160 |
161 | - bump node in engines to 10.18.0 ([08ea936](https://github.com/spotify/web-scripts/commit/08ea936faf879be18b97f8a4ba99aba5926ccff8))
162 |
163 | ### BREAKING CHANGES
164 |
165 | - increasing Node version in engines declaration
166 |
167 | # [5.2.0](https://github.com/spotify/web-scripts/compare/v5.1.0...v5.2.0) (2020-01-22)
168 |
169 | ### Features
170 |
171 | - **index.js:** Add react/jsx-curly-brace-presence rule ([fbef1ae](https://github.com/spotify/web-scripts/commit/fbef1ae18d4176819c357862a031e34c16d12bbb))
172 |
173 | # [5.0.0](https://github.com/spotify/web-scripts/compare/v4.0.2...v5.0.0) (2020-01-06)
174 |
175 | **Note:** Version bump only for package @spotify/eslint-config-react
176 |
177 | # [4.0.0](https://github.com/spotify/web-scripts/compare/v3.3.1...v4.0.0) (2020-01-03)
178 |
179 | ### chore
180 |
181 | - bump engine to >=10.13.0 ([9527453](https://github.com/spotify/web-scripts/commit/9527453a03ea0a807e6f6964469bf8482a3e3cca))
182 |
183 | ### Features
184 |
185 | - **web-scripts:** Upgrade to ESLint ^6.8.0 ([d0c37e9](https://github.com/spotify/web-scripts/commit/d0c37e9b63e4260eeaffda632a8d0840a793fec4))
186 |
187 | ### BREAKING CHANGES
188 |
189 | - Minimum Node version has been increased
190 | - **web-scripts:** Users of web-scripts that rely on ESLint 5 will see unexpected linting errors.
191 |
192 | ## [3.0.1](https://github.com/spotify/web-scripts/compare/v3.0.0...v3.0.1) (2019-10-24)
193 |
194 | ### Bug Fixes
195 |
196 | - **eslint-config-react:** Add `static-variables` to `react/sort-comp` ([f0526c0](https://github.com/spotify/web-scripts/commit/f0526c0))
197 |
198 | # [3.0.0](https://github.com/spotify/web-scripts/compare/v2.1.0...v3.0.0) (2019-10-10)
199 |
200 | **Note:** Version bump only for package @spotify/eslint-config-react
201 |
202 | # [2.0.0](https://github.com/spotify/web-scripts/compare/v1.4.0...v2.0.0) (2019-09-23)
203 |
204 | **Note:** Version bump only for package @spotify/eslint-config-react
205 |
206 | ## [1.1.4](https://github.com/spotify/web-scripts/compare/v1.1.3...v1.1.4) (2019-07-17)
207 |
208 | ### Bug Fixes
209 |
210 | - Add repostiory field to package.json files ([fccd2db](https://github.com/spotify/web-scripts/commit/fccd2db))
211 |
212 | # [1.1.0](https://github.com/spotify/web-scripts/compare/v1.0.2...v1.1.0) (2019-07-01)
213 |
214 | ### Bug Fixes
215 |
216 | - support ESLint 6 in our configs ([59341e3](https://github.com/spotify/web-scripts/commit/59341e3))
217 | - Updates engines field to node >=10 ([b3b4f58](https://github.com/spotify/web-scripts/commit/b3b4f58))
218 |
219 | ## [1.0.2](https://github.com/spotify/web-scripts/compare/v1.0.1...v1.0.2) (2019-06-26)
220 |
221 | ### Bug Fixes
222 |
223 | - update dependencies for peerDependency warnings ([eceff7c](https://github.com/spotify/web-scripts/commit/eceff7c))
224 |
225 | ## [1.0.1](https://github.com/spotify/web-scripts/compare/v1.0.0...v1.0.1) (2019-06-24)
226 |
227 | **Note:** Version bump only for package @spotify/eslint-config-react
228 |
--------------------------------------------------------------------------------
/packages/eslint-config-typescript/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [15.0.0](https://github.com/spotify/web-scripts/compare/v14.1.6...v15.0.0) (2023-05-18)
7 |
8 | ### chore
9 |
10 | - **deps:** upgrade dependencies ([ef060c7](https://github.com/spotify/web-scripts/commit/ef060c7da531060cc1d0f0fb60d3df8f355e418e))
11 | - **node:** upgrade required Node version to 18 ([9528841](https://github.com/spotify/web-scripts/commit/952884179ba7378440599b8acb109a98500535ee))
12 |
13 | ### BREAKING CHANGES
14 |
15 | - **node:** Node bump from v14 to v18
16 | - **deps:** TypeScript bump from v4 to v5, Jest bump from v28 to v29
17 |
18 | ## [14.1.6](https://github.com/spotify/web-scripts/compare/v14.1.5...v14.1.6) (2023-02-14)
19 |
20 | **Note:** Version bump only for package @spotify/eslint-config-typescript
21 |
22 | ## [14.1.5](https://github.com/spotify/web-scripts/compare/v14.1.4...v14.1.5) (2023-01-30)
23 |
24 | **Note:** Version bump only for package @spotify/eslint-config-typescript
25 |
26 | ## [14.1.4](https://github.com/spotify/web-scripts/compare/v14.1.3...v14.1.4) (2023-01-19)
27 |
28 | **Note:** Version bump only for package @spotify/eslint-config-typescript
29 |
30 | ## [14.1.3](https://github.com/spotify/web-scripts/compare/v14.1.2...v14.1.3) (2022-12-07)
31 |
32 | **Note:** Version bump only for package @spotify/eslint-config-typescript
33 |
34 | ## [14.1.2](https://github.com/spotify/web-scripts/compare/v14.1.1...v14.1.2) (2022-12-02)
35 |
36 | **Note:** Version bump only for package @spotify/eslint-config-typescript
37 |
38 | ## [14.1.1](https://github.com/spotify/web-scripts/compare/v14.1.0...v14.1.1) (2022-11-25)
39 |
40 | **Note:** Version bump only for package @spotify/eslint-config-typescript
41 |
42 | # [14.1.0](https://github.com/spotify/web-scripts/compare/v14.0.2...v14.1.0) (2022-08-08)
43 |
44 | **Note:** Version bump only for package @spotify/eslint-config-typescript
45 |
46 | ## [14.0.2](https://github.com/spotify/web-scripts/compare/v14.0.1...v14.0.2) (2022-07-15)
47 |
48 | **Note:** Version bump only for package @spotify/eslint-config-typescript
49 |
50 | ## [14.0.1](https://github.com/spotify/web-scripts/compare/v14.0.0...v14.0.1) (2022-07-12)
51 |
52 | **Note:** Version bump only for package @spotify/eslint-config-typescript
53 |
54 | # [14.0.0](https://github.com/spotify/web-scripts/compare/v13.0.1...v14.0.0) (2022-07-11)
55 |
56 | **Note:** Version bump only for package @spotify/eslint-config-typescript
57 |
58 | ## [13.0.1](https://github.com/spotify/web-scripts/compare/v13.0.0...v13.0.1) (2022-04-19)
59 |
60 | **Note:** Version bump only for package @spotify/eslint-config-typescript
61 |
62 | # [13.0.0](https://github.com/spotify/web-scripts/compare/v12.0.0...v13.0.0) (2022-03-21)
63 |
64 | ### Bug Fixes
65 |
66 | - **eslint:** specify parserOptions.project ([5ea256c](https://github.com/spotify/web-scripts/commit/5ea256cc7a05927d94dc5bf1974fdb4e3ee94bc1))
67 | - remove parserOptions.project ([c901579](https://github.com/spotify/web-scripts/commit/c901579eef6ed3723e94aca079d6f5171525ac41))
68 |
69 | ### chore
70 |
71 | - update [@typescript-eslint](https://github.com/typescript-eslint) from v4 to v5, eslint from v7 to v8 ([e284943](https://github.com/spotify/web-scripts/commit/e28494330a6dd9c2561370f56a4eed1ef152f23d))
72 |
73 | ### BREAKING CHANGES
74 |
75 | - update @typescript-eslint from v4 to v5, eslint from v7 to v8
76 |
77 | # [12.0.0](https://github.com/spotify/web-scripts/compare/v11.0.0...v12.0.0) (2021-09-22)
78 |
79 | ### Build System
80 |
81 | - **node:** drop support for Node v12. Support only NodeJS >= 14.17.x ([be04398](https://github.com/spotify/web-scripts/commit/be043986089b79feab63f2a06527f48239ac5144))
82 |
83 | ### BREAKING CHANGES
84 |
85 | - **node:** Dropped support for Node v12. Minimum supported NodeJS version is now >= 14.17.x.
86 |
87 | # [11.0.0](https://github.com/spotify/web-scripts/compare/v10.1.0...v11.0.0) (2021-07-16)
88 |
89 | **Note:** Version bump only for package @spotify/eslint-config-typescript
90 |
91 | # [10.0.0](https://github.com/spotify/web-scripts/compare/v9.0.2...v10.0.0) (2021-04-14)
92 |
93 | ### Build System
94 |
95 | - drop support for nodejs v10.x ([3fe3059](https://github.com/spotify/web-scripts/commit/3fe3059225c33cc550027dd77dbf1a48fde810a3))
96 |
97 | ### Features
98 |
99 | - **eslint-config-typescript:** turn off @typescript-eslint/no-unused-vars ([4845031](https://github.com/spotify/web-scripts/commit/48450315d99205f6ced4ca97b1de8f4899376680))
100 |
101 | ### BREAKING CHANGES
102 |
103 | - drop support for NodeJS v10.x, which reaches EOL on
104 | April 30, 2021.
105 |
106 | # [9.0.0](https://github.com/spotify/web-scripts/compare/v8.1.1...v9.0.0) (2020-10-26)
107 |
108 | ### Bug Fixes
109 |
110 | - incorporate overrides for new typescript-eslint rules ([81b7111](https://github.com/spotify/web-scripts/commit/81b711141b08613a78a2020513f1b21df0c91116))
111 | - relax no-use-before-define rule ([ee719aa](https://github.com/spotify/web-scripts/commit/ee719aa153b0debd8901006aef3b71a791ef093b))
112 | - sync [@typescript-eslint](https://github.com/typescript-eslint) versions across repo ([fb20119](https://github.com/spotify/web-scripts/commit/fb201196a551a3b942410b1e5a3b40c5f43bc721)), closes [#555](https://github.com/spotify/web-scripts/issues/555)
113 |
114 | ## [8.1.1](https://github.com/spotify/web-scripts/compare/v8.1.0...v8.1.1) (2020-09-22)
115 |
116 | **Note:** Version bump only for package @spotify/eslint-config-typescript
117 |
118 | ## [8.0.1](https://github.com/spotify/web-scripts/compare/v8.0.0...v8.0.1) (2020-07-02)
119 |
120 | ### Bug Fixes
121 |
122 | - **eslint-config-typescript:** turn off naming-convention ([ed5eec3](https://github.com/spotify/web-scripts/commit/ed5eec3b879a5a9c08916cf8fd334ae99ec7cbaa))
123 |
124 | # [8.0.0](https://github.com/spotify/web-scripts/compare/v7.0.2...v8.0.0) (2020-06-23)
125 |
126 | ### Features
127 |
128 | - **eslint:** v7 ([55ebb7f](https://github.com/spotify/web-scripts/commit/55ebb7f402546e9c8d7c7372cafbd6f49f17790c))
129 | - **typescript-eslint:** upgrade to latest to support type export syntax ([688324b](https://github.com/spotify/web-scripts/commit/688324b2702dbf393f058bed6fa55f26bce99bac))
130 | - **typescript-eslint/eslint-plugin:** v3.4.0 ([195400a](https://github.com/spotify/web-scripts/commit/195400a6082a35db59544d39b156d09d470661c7))
131 |
132 | ### BREAKING CHANGES
133 |
134 | - **eslint:** see release notes for eslint v7
135 | - **typescript-eslint:** The camelcase rule was deprecated in typescript-eslint. I've tried to replace it
136 | with an equivalent naming-convention rule config. I question if we should have this at all.
137 |
138 | # [7.0.0](https://github.com/spotify/web-scripts/compare/v6.2.0...v7.0.0) (2020-04-28)
139 |
140 | - major release- 7.0.0 (#318) ([29509b4](https://github.com/spotify/web-scripts/commit/29509b4a52325080b7a38f3aeb41ce8ed82f04f5)), closes [#318](https://github.com/spotify/web-scripts/issues/318) [#314](https://github.com/spotify/web-scripts/issues/314) [#312](https://github.com/spotify/web-scripts/issues/312) [#310](https://github.com/spotify/web-scripts/issues/310)
141 |
142 | ### BREAKING CHANGES
143 |
144 | - running web-scripts without arguments exits code 1 now instead of exiting 0
145 | - prettier 2.0 may introduce breaking changes
146 | - prettier 2.0 may introduce breaking changes
147 |
148 | - improvement(web-scripts): make stylecheck and typecheck default for lint
149 |
150 | the lint script will now default typechecking and stylechecking to true by default. You may shut
151 | these off with `--no-typecheck` and `--no-stylecheck`.
152 |
153 | - Users who have projects incompatible with TypeScript checks or with projects that
154 | do not user prettier will now fail yarn lint.
155 |
156 | # [6.2.0](https://github.com/spotify/web-scripts/compare/v6.1.1...v6.2.0) (2020-04-04)
157 |
158 | **Note:** Version bump only for package @spotify/eslint-config-typescript
159 |
160 | ## [6.1.1](https://github.com/spotify/web-scripts/compare/v6.1.0...v6.1.1) (2020-04-03)
161 |
162 | **Note:** Version bump only for package @spotify/eslint-config-typescript
163 |
164 | # [6.0.0](https://github.com/spotify/web-scripts/compare/v5.3.0...v6.0.0) (2020-01-29)
165 |
166 | ### Build System
167 |
168 | - bump node in engines to 10.18.0 ([08ea936](https://github.com/spotify/web-scripts/commit/08ea936faf879be18b97f8a4ba99aba5926ccff8))
169 |
170 | ### BREAKING CHANGES
171 |
172 | - increasing Node version in engines declaration
173 |
174 | # [5.0.0](https://github.com/spotify/web-scripts/compare/v4.0.2...v5.0.0) (2020-01-06)
175 |
176 | **Note:** Version bump only for package @spotify/eslint-config-typescript
177 |
178 | # [4.0.0](https://github.com/spotify/web-scripts/compare/v3.3.1...v4.0.0) (2020-01-03)
179 |
180 | ### Features
181 |
182 | - eslint 6 updates ([d5444b6](https://github.com/spotify/web-scripts/commit/d5444b6f1607cbd87778bbe7e7d2bb0dc8df3a55))
183 | - **web-scripts:** Upgrade to ESLint ^6.8.0 ([d0c37e9](https://github.com/spotify/web-scripts/commit/d0c37e9b63e4260eeaffda632a8d0840a793fec4))
184 |
185 | ### BREAKING CHANGES
186 |
187 | - **web-scripts:** Users of web-scripts that rely on ESLint 5 will see unexpected linting errors.
188 |
189 | # [3.0.0](https://github.com/spotify/web-scripts/compare/v2.1.0...v3.0.0) (2019-10-10)
190 |
191 | ### Bug Fixes
192 |
193 | - **eslint-config:** Update typescript-eslint packages to ^2.2.0 ([bda6c5f](https://github.com/spotify/web-scripts/commit/bda6c5f))
194 |
195 | ### BREAKING CHANGES
196 |
197 | - **eslint-config:** Major version bump
198 |
199 | ## [2.0.1](https://github.com/spotify/web-scripts/compare/v2.0.0...v2.0.1) (2019-09-27)
200 |
201 | ### Bug Fixes
202 |
203 | - **eslint-config-typescript:** add no-useless-constructor override ([72c6651](https://github.com/spotify/web-scripts/commit/72c6651))
204 |
205 | # [2.0.0](https://github.com/spotify/web-scripts/compare/v1.4.0...v2.0.0) (2019-09-23)
206 |
207 | **Note:** Version bump only for package @spotify/eslint-config-typescript
208 |
209 | ## [1.1.4](https://github.com/spotify/web-scripts/compare/v1.1.3...v1.1.4) (2019-07-17)
210 |
211 | ### Bug Fixes
212 |
213 | - Add repostiory field to package.json files ([fccd2db](https://github.com/spotify/web-scripts/commit/fccd2db))
214 |
215 | # [1.1.0](https://github.com/spotify/web-scripts/compare/v1.0.2...v1.1.0) (2019-07-01)
216 |
217 | ### Bug Fixes
218 |
219 | - support ESLint 6 in our configs ([59341e3](https://github.com/spotify/web-scripts/commit/59341e3))
220 | - Updates engines field to node >=10 ([b3b4f58](https://github.com/spotify/web-scripts/commit/b3b4f58))
221 |
222 | ## [1.0.2](https://github.com/spotify/web-scripts/compare/v1.0.1...v1.0.2) (2019-06-26)
223 |
224 | ### Bug Fixes
225 |
226 | - update dependencies for peerDependency warnings ([eceff7c](https://github.com/spotify/web-scripts/commit/eceff7c))
227 |
228 | ## [1.0.1](https://github.com/spotify/web-scripts/compare/v1.0.0...v1.0.1) (2019-06-24)
229 |
230 | **Note:** Version bump only for package @spotify/eslint-config-typescript
231 |
--------------------------------------------------------------------------------