style-dictionary 4.1.2 → 4.1.3

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.
Files changed (26) hide show
  1. package/examples/advanced/assets-base64-embed/package.json +1 -1
  2. package/examples/advanced/create-react-app/package.json +1 -1
  3. package/examples/advanced/create-react-native-app/package.json +1 -1
  4. package/examples/advanced/custom-parser/package.json +1 -1
  5. package/examples/advanced/custom-transforms/package.json +1 -1
  6. package/examples/advanced/font-face-rules/package.json +1 -1
  7. package/examples/advanced/format-helpers/package.json +1 -1
  8. package/examples/advanced/matching-build-files/package.json +1 -1
  9. package/examples/advanced/multi-brand-multi-platform/package.json +1 -1
  10. package/examples/advanced/node-modules-as-config-and-properties/package.json +1 -1
  11. package/examples/advanced/npm-module/package.json +1 -1
  12. package/examples/advanced/referencing_aliasing/package.json +1 -1
  13. package/examples/advanced/s3/package.json +1 -1
  14. package/examples/advanced/tokens-deprecation/package.json +1 -1
  15. package/examples/advanced/transitive-transforms/package.json +1 -1
  16. package/examples/advanced/variables-in-outputs/package.json +1 -1
  17. package/examples/advanced/yaml-tokens/package.json +1 -1
  18. package/lib/StyleDictionary.js +1 -1
  19. package/lib/common/formatHelpers/fileHeader.js +1 -1
  20. package/lib/common/formatHelpers/formattedVariables.js +1 -1
  21. package/lib/common/formatHelpers/sortByReference.d.ts +3 -6
  22. package/lib/common/formatHelpers/sortByReference.js +44 -45
  23. package/lib/common/formats.js +4 -4
  24. package/lib/filterTokens.js +17 -15
  25. package/package.json +1 -1
  26. package/types/File.d.ts +1 -1
@@ -12,6 +12,6 @@
12
12
  "author": "",
13
13
  "license": "Apache-2.0",
14
14
  "devDependencies": {
15
- "style-dictionary": "^4.1.2"
15
+ "style-dictionary": "^4.1.3"
16
16
  }
17
17
  }
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "devDependencies": {
14
14
  "eslint-config-react-app": "^7.0.1",
15
- "style-dictionary": "^4.1.2"
15
+ "style-dictionary": "^4.1.3"
16
16
  },
17
17
  "resolutions": {
18
18
  "immer": "8.0.1",
@@ -29,7 +29,7 @@
29
29
  "eslint-config-react-app": "^7.0.1",
30
30
  "jest": "~25.2.6",
31
31
  "react-test-renderer": "~16.13.1",
32
- "style-dictionary": "^4.1.2"
32
+ "style-dictionary": "^4.1.3"
33
33
  },
34
34
  "jest": {
35
35
  "preset": "react-native"
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
13
- "style-dictionary": "^4.1.2"
13
+ "style-dictionary": "^4.1.3"
14
14
  }
15
15
  }
@@ -16,6 +16,6 @@
16
16
  "author": "",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
- "style-dictionary": "^4.1.2"
19
+ "style-dictionary": "^4.1.3"
20
20
  }
21
21
  }
@@ -9,6 +9,6 @@
9
9
  },
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
- "style-dictionary": "^4.1.2"
12
+ "style-dictionary": "^4.1.3"
13
13
  }
14
14
  }
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
13
- "style-dictionary": "^4.1.2"
13
+ "style-dictionary": "^4.1.3"
14
14
  }
15
15
  }
@@ -17,6 +17,6 @@
17
17
  "author": "Kelly Harrop <kn.harrop@gmail.com>",
18
18
  "license": "Apache-2.0",
19
19
  "devDependencies": {
20
- "style-dictionary": "^4.1.2"
20
+ "style-dictionary": "^4.1.3"
21
21
  }
22
22
  }
@@ -16,6 +16,6 @@
16
16
  "author": "",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
- "style-dictionary": "^4.1.2"
19
+ "style-dictionary": "^4.1.3"
20
20
  }
21
21
  }
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "homepage": "https://github.com/dbanksdesign/style-dictionary-node#readme",
22
22
  "devDependencies": {
23
- "style-dictionary": "^4.1.2",
23
+ "style-dictionary": "^4.1.3",
24
24
  "tinycolor2": "^1.4.1"
25
25
  }
26
26
  }
@@ -17,6 +17,6 @@
17
17
  "author": "",
18
18
  "license": "Apache-2.0",
19
19
  "devDependencies": {
20
- "style-dictionary": "^4.1.2"
20
+ "style-dictionary": "^4.1.3"
21
21
  }
22
22
  }
