Initial commit for project Spoon!
Build and Push Next App / quality (push) Failing after 45s
Build and Push Next App / build-next (push) Has been skipped

This commit is contained in:
Gabriel Brown
2026-06-21 17:52:02 -05:00
commit cf7ff2ee4e
268 changed files with 32981 additions and 0 deletions
+122
View File
@@ -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,
},
},
},
);
+15
View File
@@ -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',
},
});
+36
View File
@@ -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"
}
+22
View File
@@ -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']!,
);
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "@spoon/tsconfig/base.json",
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"types": ["node"]
},
"include": ["."],
"exclude": ["node_modules"]
}