boss-css 0.0.19 → 0.0.20

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.
@@ -1,11 +1,10 @@
1
- const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
1
+ const require_merge_index = require('../../merge/index.cjs');
2
2
  const require_ast = require('../utils/ast.cjs');
3
3
  const require_defaults = require('../utils/defaults.cjs');
4
4
  const require_format = require('../utils/format.cjs');
5
5
  const require_boss_classes = require('../utils/boss-classes.cjs');
6
6
  const require_order = require('../utils/order.cjs');
7
7
  const require_context = require('../utils/context.cjs');
8
- let boss_css_merge = require("boss-css/merge");
9
8
 
10
9
  //#region src/eslint-plugin/rules/format-classnames.js
11
10
  const RULE_NAME = "format-classnames";
@@ -37,7 +36,7 @@ const create = (context) => {
37
36
  ...context.options[0] || {}
38
37
  };
39
38
  const patterns = createPatterns(options);
40
- const merge = (0, boss_css_merge.createBossMerge)(options.merge || {});
39
+ const merge = require_merge_index.createBossMerge(options.merge || {});
41
40
  if (!sourceCode) return {};
42
41
  const reportLiteral = (literal) => {
43
42
  if (!literal || !literal.canFix) return;
@@ -1,10 +1,10 @@
1
+ import { createBossMerge } from "../../merge/index.mjs";
1
2
  import { collectClassLiteralsFromExpression, compilePatterns, getCalleeName, getJSXAttributeName, getLiteralInfo, matchesPattern } from "../utils/ast.mjs";
2
3
  import { DEFAULT_ATTRIBUTE_PATTERNS, DEFAULT_CALLEE_PATTERNS, DEFAULT_TAG_PATTERNS, DEFAULT_VARIABLE_PATTERNS } from "../utils/defaults.mjs";
3
4
  import { buildLiteralReplacement } from "../utils/format.mjs";
4
5
  import { splitClassList } from "../utils/boss-classes.mjs";
5
6
  import { sortTokens } from "../utils/order.mjs";
6
7
  import { getSourceCode } from "../utils/context.mjs";
7
- import { createBossMerge } from "boss-css/merge";
8
8
 
9
9
  //#region src/eslint-plugin/rules/format-classnames.js
10
10
  const RULE_NAME = "format-classnames";
@@ -5,8 +5,10 @@ const require_defaults = require('../utils/defaults.cjs');
5
5
  const RULE_NAME = "redundant-cx";
6
6
  const defaultOptions = {
7
7
  components: require_defaults.DEFAULT_COMPONENTS,
8
- callees: ["^cx$", "^\\$\\$\\.cx$"]
8
+ callees: null
9
9
  };
10
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
+ const getDefaultCalleePatterns = (components) => components.map((component) => `^${escapeRegExp(component)}\\.cx$`);
10
12
  const getCallExpression = (node) => {
11
13
  if (!node) return null;
12
14
  if (node.type === "ChainExpression") return getCallExpression(node.expression);
@@ -20,7 +22,7 @@ const create = (context) => {
20
22
  ...context.options[0] || {}
21
23
  };
22
24
  const componentSet = new Set(options.components);
23
- const calleePatterns = require_ast.compilePatterns(options.callees);
25
+ const calleePatterns = require_ast.compilePatterns(Array.isArray(options.callees) ? options.callees : getDefaultCalleePatterns(options.components));
24
26
  return { JSXOpeningElement(node) {
25
27
  const rootName = require_ast.getJSXRootName(node.name);
26
28
  if (!rootName || !componentSet.has(rootName)) return;
@@ -5,8 +5,10 @@ import { DEFAULT_COMPONENTS } from "../utils/defaults.mjs";
5
5
  const RULE_NAME = "redundant-cx";
6
6
  const defaultOptions = {
7
7
  components: DEFAULT_COMPONENTS,
8
- callees: ["^cx$", "^\\$\\$\\.cx$"]
8
+ callees: null
9
9
  };
10
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
+ const getDefaultCalleePatterns = (components) => components.map((component) => `^${escapeRegExp(component)}\\.cx$`);
10
12
  const getCallExpression = (node) => {
11
13
  if (!node) return null;
12
14
  if (node.type === "ChainExpression") return getCallExpression(node.expression);
@@ -20,7 +22,7 @@ const create = (context) => {
20
22
  ...context.options[0] || {}
21
23
  };
22
24
  const componentSet = new Set(options.components);
23
- const calleePatterns = compilePatterns(options.callees);
25
+ const calleePatterns = compilePatterns(Array.isArray(options.callees) ? options.callees : getDefaultCalleePatterns(options.components));
24
26
  return { JSXOpeningElement(node) {
25
27
  const rootName = getJSXRootName(node.name);
26
28
  if (!rootName || !componentSet.has(rootName)) return;
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ let ts_deepmerge = require("ts-deepmerge");
2
3
  let _boss_css_is_css_prop = require("@boss-css/is-css-prop");
3
4
  _boss_css_is_css_prop = require_rolldown_runtime.__toESM(_boss_css_is_css_prop);
4
- let ts_deepmerge = require("ts-deepmerge");
5
5
 
6
6
  //#region src/merge/index.ts
7
7
  const cssPropCache = /* @__PURE__ */ new Map();
@@ -1,5 +1,5 @@
1
- import isCSSProp from "@boss-css/is-css-prop";
2
1
  import { merge as merge$1 } from "ts-deepmerge";
2
+ import isCSSProp from "@boss-css/is-css-prop";
3
3
 
4
4
  //#region src/merge/index.ts
5
5
  const cssPropCache = /* @__PURE__ */ new Map();
@@ -25,28 +25,62 @@ const onParse = async (api, input) => {
25
25
  });
26
26
  }
27
27
  };
28
- const templateRegexp = /`([\S\s]+?)`/g;
29
- const quoteRegexps = [
30
- /"(.+?)"/g,
31
- /'(.+?)'/g,
32
- templateRegexp
33
- ];
34
28
  const extractCode = (content) => {
35
29
  const results = [];
36
- for (const regexp of quoteRegexps) {
37
- const matches = content.matchAll(regexp);
38
- const isTemplate = regexp === templateRegexp;
39
- for (const match of matches) {
40
- const [, code] = match;
41
- if (isTemplate && code.includes("${")) {
30
+ [
31
+ "\"",
32
+ "'",
33
+ "`"
34
+ ].forEach((quote) => {
35
+ scanQuotedSegments(content, quote, ({ value, hasTemplateExpression }) => {
36
+ if (quote === "`" && hasTemplateExpression) {
42
37
  console.warn("[boss-css] classname parser skipped template literals with expressions. Classnames must be static.");
43
- console.warn(code);
38
+ console.warn(value);
39
+ return;
40
+ }
41
+ results.push(value);
42
+ });
43
+ });
44
+ return { codes: results };
45
+ };
46
+ const scanQuotedSegments = (input, quote, onSegment) => {
47
+ let index = 0;
48
+ const length = input.length;
49
+ while (index < length) {
50
+ if (input[index] !== quote) {
51
+ index += 1;
52
+ continue;
53
+ }
54
+ index += 1;
55
+ let value = "";
56
+ let escaped = false;
57
+ let hasTemplateExpression = false;
58
+ while (index < length) {
59
+ const current = input[index];
60
+ if (escaped) {
61
+ value += current;
62
+ escaped = false;
63
+ index += 1;
64
+ continue;
65
+ }
66
+ if (current === "\\") {
67
+ value += current;
68
+ escaped = true;
69
+ index += 1;
44
70
  continue;
45
71
  }
46
- results.push(code);
72
+ if (quote === "`" && current === "$" && input[index + 1] === "{") hasTemplateExpression = true;
73
+ if (current === quote) break;
74
+ value += current;
75
+ index += 1;
47
76
  }
77
+ if (index >= length) break;
78
+ onSegment({
79
+ value,
80
+ hasTemplateExpression
81
+ });
82
+ index += 1;
48
83
  }
49
- return { codes: results };
50
84
  };
51
85
  const extractPropTree = async (string, api) => {
52
86
  const tree = {};
@@ -25,28 +25,62 @@ const onParse = async (api, input) => {
25
25
  });
26
26
  }
27
27
  };
28
- const templateRegexp = /`([\S\s]+?)`/g;
29
- const quoteRegexps = [
30
- /"(.+?)"/g,
31
- /'(.+?)'/g,
32
- templateRegexp
33
- ];
34
28
  const extractCode = (content) => {
35
29
  const results = [];
36
- for (const regexp of quoteRegexps) {
37
- const matches = content.matchAll(regexp);
38
- const isTemplate = regexp === templateRegexp;
39
- for (const match of matches) {
40
- const [, code] = match;
41
- if (isTemplate && code.includes("${")) {
30
+ [
31
+ "\"",
32
+ "'",
33
+ "`"
34
+ ].forEach((quote) => {
35
+ scanQuotedSegments(content, quote, ({ value, hasTemplateExpression }) => {
36
+ if (quote === "`" && hasTemplateExpression) {
42
37
  console.warn("[boss-css] classname parser skipped template literals with expressions. Classnames must be static.");
43
- console.warn(code);
38
+ console.warn(value);
39
+ return;
40
+ }
41
+ results.push(value);
42
+ });
43
+ });
44
+ return { codes: results };
45
+ };
46
+ const scanQuotedSegments = (input, quote, onSegment) => {
47
+ let index = 0;
48
+ const length = input.length;
49
+ while (index < length) {
50
+ if (input[index] !== quote) {
51
+ index += 1;
52
+ continue;
53
+ }
54
+ index += 1;
55
+ let value = "";
56
+ let escaped = false;
57
+ let hasTemplateExpression = false;
58
+ while (index < length) {
59
+ const current = input[index];
60
+ if (escaped) {
61
+ value += current;
62
+ escaped = false;
63
+ index += 1;
64
+ continue;
65
+ }
66
+ if (current === "\\") {
67
+ value += current;
68
+ escaped = true;
69
+ index += 1;
44
70
  continue;
45
71
  }
46
- results.push(code);
72
+ if (quote === "`" && current === "$" && input[index + 1] === "{") hasTemplateExpression = true;
73
+ if (current === quote) break;
74
+ value += current;
75
+ index += 1;
47
76
  }
77
+ if (index >= length) break;
78
+ onSegment({
79
+ value,
80
+ hasTemplateExpression
81
+ });
82
+ index += 1;
48
83
  }
49
- return { codes: results };
50
84
  };
51
85
  const extractPropTree = async (string, api) => {
52
86
  const tree = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boss-css",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Polymorphic, usage-driven CSS-in-JS.",
5
5
  "bin": {
6
6
  "boss": "./dist/cli/index.cjs",