@icebreakers/eslint-config 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -179,8 +179,8 @@ const MDX_PACKAGES = ["eslint-plugin-mdx"];
179
179
  const VUE_A11Y_PACKAGES = ["eslint-plugin-vuejs-accessibility"];
180
180
  const REACT_A11Y_PACKAGES = ["eslint-plugin-jsx-a11y"];
181
181
  const QUERY_PACKAGES = ["@tanstack/eslint-plugin-query"];
182
- function resolveStylelintConfigLoader() {
183
- return import.meta.url.endsWith(".ts") ? new URL("./stylelint.ts", import.meta.url).href : new URL("./stylelint.js", import.meta.url).href;
182
+ function resolveStylelintConfigLoader(moduleUrl = import.meta.url) {
183
+ return moduleUrl.endsWith(".ts") ? new URL("./stylelint.ts", moduleUrl).href : new URL("./stylelint.js", moduleUrl).href;
184
184
  }
185
185
  function resolveTailwindPresets(option) {
186
186
  if (!option) return [];
@@ -284,8 +284,8 @@ function resolveQueryPresets(isEnabled) {
284
284
  return [(0, antfu_exports.interopDefault)(import("@tanstack/eslint-plugin-query")).then((pluginQuery) => pluginQuery.configs["flat/recommended"])];
285
285
  }
286
286
  //#endregion
287
- //#region ../../node_modules/.pnpm/defu@6.1.6/node_modules/defu/dist/defu.mjs
288
- function isPlainObject(value) {
287
+ //#region ../../node_modules/.pnpm/defu@6.1.7/node_modules/defu/dist/defu.mjs
288
+ function isPlainObject$1(value) {
289
289
  if (value === null || typeof value !== "object") return false;
290
290
  const prototype = Object.getPrototypeOf(value);
291
291
  if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) return false;
@@ -294,7 +294,7 @@ function isPlainObject(value) {
294
294
  return true;
295
295
  }
296
296
  function _defu(baseObject, defaults, namespace = ".", merger) {
297
- if (!isPlainObject(defaults)) return _defu(baseObject, {}, namespace, merger);
297
+ if (!isPlainObject$1(defaults)) return _defu(baseObject, {}, namespace, merger);
298
298
  const object = { ...defaults };
299
299
  for (const key of Object.keys(baseObject)) {
300
300
  if (key === "__proto__" || key === "constructor") continue;
@@ -302,7 +302,7 @@ function _defu(baseObject, defaults, namespace = ".", merger) {
302
302
  if (value === null || value === void 0) continue;
303
303
  if (merger && merger(object, key, value, namespace)) continue;
304
304
  if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
305
- else if (isPlainObject(value) && isPlainObject(object[key])) object[key] = _defu(value, object[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
305
+ else if (isPlainObject$1(value) && isPlainObject$1(object[key])) object[key] = _defu(value, object[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
306
306
  else object[key] = value;
307
307
  }
308
308
  return object;
@@ -398,13 +398,14 @@ function isPackageAvailable(name, paths) {
398
398
  }
399
399
  function getDefaultFormatterOptions(cwd = process.cwd()) {
400
400
  const hasXmlPlugin = isPackageAvailable("@prettier/plugin-xml", [ANTFU_PACKAGE_DIR]);
401
+ const hasSlidev = isPackageAvailable("@slidev/cli", [cwd]);
401
402
  return {
402
403
  astro: isPackageAvailable("prettier-plugin-astro", [ANTFU_PACKAGE_DIR]),
403
404
  css: true,
404
405
  graphql: true,
405
406
  html: true,
406
407
  markdown: true,
407
- slidev: isPackageAvailable("@slidev/cli", [cwd]),
408
+ slidev: hasSlidev,
408
409
  svg: hasXmlPlugin,
409
410
  xml: hasXmlPlugin
410
411
  };
@@ -474,11 +475,14 @@ function resolveFormattersOption(input, cwd = process.cwd()) {
474
475
  if (input === false) return false;
475
476
  const defaults = getDefaultFormatterOptions(cwd);
476
477
  const inferredEndOfLine = inferPrettierEndOfLineFromEditorConfig(cwd);
477
- const defaultsWithPrettier = inferredEndOfLine ? defu({ prettierOptions: { endOfLine: inferredEndOfLine } }, defaults) : defaults;
478
- if (input === void 0) return inferredEndOfLine ? defaultsWithPrettier : true;
479
- if (input === true) return defaultsWithPrettier;
480
- if (isObject(input)) return defu(input, defaultsWithPrettier);
481
- return defaultsWithPrettier;
478
+ const defaultsWithFormattingEngines = inferredEndOfLine ? defu({
479
+ oxfmtOptions: { endOfLine: inferredEndOfLine },
480
+ prettierOptions: { endOfLine: inferredEndOfLine }
481
+ }, defaults) : defaults;
482
+ if (input === void 0) return defaultsWithFormattingEngines;
483
+ if (input === true) return defaultsWithFormattingEngines;
484
+ if (isObject(input)) return defu(input, defaultsWithFormattingEngines);
485
+ return defaultsWithFormattingEngines;
482
486
  }
483
487
  function resolveUserOptions(options) {
484
488
  const resolved = defu({}, options ?? {}, BASE_DEFAULTS);
@@ -569,14 +573,74 @@ const OPTIONAL_ANTFU_FEATURE_PACKAGES = {
569
573
  "eslint-plugin-react-hooks",
570
574
  "eslint-plugin-react-refresh"
571
575
  ],
572
- nextjs: ["@next/eslint-plugin-next"]
576
+ nextjs: ["@next/eslint-plugin-next"],
577
+ unocss: ["@unocss/eslint-plugin"]
573
578
  };
579
+ function isPlainObject(value) {
580
+ return value !== null && Object.prototype.toString.call(value) === "[object Object]";
581
+ }
582
+ function cloneUserDefinedOptions(options) {
583
+ const { settings, ...restOptions } = options;
584
+ if (settings === void 0) return { ...restOptions };
585
+ return {
586
+ ...restOptions,
587
+ settings
588
+ };
589
+ }
590
+ function getSettingsRecord(settings) {
591
+ return isPlainObject(settings) ? settings : {};
592
+ }
593
+ function removeNamespacedSetting(options, namespace) {
594
+ if (!isPlainObject(options.settings)) return options;
595
+ const settings = getSettingsRecord(options.settings);
596
+ if (!(namespace in settings)) return options;
597
+ const { [namespace]: _unusedNamespace, ...restSettings } = settings;
598
+ const { settings: _settings, ...restOptions } = options;
599
+ if (Object.keys(restSettings).length === 0) return { ...restOptions };
600
+ return {
601
+ ...restOptions,
602
+ settings: restSettings
603
+ };
604
+ }
574
605
  function normalizeOptionalAntfuFeatures(options) {
575
- const normalized = { ...options };
606
+ const normalized = cloneUserDefinedOptions(options);
576
607
  if (normalized.react && !hasAllPackages([...OPTIONAL_ANTFU_FEATURE_PACKAGES.react])) normalized.react = false;
577
608
  if (normalized.nextjs && !hasAllPackages([...OPTIONAL_ANTFU_FEATURE_PACKAGES.nextjs])) normalized.nextjs = false;
609
+ if (normalized.unocss && !hasAllPackages([...OPTIONAL_ANTFU_FEATURE_PACKAGES.unocss])) {
610
+ normalized.unocss = false;
611
+ return removeNamespacedSetting(normalized, "unocss");
612
+ }
578
613
  return normalized;
579
614
  }
615
+ function mergeNamespacedSetting(options, namespace, value) {
616
+ const currentSettings = getSettingsRecord(options.settings);
617
+ const currentNamespaceSettings = isPlainObject(currentSettings[namespace]) ? currentSettings[namespace] : {};
618
+ return {
619
+ ...options,
620
+ settings: {
621
+ ...currentSettings,
622
+ [namespace]: {
623
+ ...currentNamespaceSettings,
624
+ ...value
625
+ }
626
+ }
627
+ };
628
+ }
629
+ function normalizeUnoCssOptions(options) {
630
+ if (!options.unocss || typeof options.unocss !== "object") return options;
631
+ const { configPath, ...unocssOptions } = options.unocss;
632
+ const { settings, ...restOptions } = options;
633
+ const normalized = settings === void 0 ? {
634
+ ...restOptions,
635
+ unocss: unocssOptions
636
+ } : {
637
+ ...restOptions,
638
+ settings,
639
+ unocss: unocssOptions
640
+ };
641
+ if (!configPath) return normalized;
642
+ return mergeNamespacedSetting(normalized, "unocss", { configPath });
643
+ }
580
644
  function hasGlobalIgnoreShape(config) {
581
645
  const keys = Object.keys(config).filter((key) => key !== "name");
582
646
  return keys.length === 1 && keys[0] === "ignores";
@@ -606,13 +670,70 @@ function normalizeUserConfig(userConfig) {
606
670
  const resolvedUserConfig = userConfig;
607
671
  return isComposer(resolvedUserConfig) ? resolvedUserConfig : normalizeResolvedUserConfig(resolvedUserConfig);
608
672
  }
673
+ function isFormatterOptionsObject(value) {
674
+ return !!value && typeof value === "object" && !Array.isArray(value);
675
+ }
676
+ function toOxfmtRuleEntry(options) {
677
+ return ["error", { ...options ?? {} }];
678
+ }
679
+ function normalizePrettierFormatterForAntfu(formatter) {
680
+ return formatter === "oxfmt" ? true : formatter;
681
+ }
682
+ function normalizeMarkdownFormatterForAntfu(formatter) {
683
+ return formatter === "oxfmt" ? true : formatter;
684
+ }
685
+ function toAntfuOptions(options) {
686
+ const { formatters, ...restOptions } = options;
687
+ if (!isFormatterOptionsObject(formatters)) return restOptions;
688
+ const { oxfmtOptions: _oxfmtOptions, css, html, markdown, graphql, ...restFormatters } = formatters;
689
+ return {
690
+ ...restOptions,
691
+ formatters: {
692
+ ...restFormatters,
693
+ ...css === void 0 ? {} : { css: normalizePrettierFormatterForAntfu(css) },
694
+ ...html === void 0 ? {} : { html: normalizePrettierFormatterForAntfu(html) },
695
+ ...markdown === void 0 ? {} : { markdown: normalizeMarkdownFormatterForAntfu(markdown) },
696
+ ...graphql === void 0 ? {} : { graphql: normalizePrettierFormatterForAntfu(graphql) }
697
+ }
698
+ };
699
+ }
700
+ function applyOxfmtFormatterOverrides(composer, formatters) {
701
+ if (!isFormatterOptionsObject(formatters)) return composer;
702
+ if (formatters.markdown === "oxfmt" && formatters.slidev) throw new Error("`formatters.markdown: \"oxfmt\"` cannot be combined with `formatters.slidev`.");
703
+ const oxfmtOptions = formatters.oxfmtOptions;
704
+ let nextComposer = composer;
705
+ if (formatters.css === "oxfmt") for (const name of [
706
+ "antfu/formatter/css",
707
+ "antfu/formatter/scss",
708
+ "antfu/formatter/less"
709
+ ]) nextComposer = nextComposer.override(name, { rules: {
710
+ "format/oxfmt": toOxfmtRuleEntry(oxfmtOptions),
711
+ "format/prettier": "off"
712
+ } });
713
+ if (formatters.html === "oxfmt") nextComposer = nextComposer.override("antfu/formatter/html", { rules: {
714
+ "format/oxfmt": toOxfmtRuleEntry(oxfmtOptions),
715
+ "format/prettier": "off"
716
+ } });
717
+ if (formatters.markdown === "oxfmt") nextComposer = nextComposer.override("antfu/formatter/markdown", { rules: {
718
+ "format/oxfmt": toOxfmtRuleEntry(oxfmtOptions),
719
+ "format/prettier": "off",
720
+ "format/dprint": "off"
721
+ } });
722
+ if (formatters.graphql === "oxfmt") nextComposer = nextComposer.override("antfu/formatter/graphql", { rules: {
723
+ "format/oxfmt": toOxfmtRuleEntry(oxfmtOptions),
724
+ "format/prettier": "off"
725
+ } });
726
+ return nextComposer;
727
+ }
609
728
  function icebreaker(options = {}, ...userConfigs) {
610
729
  const [resolved, ...presets] = getPresets(options);
611
- return (0, antfu_exports.antfu)(normalizeOptionalAntfuFeatures(resolved), ...presets, ...userConfigs.map(normalizeUserConfig));
730
+ const normalized = normalizeUnoCssOptions(normalizeOptionalAntfuFeatures(resolved));
731
+ return applyOxfmtFormatterOverrides((0, antfu_exports.antfu)(toAntfuOptions(normalized), ...presets, ...userConfigs.map(normalizeUserConfig)), normalized.formatters);
612
732
  }
613
733
  function icebreakerLegacy(options = {}, ...userConfigs) {
614
734
  const [resolved, ...presets] = getPresets(options, "legacy");
615
- return (0, antfu_exports.antfu)(normalizeOptionalAntfuFeatures(resolved), ...presets, ...userConfigs.map(normalizeUserConfig));
735
+ const normalized = normalizeUnoCssOptions(normalizeOptionalAntfuFeatures(resolved));
736
+ return applyOxfmtFormatterOverrides((0, antfu_exports.antfu)(toAntfuOptions(normalized), ...presets, ...userConfigs.map(normalizeUserConfig)), normalized.formatters);
616
737
  }
617
738
  //#endregion
618
739
  export { getPresets, icebreaker, icebreakerLegacy };
package/index.d.ts CHANGED
@@ -14,14 +14,21 @@ export interface TailwindcssOption {
14
14
  }
15
15
 
16
16
  export type TailwindcssConfig = boolean | TailwindcssOption
17
+ export interface UnocssOption {
18
+ configPath?: string
19
+ attributify?: boolean
20
+ strict?: boolean
21
+ }
22
+ export type UnocssConfig = boolean | UnocssOption
17
23
  export interface StylelintBridgeOption extends IcebreakerStylelintOptions {
18
24
  cwd?: string
19
25
  }
20
26
  export type StylelintBridgeConfig = boolean | StylelintBridgeOption
21
27
 
22
- export type UserDefinedOptions = OptionsConfig & TypedFlatConfigItem & {
28
+ export type UserDefinedOptions = Omit<OptionsConfig, 'unocss'> & TypedFlatConfigItem & {
23
29
  miniProgram?: boolean
24
30
  tailwindcss?: TailwindcssConfig
31
+ unocss?: UnocssConfig
25
32
  stylelint?: StylelintBridgeConfig
26
33
  mdx?: boolean
27
34
  a11y?: boolean
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icebreakers/eslint-config",
3
3
  "type": "module",
4
- "version": "4.0.0",
4
+ "version": "4.0.2",
5
5
  "description": "ESLint preset from Icebreaker's dev-configs",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -50,7 +50,7 @@
50
50
  }
51
51
  },
52
52
  "dependencies": {
53
- "@antfu/eslint-config": "8.0.0",
53
+ "@antfu/eslint-config": "8.1.0",
54
54
  "@eslint-react/eslint-plugin": "^3.0.0",
55
55
  "eslint-plugin-better-tailwindcss": "^4.3.2",
56
56
  "eslint-plugin-format": "2.0.1",
@@ -59,13 +59,13 @@
59
59
  "eslint-plugin-react-refresh": "^0.5.2",
60
60
  "eslint-plugin-tailwindcss": "3.18.2",
61
61
  "eslint-plugin-vuejs-accessibility": "^2.5.0",
62
- "@icebreakers/stylelint-config": "3.0.0",
62
+ "@icebreakers/stylelint-config": "3.0.2",
63
63
  "eslint-plugin-better-stylelint": "1.0.0"
64
64
  },
65
65
  "optionalDependencies": {
66
66
  "@next/eslint-plugin-next": "^16.2.2",
67
- "@tanstack/eslint-plugin-query": "^5.96.1",
68
- "@unocss/eslint-plugin": "66.6.7",
67
+ "@tanstack/eslint-plugin-query": "^5.96.2",
68
+ "@unocss/eslint-plugin": "66.6.8",
69
69
  "eslint-plugin-mdx": "3.7.0"
70
70
  },
71
71
  "publishConfig": {
@@ -91,6 +91,7 @@
91
91
  "scripts": {
92
92
  "dev": "tsdown --watch --sourcemap",
93
93
  "build": "tsdown",
94
+ "bench:formatters": "node --import tsx ./scripts/benchmark-formatters.ts",
94
95
  "test": "vitest run",
95
96
  "test:types": "tsd",
96
97
  "test:dev": "vitest",