tokka 0.2.2 → 0.2.3
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/dist/index.js +493 -0
- package/package.json +1 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/commands/init.ts
|
|
7
|
+
import fs from "fs-extra";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import prompts from "prompts";
|
|
11
|
+
import ora from "ora";
|
|
12
|
+
import kleur from "kleur";
|
|
13
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
var __dirname = path.dirname(__filename);
|
|
15
|
+
async function initCommand(options) {
|
|
16
|
+
console.log(kleur.bold().cyan("\n\u2728 Welcome to tokka\n"));
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const systemsDir = path.join(__dirname, "../../systems");
|
|
19
|
+
const systems = await loadSystems(systemsDir);
|
|
20
|
+
let systemId = options.system;
|
|
21
|
+
if (!systemId) {
|
|
22
|
+
const response = await prompts({
|
|
23
|
+
type: "select",
|
|
24
|
+
name: "system",
|
|
25
|
+
message: "Choose a design system:",
|
|
26
|
+
choices: systems.map((s) => ({
|
|
27
|
+
title: `${s.name} - ${s.description}`,
|
|
28
|
+
value: s.id
|
|
29
|
+
})),
|
|
30
|
+
initial: 0
|
|
31
|
+
});
|
|
32
|
+
if (!response.system) {
|
|
33
|
+
console.log(kleur.red("\u2716 Cancelled"));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
systemId = response.system;
|
|
37
|
+
}
|
|
38
|
+
const selectedSystem = systems.find((s) => s.id === systemId);
|
|
39
|
+
if (!selectedSystem) {
|
|
40
|
+
console.error(kleur.red(`\u2716 System "${systemId}" not found`));
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
console.log(kleur.dim(`
|
|
44
|
+
Setting up ${selectedSystem.name}...
|
|
45
|
+
`));
|
|
46
|
+
const spinner = ora();
|
|
47
|
+
spinner.start("Copying design tokens...");
|
|
48
|
+
const systemPath = path.join(systemsDir, systemId);
|
|
49
|
+
const tokensPath = path.join(cwd, "tokens");
|
|
50
|
+
await fs.copy(path.join(systemPath, "tokens"), tokensPath);
|
|
51
|
+
await fs.copy(path.join(systemPath, "system.json"), path.join(cwd, "system.json"));
|
|
52
|
+
spinner.succeed("Design tokens copied");
|
|
53
|
+
await fs.ensureDir(path.join(cwd, "dist"));
|
|
54
|
+
if (options.packageManager !== "skip") {
|
|
55
|
+
spinner.start("Installing dependencies...");
|
|
56
|
+
spinner.succeed("Dependencies installed");
|
|
57
|
+
}
|
|
58
|
+
spinner.start("Building tokens...");
|
|
59
|
+
try {
|
|
60
|
+
const compilerPath = path.join(__dirname, "../compiler/index.js");
|
|
61
|
+
const { compile, generateCSSOutput, generateTailwindOutput, generateTypeScriptOutput } = await import(compilerPath);
|
|
62
|
+
const result = await compile({ cwd });
|
|
63
|
+
if (result.errors.length > 0) {
|
|
64
|
+
spinner.fail("Build failed");
|
|
65
|
+
for (const error of result.errors) {
|
|
66
|
+
console.error(kleur.red(` \u2716 ${error.message}`));
|
|
67
|
+
}
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
await fs.ensureDir(path.join(cwd, "dist/css"));
|
|
71
|
+
await fs.ensureDir(path.join(cwd, "dist/tailwind"));
|
|
72
|
+
await fs.ensureDir(path.join(cwd, "dist/ts"));
|
|
73
|
+
const systemData = await fs.readJSON(path.join(cwd, "system.json"));
|
|
74
|
+
const cssOutput = generateCSSOutput(result.tokens, systemData);
|
|
75
|
+
const tailwindOutput = generateTailwindOutput(result.tokens, systemData);
|
|
76
|
+
const tsOutput = generateTypeScriptOutput(result.tokens, systemData);
|
|
77
|
+
await fs.writeFile(path.join(cwd, "dist/css/tokens.css"), cssOutput["tokens.css"]);
|
|
78
|
+
await fs.writeFile(
|
|
79
|
+
path.join(cwd, "dist/tailwind/tokens.tailwind.js"),
|
|
80
|
+
tailwindOutput
|
|
81
|
+
);
|
|
82
|
+
await fs.writeFile(path.join(cwd, "dist/ts/tokens.ts"), tsOutput["tokens.ts"]);
|
|
83
|
+
spinner.succeed("Tokens built");
|
|
84
|
+
} catch (error) {
|
|
85
|
+
spinner.fail("Build failed");
|
|
86
|
+
console.error(kleur.red(error.message));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
const lockFile = {
|
|
90
|
+
version: "1",
|
|
91
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
92
|
+
system: {
|
|
93
|
+
id: systemId,
|
|
94
|
+
version: "1.0.0"
|
|
95
|
+
},
|
|
96
|
+
compiler: {
|
|
97
|
+
version: "1.0.0"
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
await fs.writeJSON(path.join(cwd, "tokka.lock"), lockFile, { spaces: 2 });
|
|
101
|
+
console.log(kleur.green().bold("\n\u2713 All done!\n"));
|
|
102
|
+
console.log("Next steps:");
|
|
103
|
+
console.log(kleur.cyan(" 1. ") + "Import tokens in your CSS:");
|
|
104
|
+
console.log(kleur.dim(' @import "./dist/css/tokens.css";'));
|
|
105
|
+
console.log(kleur.cyan(" 2. ") + "Add components:");
|
|
106
|
+
console.log(kleur.dim(" tokka add button input card"));
|
|
107
|
+
console.log(kleur.cyan(" 3. ") + "Start building!");
|
|
108
|
+
console.log("");
|
|
109
|
+
}
|
|
110
|
+
async function loadSystems(systemsDir) {
|
|
111
|
+
const entries = await fs.readdir(systemsDir, { withFileTypes: true });
|
|
112
|
+
const systems = [];
|
|
113
|
+
for (const entry of entries) {
|
|
114
|
+
if (entry.isDirectory() && entry.name !== "node_modules") {
|
|
115
|
+
const systemJsonPath = path.join(systemsDir, entry.name, "system.json");
|
|
116
|
+
if (await fs.pathExists(systemJsonPath)) {
|
|
117
|
+
const system = await fs.readJSON(systemJsonPath);
|
|
118
|
+
systems.push(system);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return systems;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/commands/add.ts
|
|
126
|
+
import fs2 from "fs-extra";
|
|
127
|
+
import path2 from "path";
|
|
128
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
129
|
+
import ora2 from "ora";
|
|
130
|
+
import kleur2 from "kleur";
|
|
131
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
132
|
+
var __dirname2 = path2.dirname(__filename2);
|
|
133
|
+
var COMPONENT_REGISTRY = {
|
|
134
|
+
accordion: "accordion.tsx",
|
|
135
|
+
alert: "alert.tsx",
|
|
136
|
+
"alert-dialog": "alert-dialog.tsx",
|
|
137
|
+
"aspect-ratio": "aspect-ratio.tsx",
|
|
138
|
+
avatar: "avatar.tsx",
|
|
139
|
+
badge: "badge.tsx",
|
|
140
|
+
breadcrumb: "breadcrumb.tsx",
|
|
141
|
+
button: "button.tsx",
|
|
142
|
+
calendar: "calendar.tsx",
|
|
143
|
+
card: "card.tsx",
|
|
144
|
+
carousel: "carousel.tsx",
|
|
145
|
+
chart: "chart.tsx",
|
|
146
|
+
checkbox: "checkbox.tsx",
|
|
147
|
+
collapsible: "collapsible.tsx",
|
|
148
|
+
combobox: "combobox.tsx",
|
|
149
|
+
command: "command.tsx",
|
|
150
|
+
"context-menu": "context-menu.tsx",
|
|
151
|
+
"data-table": "data-table.tsx",
|
|
152
|
+
"date-picker": "date-picker.tsx",
|
|
153
|
+
dialog: "dialog.tsx",
|
|
154
|
+
drawer: "drawer.tsx",
|
|
155
|
+
"dropdown-menu": "dropdown-menu.tsx",
|
|
156
|
+
form: "form.tsx",
|
|
157
|
+
"hover-card": "hover-card.tsx",
|
|
158
|
+
input: "input.tsx",
|
|
159
|
+
"input-otp": "input-otp.tsx",
|
|
160
|
+
label: "label.tsx",
|
|
161
|
+
menubar: "menubar.tsx",
|
|
162
|
+
"native-select": "native-select.tsx",
|
|
163
|
+
"navigation-menu": "navigation-menu.tsx",
|
|
164
|
+
pagination: "pagination.tsx",
|
|
165
|
+
popover: "popover.tsx",
|
|
166
|
+
progress: "progress.tsx",
|
|
167
|
+
"radio-group": "radio-group.tsx",
|
|
168
|
+
resizable: "resizable.tsx",
|
|
169
|
+
"scroll-area": "scroll-area.tsx",
|
|
170
|
+
select: "select.tsx",
|
|
171
|
+
separator: "separator.tsx",
|
|
172
|
+
sheet: "sheet.tsx",
|
|
173
|
+
sidebar: "sidebar.tsx",
|
|
174
|
+
skeleton: "skeleton.tsx",
|
|
175
|
+
slider: "slider.tsx",
|
|
176
|
+
sonner: "sonner.tsx",
|
|
177
|
+
spinner: "spinner.tsx",
|
|
178
|
+
switch: "switch.tsx",
|
|
179
|
+
table: "table.tsx",
|
|
180
|
+
tabs: "tabs.tsx",
|
|
181
|
+
textarea: "textarea.tsx",
|
|
182
|
+
toggle: "toggle.tsx",
|
|
183
|
+
"toggle-group": "toggle-group.tsx",
|
|
184
|
+
tooltip: "tooltip.tsx"
|
|
185
|
+
};
|
|
186
|
+
async function addCommand(components) {
|
|
187
|
+
const cwd = process.cwd();
|
|
188
|
+
const spinner = ora2();
|
|
189
|
+
const componentsDir = path2.join(cwd, "components");
|
|
190
|
+
await fs2.ensureDir(componentsDir);
|
|
191
|
+
for (const component of components) {
|
|
192
|
+
if (!COMPONENT_REGISTRY[component]) {
|
|
193
|
+
console.error(kleur2.red(`\u2716 Component "${component}" not found`));
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
spinner.start(`Adding ${component}...`);
|
|
197
|
+
const sourceFile = path2.join(
|
|
198
|
+
__dirname2,
|
|
199
|
+
"../../ui/src",
|
|
200
|
+
COMPONENT_REGISTRY[component]
|
|
201
|
+
);
|
|
202
|
+
const targetFile = path2.join(componentsDir, COMPONENT_REGISTRY[component]);
|
|
203
|
+
try {
|
|
204
|
+
if (await fs2.pathExists(sourceFile)) {
|
|
205
|
+
await fs2.copy(sourceFile, targetFile);
|
|
206
|
+
spinner.succeed(`Added ${component}`);
|
|
207
|
+
} else {
|
|
208
|
+
spinner.warn(`${component} not yet implemented (coming soon)`);
|
|
209
|
+
}
|
|
210
|
+
} catch (error) {
|
|
211
|
+
spinner.fail(`Failed to add ${component}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
console.log(kleur2.green("\n\u2713 Components added"));
|
|
215
|
+
console.log(kleur2.dim("Import them in your app:"));
|
|
216
|
+
console.log(kleur2.cyan(` import { Button } from "./components/button"`));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/commands/build.ts
|
|
220
|
+
import fs3 from "fs-extra";
|
|
221
|
+
import path3 from "path";
|
|
222
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
223
|
+
import ora3 from "ora";
|
|
224
|
+
import kleur3 from "kleur";
|
|
225
|
+
var __filename3 = fileURLToPath3(import.meta.url);
|
|
226
|
+
var __dirname3 = path3.dirname(__filename3);
|
|
227
|
+
async function buildCommand(options) {
|
|
228
|
+
const cwd = process.cwd();
|
|
229
|
+
const spinner = ora3("Building tokens...").start();
|
|
230
|
+
try {
|
|
231
|
+
const compilerPath = path3.join(__dirname3, "../compiler/index.js");
|
|
232
|
+
const { compile, generateCSSOutput, generateTailwindOutput, generateTypeScriptOutput } = await import(compilerPath);
|
|
233
|
+
const result = await compile({ cwd });
|
|
234
|
+
if (result.errors.length > 0) {
|
|
235
|
+
spinner.fail("Build failed");
|
|
236
|
+
for (const error of result.errors) {
|
|
237
|
+
console.error(kleur3.red(` \u2716 ${error.message}`));
|
|
238
|
+
}
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
await fs3.ensureDir(path3.join(cwd, "dist/css"));
|
|
242
|
+
await fs3.ensureDir(path3.join(cwd, "dist/tailwind"));
|
|
243
|
+
await fs3.ensureDir(path3.join(cwd, "dist/ts"));
|
|
244
|
+
const systemPath = path3.join(cwd, "system.json");
|
|
245
|
+
const system = await fs3.readJSON(systemPath);
|
|
246
|
+
const cssOutput = generateCSSOutput(result.tokens, system);
|
|
247
|
+
const tailwindOutput = generateTailwindOutput(result.tokens, system);
|
|
248
|
+
const tsOutput = generateTypeScriptOutput(result.tokens, system);
|
|
249
|
+
await fs3.writeFile(path3.join(cwd, "dist/css/tokens.css"), cssOutput["tokens.css"]);
|
|
250
|
+
await fs3.writeFile(path3.join(cwd, "dist/tailwind/tokens.tailwind.js"), tailwindOutput);
|
|
251
|
+
await fs3.writeFile(path3.join(cwd, "dist/ts/tokens.ts"), tsOutput["tokens.ts"]);
|
|
252
|
+
spinner.succeed(`Built ${result.tokens.length} tokens`);
|
|
253
|
+
if (result.warnings.length > 0) {
|
|
254
|
+
console.log(kleur3.yellow("\nWarnings:"));
|
|
255
|
+
for (const warning of result.warnings) {
|
|
256
|
+
console.log(kleur3.yellow(` \u26A0 ${warning.message}`));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
console.log(kleur3.green("\n\u2713 Build complete"));
|
|
260
|
+
console.log(kleur3.dim("\nOutputs:"));
|
|
261
|
+
console.log(kleur3.cyan(" \u2022 ") + "dist/css/tokens.css");
|
|
262
|
+
console.log(kleur3.cyan(" \u2022 ") + "dist/tailwind/tokens.tailwind.js");
|
|
263
|
+
console.log(kleur3.cyan(" \u2022 ") + "dist/ts/tokens.ts");
|
|
264
|
+
} catch (error) {
|
|
265
|
+
spinner.fail("Build failed");
|
|
266
|
+
console.error(kleur3.red(error.message));
|
|
267
|
+
if (error.stack) {
|
|
268
|
+
console.error(kleur3.dim(error.stack));
|
|
269
|
+
}
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/commands/validate.ts
|
|
275
|
+
import fs4 from "fs-extra";
|
|
276
|
+
import path4 from "path";
|
|
277
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
278
|
+
import kleur4 from "kleur";
|
|
279
|
+
var __filename4 = fileURLToPath4(import.meta.url);
|
|
280
|
+
var __dirname4 = path4.dirname(__filename4);
|
|
281
|
+
async function validateCommand() {
|
|
282
|
+
const cwd = process.cwd();
|
|
283
|
+
const configPath = path4.join(cwd, ".figmabase");
|
|
284
|
+
let config = {};
|
|
285
|
+
if (await fs4.pathExists(configPath)) {
|
|
286
|
+
config = await fs4.readJSON(configPath);
|
|
287
|
+
}
|
|
288
|
+
if (!config.advanced) {
|
|
289
|
+
console.error(kleur4.red("\n\u2716 Validation requires advanced mode"));
|
|
290
|
+
console.error(kleur4.dim(" Run: tokka enable advanced"));
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
console.log(kleur4.cyan("\n\u{1F50D} Validating tokens and manifests...\n"));
|
|
294
|
+
const compilerPath = path4.join(__dirname4, "../compiler/index.js");
|
|
295
|
+
const { compile, validateTokens, loadTokens, loadSystem } = await import(compilerPath);
|
|
296
|
+
try {
|
|
297
|
+
const tokens = await loadTokens({ cwd });
|
|
298
|
+
const system = await loadSystem({ cwd });
|
|
299
|
+
const errors = validateTokens(tokens.all, system.modes, { strict: true });
|
|
300
|
+
if (errors.length > 0) {
|
|
301
|
+
console.error(kleur4.red(`
|
|
302
|
+
\u2716 Found ${errors.length} error(s):
|
|
303
|
+
`));
|
|
304
|
+
for (const error of errors) {
|
|
305
|
+
console.error(kleur4.red(` \u2022 ${error.message}`));
|
|
306
|
+
}
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
console.log(kleur4.green("\u2713 All validations passed"));
|
|
310
|
+
} catch (error) {
|
|
311
|
+
console.error(kleur4.red("\n\u2716 Validation failed"));
|
|
312
|
+
console.error(kleur4.red(error.message));
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/commands/export.ts
|
|
318
|
+
import fs5 from "fs-extra";
|
|
319
|
+
import path5 from "path";
|
|
320
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
321
|
+
import ora4 from "ora";
|
|
322
|
+
import kleur5 from "kleur";
|
|
323
|
+
var __filename5 = fileURLToPath5(import.meta.url);
|
|
324
|
+
var __dirname5 = path5.dirname(__filename5);
|
|
325
|
+
async function exportCommand(target, options) {
|
|
326
|
+
if (target !== "figma") {
|
|
327
|
+
console.error(kleur5.red(`\u2716 Unknown export target: ${target}`));
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
const cwd = process.cwd();
|
|
331
|
+
const spinner = ora4("Exporting Figma artifacts...").start();
|
|
332
|
+
try {
|
|
333
|
+
const compilerPath = path5.join(__dirname5, "../compiler/index.js");
|
|
334
|
+
const { compile, generateFigmaTokenOutput } = await import(compilerPath);
|
|
335
|
+
const result = await compile({ cwd });
|
|
336
|
+
if (result.errors.length > 0) {
|
|
337
|
+
spinner.fail("Export failed");
|
|
338
|
+
for (const error of result.errors) {
|
|
339
|
+
console.error(kleur5.red(` \u2716 ${error.message}`));
|
|
340
|
+
}
|
|
341
|
+
process.exit(1);
|
|
342
|
+
}
|
|
343
|
+
const system = await fs5.readJSON(path5.join(cwd, "system.json"));
|
|
344
|
+
const figmaOutput = generateFigmaTokenOutput(result.tokens, system);
|
|
345
|
+
const outputDir = options.output || path5.join(cwd, "dist/figma");
|
|
346
|
+
await fs5.ensureDir(outputDir);
|
|
347
|
+
await fs5.writeFile(
|
|
348
|
+
path5.join(outputDir, "tokka.tokens.json"),
|
|
349
|
+
figmaOutput["tokka.tokens.json"]
|
|
350
|
+
);
|
|
351
|
+
spinner.succeed("Figma artifacts exported");
|
|
352
|
+
console.log(kleur5.green("\n\u2713 Export complete"));
|
|
353
|
+
console.log(kleur5.dim("\nGenerated:"));
|
|
354
|
+
console.log(kleur5.cyan(" \u2022 ") + path5.join(outputDir, "tokka.tokens.json"));
|
|
355
|
+
console.log(kleur5.dim("\nImport this file into Tokens Studio for Figma"));
|
|
356
|
+
} catch (error) {
|
|
357
|
+
spinner.fail("Export failed");
|
|
358
|
+
console.error(kleur5.red(error.message));
|
|
359
|
+
process.exit(1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/commands/list.ts
|
|
364
|
+
import fs6 from "fs-extra";
|
|
365
|
+
import path6 from "path";
|
|
366
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
367
|
+
import kleur6 from "kleur";
|
|
368
|
+
var __filename6 = fileURLToPath6(import.meta.url);
|
|
369
|
+
var __dirname6 = path6.dirname(__filename6);
|
|
370
|
+
async function listCommand(type, options) {
|
|
371
|
+
if (type === "systems") {
|
|
372
|
+
await listSystems(options.json);
|
|
373
|
+
} else if (type === "components") {
|
|
374
|
+
await listComponents(options.json);
|
|
375
|
+
} else {
|
|
376
|
+
console.error(kleur6.red(`\u2716 Unknown list type: ${type}`));
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async function listSystems(json) {
|
|
381
|
+
const systemsDir = path6.join(__dirname6, "../../systems");
|
|
382
|
+
const systems = await loadSystemsMetadata(systemsDir);
|
|
383
|
+
if (json) {
|
|
384
|
+
console.log(JSON.stringify(systems, null, 2));
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
console.log(kleur6.bold("\nAvailable Design Systems:\n"));
|
|
388
|
+
for (const system of systems) {
|
|
389
|
+
console.log(kleur6.cyan(` ${system.id}`));
|
|
390
|
+
console.log(kleur6.dim(` ${system.description}`));
|
|
391
|
+
console.log(kleur6.dim(` Tags: ${system.tags.join(", ")}`));
|
|
392
|
+
console.log("");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
async function listComponents(json) {
|
|
396
|
+
const components = [
|
|
397
|
+
{ name: "button", status: "available" },
|
|
398
|
+
{ name: "input", status: "available" },
|
|
399
|
+
{ name: "card", status: "available" },
|
|
400
|
+
{ name: "dialog", status: "coming-soon" },
|
|
401
|
+
{ name: "select", status: "coming-soon" }
|
|
402
|
+
];
|
|
403
|
+
if (json) {
|
|
404
|
+
console.log(JSON.stringify(components, null, 2));
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
console.log(kleur6.bold("\nAvailable Components:\n"));
|
|
408
|
+
for (const component of components) {
|
|
409
|
+
const status = component.status === "available" ? kleur6.green("\u2713 Available") : kleur6.yellow("\u25CB Coming soon");
|
|
410
|
+
console.log(` ${kleur6.cyan(component.name)} ${status}`);
|
|
411
|
+
}
|
|
412
|
+
console.log("");
|
|
413
|
+
}
|
|
414
|
+
async function loadSystemsMetadata(systemsDir) {
|
|
415
|
+
const entries = await fs6.readdir(systemsDir, { withFileTypes: true });
|
|
416
|
+
const systems = [];
|
|
417
|
+
for (const entry of entries) {
|
|
418
|
+
if (entry.isDirectory()) {
|
|
419
|
+
const systemJsonPath = path6.join(systemsDir, entry.name, "system.json");
|
|
420
|
+
if (await fs6.pathExists(systemJsonPath)) {
|
|
421
|
+
const system = await fs6.readJSON(systemJsonPath);
|
|
422
|
+
systems.push(system);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return systems;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/commands/gen.ts
|
|
430
|
+
import fs7 from "fs-extra";
|
|
431
|
+
import path7 from "path";
|
|
432
|
+
import kleur7 from "kleur";
|
|
433
|
+
async function genCommand(target) {
|
|
434
|
+
if (target !== "types") {
|
|
435
|
+
console.error(kleur7.red(`\u2716 Unknown generation target: ${target}`));
|
|
436
|
+
process.exit(1);
|
|
437
|
+
}
|
|
438
|
+
const cwd = process.cwd();
|
|
439
|
+
const configPath = path7.join(cwd, ".figmabase");
|
|
440
|
+
let config = {};
|
|
441
|
+
if (await fs7.pathExists(configPath)) {
|
|
442
|
+
config = await fs7.readJSON(configPath);
|
|
443
|
+
}
|
|
444
|
+
if (!config.advanced) {
|
|
445
|
+
console.error(kleur7.red("\n\u2716 Type generation requires advanced mode"));
|
|
446
|
+
console.error(kleur7.dim(" Run: tokka enable advanced"));
|
|
447
|
+
process.exit(1);
|
|
448
|
+
}
|
|
449
|
+
console.log(kleur7.cyan("\n\u{1F527} Generating TypeScript types from manifests...\n"));
|
|
450
|
+
console.log(kleur7.yellow("\u26A0 Type generation not yet implemented"));
|
|
451
|
+
console.log(kleur7.dim(" Coming in a future update"));
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/commands/enable.ts
|
|
455
|
+
import fs8 from "fs-extra";
|
|
456
|
+
import path8 from "path";
|
|
457
|
+
import kleur8 from "kleur";
|
|
458
|
+
async function enableCommand(feature) {
|
|
459
|
+
if (feature !== "advanced") {
|
|
460
|
+
console.error(kleur8.red(`\u2716 Unknown feature: ${feature}`));
|
|
461
|
+
process.exit(1);
|
|
462
|
+
}
|
|
463
|
+
const cwd = process.cwd();
|
|
464
|
+
const configPath = path8.join(cwd, ".figmabase");
|
|
465
|
+
console.log(kleur8.cyan("\n\u{1F680} Enabling advanced mode...\n"));
|
|
466
|
+
let config = {};
|
|
467
|
+
if (await fs8.pathExists(configPath)) {
|
|
468
|
+
config = await fs8.readJSON(configPath);
|
|
469
|
+
}
|
|
470
|
+
config.advanced = true;
|
|
471
|
+
await fs8.writeJSON(configPath, config, { spaces: 2 });
|
|
472
|
+
const componentsDir = path8.join(cwd, "tokens/components");
|
|
473
|
+
await fs8.ensureDir(componentsDir);
|
|
474
|
+
console.log(kleur8.green("\u2713 Advanced mode enabled\n"));
|
|
475
|
+
console.log("Advanced features now available:");
|
|
476
|
+
console.log(kleur8.cyan(" \u2022 ") + "tokka validate - Strict validation");
|
|
477
|
+
console.log(kleur8.cyan(" \u2022 ") + "tokka gen types - Generate TypeScript types");
|
|
478
|
+
console.log(kleur8.cyan(" \u2022 ") + "Component token catalogs (tokens/components/)");
|
|
479
|
+
console.log("");
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// src/index.ts
|
|
483
|
+
var program = new Command();
|
|
484
|
+
program.name("tokka").description("A shadcn-compatible UI foundation with a real token system").version("0.0.1");
|
|
485
|
+
program.command("init").description("Initialize a new tokka project").option("-s, --system <id>", "System to use (soft-saas, corporate, dark-mode, accessible, brutalist)").option("-p, --package-manager <pm>", "Package manager to use", "pnpm").option("--no-demo", "Skip demo app creation").action(initCommand);
|
|
486
|
+
program.command("add").description("Add components to your project").argument("<components...>", "Component names (button, input, card, etc.)").action(addCommand);
|
|
487
|
+
program.command("build").description("Build design tokens and outputs").option("-f, --force", "Force rebuild").action(buildCommand);
|
|
488
|
+
program.command("list").description("List available systems or components").argument("<type>", "What to list: systems or components").option("--json", "Output as JSON").action(listCommand);
|
|
489
|
+
program.command("export").description("Export Figma artifacts").argument("<target>", "Export target (figma)").option("-o, --output <dir>", "Output directory").action(exportCommand);
|
|
490
|
+
program.command("enable").description("Enable advanced features").argument("<feature>", "Feature to enable (advanced)").action(enableCommand);
|
|
491
|
+
program.command("validate").description("Validate tokens and manifests (requires advanced mode)").action(validateCommand);
|
|
492
|
+
program.command("gen").description("Generate code from manifests").argument("<target>", "What to generate (types)").action(genCommand);
|
|
493
|
+
program.parse();
|