@nice2dev/design-tokens 1.0.28

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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,363 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createGenerator
4
+ } from "../chunk-GJ4A7ZWW.js";
5
+ import {
6
+ __commonJS,
7
+ __require
8
+ } from "../chunk-MCKGQKYU.js";
9
+
10
+ // package.json
11
+ var require_package = __commonJS({
12
+ "package.json"(exports, module) {
13
+ module.exports = {
14
+ name: "@nice2dev/design-tokens",
15
+ version: "1.0.28",
16
+ description: "W3C Design Tokens for Nice2Dev UI with CLI generator",
17
+ type: "module",
18
+ main: "./dist/index.cjs",
19
+ module: "./dist/index.js",
20
+ types: "./dist/index.d.ts",
21
+ sideEffects: false,
22
+ exports: {
23
+ ".": {
24
+ import: "./dist/index.js",
25
+ require: "./dist/index.cjs",
26
+ types: "./dist/index.d.ts"
27
+ },
28
+ "./tokens/*": "./tokens/*",
29
+ "./cli": "./dist/cli/index.js"
30
+ },
31
+ bin: {
32
+ "nice-tokens": "./dist/cli/index.js"
33
+ },
34
+ files: [
35
+ "dist",
36
+ "tokens"
37
+ ],
38
+ scripts: {
39
+ build: "tsup src/index.ts src/cli/index.ts --format esm,cjs --dts --clean",
40
+ dev: "tsup src/index.ts src/cli/index.ts --format esm,cjs --dts --watch",
41
+ generate: "node dist/cli/index.js generate",
42
+ test: "vitest run --passWithNoTests",
43
+ typecheck: "tsc --noEmit"
44
+ },
45
+ dependencies: {
46
+ "chroma-js": "^2.4.2",
47
+ commander: "^12.1.0",
48
+ "fast-glob": "^3.3.2"
49
+ },
50
+ devDependencies: {
51
+ "@types/chroma-js": "^2.4.4",
52
+ "@types/node": "^20.14.10",
53
+ tsup: "^8.3.5",
54
+ typescript: "^5.7.2",
55
+ vitest: "^2.1.8"
56
+ },
57
+ keywords: [
58
+ "design-tokens",
59
+ "w3c",
60
+ "css-variables",
61
+ "nice2dev",
62
+ "design-system"
63
+ ],
64
+ author: "Nice2Dev",
65
+ license: "MIT",
66
+ repository: {
67
+ type: "git",
68
+ url: "https://github.com/nicetogit/nice2dev-ui.git",
69
+ directory: "packages/design-tokens"
70
+ }
71
+ };
72
+ }
73
+ });
74
+
75
+ // src/cli/index.ts
76
+ import * as fs from "fs";
77
+ import * as path from "path";
78
+ import { Command } from "commander";
79
+ var pkg = require_package();
80
+ var program = new Command();
81
+ program.name("nice-tokens").description("Generate design tokens in various formats").version(pkg.version);
82
+ program.command("build").description("Build design tokens from JSON source files").option("-i, --input <dir>", "Input directory containing token JSON files", "./tokens").option("-o, --output <dir>", "Output directory for generated files", "./dist").option(
83
+ "-f, --formats <formats>",
84
+ "Output formats (comma-separated: css,scss,js,ts,json,tailwind)",
85
+ "css"
86
+ ).option("-p, --prefix <prefix>", "CSS variable prefix", "nice").option("--separate", "Generate separate files by category").option("--no-dark", "Exclude dark mode tokens").option("--no-components", "Exclude component tokens").option("--watch", "Watch for changes and rebuild").action(async (options) => {
87
+ const formats = options.formats.split(",").map((f) => f.trim());
88
+ console.log("\u{1F3A8} Nice2Dev Design Tokens Generator\n");
89
+ console.log(`\u{1F4C1} Input: ${path.resolve(options.input)}`);
90
+ console.log(`\u{1F4C1} Output: ${path.resolve(options.output)}`);
91
+ console.log(`\u{1F4C4} Formats: ${formats.join(", ")}`);
92
+ console.log("");
93
+ try {
94
+ const generator = createGenerator({
95
+ outputDir: options.output,
96
+ formats,
97
+ prefix: options.prefix,
98
+ separateFiles: options.separate,
99
+ includeDarkMode: options.dark !== false,
100
+ includeComponents: options.components !== false
101
+ });
102
+ generator.loadDirectory(options.input);
103
+ await generator.generate();
104
+ console.log("\n\u2705 Build complete!");
105
+ if (options.watch) {
106
+ console.log("\n\u{1F440} Watching for changes...");
107
+ const chokidar = await import("../esm-YLJOW3XL.js");
108
+ const watcher = chokidar.watch(path.join(options.input, "**/*.json"), {
109
+ ignoreInitial: true
110
+ });
111
+ watcher.on("change", async (file) => {
112
+ console.log(`
113
+ \u{1F504} File changed: ${path.basename(file)}`);
114
+ try {
115
+ const gen = createGenerator({
116
+ outputDir: options.output,
117
+ formats,
118
+ prefix: options.prefix,
119
+ separateFiles: options.separate,
120
+ includeDarkMode: options.dark !== false,
121
+ includeComponents: options.components !== false
122
+ });
123
+ gen.loadDirectory(options.input);
124
+ await gen.generate();
125
+ console.log("\u2705 Rebuild complete!");
126
+ } catch (err) {
127
+ console.error("\u274C Rebuild failed:", err.message);
128
+ }
129
+ });
130
+ }
131
+ } catch (err) {
132
+ console.error("\u274C Build failed:", err.message);
133
+ process.exit(1);
134
+ }
135
+ });
136
+ program.command("init").description("Initialize a new design tokens project").option("-d, --dir <dir>", "Directory to initialize", ".").action(async (options) => {
137
+ const dir = path.resolve(options.dir);
138
+ const tokensDir = path.join(dir, "tokens");
139
+ console.log("\u{1F3A8} Initializing Nice2Dev Design Tokens\n");
140
+ fs.mkdirSync(tokensDir, { recursive: true });
141
+ fs.mkdirSync(path.join(dir, "dist"), { recursive: true });
142
+ const colorsJson = {
143
+ color: {
144
+ $type: "color",
145
+ primary: {
146
+ "50": { $value: "#eff6ff" },
147
+ "100": { $value: "#dbeafe" },
148
+ "500": { $value: "#3b82f6" },
149
+ "600": { $value: "#2563eb" },
150
+ "700": { $value: "#1d4ed8" },
151
+ "900": { $value: "#1e3a8a" }
152
+ },
153
+ gray: {
154
+ "50": { $value: "#f9fafb" },
155
+ "100": { $value: "#f3f4f6" },
156
+ "500": { $value: "#6b7280" },
157
+ "700": { $value: "#374151" },
158
+ "900": { $value: "#111827" }
159
+ }
160
+ }
161
+ };
162
+ fs.writeFileSync(path.join(tokensDir, "colors.json"), JSON.stringify(colorsJson, null, 2));
163
+ const typographyJson = {
164
+ typography: {
165
+ fontFamily: {
166
+ $type: "fontFamily",
167
+ sans: { $value: ["Inter", "system-ui", "sans-serif"] },
168
+ mono: { $value: ["JetBrains Mono", "monospace"] }
169
+ },
170
+ fontSize: {
171
+ $type: "dimension",
172
+ xs: { $value: "0.75rem" },
173
+ sm: { $value: "0.875rem" },
174
+ base: { $value: "1rem" },
175
+ lg: { $value: "1.125rem" },
176
+ xl: { $value: "1.25rem" }
177
+ }
178
+ }
179
+ };
180
+ fs.writeFileSync(
181
+ path.join(tokensDir, "typography.json"),
182
+ JSON.stringify(typographyJson, null, 2)
183
+ );
184
+ const spacingJson = {
185
+ spacing: {
186
+ $type: "dimension",
187
+ "0": { $value: "0" },
188
+ "1": { $value: "0.25rem" },
189
+ "2": { $value: "0.5rem" },
190
+ "4": { $value: "1rem" },
191
+ "6": { $value: "1.5rem" },
192
+ "8": { $value: "2rem" }
193
+ }
194
+ };
195
+ fs.writeFileSync(path.join(tokensDir, "spacing.json"), JSON.stringify(spacingJson, null, 2));
196
+ console.log("\u2705 Created token files in ./tokens/");
197
+ console.log("");
198
+ console.log("Next steps:");
199
+ console.log(" 1. Edit tokens in ./tokens/*.json");
200
+ console.log(" 2. Run: nice-tokens build");
201
+ console.log(" 3. Import generated CSS/JS from ./dist/");
202
+ });
203
+ program.command("validate").description("Validate design token files").argument("[files...]", "Token files to validate").option("-d, --dir <dir>", "Directory containing token files").action(async (files, options) => {
204
+ const glob = __require("fast-glob");
205
+ let tokenFiles = files;
206
+ if (options.dir) {
207
+ tokenFiles = await glob(path.join(options.dir, "**/*.json"));
208
+ }
209
+ if (tokenFiles.length === 0) {
210
+ console.log("No token files specified");
211
+ process.exit(1);
212
+ }
213
+ console.log("\u{1F50D} Validating design tokens\n");
214
+ let hasErrors = false;
215
+ for (const file of tokenFiles) {
216
+ try {
217
+ const content = fs.readFileSync(file, "utf-8");
218
+ JSON.parse(content);
219
+ console.log(`\u2705 ${path.basename(file)}`);
220
+ } catch (err) {
221
+ console.log(`\u274C ${path.basename(file)}: ${err.message}`);
222
+ hasErrors = true;
223
+ }
224
+ }
225
+ if (hasErrors) {
226
+ console.log("\n\u274C Validation failed");
227
+ process.exit(1);
228
+ } else {
229
+ console.log("\n\u2705 All files valid");
230
+ }
231
+ });
232
+ program.command("convert").description("Convert between token formats").argument("<input>", "Input file or directory").argument("<output>", "Output file").option("-f, --format <format>", "Output format", "css").action(async (input, output, options) => {
233
+ const format = options.format;
234
+ console.log(`\u{1F504} Converting to ${format}...
235
+ `);
236
+ try {
237
+ const generator = createGenerator({
238
+ formats: [format],
239
+ outputDir: path.dirname(output)
240
+ });
241
+ const inputStat = fs.statSync(input);
242
+ if (inputStat.isDirectory()) {
243
+ generator.loadDirectory(input);
244
+ } else {
245
+ generator.load([input]);
246
+ }
247
+ await generator.generate();
248
+ console.log(`\u2705 Converted to ${output}`);
249
+ } catch (err) {
250
+ console.error("\u274C Conversion failed:", err.message);
251
+ process.exit(1);
252
+ }
253
+ });
254
+ program.command("info").description("Show information about token files").argument("<dir>", "Directory containing token files").action(async (dir) => {
255
+ const glob = __require("fast-glob");
256
+ const files = await glob(path.join(dir, "**/*.json"));
257
+ console.log("\u{1F4CA} Token Information\n");
258
+ console.log(`Directory: ${path.resolve(dir)}`);
259
+ console.log(`Files: ${files.length}`);
260
+ console.log("");
261
+ const generator = createGenerator();
262
+ generator.loadDirectory(dir);
263
+ const collection = generator.getCollection();
264
+ if (collection) {
265
+ console.log(`Total tokens: ${collection.tokens.length}`);
266
+ console.log("");
267
+ const byType = /* @__PURE__ */ new Map();
268
+ const byCategory = /* @__PURE__ */ new Map();
269
+ for (const token of collection.tokens) {
270
+ const type = token.type || "unknown";
271
+ byType.set(type, (byType.get(type) || 0) + 1);
272
+ const category = token.path[0] || "root";
273
+ byCategory.set(category, (byCategory.get(category) || 0) + 1);
274
+ }
275
+ console.log("By type:");
276
+ for (const [type, count] of byType.entries()) {
277
+ console.log(` ${type}: ${count}`);
278
+ }
279
+ console.log("\nBy category:");
280
+ for (const [category, count] of byCategory.entries()) {
281
+ console.log(` ${category}: ${count}`);
282
+ }
283
+ }
284
+ });
285
+ program.command("diff").description("Compare two token files or directories").argument("<source>", "Source file or directory").argument("<target>", "Target file or directory").action(async (source, target) => {
286
+ console.log("\u{1F50D} Comparing tokens\n");
287
+ const generatorA = createGenerator();
288
+ const generatorB = createGenerator();
289
+ const statA = fs.statSync(source);
290
+ const statB = fs.statSync(target);
291
+ if (statA.isDirectory()) {
292
+ generatorA.loadDirectory(source);
293
+ } else {
294
+ generatorA.load([source]);
295
+ }
296
+ if (statB.isDirectory()) {
297
+ generatorB.loadDirectory(target);
298
+ } else {
299
+ generatorB.load([target]);
300
+ }
301
+ const collectionA = generatorA.getCollection();
302
+ const collectionB = generatorB.getCollection();
303
+ if (!collectionA || !collectionB) {
304
+ console.error("Failed to load tokens");
305
+ process.exit(1);
306
+ }
307
+ const pathsA = new Set(collectionA.tokens.map((t) => t.path.join(".")));
308
+ const pathsB = new Set(collectionB.tokens.map((t) => t.path.join(".")));
309
+ const added = [];
310
+ const removed = [];
311
+ const changed = [];
312
+ for (const path2 of pathsB) {
313
+ if (!pathsA.has(path2)) {
314
+ added.push(path2);
315
+ }
316
+ }
317
+ for (const path2 of pathsA) {
318
+ if (!pathsB.has(path2)) {
319
+ removed.push(path2);
320
+ }
321
+ }
322
+ for (const tokenA of collectionA.tokens) {
323
+ const path2 = tokenA.path.join(".");
324
+ const tokenB = collectionB.byPath.get(path2);
325
+ if (tokenB && tokenA.resolvedValue !== tokenB.resolvedValue) {
326
+ changed.push(`${path2}: ${tokenA.resolvedValue} \u2192 ${tokenB.resolvedValue}`);
327
+ }
328
+ }
329
+ if (added.length === 0 && removed.length === 0 && changed.length === 0) {
330
+ console.log("No differences found");
331
+ return;
332
+ }
333
+ if (added.length > 0) {
334
+ console.log(`\u2795 Added (${added.length}):`);
335
+ for (const p of added.slice(0, 10)) {
336
+ console.log(` ${p}`);
337
+ }
338
+ if (added.length > 10) {
339
+ console.log(` ... and ${added.length - 10} more`);
340
+ }
341
+ console.log("");
342
+ }
343
+ if (removed.length > 0) {
344
+ console.log(`\u2796 Removed (${removed.length}):`);
345
+ for (const p of removed.slice(0, 10)) {
346
+ console.log(` ${p}`);
347
+ }
348
+ if (removed.length > 10) {
349
+ console.log(` ... and ${removed.length - 10} more`);
350
+ }
351
+ console.log("");
352
+ }
353
+ if (changed.length > 0) {
354
+ console.log(`\u{1F4DD} Changed (${changed.length}):`);
355
+ for (const p of changed.slice(0, 10)) {
356
+ console.log(` ${p}`);
357
+ }
358
+ if (changed.length > 10) {
359
+ console.log(` ... and ${changed.length - 10} more`);
360
+ }
361
+ }
362
+ });
363
+ program.parse();