release: v1.1.0 for tsconfig + prettier

This commit is contained in:
Jyotirmoy Bandyopadhayaya 2023-06-25 13:03:03 +05:30
parent 51631b65b8
commit e3f228ad5f
Signed by: bravo68web
GPG Key ID: F5671FD7BCB9917A
40 changed files with 820 additions and 748 deletions

View File

@ -1,16 +1,16 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
"access": "public",
"baseBranch": "main",
"changelog": [
"@changesets/changelog-github",
{
"repo": "bravo68web/nodejs-config"
}
],
"commit": false,
"fixed": [["@bravo68web/eslint-config", "@bravo68web/tsconfig", "@bravo68web/prettier-config"]],
"ignore": [],
"linked": [],
"updateInternalDependencies": "patch"
"$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
"access": "public",
"baseBranch": "main",
"changelog": [
"@changesets/changelog-github",
{
"repo": "bravo68web/nodejs-config"
}
],
"commit": false,
"fixed": [["@bravo68web/eslint-config", "@bravo68web/tsconfig", "@bravo68web/prettier-config"]],
"ignore": [],
"linked": [],
"updateInternalDependencies": "patch"
}

View File

@ -1,4 +1,4 @@
{
"extends": ["@bravo68web/eslint-config/code-style"],
"ignorePatterns": ["node_modules", "dist"]
"extends": ["@bravo68web/eslint-config/code-style"],
"ignorePatterns": ["node_modules", "dist"]
}

View File

