eslint-config-vuetify
Version:
eslint config for vue.js projects
1,513 lines (1,471 loc) • 42.8 kB
JavaScript
import { composer, concat } from 'eslint-flat-config-utils';
import { i as interopDefault, l as loadAutoImports, a as assertPackage, h as hasFile, b as hasPackage, c as isInEditorEnv, g as getPackageManager } from './shared/eslint-config-vuetify.BwpRBrXw.mjs';
import gitignoreConfig from 'eslint-config-flat-gitignore';
import perfectionistPlugin from 'eslint-plugin-perfectionist';
import { plugin } 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';
import 'node:fs';
import 'node:path';
import '@clack/prompts';
import 'exsolve';
import 'kolorist';
import 'local-pkg';
import 'nypm';
import 'package-manager-detector';
import '@eslint/eslintrc';
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"
}
}
];
}
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"
];
function autoimports(options = true) {
const autoimports2 = loadAutoImports(options);
return {
name: "vuetfiy/autoimports",
files: [
GLOB_JS,
GLOB_TS,
GLOB_JSX,
GLOB_TSX
],
...autoimports2
};
}
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"
});
}
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");
}
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"
}
}
];
}
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
}
]
}
}
];
}
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",
[
"parent-type",
"sibling-type",
"index-type",
"internal-type"
],
"builtin",
"external",
"internal",
["parent", "sibling", "index"],
"side-effect",
"object",
"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
}
];
}
const hasWorkspace = hasFile("pnpm-workspace.yaml");
function pnpm(options = true) {
const enforceCatalog = typeof options === "object" ? options.enforceCatalog ?? false : false;
const packageJsonFiles = typeof options === "object" && options.files ? options.files : ["package.json", "**/package.json"];
return [
{
ignores: ["**/node_modules/**", "**/dist/**"],
files: packageJsonFiles,
languageOptions: { parser: jsoncParser },
name: "vuetify/pnpm/package-json",
plugins: { pnpm: plugin },
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: plugin },
rules: {
"pnpm/yaml-no-duplicate-catalog-item": "error",
"pnpm/yaml-no-unused-catalog-item": "error"
}
}
];
}
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 stylistic2 = [
{
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) {
stylistic2.push({
files: [GLOB_VUE],
name: "vuetify/stylistic/vue",
rules: { "@stylistic/indent": ["off"] }
});
}
return stylistic2;
}
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'));
const noOnlyTests = await interopDefault(import('eslint-plugin-no-only-tests'));
const config = [
{
files,
plugins: {
"vitest": vitestVendor,
"no-only-tests": noOnlyTests
},
rules: {
...vitestVendor.configs.recommended.rules,
"no-only-tests/no-only-tests": "error"
}
}
];
return config;
}
if (runner === "jest") {
await assertPackage("eslint-plugin-jest", "test: false");
const jestVendor = await interopDefault(import('eslint-plugin-jest'));
const noOnlyTests = await interopDefault(import('eslint-plugin-no-only-tests'));
const config = [
{
files,
plugins: {
"jest": jestVendor,
"no-only-tests": noOnlyTests
},
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 config;
}
return {};
}
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"],
// https://www.totaltypescript.com/method-shorthand-syntax-considered-harmful
"@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" }
}
];
}
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"
}
}
];
}
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 recommendedRules = vueVendor.configs["flat/recommended"].map((c) => c.rules).reduce((acc, c) => ({ ...acc, ...c }), {});
const rules = {
...recommendedRules,
"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/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");
const a11yVendor = await interopDefault(import('eslint-plugin-vuejs-accessibility'));
a11config = a11yVendor.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"
}
}
];
}
//#region src/storages/globalConfig/globalConfig.ts
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
};
}
//#endregion
//#region src/storages/globalMessage/globalMessage.ts
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);
}
//#endregion
//#region src/storages/schemaMessage/schemaMessage.ts
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);
}
//#endregion
//#region src/storages/specificMessage/specificMessage.ts
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);
}
//#endregion
//#region src/utils/_stringify/_stringify.ts
/**
* 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;
}
//#endregion
//#region src/utils/_addIssue/_addIssue.ts
/**
* 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];
}
//#endregion
//#region src/utils/_getStandardProps/_getStandardProps.ts
/**
* 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());
}
};
}
//#endregion
//#region src/utils/_isValidObjectKey/_isValidObjectKey.ts
/**
* 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";
}
//#endregion
//#region src/utils/_joinExpects/_joinExpects.ts
/**
* 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";
}
//#endregion
//#region src/utils/ValiError/ValiError.ts
/**
* 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;
}
};
//#endregion
//#region src/methods/getFallback/getFallback.ts
/**
* 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;
}
//#endregion
//#region src/methods/getDefault/getDefault.ts
/**
* 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;
}
//#endregion
//#region src/schemas/array/array.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/boolean/boolean.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/exactOptional/exactOptional.ts
/* @__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);
}
};
}
//#endregion
//#region src/schemas/literal/literal.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/object/object.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/record/record.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/strictObject/strictObject.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/string/string.ts
/* @__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;
}
};
}
//#endregion
//#region src/schemas/union/utils/_subIssues/_subIssues.ts
/**
* 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;
}
//#endregion
//#region src/schemas/union/union.ts
/* @__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;
}
};
}
//#endregion
//#region src/methods/parse/parse.ts
/**
* 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;
}
//#endregion
//#region src/methods/safeParse/safeParse.ts
/**
* 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
};
}
const baseBoolSchema = exactOptional(
union([boolean(), object({ files: exactOptional(array(string())) })]),
true
);
const tsPresets = union([
literal("recommended"),
literal("strict"),
literal("recommendedTypeChecked"),
literal("strictTypeChecked"),
literal("all")
]);
const isInEditorSchema = exactOptional(boolean(), isInEditorEnv());
const typescriptSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
preset: exactOptional(tsPresets, "recommended"),
projectService: exactOptional(boolean()),
tsconfigRootDir: exactOptional(string())
})
]),
hasPackage("typescript")
);
const vueSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
a11y: exactOptional(boolean())
})
]),
hasPackage("vue") || hasPackage("@vue/compat")
);
const perfectionistSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
import: exactOptional(boolean()),
export: exactOptional(boolean())
})
]),
true
);
const globalSchema = record(
string(),
union([
boolean(),
literal("off"),
literal("readable"),
literal("readonly"),
literal("writable"),
literal("writeable")
])
);
const autoImportsSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
src: exactOptional(union([string(), object({ globals: globalSchema })]))
})
]),
true
);
const stylisticSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
severity: exactOptional(union([literal("error"), literal("warn")]))
})
]),
hasPackage("typescript")
);
const jsSchema = baseBoolSchema;
const unicornSchema = baseBoolSchema;
const jsonCSchema = baseBoolSchema;
const antfuSchema = baseBoolSchema;
const importsSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
plugin: exactOptional(union([literal("import-lite"), literal("import-x")]), "import-lite")
})
]),
true
);
const testSchema = exactOptional(
union([
boolean(),
object({
runner: exactOptional(union([literal("jest"), literal("vitest")])),
files: exactOptional(array(string()))
})
]),
hasPackage("jest") || hasPackage("vitest")
);
const gitignoreSchema = exactOptional(
union([
boolean(),
object({
sources: exactOptional(array(string())),
gitmodules: exactOptional(array(string()))
})
]),
hasFile(".gitignore")
);
const pnpmSchema = exactOptional(
union([
boolean(),
object({
files: exactOptional(array(string())),
enforceCatalog: exactOptional(boolean())
})
])
);
const ignoreSchema = exactOptional(
union([
boolean(),
object({
ignore: exactOptional(array(string())),
extendIgnore: exactOptional(array(string()))
})
]),
true
);
const optionsSchema = strictObject$1({
ts: typescriptSchema,
vue: vueSchema,
autoimports: autoImportsSchema,
perfectionist: perfectionistSchema,
isInEditor: isInEditorSchema,
stylistic: stylisticSchema,
test: testSchema,
pnpm: pnpmSchema,
gitignore: gitignoreSchema,
ignore: ignoreSchema,
js: jsSchema,
imports: importsSchema,
unicorn: unicornSchema,
json: jsonCSchema,
antfu: antfuSchema
});
function validateOptions(options) {
return parse(optionsSchema, options);
}
const strictObject = strictObject$1({});
function getFirstConfigType(maybeConfig) {
if (safeParse(strictObject, maybeConfig).success) {
return "options";
}
if (safeParse(optionsSchema, maybeConfig).success) {
return "options";
}
return "config";
}
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));
}
const pnpmEnabled = vOptions.pnpm === void 0 ? (await getPackageManager())?.name === "pnpm" : Boolean(vOptions.pnpm);
if (pnpmEnabled) {
configsToCompose.push(pnpm(vOptions.pnpm));
}
if (maybeConfigType === "config" && maybeOptions) {
configsToCompose.push(maybeOptions);
}
let composed = composer(await concat(
...configsToCompose,
...userConfigs
));
const editorMode = vOptions?.isInEditor ?? false;
if (editorMode) {
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;
}
export { buildConfig as default };