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.
- package/examples/advanced/assets-base64-embed/package.json +1 -1
- package/examples/advanced/create-react-app/package.json +1 -1
- package/examples/advanced/create-react-native-app/package.json +1 -1
- package/examples/advanced/custom-parser/package.json +1 -1
- package/examples/advanced/custom-transforms/package.json +1 -1
- package/examples/advanced/font-face-rules/package.json +1 -1
- package/examples/advanced/format-helpers/package.json +1 -1
- package/examples/advanced/matching-build-files/package.json +1 -1
- package/examples/advanced/multi-brand-multi-platform/package.json +1 -1
- package/examples/advanced/node-modules-as-config-and-properties/package.json +1 -1
- package/examples/advanced/npm-module/package.json +1 -1
- package/examples/advanced/referencing_aliasing/package.json +1 -1
- package/examples/advanced/s3/package.json +1 -1
- package/examples/advanced/tokens-deprecation/package.json +1 -1
- package/examples/advanced/transitive-transforms/package.json +1 -1
- package/examples/advanced/variables-in-outputs/package.json +1 -1
- package/examples/advanced/yaml-tokens/package.json +1 -1
- package/lib/StyleDictionary.js +1 -1
- package/lib/common/formatHelpers/fileHeader.js +1 -1
- package/lib/common/formatHelpers/formattedVariables.js +1 -1
- package/lib/common/formatHelpers/sortByReference.d.ts +3 -6
- package/lib/common/formatHelpers/sortByReference.js +44 -45
- package/lib/common/formats.js +4 -4
- package/lib/filterTokens.js +17 -15
- package/package.json +1 -1
- package/types/File.d.ts +1 -1
package/lib/StyleDictionary.js
CHANGED
|
@@ -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.
|
|
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,
|
|
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,
|
|
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
|
|
51
|
-
}
|
|
52
|
-
|
|
51
|
+
return A_COMES_FIRST;
|
|
52
|
+
}
|
|
53
|
+
if (typeof b === 'undefined') {
|
|
54
|
+
return B_COMES_FIRST;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
return
|
|
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
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
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;
|
package/lib/common/formats.js
CHANGED
|
@@ -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
|
}
|
package/lib/filterTokens.js
CHANGED
|
@@ -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
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
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
|
|
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;
|