@servicetitan/stylelint-config 16.0.1 → 17.0.1

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.
@@ -18,7 +18,7 @@ const plugin = actual => {
18
18
  }
19
19
  root.walkDecls(decl => {
20
20
  functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => {
21
- const url = trim_1.default(args, ' \'"');
21
+ const url = (0, trim_1.default)(args, ' \'"');
22
22
  if (!isAbsoluteUrl(url)) {
23
23
  return;
24
24
  }
@@ -33,5 +33,5 @@ const plugin = actual => {
33
33
  });
34
34
  };
35
35
  };
36
- module.exports = Object.assign(stylelint_1.createPlugin(ruleName, plugin), { ruleName, messages });
36
+ module.exports = Object.assign((0, stylelint_1.createPlugin)(ruleName, plugin), { ruleName, messages });
37
37
  //# sourceMappingURL=function-url-no-absolute.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"function-url-no-absolute.js","sourceRoot":"","sources":["../src/function-url-no-absolute.ts"],"names":[],"mappings":";;;;AAAA,yCAAwD;AAExD,uDAA+B;AAE/B,MAAM,uBAAuB,GAAG,OAAO,CAAC,6CAA6C,CAI5E,CAAC;AAEV,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE7E,MAAM,QAAQ,GAAG,wCAAwC,CAAC;AAC1D,MAAM,QAAQ,GAAG,iBAAK,CAAC,YAAY,CAAC,QAAQ,EAAE;IAC1C,QAAQ,EAAE,yBAAyB;CACtC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAW,MAAM,CAAC,EAAE;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QACpB,MAAM,YAAY,GAAG,iBAAK,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,YAAY,EAAE;YACf,OAAO;SACV;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;YAClB,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAC1E,MAAM,GAAG,GAAG,cAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAE/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;oBACrB,OAAO;iBACV;gBAED,iBAAK,CAAC,MAAM,CAAC;oBACT,OAAO,EAAE,QAAQ,CAAC,QAAQ;oBAC1B,IAAI,EAAE,IAAI;oBACV,KAAK;oBACL,MAAM;oBACN,QAAQ;iBACX,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,iBAAS,MAAM,CAAC,MAAM,CAAC,wBAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"function-url-no-absolute.js","sourceRoot":"","sources":["../src/function-url-no-absolute.ts"],"names":[],"mappings":";;;;AAAA,yCAAwD;AAExD,uDAA+B;AAE/B,MAAM,uBAAuB,GAAG,OAAO,CAAC,6CAA6C,CAI5E,CAAC;AAEV,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE7E,MAAM,QAAQ,GAAG,wCAAwC,CAAC;AAC1D,MAAM,QAAQ,GAAG,iBAAK,CAAC,YAAY,CAAC,QAAQ,EAAE;IAC1C,QAAQ,EAAE,yBAAyB;CACtC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAW,MAAM,CAAC,EAAE;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QACpB,MAAM,YAAY,GAAG,iBAAK,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,YAAY,EAAE;YACf,OAAO;SACV;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;YAClB,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAC1E,MAAM,GAAG,GAAG,IAAA,cAAI,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAE/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;oBACrB,OAAO;iBACV;gBAED,iBAAK,CAAC,MAAM,CAAC;oBACT,OAAO,EAAE,QAAQ,CAAC,QAAQ;oBAC1B,IAAI,EAAE,IAAI;oBACV,KAAK;oBACL,MAAM;oBACN,QAAQ;iBACX,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,iBAAS,MAAM,CAAC,MAAM,CAAC,IAAA,wBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;;AAE1C,kBAa4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;;AAE1C,kBAc4B"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  module.exports = {
3
3
  extends: ['stylelint-config-recommended', 'stylelint-prettier/recommended'],
