diff --git a/.gitignore b/.gitignore index d3473e576e..c59880f88d 100644 --- a/.gitignore +++ b/.gitignore @@ -213,3 +213,25 @@ source_docs/ ### Docker ### docker-compose.override.yml + + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +node_modules/ + + +# Wireit's cache +.wireit + +custom-elements.json + + +### Development ### +.drafts diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..35ee5a9382 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,28 @@ +# Prettier Ignorefile + +## Static Files +**/LICENSE + +## Build asset directories +/build +coverage +dist +out + +## Environment +*.env + +## Secrets +*.secrets + +## Yarn +.yarn/**/* + +## Node +node_modules + +## Configs +*.log +*.yaml +*.yml + diff --git a/packages/eslint-config/LICENSE.txt b/packages/eslint-config/LICENSE.txt new file mode 100644 index 0000000000..33b9c1516e --- /dev/null +++ b/packages/eslint-config/LICENSE.txt @@ -0,0 +1,18 @@ +The MIT License (MIT) + +Copyright (c) 2025 Authentik Security, Inc. + +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. diff --git a/packages/eslint-config/README.md b/packages/eslint-config/README.md new file mode 100644 index 0000000000..d22123853a --- /dev/null +++ b/packages/eslint-config/README.md @@ -0,0 +1,5 @@ +# `@goauthentik/eslint-config` + +This package contains the ESLint configuration used by authentik. +While it is possible to use this configuration outside of our projects, +you may find that it is not as useful as other popular configurations. diff --git a/packages/eslint-config/index.js b/packages/eslint-config/index.js new file mode 100644 index 0000000000..1d95d35ad7 --- /dev/null +++ b/packages/eslint-config/index.js @@ -0,0 +1,54 @@ +import eslint from "@eslint/js"; +import { reactConfig } from "@goauthentik/eslint-config/react-config"; +import { typescriptConfig } from "@goauthentik/eslint-config/typescript-config"; +import litconf from "eslint-plugin-lit"; +import wcconf from "eslint-plugin-wc"; +import tseslint from "typescript-eslint"; + +// @ts-check + +/** + * @typedef ESLintPackageConfigOptions Options for creating package ESLint configuration. + * @property {string[]} [ignorePatterns] Override ignore patterns for ESLint. + * @property {import("typescript-eslint").ConfigWithExtends} [overrides] Additional ESLint rules + */ + +/** + * @type {string[]} Default Ignore patterns for ESLint. + */ +export const DefaultIgnorePatterns = [ + // --- + "**/*.md", + "**/.yarn", + "**/out", + "**/dist", +]; + +/** + * Given a preferred package name, creates a ESLint configuration object. + * + * @param {ESLintPackageConfigOptions} options The preferred package configuration options. + * + * @returns The ESLint configuration object. + */ +export function createESLintPackageConfig({ + ignorePatterns = DefaultIgnorePatterns, + overrides = {}, +} = {}) { + return tseslint.config( + { + ignores: ignorePatterns, + }, + + eslint.configs.recommended, + ...tseslint.configs.recommended, + eslint.configs.recommended, + wcconf.configs["flat/recommended"], + litconf.configs["flat/recommended"], + + ...reactConfig, + ...typescriptConfig, + + overrides, + ); +} diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json new file mode 100644 index 0000000000..c687bb3f8e --- /dev/null +++ b/packages/eslint-config/package.json @@ -0,0 +1,50 @@ +{ + "name": "@goauthentik/eslint-config", + "version": "1.0.0", + "description": "authentik's ESLint config", + "license": "MIT", + "type": "module", + "exports": { + "./package.json": "./package.json", + ".": { + "import": "./index.js", + "types": "./out/index.d.ts" + }, + "./react-config": { + "import": "./react-config.js", + "types": "./out/react-config.d.ts" + }, + "./typescript-config": { + "import": "./typescript-config.js", + "types": "./out/typescript-config.d.ts" + } + }, + "types": "./out/index.d.ts", + "prettier": "@goauthentik/prettier-config", + "dependencies": { + "eslint": "^9.23.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-hooks": "^5.2.0" + }, + "devDependencies": { + "@goauthentik/tsconfig": "1.0.0", + "@types/eslint": "^9.6.1", + "@types/eslint__js": "^9.14.0", + "typescript": "^5.8.2", + "typescript-eslint": "^8.27.0" + }, + "peerDependencies": { + "typescript": "^5.8.2", + "typescript-eslint": "^8.27.0" + }, + "optionalDependencies": { + "react": "^18.3.1" + }, + "engines": { + "node": ">=20.11" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/eslint-config/react-config.js b/packages/eslint-config/react-config.js new file mode 100644 index 0000000000..8c254ccd66 --- /dev/null +++ b/packages/eslint-config/react-config.js @@ -0,0 +1,38 @@ +import reactPlugin from "eslint-plugin-react" +import hooksPlugin from "eslint-plugin-react-hooks" +import tseslint from "typescript-eslint" + +/** + * ESLint configuration for React authentik projects. + */ +export const reactConfig = tseslint.config( + { + settings: { + react: { + version: "detect", + }, + }, + + plugins: { + // @ts-ignore Fixup plugin rules. + react: reactPlugin, + // @ts-ignore Fixup plugin + "react-hooks": hooksPlugin, + }, + + rules: { + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn", + + "react/jsx-uses-react": 0, + + "react/display-name": "off", + "react/jsx-curly-brace-presence": "error", + "react/jsx-no-leaked-render": "error", + "react/prop-types": "off", + "react/react-in-jsx-scope": "off", + }, + } +) + +export default reactConfig diff --git a/packages/eslint-config/tsconfig.json b/packages/eslint-config/tsconfig.json new file mode 100644 index 0000000000..92067c4424 --- /dev/null +++ b/packages/eslint-config/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@goauthentik/tsconfig", + "compilerOptions": { + "checkJs": true, + "emitDeclarationOnly": true + } +} diff --git a/packages/eslint-config/typescript-config.js b/packages/eslint-config/typescript-config.js new file mode 100644 index 0000000000..36760f3c50 --- /dev/null +++ b/packages/eslint-config/typescript-config.js @@ -0,0 +1,61 @@ +// @ts-check +import tseslint from "typescript-eslint"; + +/** + * ESLint configuration for TypeScript authentik projects. + */ +export const typescriptConfig = tseslint.config({ + rules: { + "@typescript-eslint/ban-ts-comment": [ + "warn", + { + "ts-ignore": "allow-with-description", + }, + ], + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-extra-semi": "off", + "@typescript-eslint/no-misused-new": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-shadow": [ + "warn", + { + ignoreFunctionTypeParameterNameValueShadow: true, + ignoreTypeValueShadow: true, + }, + ], + "@typescript-eslint/no-unused-vars": [ + "warn", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + // Ignore all variables, since Prettier takes care of this. + varsIgnorePattern: "^\\w", + ignoreRestSiblings: true, + }, + ], + "@typescript-eslint/no-var-requires": "off", + + "eqeqeq": ["error", "always", { null: "ignore" }], + "no-shadow": "off", + "no-extra-semi": "off", + "no-undef": "off", + "no-unused-vars": "off", + "object-shorthand": [ + "warn", + "always", + { + avoidQuotes: true, + ignoreConstructors: true, + avoidExplicitReturnArrows: false, + }, + ], + "prefer-const": "warn", + }, +}); + +export default typescriptConfig; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..58a85613e9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +// TypeScript Project Configuration +{ + "watchOptions": { + "excludeDirectories": [ + "**/.git", // Git + "**/.yarn", // Yarn + "**/.vscode", // VS Code + "**/.vscode-test-web", // VS Code Web Test + "**/dist", // Distributed build files + "**/out", // Output build files + "**/.drafts", // Drafts + "**/.github", // GitHub + "**/node_modules" // Node modules + ] + }, + + // The root project has no sources of its own. By setting `files` to an empty + // list, TS won't automatically include all sources below root (the default). + "files": [], + "references": [ + // Note that references are in the order we want them to be built. + { "path": "./packages/tsconfig" }, + { "path": "./packages/prettier-config" }, + { "path": "./packages/eslint-config" }, + { "path": "./packages/sfe" } + ] +} diff --git a/web/.gitignore b/web/.gitignore index 8ec1375491..7e25ef5604 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -78,13 +78,8 @@ typings/ .next # nuxt.js build output -.nuxt dist -# Uncomment the public line if your project uses Gatsby -# https://nextjs.org/blog/next-9-1#public-directory-support -# https://create-react-app.dev/docs/using-the-public-folder/#docsNav -# public # Storybook build outputs .out @@ -109,8 +104,3 @@ temp/ # End of https://www.gitignore.io/api/node api/** storybook-static/ - -# Wireit's cache -.wireit - -custom-elements.json