mod compatibility;
mod compiler;
mod defaults;
mod entries;
mod experimentals;
mod features;
mod formatter;
mod sort_imports;
use formatter::RawFormatterConfig;
pub use sort_imports::{
ImportSortCustomGroup, ImportSortGroup, SortImportsConfig, SortImportsSetting,
};
mod global_types;
mod language_server;
mod library;
mod linter;
mod linter_execution;
mod linter_feature_flags;
mod linter_rule_options;
mod type_checker;
mod vue;
use self::{compiler::RawCompilerConfig, experimentals::RawExperimentalsConfig, vue::RawVueConfig};
use serde::{Deserialize, Serialize};
use crate::{String, dialect::VueDialect};
pub use compiler::{JsxCompat, JsxMode};
pub(crate) use entries::RawConfigEntry;
pub use entries::{
CompilerConfigEntry, ConfigEntryFiles, ConfigEntryIgnore, LinterConfigEntry, LinterConfigPlan,
LinterConfigPlanWithConfigRuleOptions, LinterConfigPlanWithRuleOptions, ResolvedLinterConfig,
ResolvedLinterConfigWithConfigRuleOptions,
};
pub use experimentals::ConfigExperimentalVueFlags;
pub use features::ConfigFeatureFlags;
pub use formatter::{
ArrowParens, AttributeSortOrder, EndOfLine, FormatterConfig, FormatterPreset, FormatterProfile,
QuoteProps, TrailingComma,
};
pub use global_types::{GlobalTypeDeclaration, GlobalTypesConfig, RawGlobalTypesConfig};
pub use language_server::{LanguageServerConfig, LanguageServerUnstableFlags, LspConfig};
pub use library::{LibConfig, LibRegistryConfig};
pub(crate) use linter::RawLinterConfig;
pub use linter::{LintRuleSeverity, LinterConfig};
pub use linter_execution::LinterExecutionOptions;
pub use linter_feature_flags::LinterFeatureFlags;
pub use linter_rule_options::{
ComponentNameInTemplateCasingOptions, ConfigLintRuleOptions, CustomEventNameCasing,
CustomEventNameCasingOptions, DefineMacrosOrderOptions, DefinePropsDestructuringOptions,
HtmlQuoteStyle, HtmlQuotesConfig, HtmlQuotesOptions, HtmlSelfClosingHtmlOptions,
HtmlSelfClosingOptions, HtmlSelfClosingStyle, HyphenationStyle, LintRuleOptions,
MuseaDesignToken, MuseaPreferDesignTokensOptions, MustacheInterpolationSpacingStyle,
NoMutatingPropsOptions, NoRestrictedGlobalsOptions, NoRestrictedMembersOptions,
PropsDestructureMode, RestrictedGlobal, RestrictedMember, SfcElementOrderGroup,
SfcElementOrderOptions, StrictBooleanExpressionsOptions, TemplateComponentNameCasing,
VBindStyle, VOnStyle, VSlotNamedStyle, VSlotStyle, VSlotStyleOptions, VSlotStyleValue,
VSlotUniformStyle,
};
pub use type_checker::TypeCheckerConfig;
pub use vue::{ParseVueVersionError, VueVersion};
#[derive(Debug, Clone, Default, Serialize)]
#[serde(default)]
pub struct VizeConfig {
#[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
pub schema: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dialect: Option<VueDialect>,
#[serde(skip_serializing_if = "FormatterConfig::is_default")]
pub formatter: FormatterConfig,
#[serde(
rename = "typeChecker",
skip_serializing_if = "TypeCheckerConfig::is_default"
)]
pub type_checker: TypeCheckerConfig,
#[serde(
rename = "languageServer",
skip_serializing_if = "LanguageServerConfig::is_default"
)]
pub language_server: LanguageServerConfig,
#[serde(
rename = "globalTypes",
skip_serializing_if = "GlobalTypesConfig::is_empty"
)]
pub global_types: GlobalTypesConfig,
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
pub(crate) struct RawVizeConfig {
#[serde(rename = "$schema")]
pub schema: Option<String>,
#[serde(
rename = "__vizeProjectRoot",
deserialize_with = "deserialize_project_root"
)]
pub project_root: Option<String>,
#[serde(rename = "basePath")]
pub base_path: Option<String>,
pub files: Option<Vec<String>>,
pub dialect: Option<VueDialect>,
pub formatter: RawFormatterConfig,
pub(crate) compiler: RawCompilerConfig,
pub(crate) compatibility: compatibility::RawCompatibilityConfig,
pub(crate) experimentals: RawExperimentalsConfig,
pub(crate) vue: RawVueConfig,
pub linter: RawLinterConfig,
#[serde(rename = "typeChecker")]
type_checker: RawTypeCheckerConfig,
#[serde(rename = "languageServer")]
language_server: RawLanguageServerConfig,
#[serde(rename = "globalTypes")]
pub global_types: RawGlobalTypesConfig,
pub(crate) lib: LibConfig,
pub ignores: Option<Vec<String>>,
pub entries: Option<Vec<RawConfigEntry>>,
#[serde(rename = "check")]
legacy_check: Option<LegacyCheckConfig>,
#[serde(rename = "fmt")]
legacy_formatter: Option<RawFormatterConfig>,
#[serde(rename = "lsp")]
legacy_lsp: Option<RawLanguageServerConfig>,
}
fn deserialize_project_root<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = serde_json::Value::deserialize(deserializer)?;
Ok(value.as_str().map(String::from))
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
struct RawTypeCheckerConfig {
#[serde(flatten)]
config: TypeCheckerConfig,
tsrs_path: Option<String>,
lsp_request_timeout_ms: Option<u64>,
options_api: Option<bool>,
legacy_vue2: bool,
jsx_typecheck: bool,
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default, rename_all = "camelCase")]
struct RawLanguageServerConfig {
#[serde(flatten)]
config: LanguageServerConfig,
legacy_vue2: Option<bool>,
signature_help: Option<bool>,
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
struct LegacyCheckConfig {
globals: Option<String>,
servers: Option<usize>,
}
impl RawVizeConfig {
pub(crate) fn formatter_ignore_patterns(&self) -> &[String] {
match &self.legacy_formatter {
Some(legacy) if self.formatter.is_unset() => &legacy.ignore_patterns,
_ => &self.formatter.ignore_patterns,
}
}
pub(crate) fn formatter_profile(&self) -> &FormatterProfile {
match &self.legacy_formatter {
Some(legacy) if self.formatter.is_unset() => &legacy.profile,
_ => &self.formatter.profile,
}
}
pub(crate) fn lsp_request_timeout_ms(&self) -> u64 {
self.type_checker
.lsp_request_timeout_ms
.unwrap_or(60_000)
.max(1)
}
pub(crate) fn language_server_unstable_flags(&self) -> LanguageServerUnstableFlags {
let raw = match self.legacy_lsp.as_ref() {
Some(legacy) if self.language_server.config == LanguageServerConfig::default() => {
legacy
}
_ => &self.language_server,
};
LanguageServerUnstableFlags {
signature_help: raw.signature_help,
}
}
pub(crate) fn into_config_and_features(self) -> (VizeConfig, ConfigFeatureFlags) {
let RawVizeConfig {
schema,
project_root: _,
base_path: _,
files: _,
dialect,
formatter,
compiler,
compatibility,
experimentals,
vue,
linter: _,
type_checker: raw_type_checker,
language_server: raw_language_server,
global_types,
lib: _,
ignores: _,
entries: _,
legacy_check,
legacy_formatter,
legacy_lsp,
} = self;
let type_checker_options_api = raw_type_checker.options_api.unwrap_or(true);
let vue_version = vue
.version
.or(compiler.compatibility.vue_version)
.or(compatibility.vue_version);
let type_checker_legacy_vue2 = raw_type_checker.legacy_vue2
|| matches!(vue_version, Some(VueVersion::V2 | VueVersion::V2_7));
let experimental_jsx_vapor = experimentals.jsx_vapor_enabled();
let type_checker_jsx_typecheck = raw_type_checker.jsx_typecheck || experimental_jsx_vapor;
let mut type_checker = raw_type_checker.config;
if type_checker.tsgo_path.is_none() {
type_checker.tsgo_path = raw_type_checker.tsrs_path;
}
if let Some(legacy_check) = legacy_check {
if type_checker.globals_file.is_none() {
type_checker.globals_file = legacy_check.globals;
}
if type_checker.servers.is_none() {
type_checker.servers = legacy_check.servers;
}
}
let formatter = match legacy_formatter {
Some(legacy) if formatter.is_unset() => legacy.config,
_ => formatter.config,
};
let language_server_raw = if raw_language_server.config == LanguageServerConfig::default() {
legacy_lsp.unwrap_or(raw_language_server)
} else {
raw_language_server
};
let language_server = language_server_raw.config;
let features = ConfigFeatureFlags {
type_checker_options_api,
type_checker_legacy_vue2,
type_checker_jsx_typecheck,
language_server_legacy_vue2: language_server_raw.legacy_vue2,
vue_version,
jsx_mode: compiler
.jsx_mode
.or_else(|| experimental_jsx_vapor.then_some(JsxMode::Vapor)),
jsx_compat: compiler.jsx_compat,
experimental_vapor: experimentals.vapor_enabled(),
experimental_jsx_vapor,
experimental_in_tag_comments: experimentals.in_tag_comments_enabled(),
experimental_patterned_template: experimentals.patterned_template_enabled(),
experimental_server_script: experimentals.server_script_enabled(),
};
let config = VizeConfig {
schema,
dialect,
formatter,
type_checker,
language_server,
global_types: global_types.into(),
};
(config, features)
}
}
impl From<RawVizeConfig> for VizeConfig {
fn from(raw: RawVizeConfig) -> Self {
raw.into_config_and_features().0
}
}