@spectratools/graphic-designer-cli 0.3.2 → 0.6.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/README.md +32 -2
- package/dist/cli.js +1252 -517
- package/dist/index.d.ts +105 -5
- package/dist/index.js +1271 -513
- package/dist/qa.d.ts +14 -3
- package/dist/qa.js +361 -50
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +909 -431
- package/dist/{spec.schema-DhAI-tE8.d.ts → spec.schema-Dm_wOLTd.d.ts} +2028 -599
- package/dist/spec.schema.d.ts +1 -1
- package/dist/spec.schema.js +158 -10
- package/package.json +1 -1
package/dist/spec.schema.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import 'zod';
|
|
2
|
-
export { A as AutoLayoutConfig, B as BuiltInTheme,
|
|
2
|
+
export { A as AutoLayoutConfig, B as BuiltInTheme, e as CardElement, f as CodeBlockElement, ap as CodeBlockStyle, C as ConnectionElement, g as ConstraintSpec, j as Decorator, k as DesignCardSpec, l as DesignSafeFrame, D as DesignSpec, m as DesignTheme, n as DiagramElement, o as DiagramLayout, p as DiagramSpec, q as DrawBadge, r as DrawBezier, s as DrawCircle, b as DrawCommand, t as DrawFontFamily, u as DrawGradientRect, v as DrawLine, w as DrawPath, x as DrawPoint, y as DrawRect, z as DrawText, E as Element, F as FlowNodeElement, aq as FlowNodeShadow, G as Gradient, H as GradientOverlayDecorator, ar as GradientStop, K as GridLayoutConfig, L as ImageElement, M as LayoutConfig, as as LinearGradient, O as ManualLayoutConfig, at as RadialGradient, P as RainbowRuleDecorator, S as ShapeElement, U as StackLayoutConfig, V as TerminalElement, W as TextElement, c as Theme, X as ThemeInput, Y as VignetteDecorator, _ as builtInThemeBackgrounds, $ as builtInThemes, a1 as connectionElementSchema, a2 as defaultAutoLayout, a3 as defaultCanvas, a4 as defaultConstraints, a5 as defaultGridLayout, a6 as defaultLayout, a7 as defaultStackLayout, a8 as defaultTheme, a9 as deriveSafeFrame, aa as designSpecSchema, ab as diagramElementSchema, ac as diagramLayoutSchema, ad as diagramSpecSchema, ah as flowNodeElementSchema, ai as inferLayout, ak as parseDesignSpec, al as parseDiagramSpec, an as resolveTheme } from './spec.schema-Dm_wOLTd.js';
|
|
3
3
|
import '@napi-rs/canvas';
|
package/dist/spec.schema.js
CHANGED
|
@@ -3,7 +3,62 @@ import { z as z2 } from "zod";
|
|
|
3
3
|
|
|
4
4
|
// src/themes/builtin.ts
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
// src/utils/color.ts
|
|
8
|
+
var rgbaRegex = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([01](?:\.\d+)?|0?\.\d+)\s*)?\)$/;
|
|
9
|
+
var hexColorRegex = /^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
|
|
10
|
+
function toHex(n) {
|
|
11
|
+
return n.toString(16).padStart(2, "0");
|
|
12
|
+
}
|
|
13
|
+
function parseRgbaToHex(color) {
|
|
14
|
+
const match = rgbaRegex.exec(color);
|
|
15
|
+
if (!match) {
|
|
16
|
+
throw new Error(`Invalid rgb/rgba color: ${color}`);
|
|
17
|
+
}
|
|
18
|
+
const r = Number.parseInt(match[1], 10);
|
|
19
|
+
const g = Number.parseInt(match[2], 10);
|
|
20
|
+
const b = Number.parseInt(match[3], 10);
|
|
21
|
+
if (r > 255 || g > 255 || b > 255) {
|
|
22
|
+
throw new Error(`RGB channel values must be 0-255, got: ${color}`);
|
|
23
|
+
}
|
|
24
|
+
if (match[4] !== void 0) {
|
|
25
|
+
const a = Number.parseFloat(match[4]);
|
|
26
|
+
if (a < 0 || a > 1) {
|
|
27
|
+
throw new Error(`Alpha value must be 0-1, got: ${a}`);
|
|
28
|
+
}
|
|
29
|
+
const alphaByte = Math.round(a * 255);
|
|
30
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}${toHex(alphaByte)}`;
|
|
31
|
+
}
|
|
32
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
33
|
+
}
|
|
34
|
+
function isRgbaColor(color) {
|
|
35
|
+
return rgbaRegex.test(color);
|
|
36
|
+
}
|
|
37
|
+
function isHexColor(color) {
|
|
38
|
+
return hexColorRegex.test(color);
|
|
39
|
+
}
|
|
40
|
+
function normalizeColor(color) {
|
|
41
|
+
if (isHexColor(color)) {
|
|
42
|
+
return color;
|
|
43
|
+
}
|
|
44
|
+
if (isRgbaColor(color)) {
|
|
45
|
+
return parseRgbaToHex(color);
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Expected #RRGGBB, #RRGGBBAA, rgb(), or rgba() color, got: ${color}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/themes/builtin.ts
|
|
51
|
+
var colorHexSchema = z.string().refine(
|
|
52
|
+
(v) => {
|
|
53
|
+
try {
|
|
54
|
+
normalizeColor(v);
|
|
55
|
+
return true;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{ message: "Expected #RRGGBB, #RRGGBBAA, rgb(), or rgba() color" }
|
|
61
|
+
).transform((v) => normalizeColor(v));
|
|
7
62
|
var fontFamilySchema = z.string().min(1).max(120);
|
|
8
63
|
var codeThemeSchema = z.object({
|
|
9
64
|
background: colorHexSchema,
|
|
@@ -194,7 +249,17 @@ function resolveTheme(theme) {
|
|
|
194
249
|
}
|
|
195
250
|
|
|
196
251
|
// src/spec.schema.ts
|
|
197
|
-
var colorHexSchema2 = z2.string().
|
|
252
|
+
var colorHexSchema2 = z2.string().refine(
|
|
253
|
+
(v) => {
|
|
254
|
+
try {
|
|
255
|
+
normalizeColor(v);
|
|
256
|
+
return true;
|
|
257
|
+
} catch {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{ message: "Expected #RRGGBB, #RRGGBBAA, rgb(), or rgba() color" }
|
|
262
|
+
).transform((v) => normalizeColor(v));
|
|
198
263
|
var gradientStopSchema = z2.object({
|
|
199
264
|
offset: z2.number().min(0).max(1),
|
|
200
265
|
color: colorHexSchema2
|
|
@@ -379,13 +444,32 @@ var cardElementSchema = z2.object({
|
|
|
379
444
|
tone: z2.enum(["neutral", "accent", "success", "warning", "error"]).default("neutral"),
|
|
380
445
|
icon: z2.string().min(1).max(64).optional()
|
|
381
446
|
}).strict();
|
|
447
|
+
var flowNodeShadowSchema = z2.object({
|
|
448
|
+
color: colorHexSchema2.optional(),
|
|
449
|
+
blur: z2.number().min(0).max(64).default(8),
|
|
450
|
+
offsetX: z2.number().min(-32).max(32).default(0),
|
|
451
|
+
offsetY: z2.number().min(-32).max(32).default(0),
|
|
452
|
+
opacity: z2.number().min(0).max(1).default(0.3)
|
|
453
|
+
}).strict();
|
|
382
454
|
var flowNodeElementSchema = z2.object({
|
|
383
455
|
type: z2.literal("flow-node"),
|
|
384
456
|
id: z2.string().min(1).max(120),
|
|
385
|
-
shape: z2.enum([
|
|
457
|
+
shape: z2.enum([
|
|
458
|
+
"box",
|
|
459
|
+
"rounded-box",
|
|
460
|
+
"diamond",
|
|
461
|
+
"circle",
|
|
462
|
+
"pill",
|
|
463
|
+
"cylinder",
|
|
464
|
+
"parallelogram",
|
|
465
|
+
"hexagon"
|
|
466
|
+
]).default("rounded-box"),
|
|
386
467
|
label: z2.string().min(1).max(200),
|
|
387
468
|
sublabel: z2.string().min(1).max(300).optional(),
|
|
388
469
|
sublabelColor: colorHexSchema2.optional(),
|
|
470
|
+
sublabel2: z2.string().min(1).max(300).optional(),
|
|
471
|
+
sublabel2Color: colorHexSchema2.optional(),
|
|
472
|
+
sublabel2FontSize: z2.number().min(8).max(32).optional(),
|
|
389
473
|
labelColor: colorHexSchema2.optional(),
|
|
390
474
|
labelFontSize: z2.number().min(10).max(48).optional(),
|
|
391
475
|
color: colorHexSchema2.optional(),
|
|
@@ -394,20 +478,30 @@ var flowNodeElementSchema = z2.object({
|
|
|
394
478
|
cornerRadius: z2.number().min(0).max(64).optional(),
|
|
395
479
|
width: z2.number().int().min(40).max(800).optional(),
|
|
396
480
|
height: z2.number().int().min(30).max(600).optional(),
|
|
397
|
-
|
|
481
|
+
fillOpacity: z2.number().min(0).max(1).default(1),
|
|
482
|
+
opacity: z2.number().min(0).max(1).default(1),
|
|
483
|
+
badgeText: z2.string().min(1).max(32).optional(),
|
|
484
|
+
badgeColor: colorHexSchema2.optional(),
|
|
485
|
+
badgeBackground: colorHexSchema2.optional(),
|
|
486
|
+
badgePosition: z2.enum(["top", "inside-top"]).default("inside-top"),
|
|
487
|
+
shadow: flowNodeShadowSchema.optional()
|
|
398
488
|
}).strict();
|
|
399
489
|
var connectionElementSchema = z2.object({
|
|
400
490
|
type: z2.literal("connection"),
|
|
401
491
|
from: z2.string().min(1).max(120),
|
|
402
492
|
to: z2.string().min(1).max(120),
|
|
403
493
|
style: z2.enum(["solid", "dashed", "dotted"]).default("solid"),
|
|
494
|
+
strokeStyle: z2.enum(["solid", "dashed", "dotted"]).default("solid"),
|
|
404
495
|
arrow: z2.enum(["end", "start", "both", "none"]).default("end"),
|
|
405
496
|
label: z2.string().min(1).max(200).optional(),
|
|
406
497
|
labelPosition: z2.enum(["start", "middle", "end"]).default("middle"),
|
|
407
498
|
color: colorHexSchema2.optional(),
|
|
408
|
-
width: z2.number().min(0.5).max(
|
|
499
|
+
width: z2.number().min(0.5).max(10).optional(),
|
|
500
|
+
strokeWidth: z2.number().min(0.5).max(10).default(2),
|
|
409
501
|
arrowSize: z2.number().min(4).max(32).optional(),
|
|
410
|
-
opacity: z2.number().min(0).max(1).default(1)
|
|
502
|
+
opacity: z2.number().min(0).max(1).default(1),
|
|
503
|
+
routing: z2.enum(["auto", "orthogonal", "curve", "arc"]).default("auto"),
|
|
504
|
+
tension: z2.number().min(0.1).max(0.8).default(0.35)
|
|
411
505
|
}).strict();
|
|
412
506
|
var codeBlockStyleSchema = z2.object({
|
|
413
507
|
paddingVertical: z2.number().min(0).max(128).default(56),
|
|
@@ -476,6 +570,10 @@ var elementSchema = z2.discriminatedUnion("type", [
|
|
|
476
570
|
shapeElementSchema,
|
|
477
571
|
imageElementSchema
|
|
478
572
|
]);
|
|
573
|
+
var diagramCenterSchema = z2.object({
|
|
574
|
+
x: z2.number(),
|
|
575
|
+
y: z2.number()
|
|
576
|
+
}).strict();
|
|
479
577
|
var autoLayoutConfigSchema = z2.object({
|
|
480
578
|
mode: z2.literal("auto"),
|
|
481
579
|
algorithm: z2.enum(["layered", "stress", "force", "radial", "box"]).default("layered"),
|
|
@@ -483,7 +581,17 @@ var autoLayoutConfigSchema = z2.object({
|
|
|
483
581
|
nodeSpacing: z2.number().int().min(0).max(512).default(80),
|
|
484
582
|
rankSpacing: z2.number().int().min(0).max(512).default(120),
|
|
485
583
|
edgeRouting: z2.enum(["orthogonal", "polyline", "spline"]).default("polyline"),
|
|
486
|
-
aspectRatio: z2.number().min(0.5).max(3).optional()
|
|
584
|
+
aspectRatio: z2.number().min(0.5).max(3).optional(),
|
|
585
|
+
/** ID of the root node for radial layout. Only relevant when algorithm is 'radial'. */
|
|
586
|
+
radialRoot: z2.string().min(1).max(120).optional(),
|
|
587
|
+
/** Fixed radius in pixels for radial layout. Only relevant when algorithm is 'radial'. */
|
|
588
|
+
radialRadius: z2.number().positive().optional(),
|
|
589
|
+
/** Compaction strategy for radial layout. Only relevant when algorithm is 'radial'. */
|
|
590
|
+
radialCompaction: z2.enum(["none", "radial", "wedge"]).optional(),
|
|
591
|
+
/** Sort strategy for radial layout node ordering. Only relevant when algorithm is 'radial'. */
|
|
592
|
+
radialSortBy: z2.enum(["id", "connections"]).optional(),
|
|
593
|
+
/** Explicit center used by curve/arc connection routing. */
|
|
594
|
+
diagramCenter: diagramCenterSchema.optional()
|
|
487
595
|
}).strict();
|
|
488
596
|
var gridLayoutConfigSchema = z2.object({
|
|
489
597
|
mode: z2.literal("grid"),
|
|
@@ -491,13 +599,17 @@ var gridLayoutConfigSchema = z2.object({
|
|
|
491
599
|
gap: z2.number().int().min(0).max(256).default(24),
|
|
492
600
|
cardMinHeight: z2.number().int().min(32).max(4096).optional(),
|
|
493
601
|
cardMaxHeight: z2.number().int().min(32).max(4096).optional(),
|
|
494
|
-
equalHeight: z2.boolean().default(false)
|
|
602
|
+
equalHeight: z2.boolean().default(false),
|
|
603
|
+
/** Explicit center used by curve/arc connection routing. */
|
|
604
|
+
diagramCenter: diagramCenterSchema.optional()
|
|
495
605
|
}).strict();
|
|
496
606
|
var stackLayoutConfigSchema = z2.object({
|
|
497
607
|
mode: z2.literal("stack"),
|
|
498
608
|
direction: z2.enum(["vertical", "horizontal"]).default("vertical"),
|
|
499
609
|
gap: z2.number().int().min(0).max(256).default(24),
|
|
500
|
-
alignment: z2.enum(["start", "center", "end", "stretch"]).default("stretch")
|
|
610
|
+
alignment: z2.enum(["start", "center", "end", "stretch"]).default("stretch"),
|
|
611
|
+
/** Explicit center used by curve/arc connection routing. */
|
|
612
|
+
diagramCenter: diagramCenterSchema.optional()
|
|
501
613
|
}).strict();
|
|
502
614
|
var manualPositionSchema = z2.object({
|
|
503
615
|
x: z2.number().int(),
|
|
@@ -507,7 +619,9 @@ var manualPositionSchema = z2.object({
|
|
|
507
619
|
}).strict();
|
|
508
620
|
var manualLayoutConfigSchema = z2.object({
|
|
509
621
|
mode: z2.literal("manual"),
|
|
510
|
-
positions: z2.record(z2.string().min(1), manualPositionSchema).default({})
|
|
622
|
+
positions: z2.record(z2.string().min(1), manualPositionSchema).default({}),
|
|
623
|
+
/** Explicit center used by curve/arc connection routing. */
|
|
624
|
+
diagramCenter: diagramCenterSchema.optional()
|
|
511
625
|
}).strict();
|
|
512
626
|
var layoutConfigSchema = z2.discriminatedUnion("mode", [
|
|
513
627
|
autoLayoutConfigSchema,
|
|
@@ -559,6 +673,31 @@ var canvasSchema = z2.object({
|
|
|
559
673
|
padding: z2.number().int().min(0).max(256).default(defaultCanvas.padding)
|
|
560
674
|
}).strict();
|
|
561
675
|
var themeInputSchema = z2.union([builtInThemeSchema, themeSchema]);
|
|
676
|
+
var diagramPositionSchema = z2.object({
|
|
677
|
+
x: z2.number(),
|
|
678
|
+
y: z2.number(),
|
|
679
|
+
width: z2.number().positive(),
|
|
680
|
+
height: z2.number().positive()
|
|
681
|
+
}).strict();
|
|
682
|
+
var diagramElementSchema = z2.discriminatedUnion("type", [
|
|
683
|
+
flowNodeElementSchema,
|
|
684
|
+
connectionElementSchema
|
|
685
|
+
]);
|
|
686
|
+
var diagramLayoutSchema = z2.object({
|
|
687
|
+
mode: z2.enum(["manual", "auto"]).default("manual"),
|
|
688
|
+
positions: z2.record(z2.string(), diagramPositionSchema).optional(),
|
|
689
|
+
diagramCenter: diagramCenterSchema.optional()
|
|
690
|
+
}).strict();
|
|
691
|
+
var diagramSpecSchema = z2.object({
|
|
692
|
+
version: z2.literal(1),
|
|
693
|
+
canvas: z2.object({
|
|
694
|
+
width: z2.number().int().min(320).max(4096).default(1200),
|
|
695
|
+
height: z2.number().int().min(180).max(4096).default(675)
|
|
696
|
+
}).default({ width: 1200, height: 675 }),
|
|
697
|
+
theme: themeSchema.optional(),
|
|
698
|
+
elements: z2.array(diagramElementSchema).min(1),
|
|
699
|
+
layout: diagramLayoutSchema.default({ mode: "manual" })
|
|
700
|
+
}).strict();
|
|
562
701
|
var designSpecSchema = z2.object({
|
|
563
702
|
version: z2.literal(2).default(2),
|
|
564
703
|
canvas: canvasSchema.default(defaultCanvas),
|
|
@@ -583,12 +722,16 @@ function deriveSafeFrame(spec) {
|
|
|
583
722
|
height: spec.canvas.height - spec.canvas.padding * 2
|
|
584
723
|
};
|
|
585
724
|
}
|
|
725
|
+
function parseDiagramSpec(input) {
|
|
726
|
+
return diagramSpecSchema.parse(input);
|
|
727
|
+
}
|
|
586
728
|
function parseDesignSpec(input) {
|
|
587
729
|
return designSpecSchema.parse(input);
|
|
588
730
|
}
|
|
589
731
|
export {
|
|
590
732
|
builtInThemeBackgrounds,
|
|
591
733
|
builtInThemes,
|
|
734
|
+
connectionElementSchema,
|
|
592
735
|
defaultAutoLayout,
|
|
593
736
|
defaultCanvas,
|
|
594
737
|
defaultConstraints,
|
|
@@ -598,7 +741,12 @@ export {
|
|
|
598
741
|
defaultTheme,
|
|
599
742
|
deriveSafeFrame,
|
|
600
743
|
designSpecSchema,
|
|
744
|
+
diagramElementSchema,
|
|
745
|
+
diagramLayoutSchema,
|
|
746
|
+
diagramSpecSchema,
|
|
747
|
+
flowNodeElementSchema,
|
|
601
748
|
inferLayout,
|
|
602
749
|
parseDesignSpec,
|
|
750
|
+
parseDiagramSpec,
|
|
603
751
|
resolveTheme
|
|
604
752
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectratools/graphic-designer-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Deterministic visual content generator — code screenshots, terminal shots, flowcharts, and infographics. No browser dependency.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|