@@ -16,6 +16,6 @@
16
16
  "author": "",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
- "style-dictionary": "^4.1.2"
19
+ "style-dictionary": "^4.1.3"
20
20
  }
21
21
  }
@@ -16,6 +16,6 @@
16
16
  "devDependencies": {
17
17
  "aws-sdk": "^2.7.21",
18
18
  "fs-extra": "^1.0.0",
19
- "style-dictionary": "^4.1.2"
19
+ "style-dictionary": "^4.1.3"
20
20
  }
21
21
  }
@@ -16,6 +16,6 @@
16
16
  "author": "",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
- "style-dictionary": "^4.1.2"
19
+ "style-dictionary": "^4.1.3"
20
20
  }
21
21
  }
@@ -12,6 +12,6 @@
12
12
  "license": "ISC",
13
13
  "devDependencies": {
14
14
  "colorjs.io": "^0.5.2",
15
- "style-dictionary": "^4.1.2"
15
+ "style-dictionary": "^4.1.3"
16
16
  }
17
17
  }
@@ -11,6 +11,6 @@
11
11
  "author": "",
12
12
  "license": "MIT",
13
13
  "devDependencies": {
14
- "style-dictionary": "^4.1.2"
14
+ "style-dictionary": "^4.1.3"
15
15
  }
16
16
  }
@@ -10,7 +10,7 @@
10
10
  "author": "",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
13
- "style-dictionary": "^4.1.2",
13
+ "style-dictionary": "^4.1.3",
14
14
  "yaml": "^1.10.0"
15
15
  }
16
16
  }
