Release v1.0.3
This commit is contained in:
commit
759cdf28db
|
@ -0,0 +1,8 @@
|
|||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
||||
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
||||
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
||||
|
||||
We have a quick list of common questions to get you started engaging with this project in
|
||||
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@ -0,0 +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"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": ["@bravo68web/eslint-config/code-style"],
|
||||
"ignorePatterns": ["node_modules", "dist"]
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
name: Setup Node Environment
|
||||
description: Prepare and install everything for nodejs repo
|
||||
|
||||
runs:
|
||||
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: 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: Build packages
|
||||
shell: bash
|
||||
run: pnpm build
|
|
@ -0,0 +1,25 @@
|
|||
name: Linting
|
||||
|
||||
on:
|
||||
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
|
||||
|
||||
- name: Setup Environment
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Testing
|
||||
run: pnpm test
|
||||
|
||||
- name: Run Checking
|
||||
run: pnpm lint
|
|
@ -0,0 +1,39 @@
|
|||
name: Publish to NPM
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
permissions:
|
||||
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
|
||||
|
||||
- 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 }}
|
|
@ -0,0 +1,27 @@
|
|||
name: Sync Renovate changeset
|
||||
on:
|
||||
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 }}
|
||||
|
||||
- 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: Generate changeset
|
||||
run: pnpm sync-renovate-changesets
|
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
dist
|
||||
.turbo
|
||||
.eslintcache
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# Check all files with Prettier.
|
||||
npx prettier --check .
|
|
@ -0,0 +1,6 @@
|
|||
save-exact = true
|
||||
engine-strict = false
|
||||
ignore-engines = true
|
||||
tag-version-prefix = ""
|
||||
auto-install-peers = true
|
||||
strict-peer-dependencies = false
|
|
@ -0,0 +1,3 @@
|
|||
dist
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 bravo68web
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,19 @@
|
|||
# Node.js Config
|
||||
|
||||
[![Linting](https://github.com/bravo68web/nodejs-config/actions/workflows/lint.yml/badge.svg?branch=main)](https://github.com/bravo68web/nodejs-config/actions/workflows/lint.yml)
|
||||
|
||||
This is a monorepo to share miscellaneous Node.js config for [bravo68web](https://github.com/bravo68web), monorepo is managed and versioned by [Changeset](https://github.com/changesets/changesets).
|
||||
|
||||
## Apps
|
||||
|
||||
- [@bravo68web/eslint-config](apps/eslint-config/) - ESLint config
|
||||
- [@bravo68web/tsconfig](apps/tsconfig/) - TypeScript config
|
||||
- [@bravo68web/prettier-config](apps/prettier-config/) - Prettier config
|
||||
|
||||
## Strict Configuration
|
||||
|
||||
Please be advised that this application has **strict configurations**. **_Adopt these configurations carefully_** and only if they meet the requirements of your project. It is recommended to thoroughly review and understand the configurations before implementation.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 bravo68web
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,114 @@
|
|||
# @bravo68web/eslint-config
|
||||
|
||||
[![Version](https://img.shields.io/npm/v/@bravo68web/eslint-config.svg?style=flat-square)](https://www.npmjs.com/package/@bravo68web/eslint-config)
|
||||
|
||||
Welcome to the `@bravo68web/eslint-config`! This is the official ESLint configuration for [bravo68web](https://github.com/bravo68web) projects, enforcing strict rules and best practices for a clean and organized codebase.
|
||||
|
||||
## Rules and plugins
|
||||
|
||||
This configuration includes a variety of rules and plugins, such as:
|
||||
|
||||
### [eslint-plugin-simple-import-sort](https://www.npmjs.com/package/eslint-plugin-simple-import-sort)
|
||||
|
||||
This plugin **sorts your imports, ensuring consistent formatting** across your codebase.
|
||||
|
||||
### [eslint-plugin-unicorn](https://www.npmjs.com/package/eslint-plugin-unicorn)
|
||||
|
||||
This plugin provides a set of rules for enforcing best practices for Node.js and JavaScript development, with a focus on improved security and maintainability.
|
||||
|
||||
### [eslint-plugin-tailwindcss](https://www.npmjs.com/package/eslint-plugin-tailwindcss)
|
||||
|
||||
This plugin integrates the Tailwind CSS framework into your ESLint setup, helping you write cleaner, more maintainable code when **using Tailwind**.
|
||||
|
||||
### [eslint-plugin-sonarjs](https://www.npmjs.com/package/eslint-plugin-sonarjs)
|
||||
|
||||
This plugin provides a set of rules aimed at **improving code quality and catching bugs early**, by leveraging the SonarJS engine.
|
||||
|
||||
### [eslint-plugin-promise](https://www.npmjs.com/package/eslint-plugin-promise)
|
||||
|
||||
This plugin provides a set of rules for enforcing best practices when working with **Promises in JavaScript**.
|
||||
|
||||
### [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react)
|
||||
|
||||
This plugin provides a set of rules for enforcing best practices when **writing React applications**, including guidelines for improving performance and maintainability.
|
||||
|
||||
### [@typescript-eslint/eslint-plugin](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin)
|
||||
|
||||
This plugin provides a set of rules for enforcing best practices when **writing TypeScript code**, and is specifically designed for use with the TypeScript language.
|
||||
|
||||
### [eslint-plugin-deprecation](https://www.npmjs.com/package/eslint-plugin-deprecation)
|
||||
|
||||
(Stricter TypeScript only)
|
||||
|
||||
This plugin provides a set of rules to enfore best practices when using **deprecated APIs**.
|
||||
|
||||
## Installation
|
||||
|
||||
To start using `@bravo68web/eslint-config`, simply run:
|
||||
|
||||
```bash
|
||||
npm install --save-dev @bravo68web/eslint-config
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add the following code to your `.eslintrc.js` or `.eslintrc.json` file:
|
||||
|
||||
- Default: (TypeScript is also supported)
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
extends: ['@bravo68web'],
|
||||
// extends: ['@bravo68web/eslint-config/default'], // if you want to use named config
|
||||
};
|
||||
```
|
||||
|
||||
- Code Style: (prettier)
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
extends: ['@bravo68web/eslint-config/code-style'],
|
||||
};
|
||||
```
|
||||
|
||||
- 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
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- 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
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
And that's it! You're now ready to use
|
||||
|
||||
## Compatibility
|
||||
|
||||
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
|
||||
|
||||
**Updating to the latest version of this package is recommended for the best compatibility.**
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details
|
|
@ -0,0 +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"
|
||||
},
|
||||
"./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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
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';
|
||||
|
||||
// Read the files in the src directory
|
||||
const dir = './src/';
|
||||
// Filter the .ts files
|
||||
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',
|
||||
}),
|
||||
];
|
||||
|
||||
/**
|
||||
* @typedef {import('rollup').RollupOptions} RollupOptions
|
||||
* @typedef {import('rollup').OutputOptions} OutputOptions
|
||||
* @typedef {import('rollup').Plugin} Plugin
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ParticularFormatConfig
|
||||
* @property {string} input
|
||||
* @property {OutputOptions} output
|
||||
* @property {Array<Plugin>} plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generates the Rollup configuration for CJS (CommonJS) builds.
|
||||
*
|
||||
* @param {string} filename - The name of the input TypeScript file.
|
||||
* @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,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Rollup configuration for CJS (CommonJS) builds.
|
||||
*
|
||||
* @param {string} filename - The name of the input TypeScript file.
|
||||
* @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,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Rollup configuration for CJS (CommonJS) and ESM (ECMAScript Module) builds.
|
||||
* @param {string} filename - The name of the input TypeScript file.
|
||||
* @returns {Array<ParticularFormatConfig>} The Rollup configuration for CJS and ESM builds.
|
||||
*/
|
||||
function getEntryConfigs(filename) {
|
||||
return [getCjsConfig(filename), getEsmConfig(filename)];
|
||||
}
|
||||
|
||||
export default files.flatMap(element => getEntryConfigs(element));
|
|
@ -0,0 +1,6 @@
|
|||
import merge from 'deepmerge';
|
||||
|
||||
import defaultConfig from './default';
|
||||
import strictCodeStyleConfig from './sub-rules/prettier';
|
||||
|
||||
export default merge(defaultConfig, strictCodeStyleConfig);
|
|
@ -0,0 +1,105 @@
|
|||
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,
|
||||
},
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
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;
|
|
@ -0,0 +1,12 @@
|
|||
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.
|
||||
},
|
||||
};
|
||||
|
||||
export default strictCodeStyleConfig; // Export the strictCodeStyleConfig object as the default export.
|
|
@ -0,0 +1,38 @@
|
|||
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,
|
||||
},
|
||||
};
|
||||
|
||||
export default strictTypescriptConfig;
|
|
@ -0,0 +1,6 @@
|
|||
import merge from 'deepmerge';
|
||||
|
||||
import defaultConfig from './default';
|
||||
import strictTypescriptConfig from './sub-rules/strict-typescript';
|
||||
|
||||
export default merge(defaultConfig, strictTypescriptConfig);
|
|
@ -0,0 +1,9 @@
|
|||
import merge from 'deepmerge';
|
||||
|
||||
import defaultConfig from './default';
|
||||
import strictCodeStyleConfig from './sub-rules/prettier';
|
||||
import strictTypescriptConfig from './sub-rules/strict-typescript';
|
||||
|
||||
const config = merge(strictCodeStyleConfig, strictTypescriptConfig);
|
||||
|
||||
export default merge(defaultConfig, config);
|
|
@ -0,0 +1,14 @@
|
|||
import { describe } from 'vitest';
|
||||
|
||||
import config from '../src/code-style';
|
||||
import { checkLintingErrors, checkValidity, createEngine } from './utils';
|
||||
|
||||
describe('Code Style Configuration', () => {
|
||||
const engine = createEngine(config);
|
||||
|
||||
// Check the validity of the engine.
|
||||
checkValidity(engine);
|
||||
|
||||
// Check for any linting errors.
|
||||
checkLintingErrors(engine);
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
import { describe } from 'vitest';
|
||||
|
||||
import config from '../src/default';
|
||||
import { checkLintingErrors, checkValidity, createEngine } from './utils';
|
||||
|
||||
describe('Default Configuration', () => {
|
||||
const engine = createEngine(config);
|
||||
|
||||
// Check if the script is valid
|
||||
checkValidity(engine);
|
||||
|
||||
// Check if the script has any linting errors
|
||||
checkLintingErrors(engine);
|
||||
});
|
|
@ -0,0 +1,6 @@
|
|||
const config = {
|
||||
apple: 'red',
|
||||
banana: 'yellow',
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -0,0 +1,19 @@
|
|||
import { describe } from 'vitest';
|
||||
|
||||
import config from '../src/typescript-strict';
|
||||
import { checkLintingErrorsFromFile, checkValidity, createEngine } from './utils';
|
||||
|
||||
describe('Typescript Strict Configuration', () => {
|
||||
const engine = createEngine({
|
||||
...config,
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
});
|
||||
|
||||
// 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');
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
import { describe } from 'vitest';
|
||||
|
||||
import config from '../src/ultimate';
|
||||
import { checkLintingErrorsFromFile, checkValidity, createEngine } from './utils';
|
||||
|
||||
describe('Ultimate Configuration', () => {
|
||||
const engine = createEngine({
|
||||
...config,
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
});
|
||||
|
||||
// Check the engine's configuration.
|
||||
checkValidity(engine);
|
||||
|
||||
// Check the engine's linting errors.
|
||||
checkLintingErrorsFromFile(engine, './tests/examples/example-1.ts');
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
});
|
||||
};
|
||||
|
||||
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();
|
||||
});
|
||||
};
|
||||
|
||||
// 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('');
|
||||
|
||||
// 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);
|
||||
|
||||
// Expect that the file has no errors
|
||||
expect(lintResults[0].errorCount).toBe(0);
|
||||
});
|
||||
};
|
|
@ -0,0 +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"]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 bravo68web
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,80 @@
|
|||
# @bravo68web/prettier-config
|
||||
|
||||
[![Version](https://img.shields.io/npm/v/@bravo68web/prettier-config.svg?style=flat-square)](https://www.npmjs.com/package/@bravo68web/prettier-config)
|
||||
|
||||
Welcome to the `@bravo68web/prettier-config`! This is the Prettier configuration for [bravo68web](https://github.com/bravo68web).
|
||||
|
||||
## 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.
|
||||
|
||||
> `x => x * x` instead of `(x) => x * x`
|
||||
|
||||
- **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.
|
||||
|
||||
## Prettier Plugins
|
||||
|
||||
In addition to the base Prettier configuration, this package also includes the following plugins:
|
||||
|
||||
### [prettier-plugin-package-perfection](https://npmjs.com/package/prettier-plugin-package-perfection)
|
||||
|
||||
This plugin makes sure your `package.json` file is correctly formatted and includes all necessary information.
|
||||
|
||||
### [prettier-plugin-prisma](https://npmjs.com/package/prettier-plugin-prisma)
|
||||
|
||||
This plugin makes sure your Prisma schema files are correctly formatted, making it easier to read and maintain.
|
||||
|
||||
### [prettier-plugin-sort-json](https://npmjs.com/package/prettier-plugin-sort-json)
|
||||
|
||||
This plugin sorts the properties of your JSON files, ensuring consistent formatting across your codebase.
|
||||
|
||||
### [prettier-plugin-tailwindcss](https://npmjs.com/package/prettier-plugin-tailwindcss)
|
||||
|
||||
This plugin makes sure your Tailwind CSS code is correctly formatted and adheres to best practices, helping you keep your codebase clean and maintainable.
|
||||
|
||||
## Installation
|
||||
|
||||
To start using `@bravo68web/prettier-config`, simply run:
|
||||
|
||||
```bash
|
||||
npm install --save-dev @bravo68web/prettier-config
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add the following code to your `.prettierrc` or `.prettierrc.json` file:
|
||||
|
||||
```json
|
||||
"@bravo68web/prettier-config"
|
||||
```
|
||||
|
||||
(or `package.json`)
|
||||
|
||||
```json
|
||||
{
|
||||
"prettier": "@bravo68web/prettier-config"
|
||||
}
|
||||
```
|
||||
|
||||
And that's it! You're now ready to use
|
||||
|
||||
## Compatibility
|
||||
|
||||
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
|
||||
|
||||
**Updating to the latest version of this package is recommended for the best compatibility.**
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
@ -0,0 +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"
|
||||
}
|
|
@ -0,0 +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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import prettier from 'prettier';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
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,
|
||||
);
|
||||
|
||||
// Ensure it matches the expected formatting
|
||||
expect(code).toBe(`const foo = 1;
|
||||
`);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 bravo68web
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,48 @@
|
|||
# @bravo68web/tsconfig
|
||||
|
||||
[![Version](https://img.shields.io/npm/v/@bravo68web/tsconfig.svg?style=flat-square)](https://www.npmjs.com/package/@bravo68web/tsconfig)
|
||||
|
||||
Welcome to the `@bravo68web/eslint-config`! Strict Typescript configuration for [bravo68web](https://github.com/bravo68web). Use with caution.
|
||||
|
||||
## Installation
|
||||
|
||||
To start using `@bravo68web/tsconfig`, simply run:
|
||||
|
||||
```bash
|
||||
npm install --save-dev @bravo68web/tsconfig
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add the following code to your `tsconfig.json` file:
|
||||
|
||||
- Default configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "@bravo68web/tsconfig/base.json"
|
||||
}
|
||||
```
|
||||
|
||||
- Web Frontend configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "@bravo68web/tsconfig/web.json"
|
||||
}
|
||||
```
|
||||
|
||||
And that's it! You're now ready to use
|
||||
|
||||
## Compatibility
|
||||
|
||||
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
|
||||
|
||||
**Updating to the latest version of this package is recommended for the best compatibility.**
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"alwaysStrict": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
"isolatedModules": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
|
||||
"noEmit": true,
|
||||
"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"]
|
||||
}
|
|
@ -0,0 +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"
|
||||
}
|
||||
}
|
|
@ -0,0 +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"
|
||||
}
|
|
@ -0,0 +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"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
|||
packages:
|
||||
- apps/*
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"baseBranches": ["dev"],
|
||||
"extends": ["config:base"]
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
#!/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';
|
||||
|
||||
const exec = promisify(_exec);
|
||||
|
||||
const branch = await exec('git branch --show-current');
|
||||
if (!branch.stdout.startsWith('renovate/')) {
|
||||
console.log('Not a renovate branch, skipping');
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
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');
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Get changed dependencies inside package.json files, return array of package { name, version }
|
||||
/**
|
||||
* name: '@renovate/project-demo',
|
||||
* dependencies: {
|
||||
* + "@renovate/eslint-config": "1.0.1",
|
||||
* - "@renovate/eslint-config": "1.0.0",
|
||||
* + "@renovate/stylelint-config": "1.0.1",
|
||||
* - "@renovate/stylelint-config": "1.0.0",
|
||||
* }
|
||||
*
|
||||
* so we need to get the dependency names and versions in array of { name: '@renovate/eslint-config', newVersion: '1.0.1', oldVersion: '1.0.0' }, ...
|
||||
*/
|
||||
// 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 }))),
|
||||
);
|
||||
|
||||
const dependencies: {
|
||||
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>,
|
||||
) => {
|
||||
for (const [depName, newVersion] of Object.entries(newDepsObj)) {
|
||||
if (typeof newVersion !== 'string') continue;
|
||||
|
||||
const oldVersion: string = oldDepsObj[String(depName)];
|
||||
|
||||
// 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;
|
||||
|
||||
// Add project to existing dependency
|
||||
dep.projects.push(projectName);
|
||||
|
||||
// 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] });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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`;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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`;
|
||||
|
||||
if (addedFiles.includes(fileName)) continue;
|
||||
|
||||
addedFiles.push(fileName);
|
||||
|
||||
const packageBumps = [[name, newVersion]];
|
||||
const packages = projects;
|
||||
|
||||
await createChangeset(fileName, packageBumps, packages);
|
||||
}
|
||||
|
||||
// Add changeset files to git
|
||||
for (const fileName of addedFiles) await exec('git add ' + fileName);
|
||||
|
||||
// Commit changeset
|
||||
await exec('git commit -C HEAD --amend --no-edit');
|
||||
|
||||
// Push changeset
|
||||
await exec('git push --force');
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": "@bravo68web/tsconfig/base.json"
|
||||
}
|
|
@ -0,0 +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": {}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue