@realnation/builder-shared-sdk 2.4.1 → 2.5.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/souvenir/index.d.ts +2 -2
- package/dist/souvenir/index.d.ts.map +1 -1
- package/dist/souvenir/index.js +5 -5
- package/dist/souvenir/render.d.ts +15 -5
- package/dist/souvenir/render.d.ts.map +1 -1
- package/dist/souvenir/render.js +85 -34
- package/dist/souvenir/types.d.ts +35 -0
- package/dist/souvenir/types.d.ts.map +1 -1
- package/dist/souvenir/types.js +32 -0
- package/package.json +64 -64
package/dist/souvenir/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export * from './types.js';
|
|
12
12
|
export * from './imageFit.js';
|
|
13
13
|
export { wrapText, tokenize, layoutLines, type MeasureText, type TextAlign, type TextVAlign, type PlacedLine, } from './text.js';
|
|
14
|
-
export { renderSouvenir, drawOrder, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
14
|
+
export { renderSouvenir, drawOrder, outputSize, regionOf, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
15
15
|
import { type SouvenirOptions, type SouvenirPage, type SouvenirResult, type SouvenirValues } from './types.js';
|
|
16
16
|
export { parseSouvenirOutputId } from './outputId.js';
|
|
17
17
|
/**
|
|
@@ -37,5 +37,5 @@ export declare function composeSouvenir(page: SouvenirPage, values?: SouvenirVal
|
|
|
37
37
|
* Anything else uploaded in the same submission must use a different tag, or
|
|
38
38
|
* it will be handed back the first file.
|
|
39
39
|
*/
|
|
40
|
-
export declare function souvenirTag(page: SouvenirPage, values?: SouvenirValues): string;
|
|
40
|
+
export declare function souvenirTag(page: SouvenirPage, values?: SouvenirValues, options?: SouvenirOptions): string;
|
|
41
41
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/souvenir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EACtD,MAAM,CAAC,EAAE,MAAM,GACd,cAAc,CAUhB;AAYD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,GAAE,cAAmB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/souvenir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,QAAQ,EACR,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EACtD,MAAM,CAAC,EAAE,MAAM,GACd,cAAc,CAUhB;AAYD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,GAAE,cAAmB,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAElH"}
|
package/dist/souvenir/index.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export * from './types.js';
|
|
12
12
|
export * from './imageFit.js';
|
|
13
13
|
export { wrapText, tokenize, layoutLines, } from './text.js';
|
|
14
|
-
export { renderSouvenir, drawOrder, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
14
|
+
export { renderSouvenir, drawOrder, outputSize, regionOf, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
15
15
|
import { pageHasOpaqueBackground, renderSouvenir, souvenirSignature } from './render.js';
|
|
16
16
|
import { SouvenirError, } from './types.js';
|
|
17
17
|
import { parseSouvenirOutputId } from './outputId.js';
|
|
@@ -52,7 +52,7 @@ export async function composeSouvenir(page, values = {}, options = {}) {
|
|
|
52
52
|
const canvas = await renderSouvenir(page, values, options);
|
|
53
53
|
const format = options.format && options.format !== 'auto'
|
|
54
54
|
? options.format
|
|
55
|
-
: pageHasOpaqueBackground(page)
|
|
55
|
+
: pageHasOpaqueBackground(page, options.region)
|
|
56
56
|
? 'jpeg'
|
|
57
57
|
: 'png';
|
|
58
58
|
const quality = typeof options.quality === 'number' ? options.quality : 0.9;
|
|
@@ -63,7 +63,7 @@ export async function composeSouvenir(page, values = {}, options = {}) {
|
|
|
63
63
|
return {
|
|
64
64
|
file,
|
|
65
65
|
canvas,
|
|
66
|
-
tag: souvenirTag(page, values),
|
|
66
|
+
tag: souvenirTag(page, values, options),
|
|
67
67
|
width: canvas.width,
|
|
68
68
|
height: canvas.height,
|
|
69
69
|
format,
|
|
@@ -77,6 +77,6 @@ export async function composeSouvenir(page, values = {}, options = {}) {
|
|
|
77
77
|
* Anything else uploaded in the same submission must use a different tag, or
|
|
78
78
|
* it will be handed back the first file.
|
|
79
79
|
*/
|
|
80
|
-
export function souvenirTag(page, values = {}) {
|
|
81
|
-
return `souvenir-${souvenirSignature(page, values)}`;
|
|
80
|
+
export function souvenirTag(page, values = {}, options = {}) {
|
|
81
|
+
return `souvenir-${souvenirSignature(page, values, options)}`;
|
|
82
82
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* mirrors the runner's `elementStyle`, which is what the operator sees in the
|
|
10
10
|
* editor and the preview.
|
|
11
11
|
*/
|
|
12
|
-
import { type SouvenirOptions, type SouvenirPage, type SouvenirProperty, type SouvenirValues } from './types.js';
|
|
12
|
+
import { type SouvenirOptions, type SouvenirPage, type SouvenirProperty, type SouvenirRegion, type SouvenirValues } from './types.js';
|
|
13
13
|
/**
|
|
14
14
|
* An element bound to a Data field whose field has no value is left out, the
|
|
15
15
|
* way the runner hides it on a live page. Falling back to what the Builder
|
|
@@ -30,15 +30,25 @@ export declare function loadSouvenirImage(url: string, crossOrigin: string | nul
|
|
|
30
30
|
width: number;
|
|
31
31
|
height: number;
|
|
32
32
|
}>;
|
|
33
|
+
/**
|
|
34
|
+
* 整页时用它,给了区域时按区域算。区域外的元件照常留在页面上,由 runner 画。
|
|
35
|
+
*/
|
|
36
|
+
export declare function regionOf(page: SouvenirPage, region?: SouvenirRegion): SouvenirRegion;
|
|
37
|
+
/** 出图尺寸:形状跟着区域,长边取 longEdge;不给 longEdge 就按区域原尺寸。 */
|
|
38
|
+
export declare function outputSize(region: SouvenirRegion, longEdge?: number): {
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
scale: number;
|
|
42
|
+
};
|
|
33
43
|
/** Element ids in draw order: z-index ascending, insertion order for ties. */
|
|
34
|
-
export declare function drawOrder(page: SouvenirPage): string[];
|
|
44
|
+
export declare function drawOrder(page: SouvenirPage, region?: SouvenirRegion): string[];
|
|
35
45
|
/**
|
|
36
46
|
* True when every pixel is guaranteed opaque, i.e. a `bg` element covers the
|
|
37
47
|
* page with a colour or an image. Decides JPEG versus PNG in `auto`.
|
|
38
48
|
*/
|
|
39
|
-
export declare function pageHasOpaqueBackground(page: SouvenirPage): boolean;
|
|
40
|
-
/** A stable signature for (page, values): same inputs, same tag, same upload. */
|
|
41
|
-
export declare function souvenirSignature(page: SouvenirPage, values: SouvenirValues): string;
|
|
49
|
+
export declare function pageHasOpaqueBackground(page: SouvenirPage, region?: SouvenirRegion): boolean;
|
|
50
|
+
/** A stable signature for (page, values, region, size): same inputs, same tag, same upload. */
|
|
51
|
+
export declare function souvenirSignature(page: SouvenirPage, values: SouvenirValues, options?: SouvenirOptions): string;
|
|
42
52
|
/**
|
|
43
53
|
* Draws the page and returns the canvas.
|
|
44
54
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/souvenir/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/souvenir/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AA6CpB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAI7E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO5F;AAyPD,gFAAgF;AAChF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAAC,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,cAAc,CAEpF;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAStH;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,EAAE,CAY/E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAc5F;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAQnH;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CA2E5B"}
|
package/dist/souvenir/render.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { computeImageFitDrawRect, hashSignature, normalizeImageFit } from './imageFit.js';
|
|
13
13
|
import { parseSouvenirOutputId } from './outputId.js';
|
|
14
14
|
import { layoutLines, wrapText } from './text.js';
|
|
15
|
-
import { isSouvenirSizeAllowed, SouvenirError, SOUVENIR_ELEMENT_TYPES, } from './types.js';
|
|
15
|
+
import { isInsideRegion, isSouvenirInteractive, isSouvenirSizeAllowed, SouvenirError, SOUVENIR_ELEMENT_TYPES, } from './types.js';
|
|
16
16
|
const DEFAULT_LINE_HEIGHT = 1.2;
|
|
17
17
|
const TRANSPARENT = 'TRANSPARENT';
|
|
18
18
|
const num = (value, fallback = 0) => {
|
|
@@ -144,39 +144,55 @@ function fontOf(property, fontSize) {
|
|
|
144
144
|
const quoted = /[",]/.test(family) || !/\s/.test(family) ? family : `"${family}"`;
|
|
145
145
|
return `${style}${weight}${fontSize}px ${quoted}`;
|
|
146
146
|
}
|
|
147
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Lays the text out inside the box already in element space. `padX` is the side
|
|
149
|
+
* padding the runner leaves on shape text.
|
|
150
|
+
*/
|
|
151
|
+
function drawTextInBox(c, property, radius, width, height, content, padX = 0) {
|
|
148
152
|
const fontSize = num(property['font-size'], 14);
|
|
149
153
|
if (fontSize <= 0 || !content)
|
|
150
154
|
return;
|
|
151
155
|
const lineHeight = num(property['line-height'], DEFAULT_LINE_HEIGHT) || DEFAULT_LINE_HEIGHT;
|
|
152
156
|
const align = (property['alignment'] || 'center');
|
|
153
157
|
const vAlign = (property['v-alignment'] || 'middle');
|
|
158
|
+
const boxWidth = Math.max(0, width - padX * 2);
|
|
159
|
+
if (boxWidth <= 0)
|
|
160
|
+
return;
|
|
161
|
+
c.save();
|
|
162
|
+
roundedRectPath(c, 0, 0, width, height, radius);
|
|
163
|
+
c.clip();
|
|
164
|
+
c.font = fontOf(property, fontSize);
|
|
165
|
+
c.textBaseline = 'alphabetic';
|
|
166
|
+
c.textAlign = 'left';
|
|
167
|
+
c.fillStyle = colorOf(property['color']) || '#000000';
|
|
168
|
+
const measure = (text) => c.measureText(text).width;
|
|
169
|
+
const lines = wrapText(content, boxWidth, measure);
|
|
170
|
+
const placed = layoutLines(lines, { x: padX, y: 0, width: boxWidth, height }, fontSize, lineHeight, align, vAlign, measure);
|
|
171
|
+
const formatting = Array.isArray(property['formatting']) ? property['formatting'] : [];
|
|
172
|
+
const underline = formatting.includes('Underline');
|
|
173
|
+
const strike = formatting.includes('Strikethrough');
|
|
174
|
+
for (const line of placed) {
|
|
175
|
+
if (!line.text)
|
|
176
|
+
continue;
|
|
177
|
+
c.fillText(line.text, line.x, line.y);
|
|
178
|
+
if (underline)
|
|
179
|
+
c.fillRect(line.x, line.y + fontSize * 0.12, line.width, Math.max(1, fontSize / 16));
|
|
180
|
+
if (strike)
|
|
181
|
+
c.fillRect(line.x, line.y - fontSize * 0.28, line.width, Math.max(1, fontSize / 16));
|
|
182
|
+
}
|
|
183
|
+
c.restore();
|
|
184
|
+
}
|
|
185
|
+
function drawText(ctx, property, geo, content) {
|
|
186
|
+
if (!content)
|
|
187
|
+
return;
|
|
154
188
|
inElementSpace(ctx, geo, (c, width, height) => {
|
|
155
189
|
fillBackground(c, property, width, height, geo.radius, false);
|
|
156
|
-
|
|
157
|
-
c.clip();
|
|
158
|
-
c.font = fontOf(property, fontSize);
|
|
159
|
-
c.textBaseline = 'alphabetic';
|
|
160
|
-
c.textAlign = 'left';
|
|
161
|
-
c.fillStyle = colorOf(property['color']) || '#000000';
|
|
162
|
-
const measure = (text) => c.measureText(text).width;
|
|
163
|
-
const lines = wrapText(content, width, measure);
|
|
164
|
-
const placed = layoutLines(lines, { x: 0, y: 0, width, height }, fontSize, lineHeight, align, vAlign, measure);
|
|
165
|
-
const formatting = Array.isArray(property['formatting']) ? property['formatting'] : [];
|
|
166
|
-
const underline = formatting.includes('Underline');
|
|
167
|
-
const strike = formatting.includes('Strikethrough');
|
|
168
|
-
for (const line of placed) {
|
|
169
|
-
if (!line.text)
|
|
170
|
-
continue;
|
|
171
|
-
c.fillText(line.text, line.x, line.y);
|
|
172
|
-
if (underline)
|
|
173
|
-
c.fillRect(line.x, line.y + fontSize * 0.12, line.width, Math.max(1, fontSize / 16));
|
|
174
|
-
if (strike)
|
|
175
|
-
c.fillRect(line.x, line.y - fontSize * 0.28, line.width, Math.max(1, fontSize / 16));
|
|
176
|
-
}
|
|
190
|
+
drawTextInBox(c, property, geo.radius, width, height, content);
|
|
177
191
|
});
|
|
178
192
|
inElementSpace(ctx, geo, (c, width, height) => strokeBorder(c, property, width, height, geo.radius, false));
|
|
179
193
|
}
|
|
194
|
+
/** The runner pads shape text by 4px on each side; match it so the wrap is the same. */
|
|
195
|
+
const SHAPE_TEXT_PADDING = 4;
|
|
180
196
|
function drawImage(ctx, property, geo, image) {
|
|
181
197
|
inElementSpace(ctx, geo, (c, width, height) => {
|
|
182
198
|
fillBackground(c, property, width, height, geo.radius, false);
|
|
@@ -233,6 +249,11 @@ function drawShape(ctx, type, property, geo) {
|
|
|
233
249
|
// Rectangles and ellipses take their outline from the border settings, like
|
|
234
250
|
// on a live page; a new shape stores a 1px grey border with style None.
|
|
235
251
|
strokeBorder(c, property, width, height, geo.radius, ellipse);
|
|
252
|
+
// Text typed into a shape (a Button preset is a shape with text) is part of
|
|
253
|
+
// the picture, the same as it is on a live page.
|
|
254
|
+
const content = typeof property['content'] === 'string' ? property['content'] : '';
|
|
255
|
+
if (content)
|
|
256
|
+
drawTextInBox(c, property, geo.radius, width, height, content, SHAPE_TEXT_PADDING);
|
|
236
257
|
});
|
|
237
258
|
}
|
|
238
259
|
/** Loads one image with EXIF orientation applied, or throws a SouvenirError. */
|
|
@@ -260,11 +281,33 @@ export async function loadSouvenirImage(url, crossOrigin) {
|
|
|
260
281
|
image.src = url;
|
|
261
282
|
});
|
|
262
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* 整页时用它,给了区域时按区域算。区域外的元件照常留在页面上,由 runner 画。
|
|
286
|
+
*/
|
|
287
|
+
export function regionOf(page, region) {
|
|
288
|
+
return region ?? { x: 0, y: 0, width: num(page.width), height: num(page.height) };
|
|
289
|
+
}
|
|
290
|
+
/** 出图尺寸:形状跟着区域,长边取 longEdge;不给 longEdge 就按区域原尺寸。 */
|
|
291
|
+
export function outputSize(region, longEdge) {
|
|
292
|
+
const edge = Number.isFinite(longEdge) && longEdge > 0 ? longEdge : 0;
|
|
293
|
+
const longest = Math.max(region.width, region.height);
|
|
294
|
+
const scale = edge > 0 && longest > 0 ? edge / longest : 1;
|
|
295
|
+
return {
|
|
296
|
+
width: Math.max(1, Math.round(region.width * scale)),
|
|
297
|
+
height: Math.max(1, Math.round(region.height * scale)),
|
|
298
|
+
scale,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
263
301
|
/** Element ids in draw order: z-index ascending, insertion order for ties. */
|
|
264
|
-
export function drawOrder(page) {
|
|
302
|
+
export function drawOrder(page, region) {
|
|
303
|
+
const box = region;
|
|
265
304
|
return Object.keys(page.elements ?? {})
|
|
266
305
|
.filter((eid) => SOUVENIR_ELEMENT_TYPES.includes(page.elements[eid]?.type))
|
|
267
306
|
.filter((eid) => !isHidden(page.properties?.[eid] ?? {}))
|
|
307
|
+
// Controls stay on screen over the picture, so they are not in it
|
|
308
|
+
.filter((eid) => !isSouvenirInteractive(page.elements[eid]?.type, page.properties?.[eid] ?? {}))
|
|
309
|
+
// 框外的元件是页面的一部分,不进图
|
|
310
|
+
.filter((eid) => !box || isInsideRegion(page.properties?.[eid] ?? {}, box))
|
|
268
311
|
.map((eid, index) => ({ eid, index, z: num((page.properties?.[eid] ?? {})['zIndex']) }))
|
|
269
312
|
.sort((a, b) => (a.z === b.z ? a.index - b.index : a.z - b.z))
|
|
270
313
|
.map((entry) => entry.eid);
|
|
@@ -273,7 +316,8 @@ export function drawOrder(page) {
|
|
|
273
316
|
* True when every pixel is guaranteed opaque, i.e. a `bg` element covers the
|
|
274
317
|
* page with a colour or an image. Decides JPEG versus PNG in `auto`.
|
|
275
318
|
*/
|
|
276
|
-
export function pageHasOpaqueBackground(page) {
|
|
319
|
+
export function pageHasOpaqueBackground(page, region) {
|
|
320
|
+
const box = regionOf(page, region);
|
|
277
321
|
for (const eid of Object.keys(page.elements ?? {})) {
|
|
278
322
|
if (page.elements[eid]?.type !== 'bg')
|
|
279
323
|
continue;
|
|
@@ -281,7 +325,7 @@ export function pageHasOpaqueBackground(page) {
|
|
|
281
325
|
if (isHidden(property))
|
|
282
326
|
continue;
|
|
283
327
|
const geo = geometryOf(property);
|
|
284
|
-
const covers = geo.x <=
|
|
328
|
+
const covers = geo.x <= box.x && geo.y <= box.y && geo.x + geo.width >= box.x + box.width && geo.y + geo.height >= box.y + box.height;
|
|
285
329
|
if (!covers)
|
|
286
330
|
continue;
|
|
287
331
|
if (geo.opacity < 100 || geo.radius > 0 || geo.rotation)
|
|
@@ -291,10 +335,12 @@ export function pageHasOpaqueBackground(page) {
|
|
|
291
335
|
}
|
|
292
336
|
return false;
|
|
293
337
|
}
|
|
294
|
-
/** A stable signature for (page, values): same inputs, same tag, same upload. */
|
|
295
|
-
export function souvenirSignature(page, values) {
|
|
296
|
-
const
|
|
297
|
-
|
|
338
|
+
/** A stable signature for (page, values, region, size): same inputs, same tag, same upload. */
|
|
339
|
+
export function souvenirSignature(page, values, options = {}) {
|
|
340
|
+
const box = regionOf(page, options.region);
|
|
341
|
+
const size = outputSize(box, options.longEdge);
|
|
342
|
+
const parts = [`${box.x},${box.y},${box.width}x${box.height}`, `${size.width}x${size.height}`];
|
|
343
|
+
for (const eid of drawOrder(page, options.region)) {
|
|
298
344
|
parts.push(eid, page.elements[eid]?.type ?? '', JSON.stringify(page.properties?.[eid] ?? {}), String(values[eid] ?? ''));
|
|
299
345
|
}
|
|
300
346
|
return hashSignature(parts.join('|'));
|
|
@@ -310,12 +356,14 @@ export async function renderSouvenir(page, values = {}, options = {}) {
|
|
|
310
356
|
if (typeof document === 'undefined') {
|
|
311
357
|
throw new SouvenirError('no_dom', 'The souvenir composer needs a browser document.');
|
|
312
358
|
}
|
|
313
|
-
const
|
|
314
|
-
const
|
|
359
|
+
const box = regionOf(page, options.region);
|
|
360
|
+
const size = outputSize(box, options.longEdge);
|
|
361
|
+
const width = size.width;
|
|
362
|
+
const height = size.height;
|
|
315
363
|
if (!isSouvenirSizeAllowed(width, height)) {
|
|
316
|
-
throw new SouvenirError(width < 1 || height < 1 ? 'bad_size' : 'too_large', `Souvenir
|
|
364
|
+
throw new SouvenirError(width < 1 || height < 1 ? 'bad_size' : 'too_large', `Souvenir image size ${width}x${height} is out of range.`);
|
|
317
365
|
}
|
|
318
|
-
const order = drawOrder(page);
|
|
366
|
+
const order = drawOrder(page, options.region);
|
|
319
367
|
// Webfonts first: measuring before they land silently lays the text out in
|
|
320
368
|
// the fallback font and the first souvenir of an event comes out wrong.
|
|
321
369
|
if (!options.skipFontWait && typeof document !== 'undefined' && document.fonts?.ready) {
|
|
@@ -345,6 +393,9 @@ export async function renderSouvenir(page, values = {}, options = {}) {
|
|
|
345
393
|
const ctx = canvas.getContext('2d');
|
|
346
394
|
if (!ctx)
|
|
347
395
|
throw new SouvenirError('canvas_unavailable', 'Could not get a 2d context.');
|
|
396
|
+
// 元件坐标是页面坐标:先按出图倍数放大,再把框的左上角移到画布原点。描边宽度与字号
|
|
397
|
+
// 跟着这一层变换等比放大,所以各元件照页面坐标画就行。
|
|
398
|
+
ctx.setTransform(size.scale, 0, 0, size.scale, -box.x * size.scale, -box.y * size.scale);
|
|
348
399
|
for (const eid of order) {
|
|
349
400
|
const type = page.elements[eid]?.type ?? '';
|
|
350
401
|
const property = page.properties?.[eid] ?? {};
|
package/dist/souvenir/types.d.ts
CHANGED
|
@@ -14,6 +14,19 @@
|
|
|
14
14
|
/** Element types the composer draws. Anything else on the page is skipped. */
|
|
15
15
|
export declare const SOUVENIR_ELEMENT_TYPES: readonly ["bg", "image", "image-frame", "text", "shape-rect", "shape-ellipse", "shape-line"];
|
|
16
16
|
export type SouvenirElementType = (typeof SOUVENIR_ELEMENT_TYPES)[number];
|
|
17
|
+
/**
|
|
18
|
+
* Element types that do something when the participant taps them, or that count
|
|
19
|
+
* down. On a page the module composes and displays itself, the runner keeps
|
|
20
|
+
* these on screen over the picture, so the composer must leave them out or the
|
|
21
|
+
* same thing would appear twice (`qik-sense-runner/src/services/pageRender.ts`
|
|
22
|
+
* keeps the same list).
|
|
23
|
+
*/
|
|
24
|
+
export declare const SOUVENIR_INTERACTIVE_TYPES: readonly ["timeout", "button", "qr", "link"];
|
|
25
|
+
/**
|
|
26
|
+
* True when this element is a control rather than part of the picture: an
|
|
27
|
+
* interactive type, or any element the operator gave a target to.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isSouvenirInteractive(type: string | undefined | null, property?: SouvenirProperty): boolean;
|
|
17
30
|
/** Anything the Builder stores for one element. Values arrive untyped from the API. */
|
|
18
31
|
export type SouvenirProperty = Record<string, unknown>;
|
|
19
32
|
/** One element as the Builder's `detail.elements` records it. */
|
|
@@ -42,12 +55,34 @@ export interface SouvenirPage {
|
|
|
42
55
|
*/
|
|
43
56
|
export type SouvenirValues = Record<string, string | null | undefined>;
|
|
44
57
|
export type SouvenirFormat = 'auto' | 'jpeg' | 'png';
|
|
58
|
+
/**
|
|
59
|
+
* The part of the page that becomes the image, in the page's own coordinates.
|
|
60
|
+
*
|
|
61
|
+
* A module that lays the souvenir out on a page participants see marks a frame
|
|
62
|
+
* on it: what is inside becomes the picture, what is outside stays a normal
|
|
63
|
+
* page (PF 2026-09-18). Left out, the whole page is composed.
|
|
64
|
+
*/
|
|
65
|
+
export interface SouvenirRegion {
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
width: number;
|
|
69
|
+
height: number;
|
|
70
|
+
}
|
|
71
|
+
/** 一个元件算不算在框里:按中心点判定(PF 2026-09-18),画的时候再按框裁切。 */
|
|
72
|
+
export declare function isInsideRegion(property: SouvenirProperty, region: SouvenirRegion): boolean;
|
|
45
73
|
export interface SouvenirOptions {
|
|
46
74
|
/**
|
|
47
75
|
* `auto` (default) picks JPEG unless the page has no opaque background, in
|
|
48
76
|
* which case the transparency has to survive and PNG wins.
|
|
49
77
|
*/
|
|
50
78
|
format?: SouvenirFormat;
|
|
79
|
+
/** 只合成页面上的这一块。不给就是整页(Live Input 的离屏页走这一条)。 */
|
|
80
|
+
region?: SouvenirRegion;
|
|
81
|
+
/**
|
|
82
|
+
* 出图的长边像素。短边按区域比例算,所以运营改框的形状不必再改这个数。
|
|
83
|
+
* 不给就按区域的原始尺寸出图。
|
|
84
|
+
*/
|
|
85
|
+
longEdge?: number;
|
|
51
86
|
/** JPEG quality, 0 to 1. Default 0.9. */
|
|
52
87
|
quality?: number;
|
|
53
88
|
/** File name handed to the upload endpoint. Extension is set from the format. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/souvenir/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,8FAQzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvD,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wGAAwG;IACxG,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,0EAA0E;AAC1E,qBAAa,aAAc,SAAQ,KAAK;aAEpB,IAAI,EAChB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,eAAe;gBANH,IAAI,EAChB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,eAAe,EACnB,OAAO,EAAE,MAAM;CAKlB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,WAAa,CAAC;AAE5C,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK5E;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,CAW5E"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/souvenir/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,8FAQzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,8CAA+C,CAAC;AAKvF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,QAAQ,GAAE,gBAAqB,GAAG,OAAO,CAG/G;AAED,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvD,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kDAAkD;AAClD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAa1F;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wGAAwG;IACxG,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,0EAA0E;AAC1E,qBAAa,aAAc,SAAQ,KAAK;aAEpB,IAAI,EAChB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,eAAe;gBANH,IAAI,EAChB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,eAAe,EACnB,OAAO,EAAE,MAAM;CAKlB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,WAAa,CAAC;AAE5C,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK5E;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,CAW5E"}
|
package/dist/souvenir/types.js
CHANGED
|
@@ -21,6 +21,38 @@ export const SOUVENIR_ELEMENT_TYPES = [
|
|
|
21
21
|
'shape-ellipse',
|
|
22
22
|
'shape-line',
|
|
23
23
|
];
|
|
24
|
+
/**
|
|
25
|
+
* Element types that do something when the participant taps them, or that count
|
|
26
|
+
* down. On a page the module composes and displays itself, the runner keeps
|
|
27
|
+
* these on screen over the picture, so the composer must leave them out or the
|
|
28
|
+
* same thing would appear twice (`qik-sense-runner/src/services/pageRender.ts`
|
|
29
|
+
* keeps the same list).
|
|
30
|
+
*/
|
|
31
|
+
export const SOUVENIR_INTERACTIVE_TYPES = ['timeout', 'button', 'qr', 'link'];
|
|
32
|
+
/** Property keys that turn any element into something tappable. */
|
|
33
|
+
const INTERACTIVE_PROPERTIES = ['connection-key', 'url', 'key-code'];
|
|
34
|
+
/**
|
|
35
|
+
* True when this element is a control rather than part of the picture: an
|
|
36
|
+
* interactive type, or any element the operator gave a target to.
|
|
37
|
+
*/
|
|
38
|
+
export function isSouvenirInteractive(type, property = {}) {
|
|
39
|
+
if (SOUVENIR_INTERACTIVE_TYPES.includes(String(type ?? '')))
|
|
40
|
+
return true;
|
|
41
|
+
return INTERACTIVE_PROPERTIES.some((key) => String(property?.[key] ?? '').trim() !== '');
|
|
42
|
+
}
|
|
43
|
+
/** 一个元件算不算在框里:按中心点判定(PF 2026-09-18),画的时候再按框裁切。 */
|
|
44
|
+
export function isInsideRegion(property, region) {
|
|
45
|
+
const num = (value) => {
|
|
46
|
+
const parsed = typeof value === 'number' ? value : parseFloat(String(value ?? ''));
|
|
47
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
48
|
+
};
|
|
49
|
+
const centerX = num(property['x-position']) + num(property['width']) / 2;
|
|
50
|
+
const centerY = num(property['y-position']) + num(property['height']) / 2;
|
|
51
|
+
return (centerX >= region.x &&
|
|
52
|
+
centerX <= region.x + region.width &&
|
|
53
|
+
centerY >= region.y &&
|
|
54
|
+
centerY <= region.y + region.height);
|
|
55
|
+
}
|
|
24
56
|
/** Thrown for every refusal the caller is expected to handle and show. */
|
|
25
57
|
export class SouvenirError extends Error {
|
|
26
58
|
code;
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@realnation/builder-shared-sdk",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"private": false,
|
|
6
|
-
"exports": {
|
|
7
|
-
"./package.json": "./package.json",
|
|
8
|
-
".": {
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
10
|
-
"import": "./dist/index.js"
|
|
11
|
-
},
|
|
12
|
-
"./runtime": {
|
|
13
|
-
"types": "./dist/runtime/index.d.ts",
|
|
14
|
-
"import": "./dist/runtime/index.js"
|
|
15
|
-
},
|
|
16
|
-
"./runtime/vue": {
|
|
17
|
-
"types": "./dist/runtime/vue/index.d.ts",
|
|
18
|
-
"import": "./dist/runtime/vue/index.js"
|
|
19
|
-
},
|
|
20
|
-
"./interaction": {
|
|
21
|
-
"types": "./dist/interaction/index.d.ts",
|
|
22
|
-
"import": "./dist/interaction/index.js"
|
|
23
|
-
},
|
|
24
|
-
"./interaction/vue": {
|
|
25
|
-
"types": "./dist/interaction/vue.d.ts",
|
|
26
|
-
"import": "./dist/interaction/vue.js"
|
|
27
|
-
},
|
|
28
|
-
"./souvenir": {
|
|
29
|
-
"types": "./dist/souvenir/index.d.ts",
|
|
30
|
-
"import": "./dist/souvenir/index.js"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"files": [
|
|
34
|
-
"dist"
|
|
35
|
-
],
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsc -p tsconfig.json",
|
|
38
|
-
"clean": "rimraf dist",
|
|
39
|
-
"test": "vitest run",
|
|
40
|
-
"test:watch": "vitest",
|
|
41
|
-
"prepublishOnly": "npm run clean && npm run test && npm run build",
|
|
42
|
-
"prepare": "npm run clean && npm run build"
|
|
43
|
-
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"ali-oss": "^6.23.0",
|
|
46
|
-
"axios": "^1.7.7"
|
|
47
|
-
},
|
|
48
|
-
"peerDependencies": {
|
|
49
|
-
"vue": "^3.4.0"
|
|
50
|
-
},
|
|
51
|
-
"peerDependenciesMeta": {
|
|
52
|
-
"vue": {
|
|
53
|
-
"optional": true
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@types/ali-oss": "^6.16.11",
|
|
58
|
-
"@types/node": "^26.1.2",
|
|
59
|
-
"rimraf": "^5.0.5",
|
|
60
|
-
"typescript": "^5.4.5",
|
|
61
|
-
"vitest": "^2.1.0",
|
|
62
|
-
"vue": "^3.4.0"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@realnation/builder-shared-sdk",
|
|
3
|
+
"version": "2.5.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": false,
|
|
6
|
+
"exports": {
|
|
7
|
+
"./package.json": "./package.json",
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./runtime": {
|
|
13
|
+
"types": "./dist/runtime/index.d.ts",
|
|
14
|
+
"import": "./dist/runtime/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./runtime/vue": {
|
|
17
|
+
"types": "./dist/runtime/vue/index.d.ts",
|
|
18
|
+
"import": "./dist/runtime/vue/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./interaction": {
|
|
21
|
+
"types": "./dist/interaction/index.d.ts",
|
|
22
|
+
"import": "./dist/interaction/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./interaction/vue": {
|
|
25
|
+
"types": "./dist/interaction/vue.d.ts",
|
|
26
|
+
"import": "./dist/interaction/vue.js"
|
|
27
|
+
},
|
|
28
|
+
"./souvenir": {
|
|
29
|
+
"types": "./dist/souvenir/index.d.ts",
|
|
30
|
+
"import": "./dist/souvenir/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.json",
|
|
38
|
+
"clean": "rimraf dist",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"prepublishOnly": "npm run clean && npm run test && npm run build",
|
|
42
|
+
"prepare": "npm run clean && npm run build"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"ali-oss": "^6.23.0",
|
|
46
|
+
"axios": "^1.7.7"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"vue": "^3.4.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependenciesMeta": {
|
|
52
|
+
"vue": {
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/ali-oss": "^6.16.11",
|
|
58
|
+
"@types/node": "^26.1.2",
|
|
59
|
+
"rimraf": "^5.0.5",
|
|
60
|
+
"typescript": "^5.4.5",
|
|
61
|
+
"vitest": "^2.1.0",
|
|
62
|
+
"vue": "^3.4.0"
|
|
63
|
+
}
|
|
64
|
+
}
|