@tokens-studio/tokenscript-schemas 0.0.10

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,645 @@
1
+ #!/usr/bin/env node
2
+ import cac from 'cac';
3
+ import ulog from 'ulog';
4
+ import { mkdir, writeFile, readFile, readdir, access } from 'fs/promises';
5
+ import { dirname, join } from 'path';
6
+
7
+ async function bundleSchemaFromDirectory(schemaDir, options) {
8
+ const schemaJsonPath = join(schemaDir, "schema.json");
9
+ const schemaContent = await readFile(schemaJsonPath, "utf-8");
10
+ const schema = JSON.parse(schemaContent);
11
+ if (schema.type === "function") {
12
+ return await inlineFunctionScriptReferences(
13
+ schemaDir,
14
+ schema,
15
+ options
16
+ );
17
+ } else {
18
+ return await inlineColorScriptReferences(schemaDir, schema, options);
19
+ }
20
+ }
21
+ async function inlineColorScriptReferences(schemaDir, schema, options) {
22
+ const result = JSON.parse(JSON.stringify(schema));
23
+ for (const initializer of result.initializers) {
24
+ if (initializer.script.script.startsWith("./")) {
25
+ const scriptPath = join(schemaDir, initializer.script.script.slice(2));
26
+ const scriptContent = await readFile(scriptPath, "utf-8");
27
+ initializer.script.script = scriptContent.trim();
28
+ }
29
+ if (options?.baseUrl) {
30
+ initializer.script.type = addBaseUrl(initializer.script.type, options.baseUrl);
31
+ }
32
+ }
33
+ for (const conversion of result.conversions) {
34
+ if (conversion.script.script.startsWith("./")) {
35
+ const scriptPath = join(schemaDir, conversion.script.script.slice(2));
36
+ const scriptContent = await readFile(scriptPath, "utf-8");
37
+ conversion.script.script = scriptContent.trim();
38
+ }
39
+ if (options?.baseUrl) {
40
+ conversion.script.type = addBaseUrl(conversion.script.type, options.baseUrl);
41
+ if (conversion.source !== "$self") {
42
+ conversion.source = addBaseUrl(conversion.source, options.baseUrl);
43
+ }
44
+ if (conversion.target !== "$self") {
45
+ conversion.target = addBaseUrl(conversion.target, options.baseUrl);
46
+ }
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+ async function inlineFunctionScriptReferences(schemaDir, schema, options) {
52
+ const result = JSON.parse(JSON.stringify(schema));
53
+ if (result.script.script.startsWith("./")) {
54
+ const scriptPath = join(schemaDir, result.script.script.slice(2));
55
+ const scriptContent = await readFile(scriptPath, "utf-8");
56
+ result.script.script = scriptContent.trim();
57
+ }
58
+ if (options?.baseUrl) {
59
+ result.script.type = addBaseUrl(result.script.type, options.baseUrl);
60
+ if (result.requirements) {
61
+ const baseUrl = options.baseUrl;
62
+ result.requirements = result.requirements.map((req) => addBaseUrl(req, baseUrl));
63
+ }
64
+ }
65
+ return result;
66
+ }
67
+ function addBaseUrl(uri, baseUrl) {
68
+ if (uri.includes("://")) {
69
+ return uri;
70
+ }
71
+ if (uri.startsWith("/")) {
72
+ const cleanBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
73
+ return `${cleanBaseUrl}${uri}`;
74
+ }
75
+ return uri;
76
+ }
77
+ var LOG_LEVELS = {
78
+ error: 1,
79
+ warn: 2,
80
+ info: 3,
81
+ log: 4,
82
+ debug: 5
83
+ };
84
+ var log = ulog("schema-registry");
85
+ var logLevel = process.env.LOG_LEVEL || "error";
86
+ log.level = LOG_LEVELS[logLevel] || LOG_LEVELS.error;
87
+
88
+ // src/utils/type.ts
89
+ var isSome = (v) => {
90
+ return v != null;
91
+ };
92
+
93
+ // src/utils/schema-uri.ts
94
+ function safeParseInt(value) {
95
+ const parsed = Number.parseInt(value, 10);
96
+ return Number.isNaN(parsed) ? null : parsed;
97
+ }
98
+ function parseSemverFromString(versionString) {
99
+ const parts = versionString.split(".");
100
+ const numbers = [];
101
+ for (const part of parts) {
102
+ const num = safeParseInt(part);
103
+ if (num === null) return null;
104
+ numbers.push(num);
105
+ }
106
+ if (numbers.length !== parts.length) return null;
107
+ if (numbers.length === 3) {
108
+ return { major: numbers[0], minor: numbers[1], patch: numbers[2] };
109
+ }
110
+ if (numbers.length === 2) {
111
+ return { major: numbers[0], minor: numbers[1] };
112
+ }
113
+ if (numbers.length === 1) {
114
+ return { major: numbers[0] };
115
+ }
116
+ return null;
117
+ }
118
+ function parseVersionString(versionString) {
119
+ return versionString === "latest" ? "latest" : parseSemverFromString(versionString);
120
+ }
121
+ function parseSchemaUri(uri) {
122
+ let baseUrl = "";
123
+ let pathname = uri;
124
+ try {
125
+ const url = new URL(uri);
126
+ baseUrl = `${url.protocol}//${url.host}`;
127
+ pathname = url.pathname;
128
+ } catch {
129
+ if (uri.includes("://")) {
130
+ return null;
131
+ }
132
+ pathname = uri;
133
+ }
134
+ const pathParts = pathname.split("/").filter((part) => part !== "");
135
+ if (pathParts.length < 5) {
136
+ return null;
137
+ }
138
+ if (pathParts[0] !== "api" || !pathParts[1].startsWith("v")) {
139
+ return null;
140
+ }
141
+ const category = pathParts[2];
142
+ if (category !== "schema" && category !== "core" && category !== "function") {
143
+ return null;
144
+ }
145
+ const name = pathParts[3];
146
+ const version = parseVersionString(pathParts[4]);
147
+ return {
148
+ baseUrl,
149
+ category,
150
+ name,
151
+ version
152
+ };
153
+ }
154
+ function extractSchemaName(uri) {
155
+ const components = parseSchemaUri(uri);
156
+ return components?.name || null;
157
+ }
158
+
159
+ // src/bundler/schema-dependency-resolver.ts
160
+ function extractRequirements(spec, options = {}) {
161
+ const requirements = [];
162
+ if (spec.type === "function") {
163
+ const funcSpec = spec;
164
+ if (funcSpec.requirements) {
165
+ requirements.push(...funcSpec.requirements);
166
+ }
167
+ } else if (spec.type === "color" && options.includeColorTypeDependencies) {
168
+ const colorSpec = spec;
169
+ for (const conversion of colorSpec.conversions || []) {
170
+ if (conversion.source !== "$self") {
171
+ requirements.push(conversion.source);
172
+ }
173
+ if (conversion.target !== "$self") {
174
+ requirements.push(conversion.target);
175
+ }
176
+ }
177
+ }
178
+ return requirements;
179
+ }
180
+ function resolveSchemaReference(uriOrName) {
181
+ const components = parseSchemaUri(uriOrName);
182
+ if (components) {
183
+ const type = components.category === "function" ? "function" : "type";
184
+ return {
185
+ slug: components.name,
186
+ type,
187
+ uri: uriOrName
188
+ };
189
+ }
190
+ const extractedName = extractSchemaName(uriOrName);
191
+ if (extractedName) {
192
+ return {
193
+ slug: extractedName,
194
+ type: "type",
195
+ // Default to type if we can't determine
196
+ uri: uriOrName
197
+ };
198
+ }
199
+ if (uriOrName && !uriOrName.includes("/")) {
200
+ return {
201
+ slug: uriOrName,
202
+ type: "type",
203
+ // Default to type
204
+ uri: ""
205
+ // No URI, just a slug
206
+ };
207
+ }
208
+ return null;
209
+ }
210
+ async function collectRequiredSchemas(slugOrUri, type, options = {}) {
211
+ const { baseUrl, schemasDir, ...extractOptions } = options;
212
+ const visited = /* @__PURE__ */ new Set();
213
+ const typeSchemas = /* @__PURE__ */ new Set();
214
+ const functionSchemas = /* @__PURE__ */ new Set();
215
+ async function traverse(currentSlugOrUri, currentType) {
216
+ const ref = resolveSchemaReference(currentSlugOrUri);
217
+ if (!ref) {
218
+ log.warn(`Could not resolve schema reference: ${currentSlugOrUri}`);
219
+ return;
220
+ }
221
+ const effectiveType = currentType || ref.type;
222
+ const slug = ref.slug;
223
+ const key = `${effectiveType}:${slug}`;
224
+ if (visited.has(key)) {
225
+ return;
226
+ }
227
+ visited.add(key);
228
+ let spec;
229
+ try {
230
+ const categoryDir = effectiveType === "type" ? "types" : "functions";
231
+ const resolvedSchemasDir = schemasDir || process.env.SCHEMAS_DIR || join(process.cwd(), "src/schemas");
232
+ const schemaDir = join(resolvedSchemasDir, categoryDir, slug);
233
+ spec = await bundleSchemaFromDirectory(schemaDir, baseUrl ? { baseUrl } : void 0);
234
+ } catch (error) {
235
+ log.warn(`Failed to load schema ${slug} (${effectiveType}):`, error);
236
+ return;
237
+ }
238
+ const requirements = extractRequirements(spec, extractOptions);
239
+ for (const reqUri of requirements) {
240
+ const reqRef = resolveSchemaReference(reqUri);
241
+ if (reqRef) {
242
+ if (reqRef.type === "function") {
243
+ functionSchemas.add(reqRef.slug);
244
+ } else {
245
+ typeSchemas.add(reqRef.slug);
246
+ }
247
+ await traverse(reqUri, reqRef.type);
248
+ }
249
+ }
250
+ }
251
+ await traverse(slugOrUri, type);
252
+ return {
253
+ types: Array.from(typeSchemas),
254
+ functions: Array.from(functionSchemas)
255
+ };
256
+ }
257
+ async function collectRequiredSchemasForList(schemas, options = {}) {
258
+ const allTypes = /* @__PURE__ */ new Set();
259
+ const allFunctions = /* @__PURE__ */ new Set();
260
+ for (const schema of schemas) {
261
+ const deps = await collectRequiredSchemas(schema.slug, schema.type, options);
262
+ if (schema.type === "function") {
263
+ allFunctions.add(schema.slug);
264
+ } else {
265
+ allTypes.add(schema.slug);
266
+ }
267
+ for (const t of deps.types) {
268
+ allTypes.add(t);
269
+ }
270
+ for (const f of deps.functions) {
271
+ allFunctions.add(f);
272
+ }
273
+ }
274
+ return {
275
+ types: Array.from(allTypes),
276
+ functions: Array.from(allFunctions)
277
+ };
278
+ }
279
+ async function collectDependencyTree(schemas, options = {}) {
280
+ const { baseUrl, schemasDir, ...extractOptions } = options;
281
+ const tree = /* @__PURE__ */ new Map();
282
+ for (const schema of schemas) {
283
+ const categoryDir = schema.type === "type" ? "types" : "functions";
284
+ const resolvedSchemasDir = schemasDir || process.env.SCHEMAS_DIR || join(process.cwd(), "src/schemas");
285
+ const schemaDir = join(resolvedSchemasDir, categoryDir, schema.slug);
286
+ try {
287
+ const spec = await bundleSchemaFromDirectory(schemaDir, baseUrl ? { baseUrl } : void 0);
288
+ const requirements = extractRequirements(spec, extractOptions);
289
+ const dependencySlugs = requirements.map((uri) => {
290
+ const ref = resolveSchemaReference(uri);
291
+ return ref ? `${ref.type}:${ref.slug}` : uri;
292
+ });
293
+ const key = `${schema.type}:${schema.slug}`;
294
+ tree.set(key, {
295
+ slug: schema.slug,
296
+ type: schema.type,
297
+ dependencies: dependencySlugs
298
+ });
299
+ } catch (error) {
300
+ log.warn(`Failed to load schema ${schema.slug} (${schema.type}):`, error);
301
+ }
302
+ }
303
+ return tree;
304
+ }
305
+
306
+ // src/bundler/selective-bundler.ts
307
+ async function detectSchemaType(slug, schemasDir) {
308
+ const typeDir = join(schemasDir, "types", slug);
309
+ const functionDir = join(schemasDir, "functions", slug);
310
+ try {
311
+ await access(typeDir);
312
+ return "type";
313
+ } catch {
314
+ }
315
+ try {
316
+ await access(functionDir);
317
+ return "function";
318
+ } catch {
319
+ }
320
+ return null;
321
+ }
322
+ async function bundleSelectiveSchemas(options) {
323
+ const schemasDir = options.schemasDir || join(process.cwd(), "src/schemas");
324
+ const baseUrl = options.baseUrl || "https://schema.tokenscript.dev.gcp.tokens.studio";
325
+ const parsedSchemas = await Promise.all(
326
+ options.schemas.map(async (slug) => {
327
+ if (slug.includes(":")) {
328
+ const [type, name] = slug.split(":");
329
+ return {
330
+ slug: name,
331
+ type: type === "function" ? "function" : "type"
332
+ };
333
+ }
334
+ const detectedType = await detectSchemaType(slug, schemasDir);
335
+ if (detectedType === null) {
336
+ throw new Error(
337
+ `Schema '${slug}' not found in types or functions directories. Use 'function:${slug}' or 'type:${slug}' prefix to be explicit.`
338
+ );
339
+ }
340
+ return { slug, type: detectedType };
341
+ })
342
+ );
343
+ const deps = await collectRequiredSchemasForList(parsedSchemas, {
344
+ baseUrl,
345
+ schemasDir,
346
+ includeColorTypeDependencies: true
347
+ });
348
+ const allParsedSchemas = [
349
+ ...deps.types.map((slug) => ({ slug, type: "type" })),
350
+ ...deps.functions.map((slug) => ({ slug, type: "function" }))
351
+ ];
352
+ const dependencyTree = await collectDependencyTree(allParsedSchemas, {
353
+ baseUrl,
354
+ schemasDir,
355
+ includeColorTypeDependencies: true
356
+ });
357
+ const allSchemas = [.../* @__PURE__ */ new Set([...deps.types, ...deps.functions])];
358
+ const bundledSchemas = [];
359
+ for (const typeSlug of deps.types) {
360
+ const schemaDir = join(schemasDir, "types", typeSlug);
361
+ const bundled = await bundleSchemaFromDirectory(schemaDir, { baseUrl });
362
+ if (bundled.type === "color") {
363
+ const uri = `${baseUrl}/api/v1/core/${typeSlug}/0/`;
364
+ bundledSchemas.push({
365
+ uri,
366
+ schema: bundled
367
+ });
368
+ }
369
+ }
370
+ for (const funcSlug of deps.functions) {
371
+ const schemaDir = join(schemasDir, "functions", funcSlug);
372
+ const bundled = await bundleSchemaFromDirectory(schemaDir, { baseUrl });
373
+ if (bundled.type === "function") {
374
+ const uri = `${baseUrl}/api/v1/function/${funcSlug}/0/`;
375
+ bundledSchemas.push({
376
+ uri,
377
+ schema: bundled
378
+ });
379
+ }
380
+ }
381
+ return {
382
+ schemas: bundledSchemas,
383
+ metadata: {
384
+ requestedSchemas: options.schemas,
385
+ resolvedDependencies: allSchemas,
386
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString()
387
+ },
388
+ dependencyTree
389
+ };
390
+ }
391
+
392
+ // src/cli/config-schema.ts
393
+ function validateBundleConfig(data) {
394
+ if (typeof data !== "object" || data === null) {
395
+ throw new Error("Config must be an object");
396
+ }
397
+ const config = data;
398
+ if (!Array.isArray(config.schemas)) {
399
+ throw new Error("Config must have a 'schemas' array");
400
+ }
401
+ if (!config.schemas.every((s) => typeof s === "string")) {
402
+ throw new Error("All schemas must be strings");
403
+ }
404
+ if (config.output !== void 0 && typeof config.output !== "string") {
405
+ throw new Error("Config 'output' must be a string if provided");
406
+ }
407
+ return {
408
+ schemas: config.schemas,
409
+ output: config.output
410
+ };
411
+ }
412
+
413
+ // src/cli/output-generator.ts
414
+ function generateOutput(options) {
415
+ const { schemas, includeHelper = true } = options;
416
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
417
+ const schemaList = schemas.map((s) => s.uri).join(", ");
418
+ const lines = [];
419
+ lines.push("// Auto-generated by @tokens-studio/tokenscript-schemas");
420
+ lines.push(`// Generated: ${timestamp}`);
421
+ lines.push(`// Schemas: ${schemaList}`);
422
+ lines.push("");
423
+ lines.push('import { Config } from "@tokens-studio/tokenscript-interpreter";');
424
+ lines.push("");
425
+ lines.push("export const SCHEMAS = [");
426
+ for (const entry of schemas) {
427
+ const schemaJson = JSON.stringify(entry.schema, null, 2);
428
+ const uriJson = JSON.stringify(entry.uri);
429
+ const indentedSchema = schemaJson.split("\n").map((line) => ` ${line}`).join("\n");
430
+ lines.push(` {`);
431
+ lines.push(` uri: ${uriJson},`);
432
+ lines.push(` schema: ${indentedSchema.trim()}`);
433
+ lines.push(` },`);
434
+ }
435
+ lines.push("];");
436
+ lines.push("");
437
+ if (includeHelper) {
438
+ lines.push("export function makeConfig() {");
439
+ lines.push(" return new Config().registerSchemas(SCHEMAS);");
440
+ lines.push("}");
441
+ lines.push("");
442
+ }
443
+ return lines.join("\n");
444
+ }
445
+
446
+ // src/cli/commands/bundle.ts
447
+ var log2 = ulog("bundle");
448
+ async function loadConfig(configPath) {
449
+ try {
450
+ const content = await readFile(configPath, "utf-8");
451
+ const parsed = JSON.parse(content);
452
+ return validateBundleConfig(parsed);
453
+ } catch (error) {
454
+ if (error.code === "ENOENT") {
455
+ throw new Error(`Config file not found: ${configPath}`);
456
+ }
457
+ throw error;
458
+ }
459
+ }
460
+ function formatDependencyTree(tree, requestedSchemas) {
461
+ const lines = [];
462
+ const visited = /* @__PURE__ */ new Set();
463
+ lines.push("Dependency tree:");
464
+ lines.push("");
465
+ const formatNode = (key, indent = "", isLast = true) => {
466
+ if (visited.has(key)) {
467
+ return;
468
+ }
469
+ visited.add(key);
470
+ const node = tree.get(key);
471
+ if (!node) return;
472
+ const prefix = indent + (isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ");
473
+ const label = `${node.type}:${node.slug}`;
474
+ lines.push(prefix + label);
475
+ if (node.dependencies.length > 0) {
476
+ const childIndent = indent + (isLast ? " " : "\u2502 ");
477
+ node.dependencies.forEach((dep, idx) => {
478
+ const isLastChild = idx === node.dependencies.length - 1;
479
+ const childKey = dep;
480
+ if (visited.has(childKey)) {
481
+ const childPrefix = childIndent + (isLastChild ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ");
482
+ lines.push(`${childPrefix + childKey} (already visited)`);
483
+ } else {
484
+ formatNode(childKey, childIndent, isLastChild);
485
+ }
486
+ });
487
+ }
488
+ };
489
+ requestedSchemas.forEach((schema, idx) => {
490
+ const typeKey = `type:${schema}`;
491
+ const funcKey = `function:${schema}`;
492
+ const key = tree.has(typeKey) ? typeKey : tree.has(funcKey) ? funcKey : schema;
493
+ formatNode(key, "", idx === requestedSchemas.length - 1);
494
+ });
495
+ return lines.join("\n");
496
+ }
497
+ function formatDryRunOutput(schemas, resolvedDependencies) {
498
+ const lines = [];
499
+ lines.push("Bundle preview:");
500
+ lines.push("");
501
+ lines.push(`Requested schemas: ${schemas.join(", ")}`);
502
+ lines.push(`Total schemas (with dependencies): ${resolvedDependencies.length}`);
503
+ lines.push("");
504
+ lines.push("Schemas to be bundled:");
505
+ for (const schema of resolvedDependencies.sort()) {
506
+ lines.push(` - ${schema}`);
507
+ }
508
+ return lines.join("\n");
509
+ }
510
+ async function bundleSchemas(schemas) {
511
+ const schemasDir = join(process.cwd(), "src/schemas");
512
+ log2.info("Bundling schemas:", schemas);
513
+ const result = await bundleSelectiveSchemas({
514
+ schemas,
515
+ schemasDir
516
+ });
517
+ log2.info(
518
+ `Resolved ${result.metadata.resolvedDependencies.length} schemas (including dependencies)`
519
+ );
520
+ const output = generateOutput({
521
+ schemas: result.schemas,
522
+ includeHelper: true
523
+ });
524
+ return {
525
+ output,
526
+ metadata: result.metadata,
527
+ dependencyTree: result.dependencyTree
528
+ };
529
+ }
530
+ async function handleBundleCommand(schemas, options = {}) {
531
+ try {
532
+ let configSchemas = schemas;
533
+ let outputPath = options.output || "./tokenscript-schemas.js";
534
+ if (isSome(options.config)) {
535
+ log2.info(`Loading config from ${options.config}`);
536
+ const config = await loadConfig(options.config);
537
+ configSchemas = config.schemas;
538
+ if (config.output) {
539
+ outputPath = config.output;
540
+ }
541
+ }
542
+ if (!configSchemas || configSchemas.length === 0) {
543
+ throw new Error("No schemas specified. Provide schemas as arguments or via --config");
544
+ }
545
+ const { output, metadata, dependencyTree } = await bundleSchemas(configSchemas);
546
+ console.log("");
547
+ console.log(formatDependencyTree(dependencyTree, metadata.requestedSchemas));
548
+ console.log("");
549
+ if (options.dryRun) {
550
+ const preview = formatDryRunOutput(metadata.requestedSchemas, metadata.resolvedDependencies);
551
+ console.log(preview);
552
+ return;
553
+ }
554
+ await mkdir(dirname(outputPath), { recursive: true });
555
+ await writeFile(outputPath, output, "utf-8");
556
+ log2.info(`Successfully bundled ${metadata.resolvedDependencies.length} schemas`);
557
+ log2.info(`Output written to: ${outputPath}`);
558
+ console.log(`\u2713 Bundled ${metadata.resolvedDependencies.length} schemas \u2192 ${outputPath}`);
559
+ } catch (error) {
560
+ log2.error("Bundle failed:", error);
561
+ throw error;
562
+ }
563
+ }
564
+ var log3 = ulog("list");
565
+ async function listSchemas(schemasDir = join(process.cwd(), "src/schemas"), options = {}) {
566
+ const showTypes = options.types || !options.types && !options.functions;
567
+ const showFunctions = options.functions || !options.types && !options.functions;
568
+ const types = [];
569
+ const functions = [];
570
+ if (showTypes) {
571
+ try {
572
+ const typesDir = join(schemasDir, "types");
573
+ const typeEntries = await readdir(typesDir, { withFileTypes: true });
574
+ types.push(
575
+ ...typeEntries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort()
576
+ );
577
+ } catch (error) {
578
+ log3.warn("Could not read types directory:", error);
579
+ }
580
+ }
581
+ if (showFunctions) {
582
+ try {
583
+ const functionsDir = join(schemasDir, "functions");
584
+ const funcEntries = await readdir(functionsDir, { withFileTypes: true });
585
+ functions.push(
586
+ ...funcEntries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort()
587
+ );
588
+ } catch (error) {
589
+ log3.warn("Could not read functions directory:", error);
590
+ }
591
+ }
592
+ return { types, functions };
593
+ }
594
+ function formatListOutput(result, options = {}) {
595
+ const lines = [];
596
+ const showTypes = options.types || !options.types && !options.functions;
597
+ const showFunctions = options.functions || !options.types && !options.functions;
598
+ if (showTypes && result.types.length > 0) {
599
+ lines.push("Types:");
600
+ for (const type of result.types) {
601
+ lines.push(` ${type}`);
602
+ }
603
+ }
604
+ if (showFunctions && result.functions.length > 0) {
605
+ if (lines.length > 0) lines.push("");
606
+ lines.push("Functions:");
607
+ for (const func of result.functions) {
608
+ lines.push(` function:${func}`);
609
+ }
610
+ }
611
+ if (lines.length === 0) {
612
+ lines.push("No schemas found.");
613
+ }
614
+ return lines.join("\n");
615
+ }
616
+ async function handleListCommand(options = {}) {
617
+ const result = await listSchemas(void 0, options);
618
+ const output = formatListOutput(result, options);
619
+ console.log(output);
620
+ }
621
+
622
+ // src/cli/index.ts
623
+ var log4 = ulog("cli");
624
+ var cli = cac("tokenscript-schemas");
625
+ cli.command("bundle [...schemas]", "Bundle schemas into a JS file").option("-c, --config <path>", "Path to config file").option("-o, --output <path>", "Output file path", { default: "./tokenscript-schemas.js" }).option("-d, --dry-run", "Preview what would be bundled without writing").action(async (schemas, options) => {
626
+ try {
627
+ await handleBundleCommand(schemas, options);
628
+ } catch (error) {
629
+ log4.error("Error:", error);
630
+ process.exit(1);
631
+ }
632
+ });
633
+ cli.command("list", "List available schemas").option("--types", "List only type schemas").option("--functions", "List only function schemas").action(async (options) => {
634
+ try {
635
+ await handleListCommand(options);
636
+ } catch (error) {
637
+ log4.error("Error:", error);
638
+ process.exit(1);
639
+ }
640
+ });
641
+ cli.help();
642
+ cli.version("0.0.10");
643
+ cli.parse();
644
+ //# sourceMappingURL=index.js.map
645
+ //# sourceMappingURL=index.js.map