@ -2,31 +2,31 @@ name: Setup Node Environment
description: Prepare and install everything for nodejs repo
runs:
using: composite
steps:
- uses: pnpm/action-setup@v2
using: composite
steps:
- uses: pnpm/action-setup@v2
- name: Setup Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: 18
registry-url: https://registry.npmjs.org/
- name: Setup Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: 18
registry-url: https://registry.npmjs.org/
- name: Install dependencies
shell: bash
run: pnpm i
- name: Install dependencies
shell: bash
run: pnpm i
- name: Restore Turborepo Cache
uses: actions/cache@v3
with:
path: |
apps/**/.turbo
node_modules/.cache/turbo
key: turbo-${{ runner.os }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
turbo-${{ runner.os }}-${{ github.job }}
- name: Restore Turborepo Cache
uses: actions/cache@v3
with:
path: |
apps/**/.turbo
node_modules/.cache/turbo
key: turbo-${{ runner.os }}-${{ github.job }}-${{ github.sha }}
restore-keys: |
turbo-${{ runner.os }}-${{ github.job }}
- name: Build packages
shell: bash
run: pnpm build
- name: Build packages
shell: bash
run: pnpm build

View File

@ -1,25 +1,25 @@
name: Linting
on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
workflow_dispatch:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Environment
uses: ./.github/actions/setup
- name: Setup Environment
uses: ./.github/actions/setup
- name: Testing
run: pnpm test
- name: Testing
run: pnpm test
- name: Run Checking
run: pnpm lint
- name: Run Checking
run: pnpm lint

View File

@ -1,39 +1,39 @@
name: Publish to NPM
on:
push:
branches:
- main
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: read
contents: read
jobs:
release:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
release:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Environment
uses: ./.github/actions/setup
- name: Setup Environment
uses: ./.github/actions/setup
- name: Create Release Pull Request or Publish to NPM
id: changesets
uses: changesets/action@v1
with:
version: pnpm ci:version
publish: pnpm ci:publish
commit: 'chore(release): publish packages'
title: 'chore(release): publish packages'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create Release Pull Request or Publish to NPM
id: changesets
uses: changesets/action@v1
with:
version: pnpm ci:version
publish: pnpm ci:publish
commit: "chore(release): publish packages"
title: "chore(release): publish packages"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -1,27 +1,27 @@
name: Sync Renovate changeset
on:
pull_request_target:
paths:
- '.github/workflows/sync_renovate-changesets.yml'
- 'pnpm-lock.yaml'
pull_request_target:
paths:
- ".github/workflows/sync_renovate-changesets.yml"
- "pnpm-lock.yaml"
jobs:
generate-changeset:
runs-on: ubuntu-latest
if: github.actor == 'renovate[bot]' && github.repository == 'bravo68web/nodejs-config'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 2
ref: ${{ github.head_ref }}
generate-changeset:
runs-on: ubuntu-latest
if: github.actor == 'renovate[bot]' && github.repository == 'bravo68web/nodejs-config'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 2
ref: ${{ github.head_ref }}
- name: Setup Environment
uses: ./.github/actions/setup
- name: Setup Environment
uses: ./.github/actions/setup
- name: Configure Git
run: |
git config --global user.email '41448663+BRAVO68WEB@users.noreply.github.com'
git config --global user.name 'Github changeset workflow'
- name: Configure Git
run: |
git config --global user.email '41448663+BRAVO68WEB@users.noreply.github.com'
git config --global user.name 'Github changeset workflow'
- name: Generate changeset
run: pnpm sync-renovate-changesets
- name: Generate changeset
run: pnpm sync-renovate-changesets

View File

@ -6,9 +6,9 @@ This is a monorepo to share miscellaneous Node.js config for [bravo68web](https:
## Apps
- [@bravo68web/eslint-config](apps/eslint-config/) - ESLint config
- [@bravo68web/tsconfig](apps/tsconfig/) - TypeScript config
- [@bravo68web/prettier-config](apps/prettier-config/) - Prettier config
- [@bravo68web/eslint-config](apps/eslint-config/) - ESLint config
- [@bravo68web/tsconfig](apps/tsconfig/) - TypeScript config
- [@bravo68web/prettier-config](apps/prettier-config/) - Prettier config
## Strict Configuration

View File

@ -54,46 +54,46 @@ npm install --save-dev @bravo68web/eslint-config
Add the following code to your `.eslintrc.js` or `.eslintrc.json` file:
- Default: (TypeScript is also supported)
- Default: (TypeScript is also supported)
```js
module.exports = {
extends: ['@bravo68web'],
// extends: ['@bravo68web/eslint-config/default'], // if you want to use named config
extends: ["@bravo68web"],
// extends: ['@bravo68web/eslint-config/default'], // if you want to use named config
};
```
- Code Style: (prettier)
- Code Style: (prettier)
```js
module.exports = {
extends: ['@bravo68web/eslint-config/code-style'],
extends: ["@bravo68web/eslint-config/code-style"],
};
```
- Typescript Strict:
- Typescript Strict:
```js
module.exports = {
extends: ['@bravo68web/eslint-config/typescript-strict'],
parserOptions: {
ecmaVersion: 'latest',
project: './tsconfig.json',
// tsconfigRootDir: __dirname, // if you use tsconfig.json in a different directory
},
extends: ["@bravo68web/eslint-config/typescript-strict"],
parserOptions: {
ecmaVersion: "latest",
project: "./tsconfig.json",
// tsconfigRootDir: __dirname, // if you use tsconfig.json in a different directory
},
};
```
- Ultimate: (TypeScript strict + Code Style)
- Ultimate: (TypeScript strict + Code Style)
```js
module.exports = {
extends: ['@bravo68web/eslint-config/ultimate'],
parserOptions: {
ecmaVersion: 'latest',
project: './tsconfig.json',
// tsconfigRootDir: __dirname, // if you use tsconfig.json in a different directory
},
extends: ["@bravo68web/eslint-config/ultimate"],
parserOptions: {
ecmaVersion: "latest",
project: "./tsconfig.json",
// tsconfigRootDir: __dirname, // if you use tsconfig.json in a different directory
},
};
```
@ -103,9 +103,9 @@ And that's it! You're now ready to use
This package is compatible with the following dependencies and Node.js versions:
- ESLint: 8.x
- TypeScript: 5.x
- Node.js: Any version that supports dependencies above
- ESLint: 8.x
- TypeScript: 5.x
- Node.js: Any version that supports dependencies above
**Updating to the latest version of this package is recommended for the best compatibility.**

View File

@ -1,88 +1,88 @@
{
"name": "@bravo68web/eslint-config",
"version": "1.0.3",
"description": "The official ESLint configuration for bravo68web projects",
"license": "MIT",
"author": "Bravo68web <hi@b68.dev> (https://github.com/bravo68web/)",
"homepage": "https://github.com/bravo68web/nodejs-config#readme",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"bugs": {
"url": "https://github.com/bravo68web/nodejs-config/issues"
},
"files": [
"dist"
],
"scripts": {
"build": "rollup -c --silent",
"lint": "tsc && eslint --fix . --cache",
"test": "vitest run"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "5.59.9",
"@typescript-eslint/parser": "5.59.9",
"deepmerge": "4.3.1",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-autofix": "1.1.0",
"eslint-plugin-deprecation": "1.4.1",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-regexp": "1.15.0",
"eslint-plugin-security": "1.7.1",
"eslint-plugin-simple-import-sort": "10.0.0",
"eslint-plugin-sonarjs": "0.19.0",
"eslint-plugin-tailwindcss": "3.12.1",
"eslint-plugin-unicorn": "47.0.0"
},
"peerDependencies": {
"eslint": "8.x",
"typescript": "5.x"
},
"devDependencies": {
"@bravo68web/tsconfig": "*",
"@rollup/plugin-commonjs": "25.0.1",
"@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-typescript": "11.1.1",
"@types/deepmerge": "2.2.0",
"@types/eslint": "8.40.1",
"@types/node": "18.16.17",
"@types/rollup-plugin-auto-external": "2.0.2",
"eslint": "8.42.0",
"rollup": "3.24.1",
"rollup-plugin-auto-external": "2.0.0",
"tsec": "0.2.7",
"typescript": "5.1.3",
"vitest": "0.32.0"
},
"keywords": [
"bravo68web",
"eslint",
"eslint-config"
],
"publishConfig": {
"access": "public"
},
"exports": {
".": {
"import": "./dist/default.mjs",
"require": "./dist/default.cjs"
"name": "@bravo68web/eslint-config",
"version": "1.0.3",
"description": "The official ESLint configuration for bravo68web projects",
"license": "MIT",
"author": "Bravo68web <hi@b68.dev> (https://github.com/bravo68web/)",
"homepage": "https://github.com/bravo68web/nodejs-config#readme",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"bugs": {
"url": "https://github.com/bravo68web/nodejs-config/issues"
},
"./default": {
"import": "./dist/default.mjs",
"require": "./dist/default.cjs"
"files": [
"dist"
],
"scripts": {
"build": "rollup -c --silent",
"lint": "tsc && eslint --fix . --cache",
"test": "vitest run"
},
"./code-style": {
"import": "./dist/code-style.mjs",
"require": "./dist/code-style.cjs"
"dependencies": {
"@typescript-eslint/eslint-plugin": "5.59.9",
"@typescript-eslint/parser": "5.59.9",
"deepmerge": "4.3.1",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-autofix": "1.1.0",
"eslint-plugin-deprecation": "1.4.1",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-regexp": "1.15.0",
"eslint-plugin-security": "1.7.1",
"eslint-plugin-simple-import-sort": "10.0.0",
"eslint-plugin-sonarjs": "0.19.0",
"eslint-plugin-tailwindcss": "3.12.1",
"eslint-plugin-unicorn": "47.0.0"
},
"./typescript-strict": {
"import": "./dist/typescript-strict.mjs",
"require": "./dist/typescript-strict.cjs"
"peerDependencies": {
"eslint": "8.x",
"typescript": "5.x"
},
"./ultimate": {
"import": "./dist/ultimate.mjs",
"require": "./dist/ultimate.cjs"
"devDependencies": {
"@bravo68web/tsconfig": "*",
"@rollup/plugin-commonjs": "25.0.1",
"@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-typescript": "11.1.1",
"@types/deepmerge": "2.2.0",
"@types/eslint": "8.40.1",
"@types/node": "18.16.17",
"@types/rollup-plugin-auto-external": "2.0.2",
"eslint": "8.42.0",
"rollup": "3.24.1",
"rollup-plugin-auto-external": "2.0.0",
"tsec": "0.2.7",
"typescript": "5.1.3",
"vitest": "0.32.0"
},
"keywords": [
"bravo68web",
"eslint",
"eslint-config"
],
"publishConfig": {
"access": "public"
},
"exports": {
".": {
"import": "./dist/default.mjs",
"require": "./dist/default.cjs"
},
"./default": {
"import": "./dist/default.mjs",
"require": "./dist/default.cjs"
},
"./code-style": {
"import": "./dist/code-style.mjs",
"require": "./dist/code-style.cjs"
},
"./typescript-strict": {
"import": "./dist/typescript-strict.mjs",
"require": "./dist/typescript-strict.cjs"
},
"./ultimate": {
"import": "./dist/ultimate.mjs",
"require": "./dist/ultimate.cjs"
}
}
}
}

View File

@ -1,27 +1,27 @@
import fs from 'node:fs';
import path from 'node:path';
import fs from "node:fs";
import path from "node:path";
import rollupPluginCommonjs from '@rollup/plugin-commonjs';
import rollupPluginNodeResolve from '@rollup/plugin-node-resolve';
import rollupPluginTypescript from '@rollup/plugin-typescript';
import rollupPluginAutoExternal from 'rollup-plugin-auto-external';
import rollupPluginCommonjs from "@rollup/plugin-commonjs";
import rollupPluginNodeResolve from "@rollup/plugin-node-resolve";
import rollupPluginTypescript from "@rollup/plugin-typescript";
import rollupPluginAutoExternal from "rollup-plugin-auto-external";
// Read the files in the src directory
const dir = './src/';
const dir = "./src/";
// Filter the .ts files
const files = fs.readdirSync(dir).filter(file => file.endsWith('.ts'));
const files = fs.readdirSync(dir).filter(file => file.endsWith(".ts"));
const plugins = [
// Automatically mark all dependencies as external
rollupPluginAutoExternal(),
// Resolve node modules
rollupPluginNodeResolve(),
// Convert CommonJS modules to ES6
rollupPluginCommonjs(),
// Compile TypeScript files
rollupPluginTypescript({
tsconfig: 'tsconfig.json',
}),
// Automatically mark all dependencies as external
rollupPluginAutoExternal(),
// Resolve node modules
rollupPluginNodeResolve(),
// Convert CommonJS modules to ES6
rollupPluginCommonjs(),
// Compile TypeScript files
rollupPluginTypescript({
tsconfig: "tsconfig.json",
}),
];
/**
@ -44,16 +44,16 @@ const plugins = [
* @returns {ParticularFormatConfig} The Rollup configuration for CJS builds.
*/
function getCjsConfig(filename) {
return {
input: `${dir}${filename}`,
output: {
dir: './dist',
exports: 'default',
entryFileNames: `${path.basename(filename, '.ts')}.cjs`,
format: 'cjs',
},
plugins,
};
return {
input: `${dir}${filename}`,
output: {
dir: "./dist",
exports: "default",
entryFileNames: `${path.basename(filename, ".ts")}.cjs`,
format: "cjs",
},
plugins,
};
}
/**
@ -63,16 +63,16 @@ function getCjsConfig(filename) {
* @returns {ParticularFormatConfig} The Rollup configuration for CJS builds.
*/
function getEsmConfig(filename) {
return {
input: `${dir}${filename}`,
output: {
dir: './dist',
exports: 'default',
entryFileNames: `${path.basename(filename, '.ts')}.mjs`,
format: 'esm',
},
plugins,
};
return {
input: `${dir}${filename}`,
output: {
dir: "./dist",
exports: "default",
entryFileNames: `${path.basename(filename, ".ts")}.mjs`,
format: "esm",
},
plugins,
};
}
/**
@ -81,7 +81,7 @@ function getEsmConfig(filename) {
* @returns {Array<ParticularFormatConfig>} The Rollup configuration for CJS and ESM builds.
*/
function getEntryConfigs(filename) {
return [getCjsConfig(filename), getEsmConfig(filename)];
return [getCjsConfig(filename), getEsmConfig(filename)];
}
export default files.flatMap(element => getEntryConfigs(element));

View File

@ -1,6 +1,6 @@
import merge from 'deepmerge';
import merge from "deepmerge";
import defaultConfig from './default';
import strictCodeStyleConfig from './sub-rules/prettier';
import defaultConfig from "./default";
import strictCodeStyleConfig from "./sub-rules/prettier";
export default merge(defaultConfig, strictCodeStyleConfig);

View File

@ -1,105 +1,105 @@
import type { Linter } from 'eslint';
import type { Linter } from "eslint";
const config: Linter.Config = {
env: {
browser: true,
es6: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:regexp/recommended',
'plugin:unicorn/recommended',
'plugin:sonarjs/recommended',
'plugin:security/recommended',
'plugin:tailwindcss/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/eslint-recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
env: {
browser: true,
es6: true,
node: true,
},
ecmaVersion: 'latest',
},
plugins: [
'regexp',
'jsx-a11y',
'autofix',
'react',
'sonarjs',
'unicorn',
'@typescript-eslint',
'simple-import-sort',
],
rules: {
quotes: [
2,
'single',
{
avoidEscape: true,
},
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:regexp/recommended",
"plugin:unicorn/recommended",
"plugin:sonarjs/recommended",
"plugin:security/recommended",
"plugin:tailwindcss/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended",
],
// Eslint
'prefer-arrow-callback': 2,
semi: [2, 'always'],
// Import sorting
'simple-import-sort/imports': 2,
'simple-import-sort/exports': 2,
// React
'react/react-in-jsx-scope': 0,
'react/button-has-type': 2,
'react/prop-types': 0,
'react/no-array-index-key': 2,
// SonarJS
'sonarjs/no-duplicate-string': 0,
// Unicorn
'unicorn/no-null': 0,
'unicorn/prefer-module': 0,
'unicorn/no-useless-undefined': 0,
'unicorn/prevent-abbreviations': 0,
'unicorn/no-await-expression-member': 0,
// Typescript
'@typescript-eslint/no-namespace': 0,
'@typescript-eslint/no-misused-promises': 0,
'@typescript-eslint/no-unused-vars': [2],
'@typescript-eslint/no-unsafe-call': 0,
'@typescript-eslint/no-unsafe-assignment': 0,
'@typescript-eslint/no-unsafe-member-access': 0,
},
settings: {
react: {
version: 'detect',
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: "latest",
},
},
overrides: [
{
files: ['*.js', '*.jsx', '*.cjs'],
rules: {
'@typescript-eslint/no-var-requires': 0,
},
},
{
files: ['*.js', '*.jsx', '*.ts', '*.tsx', '*.cjs', '*.mjs', '*.mts', '*.cts'],
rules: {
'simple-import-sort/imports': [
'error',
{
groups: [
['dotenv/config'],
['^node:', '^react$', '^react-dom$', '^next?/|^next$'],
['^@?\\w'],
['^[\\w]'],
['^'],
['^\\.'],
],
},
plugins: [
"regexp",
"jsx-a11y",
"autofix",
"react",
"sonarjs",
"unicorn",
"@typescript-eslint",
"simple-import-sort",
],
rules: {
quotes: [
2,
"single",
{
avoidEscape: true,
},
],
},
// Eslint
"prefer-arrow-callback": 2,
semi: [2, "always"],
// Import sorting
"simple-import-sort/imports": 2,
"simple-import-sort/exports": 2,
// React
"react/react-in-jsx-scope": 0,
"react/button-has-type": 2,
"react/prop-types": 0,
"react/no-array-index-key": 2,
// SonarJS
"sonarjs/no-duplicate-string": 0,
// Unicorn
"unicorn/no-null": 0,
"unicorn/prefer-module": 0,
"unicorn/no-useless-undefined": 0,
"unicorn/prevent-abbreviations": 0,
"unicorn/no-await-expression-member": 0,
// Typescript
"@typescript-eslint/no-namespace": 0,
"@typescript-eslint/no-misused-promises": 0,
"@typescript-eslint/no-unused-vars": [2],
"@typescript-eslint/no-unsafe-call": 0,
"@typescript-eslint/no-unsafe-assignment": 0,
"@typescript-eslint/no-unsafe-member-access": 0,
},
],
settings: {
react: {
version: "detect",
},
},
overrides: [
{
files: ["*.js", "*.jsx", "*.cjs"],
rules: {
"@typescript-eslint/no-var-requires": 0,
},
},
{
files: ["*.js", "*.jsx", "*.ts", "*.tsx", "*.cjs", "*.mjs", "*.mts", "*.cts"],
rules: {
"simple-import-sort/imports": [
"error",
{
groups: [
["dotenv/config"],
["^node:", "^react$", "^react-dom$", "^next?/|^next$"],
["^@?\\w"],
["^[\\w]"],
["^"],
["^\\."],
],
},
],
},
},
],
};
export default config;

View File

@ -1,12 +1,12 @@
import { Linter } from 'eslint';
import { Linter } from "eslint";
const strictCodeStyleConfig: Linter.Config = {
// Create a strictCodeStyleConfig object of type Linter.Config.
extends: ['prettier'], // Add the prettier package to the extends array.
plugins: ['prettier'], // Add the prettier package to the plugins array.
rules: {
'prettier/prettier': 2, // Add a rule to enforce the prettier plugin.
},
// Create a strictCodeStyleConfig object of type Linter.Config.
extends: ["prettier"], // Add the prettier package to the extends array.
plugins: ["prettier"], // Add the prettier package to the plugins array.
rules: {
"prettier/prettier": 2, // Add a rule to enforce the prettier plugin.
},
};
export default strictCodeStyleConfig; // Export the strictCodeStyleConfig object as the default export.

View File

@ -1,38 +1,38 @@
import { Linter } from 'eslint';
import { Linter } from "eslint";
const strictTypescriptConfig: Linter.Config = {
parser: '@typescript-eslint/parser',
extends: [
'plugin:@typescript-eslint/strict',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
plugins: ['deprecation', '@typescript-eslint'],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
// Enforce using the @deprecated tag in JSDoc comments
'deprecation/deprecation': 1,
// Typescript
// Disallow await on a non-promise
'@typescript-eslint/no-misused-promises': 0,
// Enforce consistent use of type imports
'@typescript-eslint/consistent-type-imports': 2,
// Enforce consistent type exports
'@typescript-eslint/consistent-type-exports': 2,
// Enforce that type arguments will use if not required
'@typescript-eslint/no-redundant-type-constituents': 2,
// Disallow calling an any type value
'@typescript-eslint/no-unsafe-call': 0,
// Disallow assigning any to variables and properties
'@typescript-eslint/no-unsafe-assignment': 0,
// Disallow member access on any typed variables
'@typescript-eslint/no-unsafe-member-access': 0,
// Disallow the use of custom TypeScript modules and namespaces
'@typescript-eslint/no-namespace': 0,
},
parser: "@typescript-eslint/parser",
extends: [
"plugin:@typescript-eslint/strict",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
],
plugins: ["deprecation", "@typescript-eslint"],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
// Enforce using the @deprecated tag in JSDoc comments
"deprecation/deprecation": 1,
// Typescript
// Disallow await on a non-promise
"@typescript-eslint/no-misused-promises": 0,
// Enforce consistent use of type imports
"@typescript-eslint/consistent-type-imports": 2,
// Enforce consistent type exports
"@typescript-eslint/consistent-type-exports": 2,
// Enforce that type arguments will use if not required
"@typescript-eslint/no-redundant-type-constituents": 2,
// Disallow calling an any type value
"@typescript-eslint/no-unsafe-call": 0,
// Disallow assigning any to variables and properties
"@typescript-eslint/no-unsafe-assignment": 0,
// Disallow member access on any typed variables
"@typescript-eslint/no-unsafe-member-access": 0,
// Disallow the use of custom TypeScript modules and namespaces
"@typescript-eslint/no-namespace": 0,
},
};
export default strictTypescriptConfig;

View File

@ -1,6 +1,6 @@
import merge from 'deepmerge';
import merge from "deepmerge";
import defaultConfig from './default';
import strictTypescriptConfig from './sub-rules/strict-typescript';
import defaultConfig from "./default";
import strictTypescriptConfig from "./sub-rules/strict-typescript";
export default merge(defaultConfig, strictTypescriptConfig);

View File

@ -1,8 +1,8 @@
import merge from 'deepmerge';
import merge from "deepmerge";
import defaultConfig from './default';
import strictCodeStyleConfig from './sub-rules/prettier';
import strictTypescriptConfig from './sub-rules/strict-typescript';
import defaultConfig from "./default";
import strictCodeStyleConfig from "./sub-rules/prettier";
import strictTypescriptConfig from "./sub-rules/strict-typescript";
const config = merge(strictCodeStyleConfig, strictTypescriptConfig);

View File

@ -1,14 +1,14 @@
import { describe } from 'vitest';
import { describe } from "vitest";
import config from '../src/code-style';
import { checkLintingErrors, checkValidity, createEngine } from './utils';
import config from "../src/code-style";
import { checkLintingErrors, checkValidity, createEngine } from "./utils";
describe('Code Style Configuration', () => {
const engine = createEngine(config);
describe("Code Style Configuration", () => {
const engine = createEngine(config);
// Check the validity of the engine.
checkValidity(engine);
// Check the validity of the engine.
checkValidity(engine);
// Check for any linting errors.
checkLintingErrors(engine);
// Check for any linting errors.
checkLintingErrors(engine);
});

View File

@ -1,14 +1,14 @@
import { describe } from 'vitest';
import { describe } from "vitest";
import config from '../src/default';
import { checkLintingErrors, checkValidity, createEngine } from './utils';
import config from "../src/default";
import { checkLintingErrors, checkValidity, createEngine } from "./utils";
describe('Default Configuration', () => {
const engine = createEngine(config);
describe("Default Configuration", () => {
const engine = createEngine(config);
// Check if the script is valid
checkValidity(engine);
// Check if the script is valid
checkValidity(engine);
// Check if the script has any linting errors
checkLintingErrors(engine);
// Check if the script has any linting errors
checkLintingErrors(engine);
});

View File

@ -1,6 +1,6 @@
const config = {
apple: 'red',
banana: 'yellow',
apple: "red",
banana: "yellow",
};
export default config;

View File

@ -1,19 +1,19 @@
import { describe } from 'vitest';
import { describe } from "vitest";
import config from '../src/typescript-strict';
import { checkLintingErrorsFromFile, checkValidity, createEngine } from './utils';
import config from "../src/typescript-strict";
import { checkLintingErrorsFromFile, checkValidity, createEngine } from "./utils";
describe('Typescript Strict Configuration', () => {
const engine = createEngine({
...config,
parserOptions: {
project: './tsconfig.json',
},
});
describe("Typescript Strict Configuration", () => {
const engine = createEngine({
...config,
parserOptions: {
project: "./tsconfig.json",
},
});
// check that the engine is valid
checkValidity(engine);
// check that the engine is valid
checkValidity(engine);
// check that there are no linting errors in the file
checkLintingErrorsFromFile(engine, './tests/examples/example-1.ts');
// check that there are no linting errors in the file
checkLintingErrorsFromFile(engine, "./tests/examples/example-1.ts");
});

View File

@ -1,19 +1,19 @@
import { describe } from 'vitest';
import { describe } from "vitest";
import config from '../src/ultimate';
import { checkLintingErrorsFromFile, checkValidity, createEngine } from './utils';
import config from "../src/ultimate";
import { checkLintingErrorsFromFile, checkValidity, createEngine } from "./utils";
describe('Ultimate Configuration', () => {
const engine = createEngine({
...config,
parserOptions: {
project: './tsconfig.json',
},
});
describe("Ultimate Configuration", () => {
const engine = createEngine({
...config,
parserOptions: {
project: "./tsconfig.json",
},
});
// Check the engine's configuration.
checkValidity(engine);
// Check the engine's configuration.
checkValidity(engine);
// Check the engine's linting errors.
checkLintingErrorsFromFile(engine, './tests/examples/example-1.ts');
// Check the engine's linting errors.
checkLintingErrorsFromFile(engine, "./tests/examples/example-1.ts");
});

View File

@ -1,38 +1,38 @@
import { ESLint, Linter } from 'eslint';
import { expect, it } from 'vitest';
import { ESLint, Linter } from "eslint";
import { expect, it } from "vitest";
// Create an ESLint engine, based on a base config.
export const createEngine = (baseConfig: Linter.Config) => {
return new ESLint({
useEslintrc: false, // do not use .eslintrc.* files
baseConfig, // set the base config
});
return new ESLint({
useEslintrc: false, // do not use .eslintrc.* files
baseConfig, // set the base config
});
};
export const checkValidity = (engine: ESLint) => {
it('is valid configuration', async () => {
// Linting an empty string is invalid, so we expect it to throw
await expect(engine.lintText('')).resolves.not.toThrow();
});
it("is valid configuration", async () => {
// Linting an empty string is invalid, so we expect it to throw
await expect(engine.lintText("")).resolves.not.toThrow();
});
};
// This test ensures that the linting engine is properly configured.
export const checkLintingErrors = (engine: ESLint) => {
it('does not produce linting errors', async () => {
// Run linting on an empty string.
const lintResults = await engine.lintText('');
it("does not produce linting errors", async () => {
// Run linting on an empty string.
const lintResults = await engine.lintText("");
// Expect that the linting engine does not produce any errors.
expect(lintResults[0].errorCount).toBe(0);
});
// Expect that the linting engine does not produce any errors.
expect(lintResults[0].errorCount).toBe(0);
});
};
export const checkLintingErrorsFromFile = (engine: ESLint, file: string) => {
it('does not produce linting errors', async () => {
// Lint the file using the ESLint engine
const lintResults = await engine.lintFiles(file);
it("does not produce linting errors", async () => {
// Lint the file using the ESLint engine
const lintResults = await engine.lintFiles(file);
// Expect that the file has no errors
expect(lintResults[0].errorCount).toBe(0);
});
// Expect that the file has no errors
expect(lintResults[0].errorCount).toBe(0);
});
};

View File

@ -1,9 +1,9 @@
{
"compilerOptions": {
"moduleResolution": "node",
"noEmit": true
},
"exclude": ["node_modules", "dist"],
"extends": "@bravo68web/tsconfig/base.json",
"include": ["src", "rollup.config.mjs", "tests/examples/example-1.ts"]
"compilerOptions": {
"moduleResolution": "node",
"noEmit": true
},
"exclude": ["node_modules", "dist"],
"extends": "@bravo68web/tsconfig/base.json",
"include": ["src", "rollup.config.mjs", "tests/examples/example-1.ts"]
}

View File

@ -6,19 +6,19 @@ Welcome to the `@bravo68web/prettier-config`! This is the Prettier configuration
## Specificed Config
- **Single Quotes** - Use single quotes instead of double quotes.
- **Tab Width** - Use **2** spaces for indentation.
- **Trailing Comma** - Use trailing commas wherever possible.
- **Print Width** - Use a print width of **100** characters.
- **Avoid Parentheses** - Avoid parentheses when possible.
- **Single Quotes** - Use single quotes instead of double quotes.
- **Tab Width** - Use **2** spaces for indentation.
- **Trailing Comma** - Use trailing commas wherever possible.
- **Print Width** - Use a print width of **100** characters.
- **Avoid Parentheses** - Avoid parentheses when possible.
> `x => x * x` instead of `(x) => x * x`
- **Truey Bracket Spacing** - Add spaces inside of curly braces.
- **Truey Bracket Spacing** - Add spaces inside of curly braces.
> `{ foo: bar }` instead of `{foo: bar}`
- **Disabled bracket same line** - Objects and arrays are formatted with each item on a new line.
- **Disabled bracket same line** - Objects and arrays are formatted with each item on a new line.
## Prettier Plugins
@ -60,7 +60,7 @@ Add the following code to your `.prettierrc` or `.prettierrc.json` file:
```json
{
"prettier": "@bravo68web/prettier-config"
"prettier": "@bravo68web/prettier-config"
}
```
@ -70,8 +70,8 @@ And that's it! You're now ready to use
This package is compatible with the following Prettier and Node.js versions:
- Prettier: 2.0 or later (recommended: latest v2, before major version 3)
- Node.js: Any version that supports Prettier
- Prettier: 2.0 or later (recommended: latest v2, before major version 3)
- Node.js: Any version that supports Prettier
**Updating to the latest version of this package is recommended for the best compatibility.**

View File

@ -1,18 +1,18 @@
{
"$schema": "http://json.schemastore.org/prettierrc",
"arrowParens": "avoid",
"bracketSameLine": false,
"bracketSpacing": true,
"jsonRecursiveSort": true,
"plugins": [
"prettier-plugin-prisma",
"prettier-plugin-sort-json",
"prettier-plugin-tailwindcss",
"prettier-plugin-package-perfection"
],
"printWidth": 100,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
"$schema": "http://json.schemastore.org/prettierrc",
"arrowParens": "avoid",
"bracketSameLine": false,
"bracketSpacing": true,
"jsonRecursiveSort": true,
"plugins": [
"prettier-plugin-prisma",
"prettier-plugin-sort-json",
"prettier-plugin-tailwindcss",
"prettier-plugin-package-perfection"
],
"printWidth": 100,
"semi": true,
"singleQuote": false,
"tabWidth": 4,
"trailingComma": "all"
}

View File

@ -1,39 +1,39 @@
{
"name": "@bravo68web/prettier-config",
"version": "1.0.3",
"description": "The official Prettier configuration for bravo68web projects",
"author": "Bravo68web <hi@b68.dev> (https://github.com/bravo68web/)",
"homepage": "https://github.com/bravo68web/nodejs-config#readme",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"bugs": {
"url": "https://github.com/bravo68web/nodejs-config/issues"
},
"main": "index.json",
"files": [
"index.json",
"package.json",
"README.md",
"LICENSE"
],
"scripts": {
"test": "vitest run"
},
"dependencies": {
"prettier-plugin-package-perfection": "1.1.0",
"prettier-plugin-prisma": "4.13.0",
"prettier-plugin-sort-json": "1.0.0",
"prettier-plugin-tailwindcss": "0.3.0",
"vitest": "0.32.0"
},
"peerDependencies": {
"prettier": "2.x"
},
"keywords": [
"bravo68web",
"prettier",
"prettier-config"
],
"publishConfig": {
"access": "public"
}
"name": "@bravo68web/prettier-config",
"version": "1.1.0",
"description": "The official Prettier configuration for bravo68web projects",
"author": "Bravo68web <hi@b68.dev> (https://github.com/bravo68web/)",
"homepage": "https://github.com/bravo68web/nodejs-config#readme",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"bugs": {
"url": "https://github.com/bravo68web/nodejs-config/issues"
},
"main": "index.json",
"files": [
"index.json",
"package.json",
"README.md",
"LICENSE"
],
"scripts": {
"test": "vitest run"
},
"dependencies": {
"prettier-plugin-package-perfection": "1.1.0",
"prettier-plugin-prisma": "4.13.0",
"prettier-plugin-sort-json": "1.0.0",
"prettier-plugin-tailwindcss": "0.3.0",
"vitest": "0.32.0"
},
"peerDependencies": {
"prettier": "2.x"
},
"keywords": [
"bravo68web",
"prettier",
"prettier-config"
],
"publishConfig": {
"access": "public"
}
}

View File

@ -1,20 +1,19 @@
import prettier from 'prettier';
import { describe, expect, it } from 'vitest';
import prettier from "prettier";
import { describe, expect, it } from "vitest";
import config from '../index.json';
import config from "../index.json";
describe('Prettier Config', () => {
it('is valid configuration', () => {
// Format the code with Prettier
const code = prettier.format(
'const foo=1',
Object.assign(config as prettier.Options, {
parser: 'typescript',
}) as prettier.Options,
);
describe("Prettier Config", () => {
it("is valid configuration", () => {
// Format the code with Prettier
const code = prettier.format(
"const foo=1",
Object.assign(config as prettier.Options, {
parser: "typescript",
}) as prettier.Options,
);
// Ensure it matches the expected formatting
expect(code).toBe(`const foo = 1;
`);
});
// Ensure it matches the expected formatting
expect(code).toBe(`const foo = 1;\n`);
});
});

View File

@ -16,19 +16,19 @@ npm install --save-dev @bravo68web/tsconfig
Add the following code to your `tsconfig.json` file:
- Default configuration
- Default configuration
```json
{
"extends": "@bravo68web/tsconfig/base.json"
"extends": "@bravo68web/tsconfig/base.json"
}
```
- Web Frontend configuration
- Web Frontend configuration
```json
{
"extends": "@bravo68web/tsconfig/web.json"
"extends": "@bravo68web/tsconfig/web.json"
}
```
@ -38,8 +38,8 @@ And that's it! You're now ready to use
This package is compatible with the following TypeScript and Node.js versions:
- TypeScript: 5.0 or later
- Node.js: Any version that supports the above TypeScript version
- TypeScript: 5.0 or later
- Node.js: Any version that supports the above TypeScript version
**Updating to the latest version of this package is recommended for the best compatibility.**

View File

@ -1,38 +1,38 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"alwaysStrict": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"alwaysStrict": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUncheckedIndexedAccess": false,
"noEmit": false,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUncheckedIndexedAccess": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"target": "esnext"
},
"display": "Default tsconfig.json",
"exclude": ["node_modules"]
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"target": "esnext"
},
"display": "Default tsconfig.json",
"exclude": ["node_modules"]
}

View File

@ -0,0 +1,25 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"alwaysStrict": false,
"declaration": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"lib": ["es2018", "es5", "dom"],
"module": "ESNext",
"moduleResolution": "node",
"noEmit": true,
"outDir": "build",
"resolveJsonModule": true,
"strict": true,
"target": "ES2017"
},
"display": "NoBuild tsconfig.json",
"exclude": ["node_modules"],
"extends": "./base.json",
"files": ["types/index.d.ts"],
"ts-node": {
"swc": true
}
}

View File

@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"noEmit": true
},
"display": "NoBuild tsconfig.json",
"exclude": ["node_modules"],
"extends": "./base.json"
}

View File

@ -0,0 +1,38 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": true,
"allowUnusedLabels": true,
"alwaysStrict": false,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"module": "esnext",
"moduleResolution": "node",
"noEmit": false,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": false,
"noImplicitOverride": true,
"noImplicitReturns": false,
"noImplicitThis": false,
"noUncheckedIndexedAccess": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": false,
"strictFunctionTypes": false,
"strictNullChecks": false,
"strictPropertyInitialization": false,
"target": "esnext"
},
"display": "Default tsconfig.json",
"exclude": ["node_modules"]
}

View File

@ -1,30 +1,30 @@
{
"name": "@bravo68web/tsconfig",
"version": "1.0.3",
"description": "Typescript config for bravo68web, ensure the consistency of code quality.",
"license": "MIT",
"author": "Bravo68web <hi@b68.dev> (https://github.com/bravo68web/)",
"homepage": "https://github.com/bravo68web/nodejs-config#readme",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"bugs": {
"url": "https://github.com/bravo68web/nodejs-config/issues"
},
"files": [
"base.json",
"web.json"
],
"peerDependencies": {
"typescript": "5.x"
},
"devDependencies": {
"typescript": "5.1.3"
},
"keywords": [
"bravo68web",
"tsconfig",
"typescript"
],
"publishConfig": {
"access": "public"
}
"name": "@bravo68web/tsconfig",
"version": "1.1.0",
"description": "Typescript config for bravo68web, ensure the consistency of code quality.",
"license": "MIT",
"author": "Bravo68web <hi@b68.dev> (https://github.com/bravo68web/)",
"homepage": "https://github.com/bravo68web/nodejs-config#readme",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"bugs": {
"url": "https://github.com/bravo68web/nodejs-config/issues"
},
"files": [
"base.json",
"web.json"
],
"peerDependencies": {
"typescript": "5.x"
},
"devDependencies": {
"typescript": "5.1.3"
},
"keywords": [
"bravo68web",
"tsconfig",
"typescript"
],
"publishConfig": {
"access": "public"
}
}

View File

@ -1,10 +1,10 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"]
},
"display": "Website tsconfig.json",
"exclude": ["node_modules"],
"extends": "./base.json"
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"]
},
"display": "Website tsconfig.json",
"exclude": ["node_modules"],
"extends": "./base.json"
}

View File

@ -1,35 +1,35 @@
{
"private": true,
"name": "@bravo68web/node-config",
"version": "0.0.0",
"description": "Sharable Node.js miscellaneous config for bravo68web",
"license": "MIT",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"type": "module",
"scripts": {
"build": "turbo build",
"ci:publish": "changeset publish",
"ci:version": "changeset version",
"format": "prettier --write .",
"preinstall": "npx only-allow pnpm",
"lint": "turbo lint",
"prepare": "is-ci || husky install",
"sync-renovate-changesets": "node --loader @esbuild-kit/esm-loader scripts/sync-renovate-changesets.ts",
"test": "turbo test"
},
"dependencies": {
"@bravo68web/eslint-config": "*",
"@bravo68web/prettier-config": "*",
"@bravo68web/tsconfig": "*",
"@changesets/changelog-github": "0.4.8",
"@changesets/cli": "2.26.1",
"@esbuild-kit/esm-loader": "2.5.5",
"@types/node": "18.16.17",
"husky": "8.0.3",
"is-ci": "3.0.1",
"prettier": "2.8.8",
"turbo": "1.10.3"
},
"packageManager": "pnpm@8.6.2",
"prettier": "@bravo68web/prettier-config"
"private": true,
"name": "@bravo68web/node-config",
"version": "0.0.0",
"description": "Sharable Node.js miscellaneous config for bravo68web",
"license": "MIT",
"repository": "git+https://github.com/bravo68web/nodejs-config",
"type": "module",
"scripts": {
"build": "turbo build",
"ci:publish": "changeset publish",
"ci:version": "changeset version",
"format": "prettier --write .",
"preinstall": "npx only-allow pnpm",
"lint": "turbo lint",
"prepare": "is-ci || husky install",
"sync-renovate-changesets": "node --loader @esbuild-kit/esm-loader scripts/sync-renovate-changesets.ts",
"test": "turbo test"
},
"dependencies": {
"@bravo68web/eslint-config": "*",
"@bravo68web/prettier-config": "*",
"@bravo68web/tsconfig": "*",
"@changesets/changelog-github": "0.4.8",
"@changesets/cli": "2.26.1",
"@esbuild-kit/esm-loader": "2.5.5",
"@types/node": "18.16.17",
"husky": "8.0.3",
"is-ci": "3.0.1",
"prettier": "2.8.8",
"turbo": "1.10.3"
},
"packageManager": "pnpm@8.6.2",
"prettier": "@bravo68web/prettier-config"
}

View File

@ -1,2 +1,2 @@
packages:
- apps/*
- apps/*

View File

@ -1,5 +1,5 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"baseBranches": ["dev"],
"extends": ["config:base"]
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"baseBranches": ["dev"],
"extends": ["config:base"]
}

View File

@ -1,35 +1,35 @@
#!/usr/bin/env node
/* eslint-disable security/detect-non-literal-fs-filename */
import { exec as _exec } from 'node:child_process';
import { promises as fs } from 'node:fs';
import { promisify } from 'node:util';
import { exec as _exec } from "node:child_process";
import { promises as fs } from "node:fs";
import { promisify } from "node:util";
const exec = promisify(_exec);
const branch = await exec('git branch --show-current');
if (!branch.stdout.startsWith('renovate/')) {
console.log('Not a renovate branch, skipping');
const branch = await exec("git branch --show-current");
if (!branch.stdout.startsWith("renovate/")) {
console.log("Not a renovate branch, skipping");
process.exit(0);
process.exit(0);
}
const diffOutput = await exec('git diff --name-only HEAD~1');
const diffOutput = await exec("git diff --name-only HEAD~1");
const diffFiles = diffOutput.stdout
.split('\n')
.filter(file => file !== 'package.json')
.filter(file => file.includes('package.json'));
if (diffFiles.some(f => f.startsWith('.changeset'))) {
console.log('Changeset already exists, skipping');
.split("\n")
.filter(file => file !== "package.json")
.filter(file => file.includes("package.json"));
if (diffFiles.some(f => f.startsWith(".changeset"))) {
console.log("Changeset already exists, skipping");
process.exit(0);
process.exit(0);
}
// If changed file does not include package.json in monorepo, skip
if (!diffFiles.some(file => file.includes('package.json'))) {
console.log('No package.json changes to published packages, skipping');
if (!diffFiles.some(file => file.includes("package.json"))) {
console.log("No package.json changes to published packages, skipping");
process.exit(0);
process.exit(0);
}
// Get changed dependencies inside package.json files, return array of package { name, version }
@ -46,100 +46,101 @@ if (!diffFiles.some(file => file.includes('package.json'))) {
*/
// Find all changed package.json files and extract their dependencies
const packageJsonFiles = await Promise.all(
diffFiles.map(file => fs.readFile(file, 'utf8').then(data => ({ file, data }))),
diffFiles.map(file => fs.readFile(file, "utf8").then(data => ({ file, data }))),
);
const dependencies: {
name: string;
newVersion: string;
projects: string[];
name: string;
newVersion: string;
projects: string[];
}[] = [];
// eslint-disable-next-line sonarjs/cognitive-complexity
const getChangedDependencies = (
projectName: string,
newDepsObj: Record<string, string>,
oldDepsObj: Record<string, string>,
projectName: string,
newDepsObj: Record<string, string>,
oldDepsObj: Record<string, string>,
) => {
for (const [depName, newVersion] of Object.entries(newDepsObj)) {
if (typeof newVersion !== 'string') continue;
for (const [depName, newVersion] of Object.entries(newDepsObj)) {
if (typeof newVersion !== "string") continue;
const oldVersion: string = oldDepsObj[String(depName)];
const oldVersion: string = oldDepsObj[String(depName)];
// Check if the dependency version has changed
if (oldVersion === newVersion) continue;
// Check if the dependency version has changed
if (oldVersion === newVersion) continue;
// Check if the dependency exists in other projects and new version is the same
if (
dependencies.some(dep => dep.name === depName) &&
dependencies.some(dep => dep.newVersion === newVersion)
) {
const dep = dependencies.find(dep => dep.name === depName);
if (!dep) continue;
// Check if the dependency exists in other projects and new version is the same
if (
dependencies.some(dep => dep.name === depName) &&
dependencies.some(dep => dep.newVersion === newVersion)
) {
const dep = dependencies.find(dep => dep.name === depName);
if (!dep) continue;
// Add project to existing dependency
dep.projects.push(projectName);
// Add project to existing dependency
dep.projects.push(projectName);
// Update the element in the array
const index = dependencies.findIndex(dep => dep.name === depName);
// Update the element in the array
const index = dependencies.findIndex(dep => dep.name === depName);
dependencies[Number(index)] = dep;
} else {
dependencies.push({ name: depName, newVersion, projects: [projectName] });
dependencies[Number(index)] = dep;
} else {
dependencies.push({ name: depName, newVersion, projects: [projectName] });
}
}
}
};
for (const { file } of packageJsonFiles) {
const { stdout: newDepsJson } = await exec(`git show HEAD:${file}`);
// Get old dependencies from git history
const { stdout: oldDepsJson } = await exec(`git show HEAD~1:${file}`);
const {
name: projectName,
dependencies: oldDeps = {},
devDependencies: oldDevDeps = {},
} = JSON.parse(oldDepsJson);
const { dependencies: newDeps = {}, devDependencies: newDevDeps = {} } = JSON.parse(newDepsJson);
const { stdout: newDepsJson } = await exec(`git show HEAD:${file}`);
// Get old dependencies from git history
const { stdout: oldDepsJson } = await exec(`git show HEAD~1:${file}`);
const {
name: projectName,
dependencies: oldDeps = {},
devDependencies: oldDevDeps = {},
} = JSON.parse(oldDepsJson);
const { dependencies: newDeps = {}, devDependencies: newDevDeps = {} } =
JSON.parse(newDepsJson);
getChangedDependencies(projectName, newDeps, oldDeps);
getChangedDependencies(projectName, newDevDeps, oldDevDeps);
getChangedDependencies(projectName, newDeps, oldDeps);
getChangedDependencies(projectName, newDevDeps, oldDevDeps);
}
// Create changeset
async function createChangeset(fileName: string, packageBumps: string[][], packages: string[]) {
let message = '';
for (const [pkg, bump] of packageBumps) {
message = message + `Updated dependency \`${pkg}\` to \`${bump}\`.\n`;
}
let message = "";
for (const [pkg, bump] of packageBumps) {
message = message + `Updated dependency \`${pkg}\` to \`${bump}\`.\n`;
}
const pkgs = packages.map((pkg: string) => `'${pkg}': patch`).join('\n');
const body = `---\n${pkgs}\n---\n\n${message.trim()}\n`;
const pkgs = packages.map((pkg: string) => `'${pkg}': patch`).join("\n");
const body = `---\n${pkgs}\n---\n\n${message.trim()}\n`;
await fs.writeFile(fileName, body);
await fs.writeFile(fileName, body);
}
const addedFiles: string[] = [];
// Create changeset for each changed dependency
for (const { name, newVersion, projects } of dependencies) {
const safeName = name.replaceAll(/[^\w-]/g, '_').toLowerCase();
const fileName = `.changeset/${safeName}-${newVersion}.md`;
const safeName = name.replaceAll(/[^\w-]/g, "_").toLowerCase();
const fileName = `.changeset/${safeName}-${newVersion}.md`;
if (addedFiles.includes(fileName)) continue;
if (addedFiles.includes(fileName)) continue;
addedFiles.push(fileName);
addedFiles.push(fileName);
const packageBumps = [[name, newVersion]];
const packages = projects;
const packageBumps = [[name, newVersion]];
const packages = projects;
await createChangeset(fileName, packageBumps, packages);
await createChangeset(fileName, packageBumps, packages);
}
// Add changeset files to git
for (const fileName of addedFiles) await exec('git add ' + fileName);
for (const fileName of addedFiles) await exec("git add " + fileName);
// Commit changeset
await exec('git commit -C HEAD --amend --no-edit');
await exec("git commit -C HEAD --amend --no-edit");
// Push changeset
await exec('git push --force');
await exec("git push --force");

View File

@ -1,3 +1,3 @@
{
"extends": "@bravo68web/tsconfig/base.json"
"extends": "@bravo68web/tsconfig/base.json"
}

View File

@ -1,15 +1,15 @@
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"cache": true,
"outputs": ["**/dist"]
},
"lint": {
"cache": true,
"inputs": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"],
"outputs": ["**/.eslintcache"]
},
"test": {}
}
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"cache": true,
"outputs": ["**/dist"]
},
"lint": {
"cache": true,
"inputs": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"],
"outputs": ["**/.eslintcache"]
},
"test": {}
}
}