UNPKG

@terrazzo/plugin-js

Version:

Generate JS, TS, and JSON from your DTCG design tokens JSON.

143 lines (139 loc) 4.9 kB
//#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