@interactivethings/scripts 0.0.9 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -12
- package/codemods/__testfixtures__/sx-to-use-styles.input.js +50 -0
- package/codemods/__testfixtures__/sx-to-use-styles.output.js +59 -0
- package/codemods/__tests__/defineTest.ts +9 -0
- package/codemods/__tests__/sx-to-use-styles.test.js +3 -0
- package/codemods/sx-to-use-styles.js +162 -0
- package/dist/__tests__/figma-cli.test.js +189 -0
- package/dist/__tests__/tokens-studio-cli.test.js +197 -0
- package/dist/__tests__/vercel-cli.test.js +86 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +103 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +167 -0
- package/dist/figma/api.d.ts +71 -0
- package/dist/figma/api.js +175 -0
- package/dist/figma/cli.d.ts +20 -0
- package/dist/figma/cli.js +163 -0
- package/dist/figma/cli.test.js +197 -0
- package/dist/figma/images.js +63 -0
- package/dist/figma/optimizeImage.js +53 -0
- package/dist/figma/utils.d.ts +10 -0
- package/dist/figma/utils.js +26 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +53 -0
- package/dist/init/cli.d.ts +3 -0
- package/dist/init/cli.js +320 -0
- package/dist/mui-tokens-studio.js +0 -0
- package/dist/plugins/figma/index.js +653 -0
- package/dist/plugins/tokens-studio/utils.js +155 -0
- package/dist/tokens-studio/__tests__/fixtures/invalid-transformer.js +12 -0
- package/dist/tokens-studio/__tests__/fixtures/test-transformer.js +18 -0
- package/dist/tokens-studio/cli.d.ts +8 -0
- package/dist/tokens-studio/cli.js +153 -0
- package/dist/tokens-studio/cli.test.js +160 -0
- package/dist/tokens-studio/index.d.ts +14 -0
- package/dist/tokens-studio/index.js +56 -0
- package/dist/tokens-studio/mui.js +212 -0
- package/dist/tokens-studio/require.js +17 -0
- package/dist/tokens-studio/tailwind.js +211 -0
- package/dist/tokens-studio/types.js +2 -0
- package/dist/tokens-studio/utils.d.ts +49 -0
- package/dist/tokens-studio/utils.js +156 -0
- package/dist/types.d.ts +1 -0
- package/dist/vercel/cli.d.ts +4 -0
- package/dist/vercel/cli.js +70 -0
- package/dist/vercel/cli.test.js +86 -0
- package/dist/vercel/deployments.js +41 -0
- package/dist/vercel/waitForDeploymentReady.js +43 -0
- package/package.json +46 -6
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.flattenTokens = exports.formatValues = exports.resolveReferences = exports.deepMerge = exports.isToken = exports.maybeParseToPx = exports.maybeParseToNumber = exports.mapEntries = exports.kebabCase = exports.simplifyValues = void 0;
|
|
4
|
+
const remeda_1 = require("remeda");
|
|
5
|
+
/**
|
|
6
|
+
* Shared utility functions for tokens-studio transformations
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Simplifies nested token values by extracting the 'value' property
|
|
10
|
+
*/
|
|
11
|
+
const simplifyValues = (x) => {
|
|
12
|
+
if (typeof x === "string") {
|
|
13
|
+
return x;
|
|
14
|
+
}
|
|
15
|
+
else if (typeof x === "object" && !!x) {
|
|
16
|
+
if ("value" in x) {
|
|
17
|
+
return x.value;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return (0, remeda_1.mapValues)(x, exports.simplifyValues);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports.simplifyValues = simplifyValues;
|
|
25
|
+
/**
|
|
26
|
+
* Converts space-separated strings to camelCase
|
|
27
|
+
*/
|
|
28
|
+
const kebabCase = (x) => {
|
|
29
|
+
return x
|
|
30
|
+
.split(" ")
|
|
31
|
+
.map((t, i) => {
|
|
32
|
+
if (i === 0) {
|
|
33
|
+
return t.toLowerCase();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
return `${t[0].toUpperCase()}${t.substring(1).toLowerCase()}`;
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
.join("");
|
|
40
|
+
};
|
|
41
|
+
exports.kebabCase = kebabCase;
|
|
42
|
+
/**
|
|
43
|
+
* Maps over object entries with a custom mapper function
|
|
44
|
+
*/
|
|
45
|
+
const mapEntries = (obj, mapper) => {
|
|
46
|
+
return Object.fromEntries(Object.entries(obj).map(([key, value]) => mapper(key, value)));
|
|
47
|
+
};
|
|
48
|
+
exports.mapEntries = mapEntries;
|
|
49
|
+
/**
|
|
50
|
+
* Attempts to parse a string or number to a number, returns original if not possible
|
|
51
|
+
*/
|
|
52
|
+
const maybeParseToNumber = (x) => {
|
|
53
|
+
const parsed = Number(x);
|
|
54
|
+
if (Number.isNaN(parsed)) {
|
|
55
|
+
return x;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return parsed;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
exports.maybeParseToNumber = maybeParseToNumber;
|
|
62
|
+
/**
|
|
63
|
+
* Converts a value to pixels (adds 'px' suffix if it's a number)
|
|
64
|
+
*/
|
|
65
|
+
const maybeParseToPx = (x) => {
|
|
66
|
+
if (typeof x === "number") {
|
|
67
|
+
return `${x}px`;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return x;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
exports.maybeParseToPx = maybeParseToPx;
|
|
74
|
+
/**
|
|
75
|
+
* Type guard to check if an object is a token with value and type properties
|
|
76
|
+
*/
|
|
77
|
+
const isToken = (obj) => {
|
|
78
|
+
return typeof obj === "object" && "value" in obj && "type" in obj;
|
|
79
|
+
};
|
|
80
|
+
exports.isToken = isToken;
|
|
81
|
+
/**
|
|
82
|
+
* Deep merge utility for combining token objects
|
|
83
|
+
*/
|
|
84
|
+
const deepMerge = (mergedTokens, tokenData) => {
|
|
85
|
+
for (const key in tokenData) {
|
|
86
|
+
if (tokenData.hasOwnProperty(key)) {
|
|
87
|
+
if (typeof tokenData[key] === "object" &&
|
|
88
|
+
!Array.isArray(tokenData[key]) &&
|
|
89
|
+
tokenData[key] !== null) {
|
|
90
|
+
if (!mergedTokens[key]) {
|
|
91
|
+
mergedTokens[key] = {};
|
|
92
|
+
}
|
|
93
|
+
(0, exports.deepMerge)(mergedTokens[key], tokenData[key]);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
mergedTokens[key] = tokenData[key];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
exports.deepMerge = deepMerge;
|
|
102
|
+
/**
|
|
103
|
+
* Resolves token references (strings like "{path.to.token}") using a value map
|
|
104
|
+
*/
|
|
105
|
+
const resolveReferences = (obj, map) => {
|
|
106
|
+
const resolveValue = (value) => {
|
|
107
|
+
if (typeof value === "string" &&
|
|
108
|
+
value.startsWith("{") &&
|
|
109
|
+
value.endsWith("}")) {
|
|
110
|
+
const key = value.slice(1, -1);
|
|
111
|
+
return map.get(key) ?? value;
|
|
112
|
+
}
|
|
113
|
+
return value;
|
|
114
|
+
};
|
|
115
|
+
const traverse = (obj, currentPath = []) => {
|
|
116
|
+
for (const key in obj) {
|
|
117
|
+
const newPath = [...currentPath, key];
|
|
118
|
+
if (obj[key] && typeof obj[key] === "object") {
|
|
119
|
+
const maybeToken = obj[key];
|
|
120
|
+
if ((0, exports.isToken)(maybeToken)) {
|
|
121
|
+
const fullPath = newPath.join(".");
|
|
122
|
+
map.set(fullPath, maybeToken.value);
|
|
123
|
+
maybeToken.value = resolveValue(maybeToken.value);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
traverse(maybeToken, newPath);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
traverse(obj);
|
|
132
|
+
};
|
|
133
|
+
exports.resolveReferences = resolveReferences;
|
|
134
|
+
/**
|
|
135
|
+
* Formats token values by extracting the value property
|
|
136
|
+
*/
|
|
137
|
+
const formatValues = (v) => {
|
|
138
|
+
return v.value;
|
|
139
|
+
};
|
|
140
|
+
exports.formatValues = formatValues;
|
|
141
|
+
const flattenTokens = (v, depth = 0, transformKey) => {
|
|
142
|
+
if (typeof v === "object") {
|
|
143
|
+
if ((0, exports.isToken)(v)) {
|
|
144
|
+
return (0, exports.formatValues)(v);
|
|
145
|
+
}
|
|
146
|
+
return (0, exports.mapEntries)(v, (k, v) => {
|
|
147
|
+
return [
|
|
148
|
+
transformKey(k, depth + 1),
|
|
149
|
+
(0, exports.flattenTokens)(v, depth + 1, transformKey),
|
|
150
|
+
];
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return v;
|
|
154
|
+
};
|
|
155
|
+
exports.flattenTokens = flattenTokens;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Invalid transformer for testing error cases
|
|
4
|
+
* This transformer does not export a transform function
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
function someOtherFunction() {
|
|
8
|
+
return "not a transformer";
|
|
9
|
+
}
|
|
10
|
+
exports.default = {
|
|
11
|
+
someOtherFunction,
|
|
12
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Test transformer for tokens-studio CLI tests
|
|
4
|
+
* This transformer simply wraps the input tokens with metadata
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
function transform(input) {
|
|
8
|
+
return {
|
|
9
|
+
source: "test-transformer",
|
|
10
|
+
metadata: input.metadata,
|
|
11
|
+
tokens: input.tokenData,
|
|
12
|
+
processed: true,
|
|
13
|
+
transformedAt: new Date().toISOString(),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
exports.default = {
|
|
17
|
+
transform,
|
|
18
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI entry point for tokens-studio transformations
|
|
4
|
+
* Supports different transformer handlers via --handler argument
|
|
5
|
+
*/
|
|
6
|
+
import { ArgumentParser } from "argparse";
|
|
7
|
+
export declare const configParser: (parser: ArgumentParser) => void;
|
|
8
|
+
export declare const run: (parser: ArgumentParser) => Promise<void>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* CLI entry point for tokens-studio transformations
|
|
5
|
+
* Supports different transformer handlers via --handler argument
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.run = exports.configParser = void 0;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const config_1 = require("../config");
|
|
45
|
+
const utils_1 = require("./utils");
|
|
46
|
+
const require_1 = require("./require");
|
|
47
|
+
const readJsonFile = (filePath) => {
|
|
48
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
49
|
+
};
|
|
50
|
+
const loadTokensFromDirectory = (tokensDir) => {
|
|
51
|
+
const metadata = readJsonFile(path.join(tokensDir, "$metadata.json"));
|
|
52
|
+
const mergedTokens = {};
|
|
53
|
+
metadata.tokenSetOrder.forEach((tokenFile) => {
|
|
54
|
+
const tokenFilePath = path.join(tokensDir, `${tokenFile}.json`);
|
|
55
|
+
const tokenData = readJsonFile(tokenFilePath);
|
|
56
|
+
(0, utils_1.deepMerge)(mergedTokens, tokenData);
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
metadata,
|
|
60
|
+
tokenData: mergedTokens,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const configParser = (parser) => {
|
|
64
|
+
parser.add_argument("--config", {
|
|
65
|
+
help: "Path to TypeScript config file (default: looks for ixt.config.ts in current directory)",
|
|
66
|
+
});
|
|
67
|
+
const subparsers = parser.add_subparsers({
|
|
68
|
+
title: "tokens-studio commands",
|
|
69
|
+
dest: "subcommand",
|
|
70
|
+
help: "Use 'ixt tokens-studio <subcommand> --help' for more information",
|
|
71
|
+
});
|
|
72
|
+
// Transform subcommand
|
|
73
|
+
const transformParser = subparsers.add_parser("transform", {
|
|
74
|
+
help: "Transform tokens using a transformer file",
|
|
75
|
+
});
|
|
76
|
+
transformParser.add_argument("--handler", {
|
|
77
|
+
help: "Path to the transformer handler file (e.g., ./my-mui-transform.ts)",
|
|
78
|
+
});
|
|
79
|
+
transformParser.add_argument("--input", {
|
|
80
|
+
help: "Input directory containing token files",
|
|
81
|
+
});
|
|
82
|
+
transformParser.add_argument("--output", {
|
|
83
|
+
help: "Output file path (e.g., theme.json)",
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
exports.configParser = configParser;
|
|
87
|
+
const run = async (args) => {
|
|
88
|
+
switch (args.subcommand) {
|
|
89
|
+
case "transform":
|
|
90
|
+
// Load configuration
|
|
91
|
+
const config = await (0, config_1.loadConfig)(args.config);
|
|
92
|
+
// Merge CLI args with config, giving precedence to CLI args
|
|
93
|
+
const mergedConfig = (0, config_1.mergeConfigWithArgs)(config, {
|
|
94
|
+
handler: args.handler,
|
|
95
|
+
input: args.input,
|
|
96
|
+
output: args.output,
|
|
97
|
+
}, "tokensStudio");
|
|
98
|
+
// Validate required configuration
|
|
99
|
+
(0, config_1.validateRequiredConfig)(mergedConfig, ["handler", "output"]);
|
|
100
|
+
// Resolve handler path
|
|
101
|
+
const handlerPath = path.resolve(mergedConfig.handler);
|
|
102
|
+
if (!fs.existsSync(handlerPath)) {
|
|
103
|
+
throw new Error(`Handler file not found: ${handlerPath}`);
|
|
104
|
+
}
|
|
105
|
+
// Load the transformer module
|
|
106
|
+
console.log("Requiring handler:", handlerPath);
|
|
107
|
+
const transformerModule = await (0, require_1.ourRequire)(handlerPath);
|
|
108
|
+
if (!transformerModule.transform ||
|
|
109
|
+
typeof transformerModule.transform !== "function") {
|
|
110
|
+
throw new Error(`Handler file must export a 'transform' function: ${handlerPath}`);
|
|
111
|
+
}
|
|
112
|
+
// Load tokens from input directory
|
|
113
|
+
const inputDir = path.resolve(mergedConfig.input || "./tokens");
|
|
114
|
+
if (!fs.existsSync(inputDir)) {
|
|
115
|
+
throw new Error(`Input directory not found: ${inputDir}`);
|
|
116
|
+
}
|
|
117
|
+
const transformInput = loadTokensFromDirectory(inputDir);
|
|
118
|
+
// Apply transformation
|
|
119
|
+
const result = transformerModule.transform(transformInput);
|
|
120
|
+
const resultSorted = sortKeysRecursively(result);
|
|
121
|
+
// Write output
|
|
122
|
+
const outputPath = path.resolve(mergedConfig.output);
|
|
123
|
+
fs.writeFileSync(outputPath, JSON.stringify(resultSorted, null, 2));
|
|
124
|
+
console.log(`✅ Transformation complete! Output written to: ${outputPath}`);
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
throw new Error(`Unknown subcommand: ${args.subcommand}`);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
exports.run = run;
|
|
131
|
+
const sortKeysRecursively = (obj) => {
|
|
132
|
+
if (Array.isArray(obj)) {
|
|
133
|
+
return obj.map(sortKeysRecursively);
|
|
134
|
+
}
|
|
135
|
+
else if (obj !== null && typeof obj === "object") {
|
|
136
|
+
const sortedObj = {};
|
|
137
|
+
const sortedKeys = Object.keys(obj).sort((a, b) => {
|
|
138
|
+
// natural sort for numeric keys
|
|
139
|
+
const numA = parseFloat(a);
|
|
140
|
+
const numB = parseFloat(b);
|
|
141
|
+
if (!isNaN(numA) && !isNaN(numB)) {
|
|
142
|
+
return numA - numB;
|
|
143
|
+
}
|
|
144
|
+
return a.localeCompare(b);
|
|
145
|
+
});
|
|
146
|
+
sortedKeys.forEach((key) => {
|
|
147
|
+
const typedKey = key;
|
|
148
|
+
sortedObj[typedKey] = sortKeysRecursively(obj[typedKey]);
|
|
149
|
+
});
|
|
150
|
+
return sortedObj;
|
|
151
|
+
}
|
|
152
|
+
return obj;
|
|
153
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const vitest_1 = require("vitest");
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const argparse_1 = require("argparse");
|
|
40
|
+
const cli_1 = require("./cli");
|
|
41
|
+
const config = __importStar(require("../config"));
|
|
42
|
+
const require_1 = require("./require");
|
|
43
|
+
const testTransformer = __importStar(require("./__tests__/fixtures/test-transformer"));
|
|
44
|
+
// Mock dependencies
|
|
45
|
+
vitest_1.vi.mock("fs");
|
|
46
|
+
vitest_1.vi.mock("../config");
|
|
47
|
+
vitest_1.vi.mock("./utils", () => ({
|
|
48
|
+
deepMerge: vitest_1.vi.fn((target, source) => {
|
|
49
|
+
Object.assign(target, source);
|
|
50
|
+
}),
|
|
51
|
+
}));
|
|
52
|
+
vitest_1.vi.mock("./require", () => ({
|
|
53
|
+
ourRequire: vitest_1.vi.fn(),
|
|
54
|
+
}));
|
|
55
|
+
(0, vitest_1.describe)("tokens-studio CLI", () => {
|
|
56
|
+
const mockedFs = vitest_1.vi.mocked(fs);
|
|
57
|
+
const mockedConfig = vitest_1.vi.mocked(config);
|
|
58
|
+
// Test fixtures paths
|
|
59
|
+
const fixturesDir = path.join(__dirname, "__tests__", "fixtures");
|
|
60
|
+
const testTransformerPath = path.join(fixturesDir, "test-transformer.ts");
|
|
61
|
+
const tokensDir = path.join(fixturesDir, "tokens");
|
|
62
|
+
(0, vitest_1.beforeEach)(() => {
|
|
63
|
+
vitest_1.vi.clearAllMocks();
|
|
64
|
+
// Reset console.log spy
|
|
65
|
+
vitest_1.vi.spyOn(console, "log").mockImplementation(() => { });
|
|
66
|
+
// Mock fs.readFileSync to read actual fixture files
|
|
67
|
+
const originalReadFileSync = require("fs").readFileSync;
|
|
68
|
+
mockedFs.readFileSync.mockImplementation((filePath, encoding) => {
|
|
69
|
+
// Use real fs to read fixture files
|
|
70
|
+
return originalReadFileSync(filePath, encoding);
|
|
71
|
+
});
|
|
72
|
+
// Mock fs.writeFileSync
|
|
73
|
+
mockedFs.writeFileSync.mockImplementation(() => { });
|
|
74
|
+
// Mock default config functions
|
|
75
|
+
mockedConfig.loadConfig.mockResolvedValue({
|
|
76
|
+
tokensStudio: {
|
|
77
|
+
input: "./tokens",
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
mockedConfig.mergeConfigWithArgs.mockReturnValue({
|
|
81
|
+
input: tokensDir,
|
|
82
|
+
handler: testTransformerPath,
|
|
83
|
+
output: "./output.json",
|
|
84
|
+
});
|
|
85
|
+
mockedConfig.validateRequiredConfig.mockImplementation(() => { });
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.afterEach)(() => {
|
|
88
|
+
vitest_1.vi.restoreAllMocks();
|
|
89
|
+
// Restore original require if it was mocked
|
|
90
|
+
if (global.require !== require) {
|
|
91
|
+
global.require = require;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
(0, vitest_1.describe)("configParser", () => {
|
|
95
|
+
(0, vitest_1.it)("should configure argument parser with correct subcommands and options", () => {
|
|
96
|
+
const parser = new argparse_1.ArgumentParser({ description: "Test parser" });
|
|
97
|
+
const addArgumentSpy = vitest_1.vi.spyOn(parser, "add_argument");
|
|
98
|
+
const addSubparsersSpy = vitest_1.vi.spyOn(parser, "add_subparsers");
|
|
99
|
+
(0, cli_1.configParser)(parser);
|
|
100
|
+
// Check that config argument is added
|
|
101
|
+
(0, vitest_1.expect)(addArgumentSpy).toHaveBeenCalledWith("--config", {
|
|
102
|
+
help: "Path to TypeScript config file (default: looks for ixt.config.ts in current directory)",
|
|
103
|
+
});
|
|
104
|
+
// Check that subparsers are added
|
|
105
|
+
(0, vitest_1.expect)(addSubparsersSpy).toHaveBeenCalledWith({
|
|
106
|
+
title: "tokens-studio commands",
|
|
107
|
+
dest: "subcommand",
|
|
108
|
+
help: "Use 'ixt tokens-studio <subcommand> --help' for more information",
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
(0, vitest_1.describe)("run function", () => {
|
|
113
|
+
(0, vitest_1.describe)("transform subcommand", () => {
|
|
114
|
+
(0, vitest_1.it)("should call transformer with correct token data structure", async () => {
|
|
115
|
+
mockedFs.existsSync.mockReturnValue(true);
|
|
116
|
+
const mockTransform = vitest_1.vi.fn().mockReturnValue({ transformed: true });
|
|
117
|
+
// Setup require to return mocked transformer based on actual fixture
|
|
118
|
+
vitest_1.vi.mocked(require_1.ourRequire).mockImplementation(async (id) => {
|
|
119
|
+
if (id === testTransformerPath) {
|
|
120
|
+
return { transform: mockTransform };
|
|
121
|
+
}
|
|
122
|
+
return testTransformer.default;
|
|
123
|
+
});
|
|
124
|
+
const args = {
|
|
125
|
+
subcommand: "transform",
|
|
126
|
+
handler: testTransformerPath,
|
|
127
|
+
input: tokensDir,
|
|
128
|
+
output: "./output.json",
|
|
129
|
+
};
|
|
130
|
+
await (0, cli_1.run)(args);
|
|
131
|
+
// Verify transformer was called with correct structure
|
|
132
|
+
(0, vitest_1.expect)(mockTransform).toHaveBeenCalledWith({
|
|
133
|
+
metadata: { tokenSetOrder: ["base", "semantic"] },
|
|
134
|
+
tokenData: vitest_1.expect.objectContaining({
|
|
135
|
+
colors: vitest_1.expect.objectContaining({}),
|
|
136
|
+
spacing: vitest_1.expect.objectContaining({
|
|
137
|
+
xs: { value: "4px", type: "spacing" },
|
|
138
|
+
}),
|
|
139
|
+
components: vitest_1.expect.objectContaining({
|
|
140
|
+
button: {
|
|
141
|
+
padding: { value: "{spacing.sm}", type: "spacing" },
|
|
142
|
+
},
|
|
143
|
+
}),
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
(0, vitest_1.it)("should handle config validation errors", async () => {
|
|
148
|
+
mockedConfig.validateRequiredConfig.mockImplementation(() => {
|
|
149
|
+
throw new Error("Missing required configuration: handler");
|
|
150
|
+
});
|
|
151
|
+
const args = {
|
|
152
|
+
subcommand: "transform",
|
|
153
|
+
input: tokensDir,
|
|
154
|
+
output: "./output.json",
|
|
155
|
+
};
|
|
156
|
+
await (0, vitest_1.expect)((0, cli_1.run)(args)).rejects.toThrow("Missing required configuration: handler");
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tokens Studio module for @interactivethings/scripts
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities and transformers for working with
|
|
5
|
+
* tokens exported from Tokens Studio (Figma plugin).
|
|
6
|
+
*/
|
|
7
|
+
export { simplifyValues, kebabCase, mapEntries, maybeParseToNumber, maybeParseToPx, isToken, deepMerge, resolveReferences, formatValues, flattenTokens, } from "./utils";
|
|
8
|
+
export interface TransformInput {
|
|
9
|
+
metadata: {
|
|
10
|
+
tokenSetOrder: string[];
|
|
11
|
+
};
|
|
12
|
+
tokenData: any;
|
|
13
|
+
}
|
|
14
|
+
export * as cli from "./cli";
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tokens Studio module for @interactivethings/scripts
|
|
4
|
+
*
|
|
5
|
+
* This module provides utilities and transformers for working with
|
|
6
|
+
* tokens exported from Tokens Studio (Figma plugin).
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.cli = exports.flattenTokens = exports.formatValues = exports.resolveReferences = exports.deepMerge = exports.isToken = exports.maybeParseToPx = exports.maybeParseToNumber = exports.mapEntries = exports.kebabCase = exports.simplifyValues = void 0;
|
|
43
|
+
// Export all utility functions
|
|
44
|
+
var utils_1 = require("./utils");
|
|
45
|
+
Object.defineProperty(exports, "simplifyValues", { enumerable: true, get: function () { return utils_1.simplifyValues; } });
|
|
46
|
+
Object.defineProperty(exports, "kebabCase", { enumerable: true, get: function () { return utils_1.kebabCase; } });
|
|
47
|
+
Object.defineProperty(exports, "mapEntries", { enumerable: true, get: function () { return utils_1.mapEntries; } });
|
|
48
|
+
Object.defineProperty(exports, "maybeParseToNumber", { enumerable: true, get: function () { return utils_1.maybeParseToNumber; } });
|
|
49
|
+
Object.defineProperty(exports, "maybeParseToPx", { enumerable: true, get: function () { return utils_1.maybeParseToPx; } });
|
|
50
|
+
Object.defineProperty(exports, "isToken", { enumerable: true, get: function () { return utils_1.isToken; } });
|
|
51
|
+
Object.defineProperty(exports, "deepMerge", { enumerable: true, get: function () { return utils_1.deepMerge; } });
|
|
52
|
+
Object.defineProperty(exports, "resolveReferences", { enumerable: true, get: function () { return utils_1.resolveReferences; } });
|
|
53
|
+
Object.defineProperty(exports, "formatValues", { enumerable: true, get: function () { return utils_1.formatValues; } });
|
|
54
|
+
Object.defineProperty(exports, "flattenTokens", { enumerable: true, get: function () { return utils_1.flattenTokens; } });
|
|
55
|
+
// Export the CLI module (for internal use)
|
|
56
|
+
exports.cli = __importStar(require("./cli"));
|