import { composer, concat } from "eslint-flat-config-utils"; import { existsSync } from "node:fs"; import { relative, resolve } from "node:path"; import { confirm, outro, spinner } from "@clack/prompts"; import { createResolver } from "exsolve"; import { blue, underline } from "kolorist"; import { isPackageExists } from "local-pkg"; import { addDevDependency } from "nypm"; import { detect } from "package-manager-detector"; import { FlatCompat } from "@eslint/eslintrc"; import gitignoreConfig from "eslint-config-flat-gitignore"; import perfectionistPlugin from "eslint-plugin-perfectionist"; import { plugin as pnpmPlugin } from "eslint-plugin-pnpm"; import tseslintVendor from "typescript-eslint"; import unicornVendor from "eslint-plugin-unicorn"; import vueVendor from "eslint-plugin-vue"; import * as vueParser from "vue-eslint-parser"; import * as jsoncParser from "jsonc-eslint-parser"; import * as yamlParser from "yaml-eslint-parser"; import "@typescript-eslint/parser"; import { globalIgnores } from "eslint/config"; import eslint from "@eslint/js"; import globals from "globals"; //#region src/utils/autoimports.ts const compat = new FlatCompat({}); const DEFAULT_AUTO_IMPORTS_PATH = ".eslintrc-auto-import"; const { resolveModulePath: resolveModulePath$1 } = createResolver({ extensions: [".json"] }); function loadAutoImports(options = true) { if (!options) return {}; if (typeof options === "object" && typeof options.src === "object") return { languageOptions: options.src }; const autoImportsFile = typeof options === "object" && typeof options.src === "string" ? options.src : DEFAULT_AUTO_IMPORTS_PATH; try { const autoImportModuleURL = resolveModulePath$1(resolve(".", autoImportsFile), { try: true }); if (!autoImportModuleURL) return {}; return compat.extends(autoImportModuleURL)[0] ?? {}; } catch { return {}; } } //#endregion //#region src/utils/index.ts const hasVuetifyConfig = hasPackage("eslint-config-vuetify"); async function interopDefault(m) { const awaited = await m; return awaited.default ?? awaited; } function isInEditorEnv() { if (process.env.CI) return false; if (isInGitHooksOrLintStaged()) return false; return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM); } function isInGitHooksOrLintStaged() { return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged")); } function hasPackage(pkg, scope) { return isPackageExists(pkg, { paths: scope ? [scope] : [] }); } const currentScope = new URL(".", import.meta.url).pathname; const currentRoot = process.cwd(); async function assertPackage(pkg, setting) { if (!hasPackage(pkg, currentScope)) { if (process.env.CI || process.stdout.isTTY === false || !hasVuetifyConfig) return; if (await confirm({ message: `Package ${pkg} is required for this config but not installed. Do you want to install it?` }) === true) { const s = spinner(); s.start(`Installing ${pkg}`); await addDevDependency(pkg); s.stop(`Installed ${pkg}`); outro("Please, rerun the command or reopen your editor to apply the changes"); } else { const { ESLint } = await import("eslint"); const config = await new ESLint({}).findConfigFile(); const configMessage = config ? `${underline(relative(currentRoot, config))}` : "config file"; if (setting) outro(`Please, install the package or set ${blue(setting)} in your ${configMessage}`); else outro(`Please, install the package or disable the setting in your ${configMessage} file`); process.exit(1); } } } function hasFile(file) { return existsSync(resolve(process.cwd(), file)); } async function getPackageManager() { return detect({ cwd: process.cwd() }); } const { resolveModulePath } = createResolver({ extensions: [ ".js", ".mjs", ".cjs", ".ts", ".mts", ".cts" ] }); resolveModulePath("./eslint.config", { try: true }); //#endregion //#region src/configs/antfu.ts async function antfu(options = true) { const filesConfig = typeof options === "boolean" || !options.files ? {} : { files: options.files }; const antfuPlugin = await interopDefault(import("eslint-plugin-antfu")); return [{ name: "vuetify/antfu", ...filesConfig, plugins: { antfu: antfuPlugin }, rules: { "antfu/import-dedupe": "error", "antfu/top-level-function": "error", "antfu/no-import-node-modules-by-path": "error", "antfu/consistent-chaining": "error" } }]; } //#endregion //#region src/globs.ts const GLOB_SRC_EXT = "?([cm])[jt]s?(x)"; const GLOB_JS = "**/*.?([cm])js"; const GLOB_JSX = "**/*.?([cm])jsx"; const GLOB_TS = "**/*.?([cm])ts"; const GLOB_TSX = "**/*.?([cm])tsx"; const GLOB_VUE = "**/*.vue"; const GLOB_TESTS = [ `**/__tests__/**/*.${GLOB_SRC_EXT}`, `**/*.spec.${GLOB_SRC_EXT}`, `**/*.test.${GLOB_SRC_EXT}`, `**/*.bench.${GLOB_SRC_EXT}`, `**/*.benchmark.${GLOB_SRC_EXT}` ]; const GLOB_EXCLUDE = [ "**/node_modules", "**/dist", "**/package-lock.json", "**/yarn.lock", "**/pnpm-lock.yaml", "**/bun.lockb", "**/output", "**/coverage", "**/temp", "**/.temp", "**/tmp", "**/.tmp", "**/.history", "**/.vitepress/cache", "**/.nuxt", "**/.vercel", "**/.changeset", "**/.idea", "**/.cache", "**/.output", "**/.vite-inspect", "**/.yarn", "**/vite.config.*.timestamp-*", "**/CHANGELOG*.md", "**/*.min.*", "**/LICENSE*", "**/__snapshots__", "**/auto-import?(s).d.ts", "**/components.d.ts" ]; //#endregion //#region src/configs/autoimports.ts function autoimports(options = true) { const autoimports = loadAutoImports(options); return { name: "vuetfiy/autoimports", files: [ GLOB_JS, GLOB_TS, GLOB_JSX, GLOB_TSX ], ...autoimports }; } //#endregion //#region src/configs/gitignore.ts const DEFAULT_OPTIONS = { sources: [".gitignore"], gitmodules: [] }; function gitignore(options = true) { if (!options) return {}; if (typeof options === "boolean") options = DEFAULT_OPTIONS; return gitignoreConfig({ files: options?.sources, filesGitModules: options?.gitmodules, name: "vuetify/gitignore" }); } //#endregion //#region src/configs/ignore.ts function ignore(options) { if (!options) return {}; if (typeof options === "boolean") options = { ignore: GLOB_EXCLUDE }; const ignoreList = options?.ignore ?? GLOB_EXCLUDE; const extendIgnoreList = options?.extendIgnore ?? []; return globalIgnores([...ignoreList, ...extendIgnoreList], "vuetify/ignore"); } //#endregion //#region src/configs/imports.ts async function imports(options = true) { const filesConfig = typeof options === "boolean" || !options?.files ? {} : { files: options.files }; const pluginType = typeof options === "boolean" || !options?.plugin ? "import-lite" : options.plugin; let selectedPlugin; if (pluginType === "import-x") { await assertPackage("eslint-plugin-import-x", "import: { plugin: \"import-lite\" }"); selectedPlugin = (await import("eslint-plugin-import-x")).default; } else selectedPlugin = (await import("eslint-plugin-import-lite")).default; return [{ name: "vuetify/imports", ...filesConfig, plugins: { import: selectedPlugin }, rules: { "import/first": "error", "import/no-duplicates": ["error", { "prefer-inline": false }], "import/no-mutable-exports": "error", "import/no-named-default": "error" } }]; } //#endregion //#region src/configs/js.ts function js(options = true) { const files = typeof options === "boolean" ? [ GLOB_JS, GLOB_TS, GLOB_JSX, GLOB_TSX ] : options.files; return [{ files, ...eslint.configs.recommended, name: "vuetify/js/recommended" }, { files, name: "vuetify/js", languageOptions: { globals: { ...globals.node, ...globals.es2021, ...globals.browser }, parserOptions: { ecmaFeatures: { jsx: true }, sourceType: "module" }, sourceType: "module" }, rules: { "complexity": ["error", 32], "curly": ["error", "all"], "no-case-declarations": "off", "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", "no-empty": "error", "no-prototype-builtins": "off", "no-return-assign": "off", "no-unused-vars": "error", "no-var": "error", "no-void": "off", "object-shorthand": ["error", "always"], "prefer-const": ["error", { destructuring: "all", ignoreReadBeforeAssign: true }] } }]; } //#endregion //#region src/configs/perfectionist.ts function perfectionist(options = true) { const filesConfig = typeof options === "boolean" || !options.files ? {} : { files: options.files }; const importRules = options === true || options && options?.import !== false; const exportRules = options === true || options && options?.export !== false; if (!importRules && !exportRules) return []; const rules = {}; if (importRules) { rules["perfectionist/sort-imports"] = ["error", { groups: [ "type", [ "type-parent", "type-sibling", "type-index", "type-internal" ], "builtin", "external", "internal", [ "parent", "sibling", "index" ], "side-effect", "unknown" ], newlinesBetween: "ignore", order: "asc", type: "natural" }]; rules["perfectionist/sort-named-imports"] = ["error", { order: "asc", type: "natural" }]; } if (exportRules) { rules["perfectionist/sort-exports"] = ["error", { order: "asc", type: "natural" }]; rules["perfectionist/sort-named-exports"] = ["error", { order: "asc", type: "natural" }]; } return [{ name: "vuetify/perfectionist", ...filesConfig, plugins: { perfectionist: perfectionistPlugin }, rules }]; } //#endregion //#region src/configs/pnpm.ts const hasWorkspace = hasFile("pnpm-workspace.yaml"); function pnpm(options = true) { const enforceCatalog = typeof options === "object" ? options.enforceCatalog ?? false : false; return [{ ignores: ["**/node_modules/**", "**/dist/**"], files: typeof options === "object" && options.files ? options.files : ["package.json", "**/package.json"], languageOptions: { parser: jsoncParser }, name: "vuetify/pnpm/package-json", plugins: { pnpm: pnpmPlugin }, rules: { "pnpm/json-prefer-workspace-settings": hasWorkspace ? "error" : "off", "pnpm/json-enforce-catalog": enforceCatalog ? "error" : "off", "pnpm/json-valid-catalog": enforceCatalog ? "error" : "off" } }, { files: ["pnpm-workspace.yaml"], languageOptions: { parser: yamlParser }, name: "vuetify/pnpm/pnpm-workspace-yaml", plugins: { pnpm: pnpmPlugin }, rules: { "pnpm/yaml-no-duplicate-catalog-item": "error", "pnpm/yaml-no-unused-catalog-item": "error" } }]; } //#endregion //#region src/configs/stylistic.ts async function stylistic(options = true, optionsVue = false) { if (!options) return []; const severity = options === true || !options?.severity ? "error" : options.severity; const stylisticPlugin = await interopDefault(import("@stylistic/eslint-plugin")); const stylistic = [{ name: "vuetify/stylistic", plugins: { "@stylistic": stylisticPlugin }, rules: { ...stylisticPlugin.configs.customize({ indent: 2, jsx: true, quotes: "single", semi: false, severity }).rules, "@stylistic/space-before-function-paren": [severity, { anonymous: "always", asyncArrow: "always", named: "always" }], "@stylistic/brace-style": [severity, "1tbs"], "@stylistic/arrow-parens": [severity, "as-needed"] } }]; if (optionsVue) stylistic.push({ files: [GLOB_VUE], name: "vuetify/stylistic/vue", rules: { "@stylistic/indent": ["off"] } }); return stylistic; } //#endregion //#region src/configs/test.ts async function test(options = true) { if (!options) return {}; else if (options === true) if (!hasPackage("@vitest/eslint-plugin") && !hasPackage("eslint-plugin-jest")) return {}; else options = { files: GLOB_TESTS, runner: hasPackage("@vitest/eslint-plugin") ? "vitest" : "jest" }; const files = options?.files ?? GLOB_TESTS; const runner = options?.runner; if (runner === "vitest") { await assertPackage("@vitest/eslint-plugin", "test: false"); const vitestVendor = await interopDefault(import("@vitest/eslint-plugin")); return [{ files, plugins: { "vitest": vitestVendor, "no-only-tests": await interopDefault(import("eslint-plugin-no-only-tests")) }, rules: { ...vitestVendor.configs.recommended.rules, "no-only-tests/no-only-tests": "error" } }]; } if (runner === "jest") { await assertPackage("eslint-plugin-jest", "test: false"); const jestVendor = await interopDefault(import("eslint-plugin-jest")); return [{ files, plugins: { "jest": jestVendor, "no-only-tests": await interopDefault(import("eslint-plugin-no-only-tests")) }, languageOptions: { globals: jestVendor.environments.globals.globals }, rules: { "jest/no-disabled-tests": "warn", "jest/no-focused-tests": "error", "jest/no-identical-title": "error", "jest/prefer-to-have-length": "warn", "jest/valid-expect": "error", "no-only-tests/no-only-tests": "error" } }]; } return {}; } //#endregion //#region src/configs/ts.ts function typescriptCore(preset) { return tseslintVendor.config({ extends: [...tseslintVendor.configs[preset]], files: [GLOB_TS, GLOB_TSX], name: "vuetify/typescript", rules: { "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/member-ordering": "error", "@typescript-eslint/no-inferrable-types": "error", "@typescript-eslint/unified-signatures": "error", "@typescript-eslint/no-invalid-this": "error", "@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports", fixStyle: "separate-type-imports" }], "@typescript-eslint/method-signature-style": ["error", "property"], "@typescript-eslint/no-empty-object-type": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-import-type-side-effects": "error", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-redeclare": "error", "@typescript-eslint/no-unsafe-function-type": "off", "@typescript-eslint/no-unused-expressions": ["error", { allowShortCircuit: true, allowTaggedTemplates: true, allowTernary: true }], "@typescript-eslint/prefer-as-const": "warn", "@typescript-eslint/prefer-literal-enum-member": ["error", { allowBitwiseExpressions: true }], "no-unused-vars": "off", "no-unused-expressions": "off", "no-restricted-syntax": ["error", "TSEnumDeclaration[const=true]"], "no-dupe-class-members": "off", "no-redeclare": "off", "no-use-before-define": "off", "no-useless-constructor": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/no-unused-vars": ["warn", { varsIgnorePattern: "^_", argsIgnorePattern: "^_" }] } }); } function typescript(options = true) { if (!options) return []; const preset = options === true || !options?.preset ? "recommended" : options.preset; const projectService = typeof options === "object" && options?.projectService || [ "recommendedTypeChecked", "strictTypeChecked", "all" ].includes(preset); const tsconfigRootDir = typeof options === "object" ? options?.tsconfigRootDir : void 0; return [ ...typescriptCore(preset), { languageOptions: { parserOptions: { projectService, tsconfigRootDir } } }, { files: ["**/*.d.ts"], name: "vuetify/typescript/dts", rules: { "eslint-comments/no-unlimited-disable": "off", "import/no-duplicates": "off", "no-restricted-syntax": "off", "unused-imports/no-unused-vars": "off" } }, { files: [GLOB_JS, "**/*.cjs"], name: "vuetify/typescript/cjs-rules", rules: { "@typescript-eslint/no-require-imports": "off" } } ]; } //#endregion //#region src/configs/unicorn.ts function unicorn(options = true) { const filesConfig = typeof options === "boolean" || !options.files ? {} : { files: options.files }; return [{ ...filesConfig, ...unicornVendor.configs["recommended"], name: "vuetify/unicorn/recommended" }, { ...filesConfig, name: "vuetify/unicorn", rules: { "unicorn/filename-case": "off", "unicorn/no-null": "off", "unicorn/number-literal-case": "off", "unicorn/template-indent": "off", "unicorn/prevent-abbreviations": "off", "unicorn/prefer-top-level-await": "off", "unicorn/prefer-spread": "off", "unicorn/no-await-expression-member": "off", "unicorn/no-useless-undefined": "off", "unicorn/no-array-reduce": "off", "unicorn/no-array-push-push": "off", "unicorn/prefer-string-replace-all": "off", "unicorn/no-abusive-eslint-disable": "off", "unicorn/import-style": "off", "unicorn/prefer-module": "off", "unicorn/consistent-function-scoping": "off", "unicorn/prefer-global-this": "off" } }]; } //#endregion //#region src/configs/vue.ts function vueTs(preset) { return typescriptCore(preset).filter((config) => config.name !== "typescript-eslint/base").map((config) => { return { ...config, files: [GLOB_VUE], name: `vuetify/vue/${config.name?.replace("vuetify/", "") || "anonymous"}` }; }); } const rules = { ...vueVendor.configs["flat/recommended"].map((c) => c.rules).reduce((acc, c) => ({ ...acc, ...c }), {}), "vue/html-closing-bracket-newline": ["error", { singleline: "never", multiline: "always" }], "vue/html-closing-bracket-spacing": "error", "vue/max-attributes-per-line": ["error", { singleline: 4, multiline: 1 }], "vue/multi-word-component-names": "off", "vue/multiline-html-element-content-newline": "off", "vue/no-v-html": "off", "vue/padding-line-between-tags": ["error", [{ blankLine: "always", prev: "*:multi-line", next: "*" }, { blankLine: "always", prev: "*", next: "*:multi-line" }]], "vue/script-indent": [ "error", 2, { baseIndent: 1, switchCase: 1, ignores: [] } ], "vue/singleline-html-element-content-newline": "off", "vue/valid-v-on": "off", "vue/valid-v-slot": ["error", { allowModifiers: true }] }; async function vue(options = true, tsOptions = true) { const plugins = { vue: vueVendor }; const tsEnabled = !!tsOptions; const tsPreset = typeof tsOptions === "boolean" ? "recommended" : tsOptions.preset || "recommended"; let a11config = []; const tsConfig = tsEnabled ? vueTs(tsPreset) : []; const languageOptions = { parser: vueParser, parserOptions: { ecmaFeatures: { jsx: true }, extraFileExtensions: [".vue"], sourceType: "module", parser: tseslintVendor.parser } }; if (tsEnabled) plugins["@typescript-eslint"] = tseslintVendor.plugin; if (typeof options === "object" && options?.a11y) { await assertPackage("eslint-plugin-vuejs-accessibility", "vue.a11y: false"); a11config = (await interopDefault(import("eslint-plugin-vuejs-accessibility"))).configs["flat/recommended"]; } return [ ...a11config, ...tsConfig, { files: [GLOB_VUE], languageOptions, name: "vuetify/vue", plugins, processor: vueVendor.processors[".vue"], rules: { ...rules, "vue/block-lang": tsEnabled ? "off" : ["error", { script: { lang: "ts" } }] } }, { name: "vuetify/vue/jsx", files: [ GLOB_VUE, GLOB_TSX, GLOB_JSX ], languageOptions, plugins, processor: vueVendor.processors[".vue"], rules: { "vue/attributes-order": ["error", { alphabetical: true }], "vue/custom-event-name-casing": [ "error", "kebab-case", { ignores: ["/^[a-z]+(?:-[a-z]+)*:[a-z]+(?:-[a-z]+)*$/u"] } ], "vue/one-component-per-file": "off", "vue/require-default-prop": "off", "vue/require-prop-types": "off" } } ]; } //#endregion //#region node_modules/.pnpm/valibot@1.3.1_typescript@6.0.3/node_modules/valibot/dist/index.mjs let store$4; /** * Returns the global configuration. * * @param config The config to merge. * * @returns The configuration. */ /* @__NO_SIDE_EFFECTS__ */ function getGlobalConfig(config$1) { return { lang: config$1?.lang ?? store$4?.lang, message: config$1?.message, abortEarly: config$1?.abortEarly ?? store$4?.abortEarly, abortPipeEarly: config$1?.abortPipeEarly ?? store$4?.abortPipeEarly }; } let store$3; /** * Returns a global error message. * * @param lang The language of the message. * * @returns The error message. */ /* @__NO_SIDE_EFFECTS__ */ function getGlobalMessage(lang) { return store$3?.get(lang); } let store$2; /** * Returns a schema error message. * * @param lang The language of the message. * * @returns The error message. */ /* @__NO_SIDE_EFFECTS__ */ function getSchemaMessage(lang) { return store$2?.get(lang); } let store$1; /** * Returns a specific error message. * * @param reference The identifier reference. * @param lang The language of the message. * * @returns The error message. */ /* @__NO_SIDE_EFFECTS__ */ function getSpecificMessage(reference, lang) { return store$1?.get(reference)?.get(lang); } /** * Stringifies an unknown input to a literal or type string. * * @param input The unknown input. * * @returns A literal or type string. * * @internal */ /* @__NO_SIDE_EFFECTS__ */ function _stringify(input) { const type = typeof input; if (type === "string") return `"${input}"`; if (type === "number" || type === "bigint" || type === "boolean") return `${input}`; if (type === "object" || type === "function") return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null"; return type; } /** * Adds an issue to the dataset. * * @param context The issue context. * @param label The issue label. * @param dataset The input dataset. * @param config The configuration. * @param other The optional props. * * @internal */ function _addIssue(context, label, dataset, config$1, other) { const input = other && "input" in other ? other.input : dataset.value; const expected = other?.expected ?? context.expects ?? null; const received = other?.received ?? /* @__PURE__ */ _stringify(input); const issue = { kind: context.kind, type: context.type, input, expected, received, message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`, requirement: context.requirement, path: other?.path, issues: other?.issues, lang: config$1.lang, abortEarly: config$1.abortEarly, abortPipeEarly: config$1.abortPipeEarly }; const isSchema = context.kind === "schema"; const message$1 = other?.message ?? context.message ?? /* @__PURE__ */ getSpecificMessage(context.reference, issue.lang) ?? (isSchema ? /* @__PURE__ */ getSchemaMessage(issue.lang) : null) ?? config$1.message ?? /* @__PURE__ */ getGlobalMessage(issue.lang); if (message$1 !== void 0) issue.message = typeof message$1 === "function" ? message$1(issue) : message$1; if (isSchema) dataset.typed = false; if (dataset.issues) dataset.issues.push(issue); else dataset.issues = [issue]; } /** * Returns the Standard Schema properties. * * @param context The schema context. * * @returns The Standard Schema properties. */ /* @__NO_SIDE_EFFECTS__ */ function _getStandardProps(context) { return { version: 1, vendor: "valibot", validate(value$1) { return context["~run"]({ value: value$1 }, /* @__PURE__ */ getGlobalConfig()); } }; } /** * Disallows inherited object properties and prevents object prototype * pollution by disallowing certain keys. * * @param object The object to check. * @param key The key to check. * * @returns Whether the key is allowed. * * @internal */ /* @__NO_SIDE_EFFECTS__ */ function _isValidObjectKey(object$1, key) { return Object.hasOwn(object$1, key) && key !== "__proto__" && key !== "prototype" && key !== "constructor"; } /** * Joins multiple `expects` values with the given separator. * * @param values The `expects` values. * @param separator The separator. * * @returns The joined `expects` property. * * @internal */ /* @__NO_SIDE_EFFECTS__ */ function _joinExpects(values$1, separator) { const list = [...new Set(values$1)]; if (list.length > 1) return `(${list.join(` ${separator} `)})`; return list[0] ?? "never"; } /** * A Valibot error with useful information. */ var ValiError = class extends Error { /** * Creates a Valibot error with useful information. * * @param issues The error issues. */ constructor(issues) { super(issues[0].message); this.name = "ValiError"; this.issues = issues; } }; /** * Returns the fallback value of the schema. * * @param schema The schema to get it from. * @param dataset The output dataset if available. * @param config The config if available. * * @returns The fallback value. */ /* @__NO_SIDE_EFFECTS__ */ function getFallback(schema, dataset, config$1) { return typeof schema.fallback === "function" ? schema.fallback(dataset, config$1) : schema.fallback; } /** * Returns the default value of the schema. * * @param schema The schema to get it from. * @param dataset The input dataset if available. * @param config The config if available. * * @returns The default value. */ /* @__NO_SIDE_EFFECTS__ */ function getDefault(schema, dataset, config$1) { return typeof schema.default === "function" ? schema.default(dataset, config$1) : schema.default; } /** * Creates an any schema. * * Hint: This schema function exists only for completeness and is not * recommended in practice. Instead, `unknown` should be used to accept * unknown data. * * @returns An any schema. */ /* @__NO_SIDE_EFFECTS__ */ function any() { return { kind: "schema", type: "any", reference: any, expects: "any", async: false, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset) { dataset.typed = true; return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function array(item, message$1) { return { kind: "schema", type: "array", reference: array, expects: "Array", async: false, item, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { const input = dataset.value; if (Array.isArray(input)) { dataset.typed = true; dataset.value = []; for (let key = 0; key < input.length; key++) { const value$1 = input[key]; const itemDataset = this.item["~run"]({ value: value$1 }, config$1); if (itemDataset.issues) { const pathItem = { type: "array", origin: "value", input, key, value: value$1 }; for (const issue of itemDataset.issues) { if (issue.path) issue.path.unshift(pathItem); else issue.path = [pathItem]; dataset.issues?.push(issue); } if (!dataset.issues) dataset.issues = itemDataset.issues; if (config$1.abortEarly) { dataset.typed = false; break; } } if (!itemDataset.typed) dataset.typed = false; dataset.value.push(itemDataset.value); } } else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function boolean(message$1) { return { kind: "schema", type: "boolean", reference: boolean, expects: "boolean", async: false, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { if (typeof dataset.value === "boolean") dataset.typed = true; else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function exactOptional(wrapped, default_) { return { kind: "schema", type: "exact_optional", reference: exactOptional, expects: wrapped.expects, async: false, wrapped, default: default_, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { return this.wrapped["~run"](dataset, config$1); } }; } /* @__NO_SIDE_EFFECTS__ */ function literal(literal_, message$1) { return { kind: "schema", type: "literal", reference: literal, expects: /* @__PURE__ */ _stringify(literal_), async: false, literal: literal_, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { if (dataset.value === this.literal) dataset.typed = true; else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function object(entries$1, message$1) { return { kind: "schema", type: "object", reference: object, expects: "Object", async: false, entries: entries$1, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { const input = dataset.value; if (input && typeof input === "object") { dataset.typed = true; dataset.value = {}; for (const key in this.entries) { const valueSchema = this.entries[key]; if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) { const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault(valueSchema); const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1); if (valueDataset.issues) { const pathItem = { type: "object", origin: "value", input, key, value: value$1 }; for (const issue of valueDataset.issues) { if (issue.path) issue.path.unshift(pathItem); else issue.path = [pathItem]; dataset.issues?.push(issue); } if (!dataset.issues) dataset.issues = valueDataset.issues; if (config$1.abortEarly) { dataset.typed = false; break; } } if (!valueDataset.typed) dataset.typed = false; dataset.value[key] = valueDataset.value; } else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback(valueSchema); else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") { _addIssue(this, "key", dataset, config$1, { input: void 0, expected: `"${key}"`, path: [{ type: "object", origin: "key", input, key, value: input[key] }] }); if (config$1.abortEarly) break; } } } else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function optional(wrapped, default_) { return { kind: "schema", type: "optional", reference: optional, expects: `(${wrapped.expects} | undefined)`, async: false, wrapped, default: default_, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { if (dataset.value === void 0) { if (this.default !== void 0) dataset.value = /* @__PURE__ */ getDefault(this, dataset, config$1); if (dataset.value === void 0) { dataset.typed = true; return dataset; } } return this.wrapped["~run"](dataset, config$1); } }; } /* @__NO_SIDE_EFFECTS__ */ function record(key, value$1, message$1) { return { kind: "schema", type: "record", reference: record, expects: "Object", async: false, key, value: value$1, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { const input = dataset.value; if (input && typeof input === "object") { dataset.typed = true; dataset.value = {}; for (const entryKey in input) if (/* @__PURE__ */ _isValidObjectKey(input, entryKey)) { const entryValue = input[entryKey]; const keyDataset = this.key["~run"]({ value: entryKey }, config$1); if (keyDataset.issues) { const pathItem = { type: "object", origin: "key", input, key: entryKey, value: entryValue }; for (const issue of keyDataset.issues) { issue.path = [pathItem]; dataset.issues?.push(issue); } if (!dataset.issues) dataset.issues = keyDataset.issues; if (config$1.abortEarly) { dataset.typed = false; break; } } const valueDataset = this.value["~run"]({ value: entryValue }, config$1); if (valueDataset.issues) { const pathItem = { type: "object", origin: "value", input, key: entryKey, value: entryValue }; for (const issue of valueDataset.issues) { if (issue.path) issue.path.unshift(pathItem); else issue.path = [pathItem]; dataset.issues?.push(issue); } if (!dataset.issues) dataset.issues = valueDataset.issues; if (config$1.abortEarly) { dataset.typed = false; break; } } if (!keyDataset.typed || !valueDataset.typed) dataset.typed = false; if (keyDataset.typed) dataset.value[keyDataset.value] = valueDataset.value; } } else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function strictObject$1(entries$1, message$1) { return { kind: "schema", type: "strict_object", reference: strictObject$1, expects: "Object", async: false, entries: entries$1, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { const input = dataset.value; if (input && typeof input === "object") { dataset.typed = true; dataset.value = {}; for (const key in this.entries) { const valueSchema = this.entries[key]; if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) { const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault(valueSchema); const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1); if (valueDataset.issues) { const pathItem = { type: "object", origin: "value", input, key, value: value$1 }; for (const issue of valueDataset.issues) { if (issue.path) issue.path.unshift(pathItem); else issue.path = [pathItem]; dataset.issues?.push(issue); } if (!dataset.issues) dataset.issues = valueDataset.issues; if (config$1.abortEarly) { dataset.typed = false; break; } } if (!valueDataset.typed) dataset.typed = false; dataset.value[key] = valueDataset.value; } else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback(valueSchema); else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") { _addIssue(this, "key", dataset, config$1, { input: void 0, expected: `"${key}"`, path: [{ type: "object", origin: "key", input, key, value: input[key] }] }); if (config$1.abortEarly) break; } } if (!dataset.issues || !config$1.abortEarly) { for (const key in input) if (!(key in this.entries)) { _addIssue(this, "key", dataset, config$1, { input: key, expected: "never", path: [{ type: "object", origin: "key", input, key, value: input[key] }] }); break; } } } else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /* @__NO_SIDE_EFFECTS__ */ function string(message$1) { return { kind: "schema", type: "string", reference: string, expects: "string", async: false, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { if (typeof dataset.value === "string") dataset.typed = true; else _addIssue(this, "type", dataset, config$1); return dataset; } }; } /** * Returns the sub issues of the provided datasets for the union issue. * * @param datasets The datasets. * * @returns The sub issues. * * @internal */ /* @__NO_SIDE_EFFECTS__ */ function _subIssues(datasets) { let issues; if (datasets) for (const dataset of datasets) if (issues) issues.push(...dataset.issues); else issues = dataset.issues; return issues; } /* @__NO_SIDE_EFFECTS__ */ function union(options, message$1) { return { kind: "schema", type: "union", reference: union, expects: /* @__PURE__ */ _joinExpects(options.map((option) => option.expects), "|"), async: false, options, message: message$1, get "~standard"() { return /* @__PURE__ */ _getStandardProps(this); }, "~run"(dataset, config$1) { let validDataset; let typedDatasets; let untypedDatasets; for (const schema of this.options) { const optionDataset = schema["~run"]({ value: dataset.value }, config$1); if (optionDataset.typed) if (optionDataset.issues) if (typedDatasets) typedDatasets.push(optionDataset); else typedDatasets = [optionDataset]; else { validDataset = optionDataset; break; } else if (untypedDatasets) untypedDatasets.push(optionDataset); else untypedDatasets = [optionDataset]; } if (validDataset) return validDataset; if (typedDatasets) { if (typedDatasets.length === 1) return typedDatasets[0]; _addIssue(this, "type", dataset, config$1, { issues: /* @__PURE__ */ _subIssues(typedDatasets) }); dataset.typed = true; } else if (untypedDatasets?.length === 1) return untypedDatasets[0]; else _addIssue(this, "type", dataset, config$1, { issues: /* @__PURE__ */ _subIssues(untypedDatasets) }); return dataset; } }; } /** * Parses an unknown input based on a schema. * * @param schema The schema to be used. * @param input The input to be parsed. * @param config The parse configuration. * * @returns The parsed input. */ function parse(schema, input, config$1) { const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1)); if (dataset.issues) throw new ValiError(dataset.issues); return dataset.value; } /** * Parses an unknown input based on a schema. * * @param schema The schema to be used. * @param input The input to be parsed. * @param config The parse configuration. * * @returns The parse result. */ /* @__NO_SIDE_EFFECTS__ */ function safeParse(schema, input, config$1) { const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1)); return { typed: dataset.typed, success: !dataset.issues, output: dataset.value, issues: dataset.issues }; } //#endregion //#region src/schema.ts const baseBoolSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())) })]), true); const tsPresets = /* @__PURE__ */ union([ /* @__PURE__ */ literal("recommended"), /* @__PURE__ */ literal("strict"), /* @__PURE__ */ literal("recommendedTypeChecked"), /* @__PURE__ */ literal("strictTypeChecked"), /* @__PURE__ */ literal("all") ]); const isInEditorSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ boolean(), isInEditorEnv()); const typescriptSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), preset: /* @__PURE__ */ exactOptional(tsPresets, "recommended"), projectService: /* @__PURE__ */ exactOptional(/* @__PURE__ */ boolean()), tsconfigRootDir: /* @__PURE__ */ exactOptional(/* @__PURE__ */ string()) })]), hasPackage("typescript")); const vueSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), a11y: /* @__PURE__ */ exactOptional(/* @__PURE__ */ boolean()) })]), hasPackage("vue") || hasPackage("@vue/compat")); const perfectionistSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), import: /* @__PURE__ */ exactOptional(/* @__PURE__ */ boolean()), export: /* @__PURE__ */ exactOptional(/* @__PURE__ */ boolean()) })]), true); const autoImportsSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), src: /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ string(), /* @__PURE__ */ object({ globals: /* @__PURE__ */ record(/* @__PURE__ */ string(), /* @__PURE__ */ union([ /* @__PURE__ */ boolean(), /* @__PURE__ */ literal("off"), /* @__PURE__ */ literal("readable"), /* @__PURE__ */ literal("readonly"), /* @__PURE__ */ literal("writable"), /* @__PURE__ */ literal("writeable") ])) })])) })]), true); const stylisticSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), severity: /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ literal("error"), /* @__PURE__ */ literal("warn")])) })]), hasPackage("typescript")); const jsSchema = baseBoolSchema; const unicornSchema = baseBoolSchema; const jsonCSchema = baseBoolSchema; const antfuSchema = baseBoolSchema; const importsSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), plugin: /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ literal("import-lite"), /* @__PURE__ */ literal("import-x")]), "import-lite") })]), true); const testSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ runner: /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ literal("jest"), /* @__PURE__ */ literal("vitest")])), files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())) })]), hasPackage("jest") || hasPackage("vitest")); const gitignoreSchema = /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ sources: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), gitmodules: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())) })]), hasFile(".gitignore")); const optionsSchema = /* @__PURE__ */ strictObject$1({ ts: typescriptSchema, vue: vueSchema, autoimports: autoImportsSchema, perfectionist: perfectionistSchema, isInEditor: isInEditorSchema, stylistic: stylisticSchema, test: testSchema, pnpm: /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ files: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), enforceCatalog: /* @__PURE__ */ exactOptional(/* @__PURE__ */ boolean()) })])), gitignore: gitignoreSchema, ignore: /* @__PURE__ */ exactOptional(/* @__PURE__ */ union([/* @__PURE__ */ boolean(), /* @__PURE__ */ object({ ignore: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())), extendIgnore: /* @__PURE__ */ exactOptional(/* @__PURE__ */ array(/* @__PURE__ */ string())) })]), true), js: jsSchema, imports: importsSchema, unicorn: unicornSchema, json: jsonCSchema, antfu: antfuSchema }); function validateOptions(options) { return parse(optionsSchema, options); } const strictObject = /* @__PURE__ */ strictObject$1({}); function getFirstConfigType(maybeConfig) { if ((/* @__PURE__ */ safeParse(strictObject, maybeConfig)).success) return "options"; if ((/* @__PURE__ */ safeParse(optionsSchema, maybeConfig)).success) return "options"; return "config"; } //#endregion //#region src/builder.ts async function buildConfig(maybeOptions, ...userConfigs) { const maybeConfigType = getFirstConfigType(maybeOptions ?? {}); const vOptions = maybeConfigType === "options" ? validateOptions(maybeOptions ?? {}) : validateOptions({}); const configsToCompose = []; if (vOptions.js) configsToCompose.push(js(vOptions.js)); if (vOptions.gitignore) configsToCompose.push(gitignore(vOptions.gitignore)); if (vOptions.autoimports) configsToCompose.push(autoimports(vOptions.autoimports)); if (vOptions.ts) configsToCompose.push(typescript(vOptions.ts)); if (vOptions.vue) configsToCompose.push(vue(vOptions.vue, vOptions.ts)); if (vOptions.perfectionist) configsToCompose.push(perfectionist(vOptions.perfectionist)); if (vOptions.stylistic) configsToCompose.push(stylistic(vOptions.stylistic, vOptions.vue)); if (vOptions.imports) configsToCompose.push(imports(vOptions.imports)); if (vOptions.unicorn) configsToCompose.push(unicorn(vOptions.unicorn)); if (vOptions.ignore) configsToCompose.push(ignore(vOptions.ignore)); if (vOptions.test) configsToCompose.push(test(vOptions.test)); if (vOptions.antfu) configsToCompose.push(antfu(vOptions.antfu)); if (vOptions.pnpm === void 0 ? (await getPackageManager())?.name === "pnpm" : Boolean(vOptions.pnpm)) configsToCompose.push(pnpm(vOptions.pnpm)); if (maybeConfigType === "config" && maybeOptions) configsToCompose.push(maybeOptions); let composed = composer(await concat(...configsToCompose, ...userConfigs)); if (vOptions?.isInEditor ?? false) composed = composed.disableRulesFix([ "unused-imports/no-unused-imports", "test/no-only-tests", "prefer-const" ], { builtinRules: () => import(["eslint", "use-at-your-own-risk"].join("/")).then((r) => r.builtinRules) }); return composed; } //#endregion export { buildConfig as default };