@supernovaio/cli
Version:
Supernova.io Command Line Interface
197 lines (195 loc) • 9.51 kB
JavaScript
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c05237d5-38a4-5f7c-aba5-dedba82a2d2e")}catch(e){}}();
import sdk from "@supernovaio/sdk";
import * as fs from "node:fs";
export class FigmaTokensDataLoader {
loadConfigFromPath(pathToFile) {
try {
const parsedDefinition = this.loadConfigFromPathAsIs(pathToFile);
this.weakValidateMapping(parsedDefinition);
return this.processFileToMapping(parsedDefinition);
}
catch (error) {
throw new Error("Unable to load JSON definition file: " + error);
}
}
loadConfigFromPathAsIs(pathToFile) {
try {
if (!(fs.existsSync(pathToFile) && fs.lstatSync(pathToFile).isFile())) {
throw new Error(`Provided configuration file directory ${pathToFile} is not a file or doesn't exist`);
}
const definition = fs.readFileSync(pathToFile, "utf8");
const parsedDefinition = this.parseDefinition(definition);
return parsedDefinition;
}
catch (error) {
throw new Error("Unable to load JSON definition file: " + error);
}
}
async loadTokensFromDirectory(pathToDirectory, settingsPath) {
try {
const fullStructuredObject = {};
if (!(fs.existsSync(pathToDirectory) && fs.lstatSync(pathToDirectory).isDirectory())) {
throw new Error(`Provided data directory ${pathToDirectory} is not a directory or doesn't exist`);
}
const jsonPaths = this.getAllJSONFiles(pathToDirectory);
for (const path of jsonPaths) {
if (path.endsWith("json") && path !== settingsPath && !path.includes("$")) {
const result = await this.loadObjectFile(path);
if (typeof result === "object") {
const name = this.getSetKey(path, pathToDirectory);
fullStructuredObject[name] = result;
}
}
}
const themePath = pathToDirectory + "/" + "$themes.json";
if (fs.existsSync(themePath)) {
const themes = await this.loadObjectFile(themePath);
fullStructuredObject.$themes = themes;
}
const metadataPath = pathToDirectory + "/" + "$metadata.json";
if (fs.existsSync(metadataPath)) {
const metadata = await this.loadObjectFile(metadataPath);
fullStructuredObject.$metadata = metadata;
}
return fullStructuredObject;
}
catch (error) {
throw new Error("Unable to load JSON definition file: " + error);
}
}
async loadTokensFromPath(pathToFile) {
try {
if (!(fs.existsSync(pathToFile) && fs.lstatSync(pathToFile).isFile())) {
throw new Error(`Provided token file directory ${pathToFile} is not a file or doesn't exist`);
}
const definition = fs.readFileSync(pathToFile, "utf8");
const parsedDefinition = this.parseDefinition(definition);
return parsedDefinition;
}
catch (error) {
throw new Error("Unable to load JSON definition file: " + error);
}
}
getAllJSONFiles(dir) {
const files = fs.readdirSync(dir);
const jsonFiles = [];
for (const file of files) {
const filePath = `${dir}/${file}`;
const fileStat = fs.statSync(filePath);
if (fileStat.isDirectory()) {
jsonFiles.push(...this.getAllJSONFiles(filePath));
}
else if (fileStat.isFile() && filePath.endsWith(".json")) {
jsonFiles.push(filePath);
}
}
return jsonFiles;
}
getSetKey(jsonFilePath, loadedDirectory) {
return jsonFilePath.slice(loadedDirectory.length + 1, -5);
}
async loadObjectFile(pathToFile) {
try {
if (!(fs.existsSync(pathToFile) && fs.lstatSync(pathToFile).isFile())) {
throw new Error(`Provided token file directory ${pathToFile} is not a file or doesn't exist`);
}
const definition = fs.readFileSync(pathToFile, "utf8");
const parsedDefinition = this.parseDefinition(definition);
return parsedDefinition;
}
catch (error) {
throw new Error("Unable to load JSON definition file: " + error);
}
}
parseDefinition(definition) {
try {
const object = JSON.parse(definition);
if (typeof object !== "object") {
throw new TypeError("Invalid Supernova mapping definition JSON file - root level entity must be object");
}
return object;
}
catch {
throw new Error("Invalid Supernova mapping definition JSON file - file structure invalid");
}
}
processFileToMapping(mapping) {
const result = [];
for (const map of mapping.mapping) {
result.push({
bindToBrand: map.supernovaBrand,
bindToTheme: map.supernovaTheme ?? null,
nodes: null,
pluginSets: map.tokenSets ?? null,
pluginTheme: map.tokensTheme ?? null,
processedGroups: null,
processedNodes: null,
type: map.tokenSets ? sdk.DTPluginToSupernovaMapType.set : sdk.DTPluginToSupernovaMapType.theme,
});
}
const settings = {
...mapping.settings,
dryRun: mapping.settings?.dryRun ?? false,
preciseCopy: sdk.toPreciseCopyStrategy(mapping.settings?.preciseCopy),
themeOverridesStrategy: mapping.settings?.themeOverridesStrategy ?? "default",
verbose: mapping.settings?.verbose ?? false,
};
return {
mapping: result,
settings,
};
}
weakValidateMapping(mapping) {
if (!Object.hasOwn(mapping, "mode") ||
typeof mapping.mode !== "string" ||
(mapping.mode !== "multi-file" && mapping.mode !== "single-file")) {
throw new Error("Unable to load mapping file: `mode` must be provided [single-file or multi-file]`");
}
if (!mapping.mapping || !Array.isArray(mapping.mapping)) {
throw new Error("Unable to load mapping file: `mapping` key must be present and array.");
}
const mapPack = mapping.mapping;
for (const map of mapPack) {
if (typeof map !== "object") {
throw new TypeError("Unable to load mapping file: `mapping` must contain objects only");
}
if (!map.tokenSets && !map.tokensTheme) {
throw new Error("Unable to load mapping file: `mapping` must contain either `tokensTheme` or `tokenSets`");
}
if (map.tokenSets && map.tokensTheme) {
throw new Error("Unable to load mapping file: `mapping` must not contain both `tokensTheme` or `tokenSets`");
}
if (map.tokenSets && (!Array.isArray(map.tokenSets) || map.tokenSets.length === 0)) {
throw new Error("Unable to load mapping file: `mapping`.`tokenSets` must be an Array with at least one entry");
}
if (map.tokensTheme &&
((typeof map.tokensTheme !== "string" && !Array.isArray(map.tokensTheme)) || map.tokensTheme.length === 0)) {
throw new Error("Unable to load mapping file: `mapping`.`tokensTheme` must be a non-empty string or non-empty array of strings");
}
if (!map.supernovaBrand || typeof map.supernovaBrand !== "string" || map.supernovaBrand.length === 0) {
throw new Error("Unable to load mapping file: `supernovaBrand` must be a non-empty string");
}
if (map.supernovaTheme && (typeof map.supernovaTheme !== "string" || map.supernovaTheme.length === 0)) {
throw new Error("Unable to load mapping file: `supernovaTheme` may be empty but must be non-empty string if not");
}
}
if (mapping.settings) {
if (typeof mapping.settings !== "object") {
throw new TypeError("Unable to load mapping file: `settings` must be an object");
}
if (Object.hasOwn(mapping.settings, "dryRun") && typeof mapping.settings.dryRun !== "boolean") {
throw new Error("Unable to load mapping file: `dryRun` must be of boolean type");
}
if (Object.hasOwn(mapping.settings, "verbose") && typeof mapping.settings.verbose !== "boolean") {
throw new Error("Unable to load mapping file: `verbose` must be of boolean type");
}
if (Object.hasOwn(mapping.settings, "preciseCopy") &&
typeof mapping.settings.preciseCopy !== "boolean" &&
typeof mapping.settings.preciseCopy !== "string") {
throw new Error("Unable to load mapping file: `preciseCopy` must be of boolean or string type");
}
}
}
}
//# sourceMappingURL=figma-tokens-data-loader.js.map
//# debugId=c05237d5-38a4-5f7c-aba5-dedba82a2d2e