Skip to content

Commit

Permalink
chore: reordered design tokens structure
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang committed Nov 13, 2024
1 parent b4d560b commit 4b065a6
Show file tree
Hide file tree
Showing 122 changed files with 7,757 additions and 3,506 deletions.
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ icons/
build-scss.js
component-generator/
example/
package.json
package-lock.json
src/i18n
tsconfig.build.json
dependent-usage.json
14 changes: 14 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,19 @@ module.exports = {
project: './tsconfig.json',
},
},
{
files: ['**/*.json'],
plugins: ['jsonc'],
extends: ['plugin:jsonc/recommended-with-json'],
rules: {
'jsonc/indent': ['error', 2],
'jsonc/quote-props': ['error', 'always'],
'jsonc/quotes': ['error', 'double'],
'jsonc/no-octal': 'error',
'jsonc/no-dupe-keys': 'error',
'jsonc/valid-json-number': 'error',
'jsonc/no-bigint-literals': 'error',
},
},
],
};
190 changes: 190 additions & 0 deletions designTokenKeySorter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/* eslint-disable no-console */
const fs = require('fs').promises;
const path = require('path');
const chalk = require('chalk');

const tokensDirectory = 'tokens/';

const DESIGN_TOKEN_KEY_ORDER = [
'$type',
'$value',
'$description',
'outputReferences',
'modify',
'source',
];

const shouldApplyFix = process.argv.includes('--fix');

let mismatchWarningCount = 0;
let totalProcessedFileCount = 0;

/**
* Reorders the keys in an object based on a specified key order.
* @param {Object} object - The object to reorder.
* @param {string[]} desiredKeyOrder - The desired order for the keys.
* @returns {Object} - An object containing the reordered object and
* a flag indicating if the key order was mismatched and a list of mismatched keys.
*/
function reorderKeysInObject(object, desiredKeyOrder) {
const objectKeys = Object.keys(object);
const objectKeySet = new Set(objectKeys);
let isOrderMismatched = false;
const mismatchedKeyList = [];

let index = 0;

const reorderedObject = desiredKeyOrder.reduce((accumulatedObject, key) => {
if (objectKeySet.has(key)) {
accumulatedObject[key] = object[key];
if (key !== objectKeys[index]) {
isOrderMismatched = true;
mismatchedKeyList.push(objectKeys[index]);
}
index++;
}
return accumulatedObject;
}, {});

objectKeys.forEach((key) => {
if (!Object.prototype.hasOwnProperty.call(reorderedObject, key)) {
reorderedObject[key] = object[key];
if (index < objectKeys.length && key !== objectKeys[index]) {
isOrderMismatched = true;
mismatchedKeyList.push(objectKeys[index]);
}
index++;
}
});

return {
reorderedObject,
isOrderMismatched,
mismatchedKeys: mismatchedKeyList,
};
}

/**
* Recursively reorders keys in JSON data based on a specified key order for nested objects.
* @param {*} jsonData - The JSON data (object, array, or primitive) to process.
* @param {string} jsonPath - The path to the current data within the JSON structure.
* @returns {Object} - An object containing the reordered data and
* a flag indicating if any key order mismatches were found.
*/
function recursivelyReorderKeys(jsonData, jsonPath = '') {
if (Array.isArray(jsonData)) {
return jsonData.map((item, index) => recursivelyReorderKeys(item, `${jsonPath}[${index}]`));
}

if (typeof jsonData === 'object' && jsonData !== null) {
const {
reorderedObject: reorderedData,
isOrderMismatched: hasMainMismatch,
mismatchedKeys: mainMismatchedKeys,
} = reorderKeysInObject(jsonData, DESIGN_TOKEN_KEY_ORDER);

let hasAnyMismatch = hasMainMismatch;
const mismatches = hasMainMismatch ? { [jsonPath]: mainMismatchedKeys } : {};

Object.entries(reorderedData).reduce((accumulatedMismatches, [key, value]) => {
if (DESIGN_TOKEN_KEY_ORDER.includes(key)) {
reorderedData[key] = value;
return accumulatedMismatches;
}

const result = recursivelyReorderKeys(value, `${jsonPath}.${key}`);
reorderedData[key] = result.reorderedData || result;

if (result.isOrderMismatched) {
Object.assign(accumulatedMismatches, result.mismatches);
hasAnyMismatch = true;
}
return accumulatedMismatches;
}, mismatches);

return {
reorderedData,
isOrderMismatched: hasAnyMismatch,
mismatches,
};
}

return jsonData;
}

/**
* Processes all JSON files in a given directory path,
* reordering keys in each file based on predefined key orders.
* @param {string} directoryPath - The path of the directory containing JSON files.
*/
async function processJsonFilesInDirectory(directoryPath) {
try {
const directoryEntries = await fs.readdir(directoryPath, { withFileTypes: true });

const fileProcessingTasks = directoryEntries.map(async (entry) => {
const entryPath = path.join(directoryPath, entry.name);

if (entry.isDirectory()) {
return processJsonFilesInDirectory(entryPath);
}

if (entry.isFile() && path.extname(entry.name) === '.json') {
try {
const fileContent = await fs.readFile(entryPath, 'utf-8');
const jsonData = JSON.parse(fileContent);

const {
reorderedData,
isOrderMismatched,
mismatches,
} = recursivelyReorderKeys(jsonData);

if (isOrderMismatched) {
mismatchWarningCount++;
if (shouldApplyFix) {
await fs.writeFile(entryPath, `${JSON.stringify(reorderedData, null, 2)}\n`, 'utf-8');
} else {
console.warn(chalk.yellow(`Warning: Key order mismatch in ${entryPath}.`));
console.warn(chalk.red('Mismatched info:'));
Object.entries(mismatches).forEach(([keyPath, keys]) => {
console.warn(chalk.cyan(` Path: ${keyPath.slice(1)}`));
console.warn(chalk.magenta(` Mismatched keys: ${keys.join(', ')}`));
console.warn();
});
}
}

if (!fileContent.endsWith('\n')) {
await fs.writeFile(entryPath, `${fileContent}\n`, 'utf-8');
}

totalProcessedFileCount++;
return null;
} catch (error) {
console.error(chalk.red(`Error processing file ${entryPath}:`), error);
return null;
}
}

return null;
});

await Promise.all(fileProcessingTasks);
} catch (error) {
console.error(chalk.red(`Error reading directory ${directoryPath}:`), error);
}
}

processJsonFilesInDirectory(tokensDirectory).then(() => {
let statusMessage;

if (shouldApplyFix) {
statusMessage = chalk.green(`Processed ${totalProcessedFileCount} files. ${mismatchWarningCount} files were updated.`);
} else if (mismatchWarningCount > 0) {
statusMessage = chalk.yellow(`Processed ${totalProcessedFileCount} files. ${mismatchWarningCount} files have key order mismatches.`);
} else {
statusMessage = chalk.green(`Processed ${totalProcessedFileCount} files. All files are in correct order.`);
}

console.log(statusMessage);
});
Loading

0 comments on commit 4b065a6

Please sign in to comment.