Skip to content

Commit

Permalink
chore: remove es6 helpers and use actual ES6
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema committed Nov 23, 2023
1 parent a4542f4 commit 3a380a6
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 249 deletions.
4 changes: 0 additions & 4 deletions lib/StyleDictionary.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ import cleanActions from './cleanActions.js';
const PROPERTY_VALUE_COLLISIONS = GroupMessages.GROUP.PropertyValueCollisions;
const PROPERTY_REFERENCE_WARNINGS = GroupMessages.GROUP.PropertyReferenceWarnings;

// const TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.TemplateDeprecationWarnings;
// const REGISTER_TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.RegisterTemplateDeprecationWarnings;
// const SASS_MAP_FORMAT_DEPRECATION_WARNINGS = GroupMessages.GROUP.SassMapFormatDeprecationWarnings;

/**
* Style Dictionary module
*
Expand Down
13 changes: 7 additions & 6 deletions lib/common/formatHelpers/getTypeScriptType.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import { unique } from '../../utils/es6_.js';

/**
* Given some value, returns a basic valid TypeScript type for that value.
Expand Down Expand Up @@ -72,11 +71,13 @@ function getArrayType(passedArray) {
if (passedArray.every((v) => getTypeScriptType(v) === firstValueType)) {
return firstValueType + '[]';
} else {
return `(${unique(
passedArray.map((item, index) => {
const isLast = passedArray.length === index + 1;
return `${getTypeScriptType(item)}${!isLast ? ' | ' : ''}`;
}),
return `(${Array.from(
new Set(
passedArray.map((item, index) => {
const isLast = passedArray.length === index + 1;
return `${getTypeScriptType(item)}${!isLast ? ' | ' : ''}`;
}),
),
).join('')})[]`;
}
}
Expand Down
12 changes: 11 additions & 1 deletion lib/common/transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@

import Color from 'tinycolor2';
import path from '@bundled-es-modules/path-browserify';
import { kebabCase, camelCase, snakeCase, upperFirst } from '../utils/es6_.js';
import {
camelCaseTransformMerge,
snakeCase,
paramCase as kebabCase,
camelCase as _camelCase,
} from 'change-case';
import convertToBase64 from '../utils/convertToBase64.js';

const camelCase = (str) => _camelCase(str, { transform: camelCaseTransformMerge });

const UNICODE_PATTERN = /&#x([^;]+);/g;

function isColor(token) {
Expand Down Expand Up @@ -281,6 +288,9 @@ export default {
'name/cti/pascal': {
type: 'name',
transformer: function (token, options) {
const upperFirst = function (str) {
return str ? str[0].toUpperCase() + str.substr(1) : '';
};
return upperFirst(camelCase([options.prefix].concat(token.path).join(' ')));
},
},
Expand Down
76 changes: 30 additions & 46 deletions lib/filterTokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

import { reduce, isObject, filter as filterUtil, assign, isEmpty } from './utils/es6_.js';
import { isPlainObject } from 'is-plain-object';

/**
* Takes a nested object of tokens and filters them using the provided
* function.
*
* @param {Object} tokens
* @param {Object|undefined|null} tokens
* @param {Function} filter - A function that receives a property object and
* returns `true` if the property should be included in the output or `false`
* if the property should be excluded from the output.
Expand All @@ -27,45 +26,26 @@ import { reduce, isObject, filter as filterUtil, assign, isEmpty } from './utils
function filterTokenObject(tokens, filter) {
// Use reduce to generate a new object with the unwanted tokens filtered
// out
return reduce(
tokens,
(result, value, key) => {
// If the value is not an object, we don't know what it is. We return it as-is.
if (!isObject(value)) {
return result;
// If the value has a `value` member we know it's a property, pass it to
// the filter function and either include it in the final `result` object or
// exclude it (by returning the `result` object without it added).
} else if (typeof value.value !== 'undefined') {
return filter(value) ? assign(result, { [key]: value }) : result;
// If we got here we have an object that is not a property. We'll assume
// it's an object containing multiple tokens and recursively filter it
// using the `filterTokenObject` function.
} else {
const filtered = filterTokenObject(value, filter);
// If the filtered object is not empty then add it to the final `result`
// object. If it is empty then every property inside of it was filtered
// out, then exclude it entirely from the final `result` object.
return isEmpty(filtered) ? result : assign(result, { [key]: filtered });
}
},
{},
);
}

/**
* Takes an array of tokens and filters them using the provided function.
*
* @param {Object[]} tokens
* @param {Function} filter - A function that receives a property object and
* returns `true` if the property should be included in the output or `false`
* if the property should be excluded from the output.
* @returns {Object[]} tokens - A new array containing only the tokens
* that matched the filter.
*/
function filterTokenArray(tokens, filter) {
// Go lodash!
return filterUtil(tokens, filter);
return Object.entries(tokens ?? []).reduce((acc, [key, value]) => {
// If the value is not an object, we don't know what it is. We return it as-is.
if (!isPlainObject(value)) {
return acc;
// If the value has a `value` member we know it's a property, pass it to
// the filter function and either include it in the final `acc` object or
// exclude it (by returning the `acc` object without it added).
} else if (typeof value.value !== 'undefined') {
return filter(value) ? { ...acc, [key]: value } : acc;
// If we got here we have an object that is not a property. We'll assume
// it's an object containing multiple tokens and recursively filter it
// using the `filterTokenObject` function.
} else {
const filtered = filterTokenObject(value, filter);
// If the filtered object is not empty then add it to the final `acc`
// object. If it is empty then every property inside of it was filtered
// out, then exclude it entirely from the final `acc` object.
return Object.entries(filtered || {}).length < 1 ? acc : { ...acc, [key]: filtered };
}
}, {});
}

