@flowgram.ai/export-plugin 1.0.6

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.
@@ -0,0 +1,60 @@
1
+ import * as _flowgram_ai_core from '@flowgram.ai/core';
2
+ import * as _flowgram_ai_utils from '@flowgram.ai/utils';
3
+
4
+ /**
5
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
6
+ * SPDX-License-Identifier: MIT
7
+ */
8
+ declare enum FlowDownloadFormat {
9
+ JSON = "json",
10
+ YAML = "yaml",
11
+ PNG = "png",
12
+ JPEG = "jpeg",
13
+ SVG = "svg"
14
+ }
15
+
16
+ /**
17
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
18
+ * SPDX-License-Identifier: MIT
19
+ */
20
+
21
+ interface WorkflowDownloadParams {
22
+ format: FlowDownloadFormat;
23
+ }
24
+ interface DownloadServiceOptions {
25
+ getFilename?: (format: FlowDownloadFormat) => string;
26
+ watermarkSVG?: string;
27
+ }
28
+
29
+ declare class FlowDownloadService {
30
+ private readonly document;
31
+ private readonly exportImageService;
32
+ private toDispose;
33
+ downloading: boolean;
34
+ private onDownloadingChangeEmitter;
35
+ private options;
36
+ onDownloadingChange: _flowgram_ai_utils.Event<boolean>;
37
+ init(options?: Partial<DownloadServiceOptions>): void;
38
+ dispose(): void;
39
+ download(params: WorkflowDownloadParams): Promise<void>;
40
+ setDownloading(value: boolean): void;
41
+ private handleImageDownload;
42
+ private handleDataDownload;
43
+ private downloadData;
44
+ private formatDataContent;
45
+ private downloadImage;
46
+ private getFileName;
47
+ private downloadFile;
48
+ }
49
+
50
+ /**
51
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
52
+ * SPDX-License-Identifier: MIT
53
+ */
54
+
55
+ interface CreateDownloadPluginOptions extends Partial<DownloadServiceOptions> {
56
+ }
57
+
58
+ declare const createDownloadPlugin: _flowgram_ai_core.PluginCreator<CreateDownloadPluginOptions>;
59
+
60
+ export { type CreateDownloadPluginOptions, type DownloadServiceOptions, FlowDownloadFormat, FlowDownloadService, createDownloadPlugin };
package/dist/index.js ADDED
@@ -0,0 +1,537 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __decorateClass = (decorators, target, key, kind) => {
30
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
31
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
32
+ if (decorator = decorators[i])
33
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
34
+ if (kind && result) __defProp(target, key, result);
35
+ return result;
36
+ };
37
+
38
+ // src/index.ts
39
+ var index_exports = {};
40
+ __export(index_exports, {
41
+ FlowDownloadFormat: () => FlowDownloadFormat,
42
+ FlowDownloadService: () => FlowDownloadService,
43
+ createDownloadPlugin: () => createDownloadPlugin
44
+ });
45
+ module.exports = __toCommonJS(index_exports);
46
+
47
+ // src/create-plugin.ts
48
+ var import_core2 = require("@flowgram.ai/core");
49
+
50
+ // src/export-image-service/service.ts
51
+ var import_inversify = require("inversify");
52
+ var import_document = require("@flowgram.ai/document");
53
+
54
+ // src/export-image-service/utils.ts
55
+ var import_core = require("@flowgram.ai/core");
56
+ var getNodesRect = (nodes) => {
57
+ const rects = nodes.map((node) => node.getData(import_core.TransformData)?.bounds).filter(Boolean);
58
+ const x1 = Math.min(...rects.map((rect) => rect.x));
59
+ const x2 = Math.max(...rects.map((rect) => rect.x + rect.width));
60
+ const y1 = Math.min(...rects.map((rect) => rect.y));
61
+ const y2 = Math.max(...rects.map((rect) => rect.y + rect.height));
62
+ const width = x2 - x1;
63
+ const height = y2 - y1;
64
+ return {
65
+ width,
66
+ height,
67
+ x: x1,
68
+ y: y1
69
+ };
70
+ };
71
+ var getWorkflowRect = (document2) => getNodesRect(document2.getAllNodes());
72
+
73
+ // src/export-image-service/constant.ts
74
+ var USER_AGENT = navigator?.userAgent ?? "";
75
+ var IN_CHROME = USER_AGENT.includes("Chrome");
76
+ var IN_SAFARI = USER_AGENT.includes("AppleWebKit") && !IN_CHROME;
77
+ var IN_FIREFOX = USER_AGENT.includes("Firefox");
78
+ var EXPORT_IMAGE_WATERMARK_SVG = `
79
+ <svg width="201" height="133" viewBox="0 0 201 133" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
80
+ <image id="-" x="0" y="0" width="200" height="133" xlink:href="data:image/png;base64, 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"/>
81
+ </svg>
82
+ `;
83
+ var EXPORT_IMAGE_STYLE_PROPERTIES = [
84
+ "width",
85
+ "height",
86
+ "box-sizing",
87
+ "display",
88
+ "align-items",
89
+ "justify-content",
90
+ "font-size",
91
+ "gap",
92
+ "color",
93
+ "background",
94
+ "background-color",
95
+ "font",
96
+ "font-family",
97
+ "fill",
98
+ "stroke",
99
+ "stroke-width",
100
+ "margin",
101
+ "padding",
102
+ "padding-left",
103
+ "padding-top",
104
+ "padding-bottom",
105
+ "padding-right",
106
+ "flex-direction",
107
+ "filter",
108
+ "position",
109
+ "top",
110
+ "left",
111
+ "bottom",
112
+ "right",
113
+ "content",
114
+ "line-height",
115
+ "text-decoration",
116
+ "border-radius",
117
+ "opacity",
118
+ "border-right",
119
+ "border-left",
120
+ "border-width",
121
+ "border-style",
122
+ "border-color",
123
+ "margin-right",
124
+ "margin-left",
125
+ "margin-top",
126
+ "margin-bottom",
127
+ "white-space",
128
+ "overflow",
129
+ "text-overflow",
130
+ "font-weight",
131
+ "min-width",
132
+ "min-height",
133
+ "transform",
134
+ "z-index",
135
+ "flex",
136
+ "border-width",
137
+ "text-wrap",
138
+ "word-break",
139
+ "vertical-align",
140
+ "aspect-ratio",
141
+ "object-fit",
142
+ "align-content",
143
+ "align-self",
144
+ "background-attachment",
145
+ "background-clip",
146
+ "background-image",
147
+ "background-origin",
148
+ "background-repeat",
149
+ "background-size",
150
+ "block-size",
151
+ "border-block-end-color",
152
+ "border-block-end-style",
153
+ "border-block-end-width",
154
+ "border-block-start-color",
155
+ "border-block-start-style",
156
+ "border-block-start-width",
157
+ "border-bottom-color",
158
+ "border-bottom-style",
159
+ "border-bottom-width",
160
+ "border-bottom-left-radius",
161
+ "border-bottom-right-radius",
162
+ "border-end-end-radius",
163
+ "border-end-start-radius",
164
+ "border-inline-end-color",
165
+ "border-inline-end-style",
166
+ "border-inline-end-width",
167
+ "border-inline-start-color",
168
+ "border-inline-start-style",
169
+ "border-inline-start-width",
170
+ "border-right-color",
171
+ "border-right-style",
172
+ "border-right-width",
173
+ "border-start-end-radius",
174
+ "border-start-start-radius",
175
+ "border-top-color",
176
+ "border-top-style",
177
+ "border-top-width",
178
+ "border-top-left-radius",
179
+ "border-top-right-radius",
180
+ "flex-basis",
181
+ "flex-grow",
182
+ "flex-shrink",
183
+ "flex-wrap",
184
+ "font-kerning",
185
+ "font-palette",
186
+ "font-stretch",
187
+ "font-style",
188
+ "inline-size",
189
+ "inset-block-end",
190
+ "inset-block-start",
191
+ "inset-inline-end",
192
+ "inset-inline-start",
193
+ "justify-items",
194
+ "justify-self",
195
+ "line-break",
196
+ "margin-trim",
197
+ "margin-inline-end",
198
+ "margin-inline-start",
199
+ "min-block-size",
200
+ "min-inline-size",
201
+ "overflow-wrap",
202
+ "overflow-x",
203
+ "overflow-y",
204
+ "perspective-origin",
205
+ "transform-box",
206
+ "transform-origin",
207
+ "transform-style",
208
+ "grid-template",
209
+ "grid-template-rows",
210
+ "grid-template-columns",
211
+ "grid-template-areas"
212
+ ];
213
+
214
+ // src/constant.ts
215
+ var FlowDownloadFormat = /* @__PURE__ */ ((FlowDownloadFormat2) => {
216
+ FlowDownloadFormat2["JSON"] = "json";
217
+ FlowDownloadFormat2["YAML"] = "yaml";
218
+ FlowDownloadFormat2["PNG"] = "png";
219
+ FlowDownloadFormat2["JPEG"] = "jpeg";
220
+ FlowDownloadFormat2["SVG"] = "svg";
221
+ return FlowDownloadFormat2;
222
+ })(FlowDownloadFormat || {});
223
+ var FlowImageFormats = [
224
+ "png" /* PNG */,
225
+ "jpeg" /* JPEG */,
226
+ "svg" /* SVG */
227
+ ];
228
+ var FlowDataFormats = ["json" /* JSON */, "yaml" /* YAML */];
229
+
230
+ // src/export-image-service/service.ts
231
+ var PADDING_X = 58;
232
+ var PADDING_Y = 138;
233
+ var FlowExportImageService = class {
234
+ async export(options) {
235
+ try {
236
+ const imgUrl = await this.doExport(options);
237
+ return imgUrl;
238
+ } catch (e) {
239
+ console.error("Export image failed:", e);
240
+ return;
241
+ }
242
+ }
243
+ async loadModernScreenshot() {
244
+ if (this.modernScreenshot) {
245
+ return this.modernScreenshot;
246
+ }
247
+ const modernScreenshot = await import("modern-screenshot");
248
+ this.modernScreenshot = modernScreenshot;
249
+ }
250
+ async doExport(exportOptions) {
251
+ if (this.document.layout.name.includes("fixed-layout")) {
252
+ return await this.doFixedExport(exportOptions);
253
+ }
254
+ return await this.doFreeExport(exportOptions);
255
+ }
256
+ async doFreeExport(exportOptions) {
257
+ const { format } = exportOptions;
258
+ const renderLayer = window.document.querySelector(".gedit-flow-render-layer");
259
+ if (!renderLayer) {
260
+ return;
261
+ }
262
+ const { width, height, x, y } = getWorkflowRect(this.document);
263
+ await this.loadModernScreenshot();
264
+ const { domToPng, domToForeignObjectSvg, domToJpeg } = this.modernScreenshot;
265
+ let imgUrl;
266
+ const options = {
267
+ scale: 2,
268
+ includeStyleProperties: IN_SAFARI || IN_FIREFOX ? EXPORT_IMAGE_STYLE_PROPERTIES : void 0,
269
+ width: width + PADDING_X * 2,
270
+ height: height + PADDING_Y * 2,
271
+ onCloneEachNode: (cloned) => {
272
+ this.handleFreeClone(cloned, { width, height, x, y, options: exportOptions });
273
+ }
274
+ };
275
+ switch (format) {
276
+ case "png" /* PNG */:
277
+ imgUrl = await domToPng(renderLayer, options);
278
+ break;
279
+ case "svg" /* SVG */: {
280
+ const svg = await domToForeignObjectSvg(renderLayer, options);
281
+ imgUrl = await this.svgToDataURL(svg);
282
+ break;
283
+ }
284
+ case "jpeg" /* JPEG */:
285
+ imgUrl = await domToJpeg(renderLayer, options);
286
+ break;
287
+ default:
288
+ imgUrl = await domToPng(renderLayer, options);
289
+ }
290
+ return imgUrl;
291
+ }
292
+ async doFixedExport(exportOptions) {
293
+ const { format } = exportOptions;
294
+ const el = window.document.querySelector(".gedit-flow-nodes-layer");
295
+ if (!el) {
296
+ return;
297
+ }
298
+ const { width, height, x, y } = getWorkflowRect(this.document);
299
+ await this.loadModernScreenshot();
300
+ const { domToPng, domToForeignObjectSvg, domToJpeg } = this.modernScreenshot;
301
+ let imgUrl;
302
+ const options = {
303
+ scale: 2,
304
+ includeStyleProperties: IN_SAFARI || IN_FIREFOX ? EXPORT_IMAGE_STYLE_PROPERTIES : void 0,
305
+ width: width + PADDING_X * 2,
306
+ height: height + PADDING_Y * 2,
307
+ onCloneEachNode: (cloned) => {
308
+ this.handleFixedClone(cloned, { width, height, x, y, options: exportOptions });
309
+ }
310
+ };
311
+ switch (format) {
312
+ case "png" /* PNG */:
313
+ imgUrl = await domToPng(el, options);
314
+ break;
315
+ case "svg" /* SVG */: {
316
+ const svg = await domToForeignObjectSvg(el, options);
317
+ imgUrl = await this.svgToDataURL(svg);
318
+ break;
319
+ }
320
+ case "jpeg" /* JPEG */:
321
+ imgUrl = await domToJpeg(el, options);
322
+ break;
323
+ default:
324
+ imgUrl = await domToPng(el, options);
325
+ }
326
+ return imgUrl;
327
+ }
328
+ async svgToDataURL(svg) {
329
+ return Promise.resolve().then(() => new XMLSerializer().serializeToString(svg)).then(encodeURIComponent).then((html) => `data:image/svg+xml;charset=utf-8,${html}`);
330
+ }
331
+ // 处理克隆节点
332
+ handleFreeClone(cloned, {
333
+ width,
334
+ height,
335
+ x,
336
+ y,
337
+ options
338
+ }) {
339
+ if (cloned?.classList?.contains("gedit-flow-activity-node") || cloned?.classList?.contains("gedit-flow-activity-line")) {
340
+ this.handlePosition(cloned, x, y);
341
+ }
342
+ if (cloned?.classList?.contains("gedit-flow-render-layer")) {
343
+ this.handleCanvas(cloned, width, height, options);
344
+ }
345
+ }
346
+ // 处理克隆节点
347
+ handleFixedClone(cloned, {
348
+ width,
349
+ height,
350
+ x,
351
+ y,
352
+ options
353
+ }) {
354
+ if (cloned?.classList?.contains("gedit-flow-activity-node") || cloned?.classList?.contains("gedit-flow-activity-line")) {
355
+ this.handlePosition(cloned, x, y);
356
+ }
357
+ if (cloned?.classList?.contains("gedit-flow-nodes-layer")) {
358
+ const linesLayer = window.document.querySelector(".gedit-flow-lines-layer")?.cloneNode(true);
359
+ this.handleLines(linesLayer, width, height);
360
+ cloned.appendChild(linesLayer);
361
+ this.handleCanvas(cloned, width, height, options);
362
+ }
363
+ }
364
+ // 处理节点位置
365
+ handlePosition(cloned, x, y) {
366
+ cloned.style.transform = `translate(${-x + PADDING_X}px, ${-y + PADDING_Y}px)`;
367
+ }
368
+ // 处理画布
369
+ handleLines(cloned, width, height) {
370
+ cloned.style.position = "absolute";
371
+ cloned.style.width = `${width}px`;
372
+ cloned.style.height = `${height}px`;
373
+ cloned.style.left = `${width / 2 - PADDING_X}px`;
374
+ cloned.style.top = `${PADDING_Y}px`;
375
+ cloned.style.transform = "none";
376
+ cloned.style.backgroundColor = "transparent";
377
+ cloned.querySelector(".flow-lines-container").setAttribute("viewBox", `0 0 1000 1000`);
378
+ }
379
+ // 处理画布
380
+ handleCanvas(cloned, width, height, options) {
381
+ cloned.style.width = `${width + PADDING_X * 2}px`;
382
+ cloned.style.height = `${height + PADDING_Y * 2}px`;
383
+ cloned.style.transform = "none";
384
+ cloned.style.backgroundColor = "#ECECEE";
385
+ this.handleWaterMark(cloned, options);
386
+ }
387
+ // 添加水印节点
388
+ handleWaterMark(element, options) {
389
+ const watermarkNode = document.createElement("div");
390
+ watermarkNode.innerHTML = options?.watermarkSVG ?? EXPORT_IMAGE_WATERMARK_SVG;
391
+ watermarkNode.style.position = "absolute";
392
+ watermarkNode.style.bottom = "32px";
393
+ watermarkNode.style.right = "32px";
394
+ watermarkNode.style.zIndex = "999999";
395
+ element.appendChild(watermarkNode);
396
+ }
397
+ };
398
+ __decorateClass([
399
+ (0, import_inversify.inject)(import_document.FlowDocument)
400
+ ], FlowExportImageService.prototype, "document", 2);
401
+ FlowExportImageService = __decorateClass([
402
+ (0, import_inversify.injectable)()
403
+ ], FlowExportImageService);
404
+
405
+ // src/download-service/service.ts
406
+ var import_nanoid = require("nanoid");
407
+ var import_inversify2 = require("inversify");
408
+ var import_utils2 = require("@flowgram.ai/utils");
409
+ var import_document2 = require("@flowgram.ai/document");
410
+ var FlowDownloadService = class {
411
+ constructor() {
412
+ this.toDispose = new import_utils2.DisposableCollection();
413
+ this.downloading = false;
414
+ this.onDownloadingChangeEmitter = new import_utils2.Emitter();
415
+ this.options = {};
416
+ this.onDownloadingChange = this.onDownloadingChangeEmitter.event;
417
+ }
418
+ init(options) {
419
+ this.options = options ?? {};
420
+ this.toDispose.push(this.onDownloadingChangeEmitter);
421
+ }
422
+ dispose() {
423
+ this.toDispose.dispose();
424
+ }
425
+ async download(params) {
426
+ if (this.downloading) {
427
+ return;
428
+ }
429
+ const { format } = params;
430
+ if (FlowImageFormats.includes(format)) {
431
+ await this.handleImageDownload(format);
432
+ } else if (FlowDataFormats.includes(format)) {
433
+ await this.handleDataDownload(format);
434
+ }
435
+ }
436
+ setDownloading(value) {
437
+ this.downloading = value;
438
+ this.onDownloadingChangeEmitter.fire(value);
439
+ }
440
+ async handleImageDownload(format) {
441
+ this.setDownloading(true);
442
+ try {
443
+ await this.downloadImage(format);
444
+ } finally {
445
+ this.setDownloading(false);
446
+ }
447
+ }
448
+ async handleDataDownload(format) {
449
+ this.setDownloading(true);
450
+ try {
451
+ await this.downloadData(format);
452
+ } finally {
453
+ this.setDownloading(false);
454
+ }
455
+ }
456
+ async downloadData(format) {
457
+ const json = this.document.toJSON();
458
+ const { content, mimeType } = await this.formatDataContent(json, format);
459
+ const blob = new Blob([content], { type: mimeType });
460
+ const url = URL.createObjectURL(blob);
461
+ const filename = this.getFileName(format);
462
+ this.downloadFile(url, filename);
463
+ URL.revokeObjectURL(url);
464
+ }
465
+ async formatDataContent(json, format) {
466
+ if (format === "yaml" /* YAML */) {
467
+ const yaml = await import("js-yaml");
468
+ return {
469
+ content: yaml.dump(json, {
470
+ indent: 2,
471
+ lineWidth: -1,
472
+ noRefs: true
473
+ }),
474
+ mimeType: "application/x-yaml"
475
+ };
476
+ }
477
+ return {
478
+ content: JSON.stringify(json, null, 2),
479
+ mimeType: "application/json"
480
+ };
481
+ }
482
+ async downloadImage(format) {
483
+ const imageUrl = await this.exportImageService.export({
484
+ format,
485
+ watermarkSVG: this.options.watermarkSVG
486
+ });
487
+ if (!imageUrl) {
488
+ return;
489
+ }
490
+ const filename = this.getFileName(format);
491
+ this.downloadFile(imageUrl, filename);
492
+ }
493
+ getFileName(format) {
494
+ if (this.options.getFilename) {
495
+ return this.options.getFilename(format);
496
+ }
497
+ return `flowgram-${(0, import_nanoid.nanoid)(5)}.${format}`;
498
+ }
499
+ downloadFile(href, filename) {
500
+ const link = document.createElement("a");
501
+ link.href = href;
502
+ link.download = filename;
503
+ document.body.appendChild(link);
504
+ link.click();
505
+ document.body.removeChild(link);
506
+ }
507
+ };
508
+ __decorateClass([
509
+ (0, import_inversify2.inject)(import_document2.FlowDocument)
510
+ ], FlowDownloadService.prototype, "document", 2);
511
+ __decorateClass([
512
+ (0, import_inversify2.inject)(FlowExportImageService)
513
+ ], FlowDownloadService.prototype, "exportImageService", 2);
514
+ FlowDownloadService = __decorateClass([
515
+ (0, import_inversify2.injectable)()
516
+ ], FlowDownloadService);
517
+
518
+ // src/create-plugin.ts
519
+ var createDownloadPlugin = (0, import_core2.definePluginCreator)({
520
+ onBind: ({ bind }) => {
521
+ bind(FlowExportImageService).toSelf().inSingletonScope();
522
+ bind(FlowDownloadService).toSelf().inSingletonScope();
523
+ },
524
+ onInit: (ctx, opts) => {
525
+ ctx.get(FlowDownloadService).init(opts);
526
+ },
527
+ onDispose: (ctx) => {
528
+ ctx.get(FlowDownloadService).dispose();
529
+ }
530
+ });
531
+ // Annotate the CommonJS export names for ESM import in node:
532
+ 0 && (module.exports = {
533
+ FlowDownloadFormat,
534
+ FlowDownloadService,
535
+ createDownloadPlugin
536
+ });
537
+ //# sourceMappingURL=index.js.map