abstract-image 13.3.6 → 14.0.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/CHANGELOG.md +4 -0
- package/lib/dynamic-image/dynamic-image.d.ts +3 -3
- package/lib/dynamic-image/dynamic-image.d.ts.map +1 -1
- package/lib/dynamic-image/dynamic-image.js.map +1 -1
- package/lib/dynamic-image/schema.d.ts +2 -234
- package/lib/dynamic-image/schema.d.ts.map +1 -1
- package/lib/dynamic-image/schema.js +198 -175
- package/lib/dynamic-image/schema.js.map +1 -1
- package/lib/dynamic-image/utils.d.ts +5 -2
- package/lib/dynamic-image/utils.d.ts.map +1 -1
- package/lib/dynamic-image/utils.js +10 -45
- package/lib/dynamic-image/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/dynamic-image/dynamic-image.ts +3 -3
- package/src/dynamic-image/schema.ts +200 -177
- package/src/dynamic-image/utils.ts +13 -55
|
@@ -1,54 +1,59 @@
|
|
|
1
1
|
import type { Schema } from "jsxpression";
|
|
2
2
|
|
|
3
|
-
export const baseSchema = {
|
|
3
|
+
export const baseSchema: Schema = {
|
|
4
4
|
elements: {
|
|
5
5
|
AbstractImage: {
|
|
6
6
|
description: "Root container — defines the image canvas and its coordinate system.",
|
|
7
7
|
props: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
width: {
|
|
11
|
+
type: "number",
|
|
12
|
+
description: "Total width of the image canvas (in px).",
|
|
13
|
+
},
|
|
14
|
+
height: {
|
|
15
|
+
type: "number",
|
|
16
|
+
description: "Total height of the image canvas (in px).",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ["width", "height"],
|
|
18
20
|
},
|
|
19
21
|
allowedChildren: ["Image", "Text", "Rectangle", "Ellipse", "Line", "Polyline", "Polygon", "Group"],
|
|
20
22
|
},
|
|
21
23
|
|
|
22
24
|
Group: {
|
|
23
25
|
description: "Groups elements together.",
|
|
24
|
-
props: {},
|
|
26
|
+
props: { type: "object", properties: {} },
|
|
25
27
|
allowedChildren: ["Image", "Text", "Rectangle", "Ellipse", "Line", "Polyline", "Polygon", "Group"],
|
|
26
28
|
},
|
|
27
29
|
|
|
28
30
|
Image: {
|
|
29
31
|
description: "Displays a raster image.",
|
|
30
32
|
props: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
src: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Source of the image (URL or asset ID).",
|
|
38
|
+
},
|
|
39
|
+
x: {
|
|
40
|
+
type: "number",
|
|
41
|
+
description: "X position in pixels.",
|
|
42
|
+
},
|
|
43
|
+
y: {
|
|
44
|
+
type: "number",
|
|
45
|
+
description: "Y position in pixels.",
|
|
46
|
+
},
|
|
47
|
+
width: {
|
|
48
|
+
type: "number",
|
|
49
|
+
description: "Display width in pixels.",
|
|
50
|
+
},
|
|
51
|
+
height: {
|
|
52
|
+
type: "number",
|
|
53
|
+
description: "Display height in pixels.",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
required: ["src"],
|
|
52
57
|
},
|
|
53
58
|
allowedChildren: [],
|
|
54
59
|
},
|
|
@@ -56,35 +61,38 @@ export const baseSchema = {
|
|
|
56
61
|
Ellipse: {
|
|
57
62
|
description: "Draws an ellipse using x, y, width, and height.",
|
|
58
63
|
props: {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
x: {
|
|
67
|
+
type: "number",
|
|
68
|
+
description: "X coordinate of the top-left of the ellipse box.",
|
|
69
|
+
},
|
|
70
|
+
y: {
|
|
71
|
+
type: "number",
|
|
72
|
+
description: "Y coordinate of the top-left of the ellipse box.",
|
|
73
|
+
},
|
|
74
|
+
width: {
|
|
75
|
+
type: "number",
|
|
76
|
+
description: "Box width.",
|
|
77
|
+
},
|
|
78
|
+
height: {
|
|
79
|
+
type: "number",
|
|
80
|
+
description: "Box height.",
|
|
81
|
+
},
|
|
82
|
+
stroke: {
|
|
83
|
+
type: "string",
|
|
84
|
+
format: "color",
|
|
85
|
+
description: "Stroke color (CSS color string).",
|
|
86
|
+
},
|
|
87
|
+
strokeWidth: {
|
|
88
|
+
type: "number",
|
|
89
|
+
description: "Stroke width in pixels.",
|
|
90
|
+
},
|
|
91
|
+
fill: {
|
|
92
|
+
type: "string",
|
|
93
|
+
format: "color",
|
|
94
|
+
description: "Fill color (inside the ellipse).",
|
|
95
|
+
},
|
|
88
96
|
},
|
|
89
97
|
},
|
|
90
98
|
allowedChildren: [],
|
|
@@ -93,30 +101,33 @@ export const baseSchema = {
|
|
|
93
101
|
Line: {
|
|
94
102
|
description: "Draws a straight line between two points.",
|
|
95
103
|
props: {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
type: "object",
|
|
105
|
+
properties: {
|
|
106
|
+
x1: {
|
|
107
|
+
type: "number",
|
|
108
|
+
description: "X coordinate of the start point.",
|
|
109
|
+
},
|
|
110
|
+
y1: {
|
|
111
|
+
type: "number",
|
|
112
|
+
description: "Y coordinate of the start point.",
|
|
113
|
+
},
|
|
114
|
+
x2: {
|
|
115
|
+
type: "number",
|
|
116
|
+
description: "X coordinate of the end point.",
|
|
117
|
+
},
|
|
118
|
+
y2: {
|
|
119
|
+
type: "number",
|
|
120
|
+
description: "Y coordinate of the end point.",
|
|
121
|
+
},
|
|
122
|
+
stroke: {
|
|
123
|
+
type: "string",
|
|
124
|
+
format: "color",
|
|
125
|
+
description: "Stroke color of the line.",
|
|
126
|
+
},
|
|
127
|
+
strokeWidth: {
|
|
128
|
+
type: "number",
|
|
129
|
+
description: "Width of the stroke in px.",
|
|
130
|
+
},
|
|
120
131
|
},
|
|
121
132
|
},
|
|
122
133
|
allowedChildren: [],
|
|
@@ -125,20 +136,23 @@ export const baseSchema = {
|
|
|
125
136
|
Polyline: {
|
|
126
137
|
description: "A connected set of line segments (open shape).",
|
|
127
138
|
props: {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
type: "object",
|
|
140
|
+
properties: {
|
|
141
|
+
points: {
|
|
142
|
+
type: "string",
|
|
143
|
+
description: "List of points: 'x0,y0 x1,y1 x2,y2'.",
|
|
144
|
+
},
|
|
145
|
+
stroke: {
|
|
146
|
+
type: "string",
|
|
147
|
+
format: "color",
|
|
148
|
+
description: "Stroke color.",
|
|
149
|
+
},
|
|
150
|
+
strokeWidth: {
|
|
151
|
+
type: "number",
|
|
152
|
+
description: "Stroke width in px.",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
required: ["points"],
|
|
142
156
|
},
|
|
143
157
|
allowedChildren: [],
|
|
144
158
|
},
|
|
@@ -146,25 +160,28 @@ export const baseSchema = {
|
|
|
146
160
|
Polygon: {
|
|
147
161
|
description: "A closed polygon shape.",
|
|
148
162
|
props: {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
type: "object",
|
|
164
|
+
properties: {
|
|
165
|
+
points: {
|
|
166
|
+
type: "string",
|
|
167
|
+
description: "List of vertex points: 'x0,y0 x1,y1 ...'.",
|
|
168
|
+
},
|
|
169
|
+
stroke: {
|
|
170
|
+
type: "string",
|
|
171
|
+
format: "color",
|
|
172
|
+
description: "Stroke color.",
|
|
173
|
+
},
|
|
174
|
+
strokeWidth: {
|
|
175
|
+
type: "number",
|
|
176
|
+
description: "Stroke width in px.",
|
|
177
|
+
},
|
|
178
|
+
fill: {
|
|
179
|
+
type: "string",
|
|
180
|
+
format: "color",
|
|
181
|
+
description: "Fill color of the polygon.",
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
required: ["points"],
|
|
168
185
|
},
|
|
169
186
|
allowedChildren: [],
|
|
170
187
|
},
|
|
@@ -172,39 +189,42 @@ export const baseSchema = {
|
|
|
172
189
|
Rectangle: {
|
|
173
190
|
description: "Draws a rectangle, optionally with rounded corners.",
|
|
174
191
|
props: {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
192
|
+
type: "object",
|
|
193
|
+
properties: {
|
|
194
|
+
x: {
|
|
195
|
+
type: "number",
|
|
196
|
+
description: "X position of the rectangle (top-left).",
|
|
197
|
+
},
|
|
198
|
+
y: {
|
|
199
|
+
type: "number",
|
|
200
|
+
description: "Y position of the rectangle (top-left).",
|
|
201
|
+
},
|
|
202
|
+
width: {
|
|
203
|
+
type: "number",
|
|
204
|
+
description: "Rectangle width in px.",
|
|
205
|
+
},
|
|
206
|
+
height: {
|
|
207
|
+
type: "number",
|
|
208
|
+
description: "Rectangle height in px.",
|
|
209
|
+
},
|
|
210
|
+
stroke: {
|
|
211
|
+
type: "string",
|
|
212
|
+
format: "color",
|
|
213
|
+
description: "Stroke color.",
|
|
214
|
+
},
|
|
215
|
+
strokeWidth: {
|
|
216
|
+
type: "number",
|
|
217
|
+
description: "Stroke width in px.",
|
|
218
|
+
},
|
|
219
|
+
fill: {
|
|
220
|
+
type: "string",
|
|
221
|
+
format: "color",
|
|
222
|
+
description: "Fill color of the rectangle.",
|
|
223
|
+
},
|
|
224
|
+
radius: {
|
|
225
|
+
type: "number",
|
|
226
|
+
description: "Corner radius in px (uniform).",
|
|
227
|
+
},
|
|
208
228
|
},
|
|
209
229
|
},
|
|
210
230
|
allowedChildren: [],
|
|
@@ -213,32 +233,35 @@ export const baseSchema = {
|
|
|
213
233
|
Text: {
|
|
214
234
|
description: "Renders a text element.",
|
|
215
235
|
props: {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
236
|
+
type: "object",
|
|
237
|
+
properties: {
|
|
238
|
+
x: {
|
|
239
|
+
type: "number",
|
|
240
|
+
description: "X position of the text anchor.",
|
|
241
|
+
},
|
|
242
|
+
y: {
|
|
243
|
+
type: "number",
|
|
244
|
+
description: "Y position of the text baseline.",
|
|
245
|
+
},
|
|
246
|
+
fontFamily: {
|
|
247
|
+
type: "string",
|
|
248
|
+
description: "Font family, e.g. 'Inter, system-ui'.",
|
|
249
|
+
},
|
|
250
|
+
fontSize: {
|
|
251
|
+
type: "number",
|
|
252
|
+
description: "Font size in pixels.",
|
|
253
|
+
},
|
|
254
|
+
fontWeight: {
|
|
255
|
+
type: "string",
|
|
256
|
+
description: "Font weight, e.g. 'bold', '700'.",
|
|
257
|
+
},
|
|
258
|
+
fill: {
|
|
259
|
+
type: "string",
|
|
260
|
+
format: "color",
|
|
261
|
+
description: "Fill color (text color).",
|
|
262
|
+
},
|
|
240
263
|
},
|
|
241
264
|
},
|
|
242
265
|
},
|
|
243
266
|
},
|
|
244
|
-
}
|
|
267
|
+
};
|
|
@@ -1,64 +1,22 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Schema } from "jsxpression";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const schema: Record<string, PropertySchema> = {};
|
|
3
|
+
type DataSchema = NonNullable<Schema["data"]>;
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return schema;
|
|
5
|
+
/** The JSON schema of data like the given, each value's schema inferred from it, an array's from its first item */
|
|
6
|
+
export function generateDataSchema(data: Record<string, unknown>): DataSchema {
|
|
7
|
+
return { type: "object", properties: Object.fromEntries(Object.entries(data).map(([key, value]) => [key, inferSchema(value)])) };
|
|
11
8
|
}
|
|
12
9
|
|
|
13
|
-
function
|
|
14
|
-
if (value ===
|
|
15
|
-
return {
|
|
16
|
-
type: "string",
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (typeof value === "string") {
|
|
21
|
-
return {
|
|
22
|
-
type: "string",
|
|
23
|
-
};
|
|
10
|
+
function inferSchema(value: unknown): DataSchema {
|
|
11
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
12
|
+
return { type: typeof value as "string" | "number" | "boolean" };
|
|
24
13
|
}
|
|
25
|
-
|
|
26
|
-
if (typeof value === "number") {
|
|
27
|
-
return {
|
|
28
|
-
type: "number",
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (typeof value === "boolean") {
|
|
33
|
-
return {
|
|
34
|
-
type: "boolean",
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (typeof value === "function") {
|
|
39
|
-
return {
|
|
40
|
-
type: "function",
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
14
|
if (Array.isArray(value)) {
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
type: "array",
|
|
48
|
-
shape: itemSchema,
|
|
49
|
-
};
|
|
15
|
+
return { type: "array", items: value.length > 0 ? inferSchema(value[0]) : {} };
|
|
50
16
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const shape: Record<string, PropertySchema> = {};
|
|
54
|
-
for (const [k, v] of Object.entries(value)) {
|
|
55
|
-
shape[k] = inferPropertySchema(v);
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
type: "object",
|
|
59
|
-
shape,
|
|
60
|
-
};
|
|
17
|
+
if (typeof value === "object" && value !== null) {
|
|
18
|
+
return { type: "object", properties: Object.fromEntries(Object.entries(value).map(([k, v]) => [k, inferSchema(v)])) };
|
|
61
19
|
}
|
|
62
|
-
|
|
63
|
-
return {
|
|
20
|
+
// null, undefined and functions, which JSON schemas don't describe
|
|
21
|
+
return {};
|
|
64
22
|
}
|