@terrazzo/plugin-js
Version:
Generate JS, TS, and JSON from your DTCG design tokens JSON.
143 lines (139 loc) • 4.9 kB
JavaScript
//#region ../token-tools/dist/js.js
/**
* Convert token value to a JS string via acorn/astring.
*/
function transformJSValue(token, { mode, indent = 2, startingIndent = 0 }) {
if (!(mode in token.mode)) return;
const indentStart = startingIndent > 0 ? " ".repeat(startingIndent ?? 2) : "";
return JSON.stringify(token.mode[mode].$value, void 0, indent).replace(/\n/g, `\n${indentStart}`);
}
//#endregion
//#region src/lib.ts
const FORMAT_JS_ID = "js";
const FORMAT_DTS_ID = "d.ts";
const FILE_HEADER = `/** ------------------------------------------
* Autogenerated by ⛋ Terrazzo. DO NOT EDIT!
* ------------------------------------------- */`;
const TYPE_MAP = {
boolean: "BooleanTokenNormalized",
border: "BorderTokenNormalized",
color: "ColorTokenNormalized",
cubicBezier: "CubicBezierTokenNormalized",
dimension: "DimensionTokenNormalized",
duration: "DurationTokenNormalized",
fontFamily: "FontFamilyTokenNormalized",
fontWeight: "FontWeightTokenNormalized",
gradient: "GradientTokenNormalized",
link: "LinkTokenNormalized",
number: "NumberTokenNormalized",
shadow: "ShadowTokenNormalized",
string: "StringTokenNormalized",
strokeStyle: "StrokeStyleTokenNormalized",
typography: "TypographyTokenNormalized",
transition: "TransitionTokenNormalized"
};
//#endregion
//#region src/build.ts
function buildJS({ getTransforms }) {
const output = [FILE_HEADER, ""];
const tokenVals = {};
for (const token of getTransforms({
format: FORMAT_JS_ID,
id: "*"
})) {
if (!tokenVals[token.token.id]) tokenVals[token.token.id] = {};
tokenVals[token.token.id][token.mode] = token.value;
}
output.push("export const tokens = {");
for (const [id, tokenValue] of Object.entries(tokenVals)) {
output.push(` "${id}": {`);
for (const [mode, modeValue] of Object.entries(tokenValue)) output.push(` "${mode}": ${modeValue},`);
output.push(" },");
}
output.push("};", "");
output.push(`/** Get individual token */
export function token(tokenID, modeName = ".") {
return tokens[tokenID]?.[modeName];
}`, "");
return output.join("\n");
}
function buildDTS({ getTransforms }) {
const output = [FILE_HEADER, ""];
const importDeps = /* @__PURE__ */ new Set();
const types = getTransforms({
format: FORMAT_DTS_ID,
id: "*",
mode: "."
}).map((t) => {
importDeps.add(TYPE_MAP[t.token.$type]);
if (t.type === "MULTI_VALUE") {
const description = t.value.description ? ` /** ${t.value.description} */\n` : "";
return `${description} "${t.token.id}": ${t.value.value};`;
}
return `"${t.token.id}": ${t.value};`;
});
output.push("import type {", ...[...importDeps].sort((a, b) => a.localeCompare(b)).map((dep) => ` ${dep},`), "} from \"@terrazzo/parser\";", "", "export declare const tokens: {", ...types, "};", "", `export declare function token<K extends keyof typeof tokens>(tokenID: K, modeName?: never): (typeof tokens)[K]["."];
export declare function token<K extends keyof typeof tokens, M extends keyof (typeof tokens)[K]>(tokenID: K, modeName: M): (typeof tokens)[K][M];`, "");
return output.join("\n");
}
//#endregion
//#region src/index.ts
function pluginJS(options) {
const customTransform = options?.transform;
return {
name: "@terrazzo/plugin-js",
async transform({ tokens, getTransforms, setTransform }) {
const jsTokens = getTransforms({
format: FORMAT_JS_ID,
id: "*",
mode: "."
});
if (jsTokens.length) return;
for (const [id, token] of Object.entries(tokens)) {
setTransform(id, {
format: FORMAT_DTS_ID,
value: {
description: token.$description,
value: `Record<"${Object.keys(token.mode).join("\" | \"")}", ${TYPE_MAP[token.$type]}["$value"]>`
},
mode: "."
});
for (const mode of Object.keys(token.mode)) {
if (customTransform) {
const transformedValue$1 = customTransform(token, mode);
if (transformedValue$1 !== void 0 && transformedValue$1 !== null) {
setTransform(id, {
format: FORMAT_JS_ID,
value: transformedValue$1,
mode
});
continue;
}
}
const transformedValue = transformJSValue(token, {
mode,
startingIndent: 4
});
if (transformedValue !== void 0) setTransform(id, {
format: FORMAT_JS_ID,
value: transformedValue,
mode
});
}
}
},
async build({ getTransforms, outputFile }) {
if (options?.js) {
const js = buildJS({ getTransforms });
const jsFilename = typeof options?.js === "string" ? options.js : "index.js";
outputFile(jsFilename, js);
const dts = buildDTS({ getTransforms });
const dtsFilename = typeof options?.js === "string" ? options.js.replace(/\.js$/, ".d.ts") : "index.d.ts";
outputFile(dtsFilename, dts);
}
}
};
}
//#endregion
export { FILE_HEADER, FORMAT_DTS_ID, FORMAT_JS_ID, TYPE_MAP, buildDTS, buildJS, pluginJS as default };
//# sourceMappingURL=index.js.map