/**
Expand All @@ -84,9 +64,13 @@ export default function filterTokens(dictionary, filter) {
if (!filter) {
return dictionary;
} else {
return {
allTokens: filterTokenArray(dictionary.allTokens, filter),
tokens: filterTokenObject(dictionary.tokens, filter),
};
if (typeof filter !== 'function') {
throw new Error('filter is not a function');
} else {
return {
allTokens: (dictionary.allTokens ?? []).filter(filter),
tokens: filterTokenObject(dictionary.tokens, filter),
};
}
}
}
4 changes: 1 addition & 3 deletions lib/register/transformGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
* and limitations under the License.
*/

import { isArray } from '../utils/es6_.js';

/**
* Add a custom transformGroup to the Style Dictionary, which is a
* group of transforms.
Expand All @@ -36,7 +34,7 @@ import { isArray } from '../utils/es6_.js';
*/
export default function registerTransformGroup(options) {
if (typeof options.name !== 'string') throw new Error('transform name must be a string');
if (!isArray(options.transforms))
if (!Array.isArray(options.transforms))
throw new Error('transforms must be an array of registered value transforms');

options.transforms.forEach(
Expand Down
20 changes: 17 additions & 3 deletions lib/transform/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
* and limitations under the License.
*/

import { clone, matches } from '../utils/es6_.js';
import { isPlainObject } from 'is-plain-object';
import deepExtend from '../utils/deepExtend.js';
import GroupMessages from '../utils/groupMessages.js';

const TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.TemplateDeprecationWarnings;
const MISSING_TRANSFORM_ERRORS = GroupMessages.GROUP.MissingRegisterTransformErrors;

/**
Expand All @@ -29,7 +28,7 @@ const MISSING_TRANSFORM_ERRORS = GroupMessages.GROUP.MissingRegisterTransformErr
* @returns {Object}
*/
export default function transformConfig(platformConfig, dictionary, platformName) {
const to_ret = clone(platformConfig);
const to_ret = { ...platformConfig }; // structuredClone not suitable due to config being able to contain Function() etc.
to_ret.log = platformConfig.log ?? dictionary.log;

// The platform can define either a transformGroup or an array
Expand Down Expand Up @@ -123,6 +122,21 @@ None of ${transform_warnings} match the name of a registered transform.
throw new Error("Can't find filter: " + file.filter);
}
} else if (typeof file.filter === 'object') {
// Recursively go over the object keys of filter object and
// return a filter Function that filters tokens
// by the specified object keys.
const matchFn = function (inputObj, testObj) {
if (isPlainObject(testObj)) {
return Object.keys(testObj).every((key) => matchFn(inputObj[key], testObj[key]));
} else {
return inputObj == testObj;
}
};
const matches = function (matchObj) {
let cloneObj = { ...matchObj }; // shallow clone, structuredClone not suitable because obj can contain "Function()"
let matchesFn = (inputObj) => matchFn(inputObj, cloneObj);
return matchesFn;
};
ext.filter = matches(file.filter);
} else if (typeof file.filter === 'function') {
ext.filter = file.filter;
Expand Down
20 changes: 13 additions & 7 deletions lib/transform/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* and limitations under the License.
*/

import { isPlainObject, pull } from '../utils/es6_.js';
import { isPlainObject } from 'is-plain-object';
import usesValueReference from '../utils/references/usesReference.js';
import getName from '../utils/references/getName.js';
import transformToken from './token.js';
Expand All @@ -26,21 +26,20 @@ import tokenSetup from './tokenSetup.js';
* @private
* @param {Object} obj
* @param {Object} options
* @param {Object} [transformationContext={}]
* @param {Object} [ctx={}]
* @param {Array} [path=[]]
* @param {Object} [transformedObj={}]
* @returns {Object}
*/
export default function transformObject(
obj,
options,
transformationContext = {},
{ transformedPropRefs = [], deferredPropValueTransforms = [] } = {},
path,
transformedObj,
) {
transformedObj = transformedObj || {};
path = path || [];
const { transformedPropRefs = [], deferredPropValueTransforms = [] } = transformationContext;

for (const name in obj) {
if (!obj.hasOwnProperty(name)) {
Expand Down Expand Up @@ -87,16 +86,23 @@ export default function transformObject(
// If we got here, the property hasn't been transformed yet and
// does not use a value reference. Transform the property now and assign it.
transformedObj[name] = transformToken(setupProperty, options);
// Remove the property path from the deferred transform list
pull(deferredPropValueTransforms, pathName);

// Remove the property path from the deferred transform list, starting from end of array
for (let i = deferredPropValueTransforms.length - 1; i >= 0; i--) {
if (deferredPropValueTransforms[i] === pathName) {
// Important to use .splice and mutate the original array all the way up
deferredPropValueTransforms.splice(i, 1);
}
}

// Add the property path to the transformed list so we don't transform it again.
transformedPropRefs.push(pathName);
} else if (isObj) {
// objProp is not a token -> go deeper down the object tree
transformedObj[name] = transformObject(
objProp,
options,
transformationContext,
{ transformedPropRefs, deferredPropValueTransforms },
path,
transformedObj[name],
);
Expand Down
3 changes: 1 addition & 2 deletions lib/transform/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
* and limitations under the License.
*/

import { clone } from '../utils/es6_.js';
import usesReference from '../utils/references/usesReference.js';

/**
Expand All @@ -23,7 +22,7 @@ import usesReference from '../utils/references/usesReference.js';
* @returns {Object} - A new property object with transforms applied.
*/
export default function transformProperty(property, options) {
const to_ret = clone(property);
const to_ret = structuredClone(property);
const transforms = options.transforms;

for (let i = 0; i < transforms.length; i++) {
Expand Down
8 changes: 4 additions & 4 deletions lib/transform/tokenSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* and limitations under the License.
*/

import { isPlainObject } from 'is-plain-object';
import deepExtend from '../utils/deepExtend.js';
import { isPlainObject, isString, isArray, clone } from '../utils/es6_.js';

/**
* Takes a token object, a leaf node in a tokens object, and
Expand All @@ -27,8 +27,8 @@ import { isPlainObject, isString, isArray, clone } from '../utils/es6_.js';
*/
export default function tokenSetup(token, name, path) {
if (!token && !isPlainObject(token)) throw new Error('Property object must be an object');
if (!name || !isString(name)) throw new Error('Name must be a string');
if (!path || !isArray(path)) throw new Error('Path must be an array');
if (!name || !(typeof name === 'string')) throw new Error('Name must be a string');
if (!path || !Array.isArray(path)) throw new Error('Path must be an array');

let to_ret = token;

Expand All @@ -49,7 +49,7 @@ export default function tokenSetup(token, name, path) {
to_ret.attributes = to_ret.attributes || {};
// An array of the path down the object tree; we will use it to build readable names
// like color_font_base
to_ret.path = clone(path);
to_ret.path = structuredClone(path);
}

return to_ret;
Expand Down
Loading

0 comments on commit 3a380a6

Please sign in to comment.