@@ -78,7 +78,7 @@ export default class StyleDictionary extends Register {
78
78
  // Placeholder is transformed on prepublish -> see scripts/inject-version.js
79
79
  // Another option might be import pkg from './package.json' with { "type": "json" } which would work in both browser and node, but support is not there yet.
80
80
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility
81
- static VERSION = '4.1.2';
81
+ static VERSION = '4.1.3';
82
82
 
83
83
  /** @returns {Config} */
84
84
  get options() {
@@ -67,7 +67,7 @@ export default async function fileHeader({ file, commentStyle, formatting = {},
67
67
  /**
68
68
  * @type {FileHeader}
69
69
  */
70
- let fn = (arr) => arr;
70
+ let fn = (arr) => arr ?? [];
71
71
  if (file?.options?.fileHeader && typeof file?.options?.fileHeader !== 'string') {
72
72
  fn = file.options.fileHeader;
73
73
  }
@@ -80,7 +80,7 @@ export default function formattedVariables({
80
80
  // note: using the spread operator here so we get a new array rather than
81
81
  // mutating the original
82
82
  allTokens = [...allTokens].sort(
83
- sortByReference(tokens, { unfilteredTokens: dictionary.unfilteredTokens }),
83
+ sortByReference(tokens, { unfilteredTokens: dictionary.unfilteredTokens, usesDtcg }),
84
84
  );
85
85
  }
86
86
 
@@ -1,7 +1,3 @@
1
- /**
2
- * @typedef {import('../../../types/DesignToken.ts').TransformedTokens} Tokens
3
- * @typedef {import('../../../types/DesignToken.ts').TransformedToken} Token
4
- */
5
1
  /**
6
2
  * A function that returns a sorting function to be used with Array.sort that
7
3
  * will sort the allTokens array based on references. This is to make sure
@@ -14,11 +10,12 @@
14
10
  * dictionary.allTokens.sort(sortByReference(dictionary))
15
11
  * ```
16
12
  * @param {Tokens} tokens
17
- * @param {{unfilteredTokens?: Tokens}} [opts]
13
+ * @param {{unfilteredTokens?: Tokens, usesDtcg?: boolean}} [opts]
18
14
  * @returns {(a: Token, b: Token) => number}
19
15
  */
20
- export default function sortByReference(tokens: Tokens, opts?: {
16
+ export default function sortByReference(tokens: Tokens, { unfilteredTokens, usesDtcg }?: {
21
17
  unfilteredTokens?: Tokens;
18
+ usesDtcg?: boolean;
22
19
  } | undefined): (a: Token, b: Token) => number;
23
20
  export type Tokens = import("../../../types/DesignToken.ts").TransformedTokens;
24
21
  export type Token = import("../../../types/DesignToken.ts").TransformedToken;
@@ -19,6 +19,9 @@ import { getReferences } from '../../utils/references/getReferences.js';
19
19
  * @typedef {import('../../../types/DesignToken.ts').TransformedToken} Token
20
20
  */
21
21
 
22
+ const A_COMES_FIRST = -1;
23
+ const B_COMES_FIRST = 1;
24
+
22
25
  /**
23
26
  * A function that returns a sorting function to be used with Array.sort that
24
27
  * will sort the allTokens array based on references. This is to make sure
@@ -31,66 +34,62 @@ import { getReferences } from '../../utils/references/getReferences.js';
31
34
  * dictionary.allTokens.sort(sortByReference(dictionary))
32
35
  * ```
33
36
  * @param {Tokens} tokens
34
- * @param {{unfilteredTokens?: Tokens}} [opts]
37
+ * @param {{unfilteredTokens?: Tokens, usesDtcg?: boolean}} [opts]
35
38
  * @returns {(a: Token, b: Token) => number}
36
39
  */
37
- export default function sortByReference(tokens, opts) {
40
+ export default function sortByReference(tokens, { unfilteredTokens, usesDtcg } = {}) {
41
+ const valueKey = usesDtcg ? '$value' : 'value';
42
+
38
43
  /**
39
44
  * The sorter function is recursive to account for multiple levels of nesting
40
45
  * @param {Token} a
41
46
  * @param {Token} b
42
- * @returns
47
+ * @returns {number}
43
48
  */
44
49
  function sorter(a, b) {
45
- const aComesFirst = -1;
46
- const bComesFirst = 1;
47
-
48
- // return early if a or b ar undefined
49
50
  if (typeof a === 'undefined') {
50
- return aComesFirst;
51
- } else if (typeof b === 'undefined') {
52
- return bComesFirst;
51
+ return A_COMES_FIRST;
52
+ }
53
+ if (typeof b === 'undefined') {
54
+ return B_COMES_FIRST;
53
55
  }
54
56
 
55
- // If token a uses a reference and token b doesn't, b might come before a
56
- // read on..
57
- if (a.original && usesReferences(a.original.value)) {
58
- // Both a and b have references, we need to see if they reference each other
59
- if (b.original && usesReferences(b.original.value)) {
60
- const aRefs = getReferences(a.original.value, tokens, {
61
- unfilteredTokens: opts?.unfilteredTokens,
62
- warnImmediately: false,
63
- });
64
- const bRefs = getReferences(b.original.value, tokens, {
65
- unfilteredTokens: opts?.unfilteredTokens,
66
- warnImmediately: false,
67
- });
68
-
69
- aRefs.forEach((aRef) => {
70
- // a references b, we want b to come first
71
- if (aRef.name === b.name) {
72
- return bComesFirst;
73
- }
74
- });
57
+ const aUsesRefs = a.original && usesReferences(a.original[valueKey]);
58
+ const bUsesRefs = b.original && usesReferences(b.original[valueKey]);
75
59
 
76
- bRefs.forEach((bRef) => {
77
- // ditto but opposite
78
- if (bRef.name === a.name) {
79
- return aComesFirst;
80
- }
81
- });
60
+ // -----BOTH REFERENCE-----
61
+ if (aUsesRefs && bUsesRefs) {
62
+ // Collect references for 'a' and 'b'
63
+ const aRefs = getReferences(a.original[valueKey], tokens, {
64
+ unfilteredTokens,
65
+ warnImmediately: false,
66
+ });
67
+ const bRefs = getReferences(b.original[valueKey], tokens, {
68
+ unfilteredTokens,
69
+ warnImmediately: false,
70
+ });
82
71
 
83
- // both a and b have references and don't reference each other
84
- // we go further down the rabbit hole (reference chain)
85
- return sorter(aRefs[0], bRefs[0]);
86
- } else {
87
- // a has a reference and b does not:
88
- return bComesFirst;
72
+ // 'a' references 'b' -> 'b' should come first
73
+ if (aRefs.some((aRef) => aRef.name === b.name)) {
74
+ return B_COMES_FIRST;
89
75
  }
90
- // a does not have a reference it should come first regardless if b has one
91
- } else {
92
- return aComesFirst;
76
+ // 'b' references 'a' -> 'a' should come first
77
+ if (bRefs.some((bRef) => bRef.name === a.name)) {
78
+ return A_COMES_FIRST;
79
+ }
80
+
81
+ // 'a' and 'b' reference, but not each other. Recurse to next level
82
+ return sorter(aRefs[0], bRefs[0]);
93
83
  }
84
+
85
+ // ----- ONLY ONE REFERENCES -----
86
+ // 'a' references, 'b' doesn't -> 'b' should come first
87
+ if (aUsesRefs) {
88
+ return B_COMES_FIRST;
89
+ }
90
+
91
+ // 'a' doesn't reference. It should come first regardless of 'b'
92
+ return A_COMES_FIRST;
94
93
  }
95
94
 
96
95
  return sorter;
@@ -1190,7 +1190,7 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
1190
1190
 
1191
1191
  let sortedTokens;
1192
1192
  if (outputReferences) {
1193
- sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens }));
1193
+ sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens, usesDtcg }));
1194
1194
  } else {
1195
1195
  sortedTokens = [...allTokens].sort(sortByName);
1196
1196
  }
@@ -1238,7 +1238,7 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
1238
1238
 
1239
1239
  let sortedTokens;
1240
1240
  if (outputReferences) {
1241
- sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens }));
1241
+ sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens, usesDtcg }));
1242
1242
  } else {
1243
1243
  sortedTokens = [...allTokens].sort(sortByName);
1244
1244
  }
