@spectratools/graphic-designer-cli 0.9.0 → 0.10.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 +163 -19
- package/dist/index.d.ts +6 -6
- package/dist/index.js +163 -19
- package/dist/qa.d.ts +1 -1
- package/dist/qa.js +18 -0
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +104 -17
- package/dist/{spec.schema-B_Z-KNqt.d.ts → spec.schema-B6sXTTou.d.ts} +1664 -1314
- package/dist/spec.schema.d.ts +1 -1
- package/dist/spec.schema.js +18 -0
- package/package.json +1 -1
package/dist/renderer.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { i as DEFAULT_GENERATOR_VERSION, S as LayoutSnapshot, a as Rect, R as RenderMetadata,
|
|
1
|
+
export { i as DEFAULT_GENERATOR_VERSION, S as IterationMeta, V as LayoutSnapshot, a as Rect, Y as RenderDesignOptions, R as RenderMetadata, Z as RenderResult, d as RenderedElement, a4 as WrittenArtifacts, a7 as computeSpecHash, aq as inferSidecarPath, at as renderDesign, av as writeRenderArtifacts } from './spec.schema-B6sXTTou.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import '@napi-rs/canvas';
|
package/dist/renderer.js
CHANGED
|
@@ -2008,16 +2008,6 @@ function drawBezier(ctx, points, style) {
|
|
|
2008
2008
|
ctx.quadraticCurveTo(penultimate.x, penultimate.y, last.x, last.y);
|
|
2009
2009
|
ctx.stroke();
|
|
2010
2010
|
}
|
|
2011
|
-
function drawOrthogonalPath(ctx, from, to, style) {
|
|
2012
|
-
const midX = (from.x + to.x) / 2;
|
|
2013
|
-
applyLineStyle(ctx, style);
|
|
2014
|
-
ctx.beginPath();
|
|
2015
|
-
ctx.moveTo(from.x, from.y);
|
|
2016
|
-
ctx.lineTo(midX, from.y);
|
|
2017
|
-
ctx.lineTo(midX, to.y);
|
|
2018
|
-
ctx.lineTo(to.x, to.y);
|
|
2019
|
-
ctx.stroke();
|
|
2020
|
-
}
|
|
2021
2011
|
|
|
2022
2012
|
// src/renderers/connection.ts
|
|
2023
2013
|
var ELLIPSE_KAPPA = 4 * (Math.sqrt(2) - 1) / 3;
|
|
@@ -2257,11 +2247,36 @@ function pointAlongPolyline(points, t) {
|
|
|
2257
2247
|
}
|
|
2258
2248
|
return points[points.length - 1];
|
|
2259
2249
|
}
|
|
2260
|
-
function
|
|
2250
|
+
function createConnectionGradient(ctx, start, end, fromColor, baseColor, toColor) {
|
|
2251
|
+
const gradient = ctx.createLinearGradient(start.x, start.y, end.x, end.y);
|
|
2252
|
+
gradient.addColorStop(0, fromColor);
|
|
2253
|
+
gradient.addColorStop(0.5, baseColor);
|
|
2254
|
+
gradient.addColorStop(1, toColor);
|
|
2255
|
+
return gradient;
|
|
2256
|
+
}
|
|
2257
|
+
function resolveConnectionStroke(ctx, start, end, fromColor, baseColor, toColor) {
|
|
2258
|
+
if (!fromColor || !toColor) {
|
|
2259
|
+
return baseColor;
|
|
2260
|
+
}
|
|
2261
|
+
return createConnectionGradient(ctx, start, end, fromColor, baseColor, toColor);
|
|
2262
|
+
}
|
|
2263
|
+
function drawOrthogonalPathWithStroke(ctx, from, to, style, stroke) {
|
|
2264
|
+
const midX = (from.x + to.x) / 2;
|
|
2265
|
+
ctx.strokeStyle = stroke;
|
|
2266
|
+
ctx.lineWidth = style.width;
|
|
2267
|
+
ctx.setLineDash(style.dash ?? []);
|
|
2268
|
+
ctx.beginPath();
|
|
2269
|
+
ctx.moveTo(from.x, from.y);
|
|
2270
|
+
ctx.lineTo(midX, from.y);
|
|
2271
|
+
ctx.lineTo(midX, to.y);
|
|
2272
|
+
ctx.lineTo(to.x, to.y);
|
|
2273
|
+
ctx.stroke();
|
|
2274
|
+
}
|
|
2275
|
+
function drawCubicInterpolatedPath(ctx, points, style, stroke) {
|
|
2261
2276
|
if (points.length < 2) {
|
|
2262
2277
|
return;
|
|
2263
2278
|
}
|
|
2264
|
-
ctx.strokeStyle =
|
|
2279
|
+
ctx.strokeStyle = stroke;
|
|
2265
2280
|
ctx.lineWidth = style.width;
|
|
2266
2281
|
ctx.setLineDash(style.dash ?? []);
|
|
2267
2282
|
ctx.beginPath();
|
|
@@ -2332,7 +2347,8 @@ function renderConnection(ctx, conn, fromBounds, toBounds, theme, edgeRoute, opt
|
|
|
2332
2347
|
conn.fromAnchor,
|
|
2333
2348
|
conn.toAnchor
|
|
2334
2349
|
);
|
|
2335
|
-
ctx.
|
|
2350
|
+
const stroke = resolveConnectionStroke(ctx, p0, p3, conn.fromColor, style.color, conn.toColor);
|
|
2351
|
+
ctx.strokeStyle = stroke;
|
|
2336
2352
|
ctx.lineWidth = style.width;
|
|
2337
2353
|
ctx.setLineDash(style.dash ?? []);
|
|
2338
2354
|
ctx.beginPath();
|
|
@@ -2374,7 +2390,8 @@ function renderConnection(ctx, conn, fromBounds, toBounds, theme, edgeRoute, opt
|
|
|
2374
2390
|
);
|
|
2375
2391
|
const [p0, cp1, cp2, pMid] = first;
|
|
2376
2392
|
const [, cp3, cp4, p3] = second;
|
|
2377
|
-
ctx.
|
|
2393
|
+
const stroke = resolveConnectionStroke(ctx, p0, p3, conn.fromColor, style.color, conn.toColor);
|
|
2394
|
+
ctx.strokeStyle = stroke;
|
|
2378
2395
|
ctx.lineWidth = style.width;
|
|
2379
2396
|
ctx.setLineDash(style.dash ?? []);
|
|
2380
2397
|
ctx.beginPath();
|
|
@@ -2417,10 +2434,18 @@ function renderConnection(ctx, conn, fromBounds, toBounds, theme, edgeRoute, opt
|
|
|
2417
2434
|
endPoint = linePoints[linePoints.length - 1] ?? linePoints[0];
|
|
2418
2435
|
startAngle = Math.atan2(startSegment.y - linePoints[0].y, startSegment.x - linePoints[0].x) + Math.PI;
|
|
2419
2436
|
endAngle = Math.atan2(endPoint.y - endStart.y, endPoint.x - endStart.x);
|
|
2437
|
+
const stroke = resolveConnectionStroke(
|
|
2438
|
+
ctx,
|
|
2439
|
+
startPoint,
|
|
2440
|
+
endPoint,
|
|
2441
|
+
conn.fromColor,
|
|
2442
|
+
style.color,
|
|
2443
|
+
conn.toColor
|
|
2444
|
+
);
|
|
2420
2445
|
if (useElkRoute) {
|
|
2421
|
-
drawCubicInterpolatedPath(ctx, linePoints, style);
|
|
2446
|
+
drawCubicInterpolatedPath(ctx, linePoints, style, stroke);
|
|
2422
2447
|
} else {
|
|
2423
|
-
|
|
2448
|
+
drawOrthogonalPathWithStroke(ctx, startPoint, endPoint, style, stroke);
|
|
2424
2449
|
}
|
|
2425
2450
|
labelPoint = pointAlongPolyline(linePoints, labelT);
|
|
2426
2451
|
}
|
|
@@ -2725,6 +2750,9 @@ function measureTextBounds(ctx, options) {
|
|
|
2725
2750
|
function angleBetween(from, to) {
|
|
2726
2751
|
return Math.atan2(to.y - from.y, to.x - from.x);
|
|
2727
2752
|
}
|
|
2753
|
+
function degreesToRadians(angle) {
|
|
2754
|
+
return angle * Math.PI / 180;
|
|
2755
|
+
}
|
|
2728
2756
|
function pathBounds(operations) {
|
|
2729
2757
|
let minX = Number.POSITIVE_INFINITY;
|
|
2730
2758
|
let minY = Number.POSITIVE_INFINITY;
|
|
@@ -2962,6 +2990,34 @@ function renderDrawCommands(ctx, commands, theme) {
|
|
|
2962
2990
|
});
|
|
2963
2991
|
break;
|
|
2964
2992
|
}
|
|
2993
|
+
case "arc": {
|
|
2994
|
+
const startAngle = degreesToRadians(command.startAngle);
|
|
2995
|
+
const endAngle = degreesToRadians(command.endAngle);
|
|
2996
|
+
withOpacity(ctx, command.opacity, () => {
|
|
2997
|
+
applyDrawShadow(ctx, command.shadow);
|
|
2998
|
+
ctx.beginPath();
|
|
2999
|
+
ctx.setLineDash(command.dash ?? []);
|
|
3000
|
+
ctx.lineWidth = command.width;
|
|
3001
|
+
ctx.strokeStyle = command.color;
|
|
3002
|
+
ctx.arc(command.center.x, command.center.y, command.radius, startAngle, endAngle);
|
|
3003
|
+
ctx.stroke();
|
|
3004
|
+
});
|
|
3005
|
+
rendered.push({
|
|
3006
|
+
id,
|
|
3007
|
+
kind: "draw",
|
|
3008
|
+
bounds: expandRect(
|
|
3009
|
+
{
|
|
3010
|
+
x: command.center.x - command.radius,
|
|
3011
|
+
y: command.center.y - command.radius,
|
|
3012
|
+
width: command.radius * 2,
|
|
3013
|
+
height: command.radius * 2
|
|
3014
|
+
},
|
|
3015
|
+
command.width / 2
|
|
3016
|
+
),
|
|
3017
|
+
foregroundColor: command.color
|
|
3018
|
+
});
|
|
3019
|
+
break;
|
|
3020
|
+
}
|
|
2965
3021
|
case "bezier": {
|
|
2966
3022
|
const points = command.points;
|
|
2967
3023
|
withOpacity(ctx, command.opacity, () => {
|
|
@@ -3545,6 +3601,21 @@ var drawLineSchema = z2.object({
|
|
|
3545
3601
|
opacity: z2.number().min(0).max(1).default(1),
|
|
3546
3602
|
shadow: drawShadowSchema.optional()
|
|
3547
3603
|
}).strict();
|
|
3604
|
+
var drawArcSchema = z2.object({
|
|
3605
|
+
type: z2.literal("arc"),
|
|
3606
|
+
center: z2.object({
|
|
3607
|
+
x: z2.number(),
|
|
3608
|
+
y: z2.number()
|
|
3609
|
+
}).strict(),
|
|
3610
|
+
radius: z2.number().positive(),
|
|
3611
|
+
startAngle: z2.number(),
|
|
3612
|
+
endAngle: z2.number(),
|
|
3613
|
+
color: colorHexSchema2.default("#FFFFFF"),
|
|
3614
|
+
width: z2.number().min(0.5).max(32).default(2),
|
|
3615
|
+
dash: z2.array(z2.number()).max(6).optional(),
|
|
3616
|
+
opacity: z2.number().min(0).max(1).default(1),
|
|
3617
|
+
shadow: drawShadowSchema.optional()
|
|
3618
|
+
}).strict();
|
|
3548
3619
|
var drawPointSchema = z2.object({
|
|
3549
3620
|
x: z2.number(),
|
|
3550
3621
|
y: z2.number()
|
|
@@ -3629,6 +3700,7 @@ var drawCommandSchema = z2.discriminatedUnion("type", [
|
|
|
3629
3700
|
drawCircleSchema,
|
|
3630
3701
|
drawTextSchema,
|
|
3631
3702
|
drawLineSchema,
|
|
3703
|
+
drawArcSchema,
|
|
3632
3704
|
drawBezierSchema,
|
|
3633
3705
|
drawPathSchema,
|
|
3634
3706
|
drawBadgeSchema,
|
|
@@ -3764,6 +3836,8 @@ var connectionElementSchema = z2.object({
|
|
|
3764
3836
|
label: z2.string().min(1).max(200).optional(),
|
|
3765
3837
|
labelPosition: z2.enum(["start", "middle", "end"]).default("middle"),
|
|
3766
3838
|
color: colorHexSchema2.optional(),
|
|
3839
|
+
fromColor: colorHexSchema2.optional(),
|
|
3840
|
+
toColor: colorHexSchema2.optional(),
|
|
3767
3841
|
width: z2.number().min(0.5).max(10).optional(),
|
|
3768
3842
|
strokeWidth: z2.number().min(0.5).max(10).default(2),
|
|
3769
3843
|
arrowSize: z2.number().min(4).max(32).optional(),
|
|
@@ -4149,6 +4223,18 @@ async function renderDesign(input, options = {}) {
|
|
|
4149
4223
|
const specHash = computeSpecHash(spec);
|
|
4150
4224
|
const generatorVersion = options.generatorVersion ?? DEFAULT_GENERATOR_VERSION;
|
|
4151
4225
|
const renderedAt = options.renderedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4226
|
+
const iteration = options.iteration;
|
|
4227
|
+
if (iteration) {
|
|
4228
|
+
if (!Number.isInteger(iteration.iteration) || iteration.iteration <= 0) {
|
|
4229
|
+
throw new Error("Iteration metadata requires iteration to be a positive integer.");
|
|
4230
|
+
}
|
|
4231
|
+
if (iteration.maxIterations != null && (!Number.isInteger(iteration.maxIterations) || iteration.maxIterations <= 0)) {
|
|
4232
|
+
throw new Error("Iteration metadata requires maxIterations to be a positive integer.");
|
|
4233
|
+
}
|
|
4234
|
+
if (iteration.maxIterations != null && iteration.maxIterations < iteration.iteration) {
|
|
4235
|
+
throw new Error("Iteration metadata requires maxIterations to be >= iteration.");
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4152
4238
|
const renderScale = resolveRenderScale(spec);
|
|
4153
4239
|
const canvas = createCanvas(spec.canvas.width * renderScale, spec.canvas.height * renderScale);
|
|
4154
4240
|
const ctx = canvas.getContext("2d");
|
|
@@ -4389,7 +4475,8 @@ async function renderDesign(input, options = {}) {
|
|
|
4389
4475
|
layout: {
|
|
4390
4476
|
safeFrame,
|
|
4391
4477
|
elements
|
|
4392
|
-
}
|
|
4478
|
+
},
|
|
4479
|
+
...iteration ? { iteration } : {}
|
|
4393
4480
|
};
|
|
4394
4481
|
return {
|
|
4395
4482
|
png: pngBuffer,
|