@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/cli.js +559 -319
- package/dist/index.d.ts +2 -2
- package/dist/index.js +559 -319
- package/dist/qa.d.ts +1 -1
- package/dist/qa.js +121 -41
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +627 -389
- package/dist/{spec.schema-DhAI-tE8.d.ts → spec.schema-BUTof436.d.ts} +625 -457
- package/dist/spec.schema.d.ts +1 -1
- package/dist/spec.schema.js +85 -4
- package/package.json +1 -1
package/dist/qa.d.ts
CHANGED
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
|
-
|
|
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().
|
|
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
|
-
|
|
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;
|
package/dist/renderer.d.ts
CHANGED
|
@@ -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-
|
|
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';
|