4
- plugins: ['./function-url-no-absolute'],
4
+ plugins: ['./function-url-no-absolute', './use-tokens'],
5
5
  rules: {
6
6
  'selector-pseudo-class-no-unknown': [
7
7
  true,
@@ -10,6 +10,7 @@ module.exports = {
10
10
  },
11
11
  ],
12
12
  '@servicetitan/function-url-no-absolute': true,
13
+ '@servicetitan/use-tokens': true,
13
14
  'no-invalid-position-at-import-rule': null, // Not supported for LESS/SASS. Enable for CSS when https://github.com/stylelint/stylelint/issues/3128 is implemented.
14
15
  },
15
16
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,iBAAS;IACL,OAAO,EAAE,CAAC,8BAA8B,EAAE,gCAAgC,CAAC;IAC3E,OAAO,EAAE,CAAC,4BAA4B,CAAC;IACvC,KAAK,EAAE;QACH,kCAAkC,EAAE;YAChC,IAAI;YACJ;gBACI,mBAAmB,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;aAC3C;SACJ;QACD,wCAAwC,EAAE,IAAI;QAC9C,oCAAoC,EAAE,IAAI,EAAE,sHAAsH;KACrK;CACsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,iBAAS;IACL,OAAO,EAAE,CAAC,8BAA8B,EAAE,gCAAgC,CAAC;IAC3E,OAAO,EAAE,CAAC,4BAA4B,EAAE,cAAc,CAAC;IACvD,KAAK,EAAE;QACH,kCAAkC,EAAE;YAChC,IAAI;YACJ;gBACI,mBAAmB,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;aAC3C;SACJ;QACD,wCAAwC,EAAE,IAAI;QAC9C,0BAA0B,EAAE,IAAI;QAChC,oCAAoC,EAAE,IAAI,EAAE,sHAAsH;KACrK;CACsB,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+ export = _default;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/use-tokens/index.ts"],"names":[],"mappings":";AAmKA,kBAAiG"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const stylelint_1 = require("stylelint");
6
+ const color_1 = __importDefault(require("color"));
7
+ const values_1 = require("./values");
8
+ const ruleName = '@servicetitan/use-tokens';
9
+ const messages = stylelint_1.utils.ruleMessages(ruleName, {
10
+ variableExpected: (expected, found) => `You should use "${expected}" variable from the \`@servicetitan/tokens\` instead of "${found}".`,
11
+ });
12
+ const plugin = (_0, _1, context) => {
13
+ return (root, result) => {
14
+ var _a, _b, _c;
15
+ const extension = (_c = (_b = (_a = result.opts) === null || _a === void 0 ? void 0 : _a.from) === null || _b === void 0 ? void 0 : _b.split('.').pop()) === null || _c === void 0 ? void 0 : _c.toLowerCase();
16
+ function convertToVariable(key) {
17
+ switch (extension) {
18
+ case 'less':
19
+ return `@${key}`;
20
+ case 'sass':
21
+ case 'scss':
22
+ return `$${key}`;
23
+ default:
24
+ return `var(--${key})`;
25
+ }
26
+ }
27
+ root.walkDecls(decl => {
28
+ function lint(collection, { condition, transformer, solid, } = {}) {
29
+ var _a;
30
+ if (condition && !condition(decl.prop)) {
31
+ return true;
32
+ }
33
+ const values = !solid ? decl.value.split(' ') : [decl.value];
34
+ let reported = false;
35
+ for (const rawValue of values) {
36
+ const value = (_a = transformer === null || transformer === void 0 ? void 0 : transformer(rawValue)) !== null && _a !== void 0 ? _a : rawValue;
37
+ if (collection[value]) {
38
+ const variable = convertToVariable(collection[value]);
39
+ if (context.fix) {
40
+ values[values.indexOf(rawValue)] = variable;
41
+ }
42
+ else {
43
+ stylelint_1.utils.report({
44
+ node: decl,
45
+ message: messages.variableExpected(variable, rawValue),
46
+ word: value,
47
+ ruleName,
48
+ result,
49
+ });
50
+ }
51
+ reported = true;
52
+ }
53
+ }
54
+ if (context.fix) {
55
+ decl.value = values.join(' ');
56
+ }
57
+ return !reported;
58
+ }
59
+ const linters = {
60
+ colors: () => lint(values_1.colors, {
61
+ transformer: value => {
62
+ try {
63
+ return new color_1.default(value).hex();
64
+ }
65
+ catch (_a) {
66
+ return '';
67
+ }
68
+ },
69
+ }),
70
+ typescales: () => lint(values_1.typescales, {
71
+ condition: property => property === 'font-size',
72
+ solid: true,
73
+ }),
74
+ borderRadiuses: () => lint(values_1.borderRadiuses, {
75
+ condition: property => property.startsWith('border-') && property.endsWith('-radius'),
76
+ transformer: value => (value === '0px' ? '0' : value),
77
+ }),
78
+ lintSpacings: () => lint(values_1.spacings, {
79
+ // other spacings like "top"?
80
+ condition: property => property.startsWith('margin') || property.startsWith('padding'),
81
+ transformer: value => value === '0px' ? '0' : value.startsWith('-') ? value.slice(1) : value,
82
+ }),
83
+ fontWeights: () => lint(values_1.fontWeights, {
84
+ condition: property => property === 'font-weight',
85
+ solid: true,
86
+ }),
87
+ opacities: () => lint(values_1.opacities, {
88
+ condition: property => property === 'opacity',
89
+ transformer: value => (value.startsWith('0.') ? value.slice(1) : value),
90
+ solid: true,
91
+ }),
92
+ zIndexes: () => lint(values_1.zIndexes, { condition: property => property === 'z-index', solid: true }),
93
+ lineHeights: () => lint(values_1.lineHeights, {
94
+ condition: property => property === 'line-height',
95
+ solid: true,
96
+ }),
97
+ fontFamilies: () => lint(values_1.fontFamilies, {
98
+ condition: property => property === 'font-family',
99
+ solid: true,
100
+ }),
101
+ };
102
+ for (const handler of Object.values(linters)) {
103
+ if (!handler()) {
104
+ return;
105
+ }
106
+ }
107
+ });
108
+ };
109
+ };
110
+ module.exports = Object.assign((0, stylelint_1.createPlugin)(ruleName, plugin), { ruleName, messages });
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/use-tokens/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const colors: Record<string, string>;
2
+ export declare const typescales: Record<string, string>;
3
+ export declare const borderRadiuses: Record<string, string>;
4
+ export declare const spacings: Record<string, string>;
5
+ export declare const fontWeights: Record<string, string>;
6
+ export declare const opacities: Record<string, string>;
7
+ export declare const zIndexes: Record<string, string>;
8
+ export declare const lineHeights: Record<string, string>;
9
+ export declare const fontFamilies: Record<string, string>;
10
+ //# sourceMappingURL=values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/use-tokens/values.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,MAAM,wBAGlB,CAAC;AACF,eAAO,MAAM,UAAU,wBAA0D,CAAC;AAClF,eAAO,MAAM,cAAc,wBAA6D,CAAC;AACzF,eAAO,MAAM,QAAQ,wBAAwD,CAAC;AAC9E,eAAO,MAAM,WAAW,wBAA2D,CAAC;AACpF,eAAO,MAAM,SAAS,wBAAwD,CAAC;AAC/E,eAAO,MAAM,QAAQ,wBAAuD,CAAC;AAC7E,eAAO,MAAM,WAAW,wBAAyD,CAAC;AAClF,eAAO,MAAM,YAAY,wBAGxB,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fontFamilies = exports.lineHeights = exports.zIndexes = exports.opacities = exports.fontWeights = exports.spacings = exports.borderRadiuses = exports.typescales = exports.colors = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const color_1 = __importDefault(require("color"));
9
+ const tokens_1 = __importDefault(require("@servicetitan/tokens"));
10
+ const toCamelCase = (str) => str.replace(/(-[a-z])/g, ([, letter]) => letter.toUpperCase());
11
+ const toSnakeCase = (str) => str.replace(/([A-Z]|[a-z][0-9])/g, ([letter, digit]) => digit === undefined ? `-${letter.toLowerCase()}` : `${letter}-${digit}`);
12
+ const aliases = fs_1.default
13
+ .readFileSync(require.resolve('@servicetitan/tokens/dist/tokens.less'), 'utf8')
14
+ .split('\n')
15
+ .filter(row => row.startsWith('@') && row.endsWith('(alias)'))
16
+ .map(row => toCamelCase(row.split(':')[0].slice(1)));
17
+ function getValues(condition, transformer) {
18
+ return Object.entries(tokens_1.default)
19
+ .filter(([variable]) => !aliases.includes(variable) && condition(variable))
20
+ .reduce((result, [variable, value]) => {
21
+ var _a;
22
+ return (Object.assign(Object.assign({}, result), { [(_a = transformer === null || transformer === void 0 ? void 0 : transformer(value)) !== null && _a !== void 0 ? _a : value]: toSnakeCase(variable) }));
23
+ }, {});
24
+ }
25
+ exports.colors = getValues(variable => variable.startsWith('color'), value => new color_1.default(value).hex());
26
+ exports.typescales = getValues(variable => variable.startsWith('typescale'));
27
+ exports.borderRadiuses = getValues(variable => variable.startsWith('borderRadius'));
28
+ exports.spacings = getValues(variable => variable.startsWith('spacing'));
29
+ exports.fontWeights = getValues(variable => variable.startsWith('fontWeight'));
30
+ exports.opacities = getValues(variable => variable.startsWith('opacity'));
31
+ exports.zIndexes = getValues(variable => variable.startsWith('zIndex'));
32
+ exports.lineHeights = getValues(variable => variable.endsWith('LineHeight'));
33
+ exports.fontFamilies = getValues(variable => variable.endsWith('FontFamily'), value => value.replace(/&#x27;/g, "'"));
34
+ //# sourceMappingURL=values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"values.js","sourceRoot":"","sources":["../../src/use-tokens/values.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/stylelint-config",
3
- "version": "16.0.1",
3
+ "version": "17.0.1",
4
4
  "description": "",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/eslint-stylelint-configurations",
6
6
  "repository": {
@@ -15,17 +15,21 @@
15
15
  "src"
16
16
  ],
17
17
  "dependencies": {
18
+ "color": "~4.0.1",
18
19
  "lodash": "~4.17.21",
19
20
  "stylelint-config-prettier": "~8.0.2",
20
21
  "stylelint-config-standard": "~22.0.0",
21
22
  "stylelint-prettier": "~1.2.0"
22
23
  },
23
24
  "devDependencies": {
24
- "@types/lodash": "~4.14.174",
25
+ "@servicetitan/tokens": "*",
26
+ "@types/color": "~3.0.2",
27
+ "@types/lodash": "~4.14.175",
25
28
  "@types/stylelint": "~13.13.2",
26
29
  "stylelint": "~13.13.1"
27
30
  },
28
31
  "peerDependencies": {
32
+ "@servicetitan/tokens": "*",
29
33
  "stylelint": "~13.13.1"
30
34
  },
31
35
  "publishConfig": {
@@ -34,5 +38,5 @@
34
38
  "cli": {
35
39
  "webpack": false
36
40
  },
37
- "gitHead": "43d6c7713ae09594d44e7d638d6b8399c5109a93"
41
+ "gitHead": "32b287da19c96ec114b90d9f27fdead809fe5d75"
38
42
  }
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@ import { Configuration } from 'stylelint';
2
2
 
3
3
  export = {
4
4
  extends: ['stylelint-config-recommended', 'stylelint-prettier/recommended'],
5
- plugins: ['./function-url-no-absolute'],
5
+ plugins: ['./function-url-no-absolute', './use-tokens'],
6
6
  rules: {
7
7
  'selector-pseudo-class-no-unknown': [
8
8
  true,
@@ -11,6 +11,7 @@ export = {
11
11
  },
12
12
  ],
13
13
  '@servicetitan/function-url-no-absolute': true,
14
+ '@servicetitan/use-tokens': true,
14
15
  'no-invalid-position-at-import-rule': null, // Not supported for LESS/SASS. Enable for CSS when https://github.com/stylelint/stylelint/issues/3128 is implemented.
15
16
  },
16
17
  } as Partial<Configuration>;
@@ -0,0 +1,164 @@
1
+ import { Plugin as OriginalPlugin, createPlugin, utils } from 'stylelint';
2
+
3
+ import Color from 'color';
4
+
5
+ import {
6
+ colors,
7
+ typescales,
8
+ borderRadiuses,
9
+ spacings,
10
+ fontWeights,
11
+ opacities,
12
+ zIndexes,
13
+ lineHeights,
14
+ fontFamilies,
15
+ } from './values';
16
+
17
+ type Plugin = (
18
+ ...args: [...Parameters<OriginalPlugin>, { fix: boolean }]
19
+ ) => ReturnType<OriginalPlugin>;
20
+
21
+ const ruleName = '@servicetitan/use-tokens';
22
+ const messages = utils.ruleMessages(ruleName, {
23
+ variableExpected: (expected: string, found: string) =>
24
+ `You should use "${expected}" variable from the \`@servicetitan/tokens\` instead of "${found}".`,
25
+ });
26
+
27
+ const plugin: Plugin = (_0, _1, context) => {
28
+ return (root, result) => {
29
+ const extension = result.opts?.from?.split('.').pop()?.toLowerCase();
30
+
31
+ function convertToVariable(key: string) {
32
+ switch (extension) {
33
+ case 'less':
34
+ return `@${key}`;
35
+
36
+ case 'sass':
37
+ case 'scss':
38
+ return `$${key}`;
39
+
40
+ default:
41
+ return `var(--${key})`;
42
+ }
43
+ }
44
+
45
+ root.walkDecls(decl => {
46
+ function lint(
47
+ collection: Record<string, string>,
48
+ {
49
+ condition,
50
+ transformer,
51
+ solid,
52
+ }: {
53
+ condition?: (property: string) => boolean;
54
+ transformer?: (value: string) => string;
55
+ solid?: boolean;
56
+ } = {}
57
+ ) {
58
+ if (condition && !condition(decl.prop)) {
59
+ return true;
60
+ }
61
+
62
+ const values = !solid ? decl.value.split(' ') : [decl.value];
63
+
64
+ let reported = false;
65
+ for (const rawValue of values) {
66
+ const value = transformer?.(rawValue) ?? rawValue;
67
+ if (collection[value]) {
68
+ const variable = convertToVariable(collection[value]);
69
+
70
+ if (context.fix) {
71
+ values[values.indexOf(rawValue)] = variable;
72
+ } else {
73
+ utils.report({
74
+ node: decl,
75
+ message: messages.variableExpected(variable, rawValue),
76
+ word: value,
77
+ ruleName,
78
+ result,
79
+ });
80
+ }
81
+ reported = true;
82
+ }
83
+ }
84
+
85
+ if (context.fix) {
86
+ decl.value = values.join(' ');
87
+ }
88
+
89
+ return !reported;
90
+ }
91
+
92
+ const linters = {
93
+ colors: () =>
94
+ lint(colors, {
95
+ transformer: value => {
96
+ try {
97
+ return new Color(value).hex();
98
+ } catch {
99
+ return '';
100
+ }
101
+ },
102
+ }),
103
+
104
+ typescales: () =>
105
+ lint(typescales, {
106
+ condition: property => property === 'font-size',
107
+ solid: true,
108
+ }),
109
+
110
+ borderRadiuses: () =>
111
+ lint(borderRadiuses, {
112
+ condition: property =>
113
+ property.startsWith('border-') && property.endsWith('-radius'),
114
+ transformer: value => (value === '0px' ? '0' : value),
115
+ }),
116
+
117
+ lintSpacings: () =>
118
+ lint(spacings, {
119
+ // other spacings like "top"?
120
+ condition: property =>
121
+ property.startsWith('margin') || property.startsWith('padding'),
122
+ transformer: value =>
123
+ value === '0px' ? '0' : value.startsWith('-') ? value.slice(1) : value,
124
+ }),
125
+
126
+ fontWeights: () =>
127
+ lint(fontWeights, {
128
+ condition: property => property === 'font-weight',
129
+ solid: true,
130
+ }),
131
+
132
+ opacities: () =>
133
+ lint(opacities, {
134
+ condition: property => property === 'opacity',
135
+ transformer: value => (value.startsWith('0.') ? value.slice(1) : value),
136
+ solid: true,
137
+ }),
138
+
139
+ zIndexes: () =>
140
+ lint(zIndexes, { condition: property => property === 'z-index', solid: true }),
141
+
142
+ lineHeights: () =>
143
+ lint(lineHeights, {
144
+ condition: property => property === 'line-height',
145
+ solid: true,
146
+ }),
147
+
148
+ fontFamilies: () =>
149
+ lint(fontFamilies, {
150
+ condition: property => property === 'font-family',
151
+ solid: true,
152
+ }),
153
+ };
154
+
155
+ for (const handler of Object.values(linters)) {
156
+ if (!handler()) {
157
+ return;
158
+ }
159
+ }
160
+ });
161
+ };
162
+ };
163
+
164
+ export = Object.assign(createPlugin(ruleName, plugin as OriginalPlugin), { ruleName, messages });
@@ -0,0 +1,48 @@
1
+ import fs from 'fs';
2
+
3
+ import Color from 'color';
4
+
5
+ import tokens from '@servicetitan/tokens';
6
+
7
+ const toCamelCase = (str: string) => str.replace(/(-[a-z])/g, ([, letter]) => letter.toUpperCase());
8
+ const toSnakeCase = (str: string) =>
9
+ str.replace(/([A-Z]|[a-z][0-9])/g, ([letter, digit]) =>
10
+ digit === undefined ? `-${letter.toLowerCase()}` : `${letter}-${digit}`
11
+ );
12
+
13
+ const aliases = fs
14
+ .readFileSync(require.resolve('@servicetitan/tokens/dist/tokens.less'), 'utf8')
15
+ .split('\n')
16
+ .filter(row => row.startsWith('@') && row.endsWith('(alias)'))
17
+ .map(row => toCamelCase(row.split(':')[0].slice(1)));
18
+
19
+ function getValues(
20
+ condition: (variable: string) => boolean,
21
+ transformer?: (value: string) => string
22
+ ) {
23
+ return Object.entries(tokens)
24
+ .filter(([variable]) => !aliases.includes(variable) && condition(variable))
25
+ .reduce<Record<string, string>>(
26
+ (result, [variable, value]) => ({
27
+ ...result,
28
+ [transformer?.(value) ?? value]: toSnakeCase(variable),
29
+ }),
30
+ {}
31
+ );
32
+ }
33
+
34
+ export const colors = getValues(
35
+ variable => variable.startsWith('color'),
36
+ value => new Color(value).hex()
37
+ );
38
+ export const typescales = getValues(variable => variable.startsWith('typescale'));
39
+ export const borderRadiuses = getValues(variable => variable.startsWith('borderRadius'));
40
+ export const spacings = getValues(variable => variable.startsWith('spacing'));
41
+ export const fontWeights = getValues(variable => variable.startsWith('fontWeight'));
42
+ export const opacities = getValues(variable => variable.startsWith('opacity'));
43
+ export const zIndexes = getValues(variable => variable.startsWith('zIndex'));
44
+ export const lineHeights = getValues(variable => variable.endsWith('LineHeight'));
45
+ export const fontFamilies = getValues(
46
+ variable => variable.endsWith('FontFamily'),
47
+ value => value.replace(/&#x27;/g, "'")
48
+ );