@spectratools/graphic-designer-cli 0.3.2 → 0.4.0

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/qa.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RenderMetadata, D as DesignSpec } from './spec.schema-DhAI-tE8.js';
1
+ import { R as RenderMetadata, D as DesignSpec } from './spec.schema-BUTof436.js';
2
2
  import 'zod';
3
3
  import '@napi-rs/canvas';
4
4
 
package/dist/qa.js CHANGED
@@ -62,7 +62,98 @@ import { z as z2 } from "zod";
62
62
 
63
63
  // src/themes/builtin.ts
64
64
  import { z } from "zod";
65
- var colorHexSchema = z.string().regex(/^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/, "Expected #RRGGBB or #RRGGBBAA color");
65
+
66
+ // src/utils/color.ts
67
+ function parseChannel(hex, offset) {
68
+ return Number.parseInt(hex.slice(offset, offset + 2), 16);
69
+ }
70
+ function parseHexColor(hexColor) {
71
+ const normalized = hexColor.startsWith("#") ? hexColor.slice(1) : hexColor;
72
+ if (normalized.length !== 6 && normalized.length !== 8) {
73
+ throw new Error(`Unsupported color format: ${hexColor}`);
74
+ }
75
+ return {
76
+ r: parseChannel(normalized, 0),
77
+ g: parseChannel(normalized, 2),
78
+ b: parseChannel(normalized, 4)
79
+ };
80
+ }
81
+ var rgbaRegex = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([01](?:\.\d+)?|0?\.\d+)\s*)?\)$/;
82
+ var hexColorRegex = /^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
83
+ function toHex(n) {
84
+ return n.toString(16).padStart(2, "0");
85
+ }
86
+ function parseRgbaToHex(color) {
87
+ const match = rgbaRegex.exec(color);
88
+ if (!match) {
89
+ throw new Error(`Invalid rgb/rgba color: ${color}`);
90
+ }
91
+ const r = Number.parseInt(match[1], 10);
92
+ const g = Number.parseInt(match[2], 10);
93
+ const b = Number.parseInt(match[3], 10);
94
+ if (r > 255 || g > 255 || b > 255) {
95
+ throw new Error(`RGB channel values must be 0-255, got: ${color}`);
96
+ }
97
+ if (match[4] !== void 0) {
98
+ const a = Number.parseFloat(match[4]);
99
+ if (a < 0 || a > 1) {
100
+ throw new Error(`Alpha value must be 0-1, got: ${a}`);
101
+ }
102
+ const alphaByte = Math.round(a * 255);
103
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}${toHex(alphaByte)}`;
104
+ }
105
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
106
+ }
107
+ function isRgbaColor(color) {
108
+ return rgbaRegex.test(color);
109
+ }
110
+ function isHexColor(color) {
111
+ return hexColorRegex.test(color);
112
+ }
113
+ function normalizeColor(color) {
114
+ if (isHexColor(color)) {
115
+ return color;
116
+ }
117
+ if (isRgbaColor(color)) {
118
+ return parseRgbaToHex(color);
119
+ }
120
+ throw new Error(`Expected #RRGGBB, #RRGGBBAA, rgb(), or rgba() color, got: ${color}`);
121
+ }
122
+ function srgbToLinear(channel) {
123
+ const normalized = channel / 255;
124
+ if (normalized <= 0.03928) {
125
+ return normalized / 12.92;
126
+ }
127
+ return ((normalized + 0.055) / 1.055) ** 2.4;
128
+ }
129
+ function relativeLuminance(hexColor) {
130
+ const normalized = isRgbaColor(hexColor) ? parseRgbaToHex(hexColor) : hexColor;
131
+ const rgb = parseHexColor(normalized);
132
+ const r = srgbToLinear(rgb.r);
133
+ const g = srgbToLinear(rgb.g);
134
+ const b = srgbToLinear(rgb.b);
135
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
136
+ }
137
+ function contrastRatio(foreground, background) {
138
+ const fg = relativeLuminance(foreground);
139
+ const bg = relativeLuminance(background);
140
+ const lighter = Math.max(fg, bg);
141
+ const darker = Math.min(fg, bg);
142
+ return (lighter + 0.05) / (darker + 0.05);
143
+ }
144
+
145
+ // src/themes/builtin.ts
146
+ var colorHexSchema = z.string().refine(
147
+ (v) => {
148
+ try {
149
+ normalizeColor(v);
150
+ return true;
151
+ } catch {
152
+ return false;
153
+ }
154
+ },
155
+ { message: "Expected #RRGGBB, #RRGGBBAA, rgb(), or rgba() color" }
156
+ ).transform((v) => normalizeColor(v));
66
157
  var fontFamilySchema = z.string().min(1).max(120);