@@ -1297,7 +1297,7 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
1297
1297
 
1298
1298
  let sortedTokens;
1299
1299
  if (outputReferences) {
1300
- sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens }));
1300
+ sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens, usesDtcg }));
1301
1301
  } else {
1302
1302
  sortedTokens = [...allTokens].sort(sortByName);
1303
1303
  }
@@ -1520,7 +1520,7 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
1520
1520
 
1521
1521
  let sortedTokens;
1522
1522
  if (outputReferences) {
1523
- sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens }));
1523
+ sortedTokens = [...allTokens].sort(sortByReference(tokens, { unfilteredTokens, usesDtcg }));
1524
1524
  } else {
1525
1525
  sortedTokens = [...allTokens].sort(sortByName);
1526
1526
  }
@@ -48,25 +48,27 @@ async function filterTokenObject(tokens, filter, options) {
48
48
  // out
49
49
  const result = await Object.entries(tokens ?? []).reduce(async (_acc, [key, token]) => {
50
50
  const acc = await _acc;
51
- const tokenValue = options.usesDtcg ? token.$value : token.value;
52
51
  // If the token is not an object, we don't know what it is. We return it as-is.
53
52
  if (!isPlainObject(token)) {
54
53
  return acc;
55
- // If the token has a `value` member we know it's a property, pass it to
56
- // the filter function and either include it in the final `acc` object or
57
- // exclude it (by returning the `acc` object without it added).
58
- } else if (typeof tokenValue !== 'undefined') {
59
- const filtered = await asyncFilter(/** @type {Token[]} */ ([token]), filter, options);
60
- return filtered.length === 0 ? acc : { ...acc, [key]: token };
61
- // If we got here we have an object that is not a property. We'll assume
62
- // it's an object containing multiple tokens and recursively filter it
63
- // using the `filterTokenObject` function.
64
54
  } else {
65
- const filtered = await filterTokenObject(token, filter, options);
66
- // If the filtered object is not empty then add it to the final `acc`
67
- // object. If it is empty then every property inside of it was filtered
68
- // out, then exclude it entirely from the final `acc` object.
69
- return Object.entries(filtered || {}).length < 1 ? acc : { ...acc, [key]: filtered };
55
+ const tokenValue = options.usesDtcg ? token.$value : token.value;
56
+ if (typeof tokenValue === 'undefined') {
57
+ // If we got here we have an object that is not a token. We'll assume
58
+ // it's token group containing multiple tokens and recursively filter it
59
+ // using the `filterTokenObject` function.
60
+ const filtered = await filterTokenObject(token, filter, options);
61
+ // If the filtered object is not empty then add it to the final `acc`
62
+ // object. If it is empty then every token inside of it was filtered
63
+ // out, then exclude it entirely from the final `acc` object.
64
+ return Object.entries(filtered || {}).length < 1 ? acc : { ...acc, [key]: filtered };
65
+ } else {
66
+ // If the token has a `value` member we know it's a token, pass it to
67
+ // the filter function and either include it in the final `acc` object or
68
+ // exclude it (by returning the `acc` object without it added).
69
+ const filtered = await asyncFilter(/** @type {Token[]} */ ([token]), filter, options);
70
+ return filtered.length === 0 ? acc : { ...acc, [key]: token };
71
+ }
70
72
  }
71
73
  }, {});
72
74
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "style-dictionary",
3
- "version": "4.1.2",
3
+ "version": "4.1.3",
4
4
  "description": "Style once, use everywhere. A build system for creating cross-platform styles.",
5
5
  "keywords": [
6
6
  "style dictionary",
package/types/File.d.ts CHANGED
@@ -16,7 +16,7 @@ export interface FormattingOverrides {
16
16
  footer?: string;
17
17
  fileHeaderTimestamp?: boolean;
18
18
  }
19
- export type FileHeader = (defaultMessage: string[], options?: Config) => Promise<string[]> | string[];
19
+ export type FileHeader = (defaultMessage?: string[], options?: Config) => Promise<string[]> | string[];
20
20
  export interface File {
21
21
  destination?: string;
22
22
  format?: string | FormatFn;