Initial commit for project Spoon!
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
import * as path from 'node:path';
|
||||
import { includeIgnoreFile } from '@eslint/compat';
|
||||
import eslint from '@eslint/js';
|
||||
import importPlugin from 'eslint-plugin-import';
|
||||
// eslint-plugin-prefer-arrow-functions doesn't ship flat config types — cast needed
|
||||
import preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';
|
||||
import turboPlugin from 'eslint-plugin-turbo';
|
||||
import { defineConfig } from 'eslint/config';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const preferArrowPlugin = preferArrowFunctions as any;
|
||||
|
||||
const turboRecommendedRules = (
|
||||
turboPlugin as unknown as {
|
||||
configs: { recommended: { rules: Record<string, string> } };
|
||||
}
|
||||
).configs.recommended.rules;
|
||||
|
||||
/**
|
||||
* All packages that leverage t3-env should use this rule
|
||||
*/
|
||||
export const restrictEnvAccess = defineConfig(
|
||||
{ ignores: ['**/env.ts'] },
|
||||
{
|
||||
files: ['**/*.js', '**/*.ts', '**/*.tsx'],
|
||||
rules: {
|
||||
'no-restricted-properties': [
|
||||
'error',
|
||||
{
|
||||
object: 'process',
|
||||
property: 'env',
|
||||
message:
|
||||
"Use `import { env } from '@/env'` instead to ensure validated types.",
|
||||
},
|
||||
],
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
name: 'process',
|
||||
importNames: ['env'],
|
||||
message:
|
||||
"Use `import { env } from '@/env'` instead to ensure validated types.",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export const baseConfig = defineConfig(
|
||||
// Ignore files not tracked by VCS and any config files
|
||||
includeIgnoreFile(path.join(import.meta.dirname, '../../.gitignore')),
|
||||
{ ignores: ['**/*.config.*'] },
|
||||
{
|
||||
files: ['**/*.js', '**/*.ts', '**/*.tsx'],
|
||||
plugins: {
|
||||
import: importPlugin,
|
||||
turbo: turboPlugin,
|
||||
'prefer-arrow-functions': preferArrowPlugin,
|
||||
},
|
||||
extends: [
|
||||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...tseslint.configs.recommendedTypeChecked,
|
||||
...tseslint.configs.stylisticTypeChecked,
|
||||
],
|
||||
rules: {
|
||||
...turboRecommendedRules,
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-misused-promises': [
|
||||
2,
|
||||
{ checksVoidReturn: { attributes: false } },
|
||||
],
|
||||
'@typescript-eslint/no-unnecessary-condition': [
|
||||
'error',
|
||||
{
|
||||
allowConstantLoopConditions: true,
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-non-null-assertion': 'error',
|
||||
'@typescript-eslint/consistent-type-definitions': 'off',
|
||||
'prefer-arrow-functions/prefer-arrow-functions': [
|
||||
'warn',
|
||||
{
|
||||
allowNamedFunctions: false,
|
||||
classPropertiesAllowed: false,
|
||||
disallowPrototype: false,
|
||||
returnStyle: 'unchanged',
|
||||
singleReturnOnly: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'**/tests/**/*.{ts,tsx}',
|
||||
'**/*.test.{ts,tsx}',
|
||||
'**/*.spec.{ts,tsx}',
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||
'@typescript-eslint/no-unsafe-call': 'off',
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/no-unsafe-argument': 'off',
|
||||
'@typescript-eslint/no-unnecessary-condition': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
linterOptions: { reportUnusedDisableDirectives: true },
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
import nextPlugin from '@next/eslint-plugin-next';
|
||||
import { defineConfig } from 'eslint/config';
|
||||
|
||||
export const nextjsConfig = defineConfig({
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
plugins: {
|
||||
'@next/next': nextPlugin,
|
||||
},
|
||||
rules: {
|
||||
...nextPlugin.configs.recommended.rules,
|
||||
...nextPlugin.configs['core-web-vitals'].rules,
|
||||
// TypeError: context.getAncestors is not a function
|
||||
'@next/next/no-duplicate-head': 'off',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@spoon/eslint-config",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./base": "./base.ts",
|
||||
"./nextjs": "./nextjs.ts",
|
||||
"./react": "./react.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "git clean -xdf .cache .turbo node_modules",
|
||||
"format": "prettier --check . --ignore-path ../../.gitignore",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint/compat": "^2.0.3",
|
||||
"@eslint/js": "catalog:",
|
||||
"@next/eslint-plugin-next": "^16.2.1",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-prefer-arrow-functions": "^3.9.1",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-turbo": "^2.8.20",
|
||||
"typescript-eslint": "^8.57.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@spoon/prettier-config": "workspace:*",
|
||||
"@spoon/tsconfig": "workspace:*",
|
||||
"@types/node": "catalog:",
|
||||
"eslint": "catalog:",
|
||||
"prettier": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"prettier": "@spoon/prettier-config"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { Linter } from 'eslint';
|
||||
import reactPlugin from 'eslint-plugin-react';
|
||||
import reactHooks from 'eslint-plugin-react-hooks';
|
||||
import { defineConfig } from 'eslint/config';
|
||||
|
||||
const reactFlat = reactPlugin.configs.flat as Record<string, Linter.Config>;
|
||||
|
||||
export const reactConfig = defineConfig(
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
...reactFlat.recommended,
|
||||
...reactFlat['jsx-runtime'],
|
||||
languageOptions: {
|
||||
...reactFlat.recommended?.languageOptions,
|
||||
...reactFlat['jsx-runtime']?.languageOptions,
|
||||
globals: {
|
||||
React: 'writable',
|
||||
},
|
||||
},
|
||||
},
|
||||
reactHooks.configs.flat['recommended-latest']!,
|
||||
);
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "@spoon/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user