67
158
  var codeThemeSchema = z.object({
68
159
  background: colorHexSchema,
@@ -235,7 +326,17 @@ var builtInThemes = {
235
326
  var defaultTheme = builtInThemes.dark;
236
327
 
237
328
  // src/spec.schema.ts
238
- var colorHexSchema2 = z2.string().regex(/^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/, "Expected #RRGGBB or #RRGGBBAA color");
329
+ var colorHexSchema2 = z2.string().refine(
330
+ (v) => {
331
+ try {
332
+ normalizeColor(v);
333
+ return true;
334
+ } catch {
335
+ return false;
336
+ }
337
+ },
338
+ { message: "Expected #RRGGBB, #RRGGBBAA, rgb(), or rgba() color" }
339
+ ).transform((v) => normalizeColor(v));
239
340
  var gradientStopSchema = z2.object({
240
341
  offset: z2.number().min(0).max(1),
241
342
  color: colorHexSchema2
@@ -426,6 +527,9 @@ var flowNodeElementSchema = z2.object({
426
527
  label: z2.string().min(1).max(200),
427
528
  sublabel: z2.string().min(1).max(300).optional(),
428
529
  sublabelColor: colorHexSchema2.optional(),
530
+ sublabel2: z2.string().min(1).max(300).optional(),
531
+ sublabel2Color: colorHexSchema2.optional(),
532
+ sublabel2FontSize: z2.number().min(8).max(32).optional(),
429
533
  labelColor: colorHexSchema2.optional(),
430
534
  labelFontSize: z2.number().min(10).max(48).optional(),
431
535
  color: colorHexSchema2.optional(),
@@ -434,7 +538,12 @@ var flowNodeElementSchema = z2.object({
434
538
  cornerRadius: z2.number().min(0).max(64).optional(),
435
539
  width: z2.number().int().min(40).max(800).optional(),
436
540
  height: z2.number().int().min(30).max(600).optional(),
437
- opacity: z2.number().min(0).max(1).default(1)
541
+ fillOpacity: z2.number().min(0).max(1).default(1),
542
+ opacity: z2.number().min(0).max(1).default(1),
543
+ badgeText: z2.string().min(1).max(32).optional(),
544
+ badgeColor: colorHexSchema2.optional(),
545
+ badgeBackground: colorHexSchema2.optional(),
546
+ badgePosition: z2.enum(["top", "inside-top"]).default("inside-top")
438
547
  }).strict();
439
548
  var connectionElementSchema = z2.object({
440
549
  type: z2.literal("connection"),
@@ -523,7 +632,15 @@ var autoLayoutConfigSchema = z2.object({
523
632
  nodeSpacing: z2.number().int().min(0).max(512).default(80),
524
633
  rankSpacing: z2.number().int().min(0).max(512).default(120),
525
634
  edgeRouting: z2.enum(["orthogonal", "polyline", "spline"]).default("polyline"),
526
- aspectRatio: z2.number().min(0.5).max(3).optional()
635
+ aspectRatio: z2.number().min(0.5).max(3).optional(),
636
+ /** ID of the root node for radial layout. Only relevant when algorithm is 'radial'. */
637
+ radialRoot: z2.string().min(1).max(120).optional(),
638
+ /** Fixed radius in pixels for radial layout. Only relevant when algorithm is 'radial'. */
639
+ radialRadius: z2.number().positive().optional(),
640
+ /** Compaction strategy for radial layout. Only relevant when algorithm is 'radial'. */
641
+ radialCompaction: z2.enum(["none", "radial", "wedge"]).optional(),
642
+ /** Sort strategy for radial layout node ordering. Only relevant when algorithm is 'radial'. */
643
+ radialSortBy: z2.enum(["id", "connections"]).optional()
527
644
  }).strict();
528
645
  var gridLayoutConfigSchema = z2.object({
529
646
  mode: z2.literal("grid"),
@@ -627,43 +744,6 @@ function parseDesignSpec(input) {
627
744
  return designSpecSchema.parse(input);
628
745
  }
629
746
 
630
- // src/utils/color.ts
631
- function parseChannel(hex, offset) {
632
- return Number.parseInt(hex.slice(offset, offset + 2), 16);
633
- }
634
- function parseHexColor(hexColor) {
635
- const normalized = hexColor.startsWith("#") ? hexColor.slice(1) : hexColor;
636
- if (normalized.length !== 6 && normalized.length !== 8) {
637
- throw new Error(`Unsupported color format: ${hexColor}`);
638
- }
639
- return {
640
- r: parseChannel(normalized, 0),
641
- g: parseChannel(normalized, 2),
642
- b: parseChannel(normalized, 4)
643
- };
644
- }
645
- function srgbToLinear(channel) {
646
- const normalized = channel / 255;
647
- if (normalized <= 0.03928) {
648
- return normalized / 12.92;
649
- }
650
- return ((normalized + 0.055) / 1.055) ** 2.4;
651
- }
652
- function relativeLuminance(hexColor) {
653
- const rgb = parseHexColor(hexColor);
654
- const r = srgbToLinear(rgb.r);
655
- const g = srgbToLinear(rgb.g);
656
- const b = srgbToLinear(rgb.b);
657
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
658
- }
659
- function contrastRatio(foreground, background) {
660
- const fg = relativeLuminance(foreground);
661
- const bg = relativeLuminance(background);
662
- const lighter = Math.max(fg, bg);
663
- const darker = Math.min(fg, bg);
664
- return (lighter + 0.05) / (darker + 0.05);
665
- }
666
-
667
747
  // src/qa.ts
668
748
  function rectWithin(outer, inner) {
669
749
  return inner.x >= outer.x && inner.y >= outer.y && inner.x + inner.width <= outer.x + outer.width && inner.y + inner.height <= outer.y + outer.height;
@@ -1,3 +1,3 @@
1
- export { h as DEFAULT_GENERATOR_VERSION, z as LayoutSnapshot, a as Rect, R as RenderMetadata, J as RenderResult, d as RenderedElement, W as WrittenArtifacts, X as computeSpecHash, a9 as inferSidecarPath, ab as renderDesign, ad as writeRenderArtifacts } from './spec.schema-DhAI-tE8.js';
1
+ export { h as DEFAULT_GENERATOR_VERSION, z as LayoutSnapshot, a as Rect, R as RenderMetadata, J as RenderResult, d as RenderedElement, W as WrittenArtifacts, X as computeSpecHash, a9 as inferSidecarPath, ab as renderDesign, ad as writeRenderArtifacts } from './spec.schema-BUTof436.js';
2
2
  import 'zod';
3
3
  import '@napi-rs/canvas';