@anu3ev/fabric-image-editor 0.1.58 → 0.1.60
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/main.js +100 -70
- package/package.json +9 -2
package/dist/main.js
CHANGED
|
@@ -143,7 +143,7 @@ class z {
|
|
|
143
143
|
*/
|
|
144
144
|
handleCopyEvent(e) {
|
|
145
145
|
const { ctrlKey: t, metaKey: s, code: n } = e;
|
|
146
|
-
!t && !s || n !== "KeyC" || (e.preventDefault(), this.editor.clipboardManager.copy());
|
|
146
|
+
this._shouldIgnoreKeyboardEvent(e) || !t && !s || n !== "KeyC" || (e.preventDefault(), this.editor.clipboardManager.copy());
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* Обработчик вставки объекта или изображения из буфера обмена.
|
|
@@ -162,7 +162,7 @@ class z {
|
|
|
162
162
|
handleUndoRedoEvent(e) {
|
|
163
163
|
return I(this, null, function* () {
|
|
164
164
|
const { ctrlKey: t, metaKey: s, code: n, repeat: i } = e;
|
|
165
|
-
!t && !s || i || !/Mac/i.test(navigator.userAgent) && this.isUndoRedoKeyPressed || (n === "KeyZ" ? (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.undo()) : n === "KeyY" && (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.redo()));
|
|
165
|
+
this._shouldIgnoreKeyboardEvent(e) || !t && !s || i || !/Mac/i.test(navigator.userAgent) && this.isUndoRedoKeyPressed || (n === "KeyZ" ? (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.undo()) : n === "KeyY" && (e.preventDefault(), this.isUndoRedoKeyPressed = !0, yield this.editor.historyManager.redo()));
|
|
166
166
|
});
|
|
167
167
|
}
|
|
168
168
|
/**
|
|
@@ -170,8 +170,8 @@ class z {
|
|
|
170
170
|
* @param event — объект события
|
|
171
171
|
* @param event.code — код клавиши
|
|
172
172
|
*/
|
|
173
|
-
handleUndoRedoKeyUp(
|
|
174
|
-
["KeyZ", "KeyY"].includes(e) && (this.isUndoRedoKeyPressed = !1);
|
|
173
|
+
handleUndoRedoKeyUp(e) {
|
|
174
|
+
this._shouldIgnoreKeyboardEvent(e) || ["KeyZ", "KeyY"].includes(e.code) && (this.isUndoRedoKeyPressed = !1);
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
177
|
* Обработчик для выделения всех объектов (Ctrl+A).
|
|
@@ -181,16 +181,17 @@ class z {
|
|
|
181
181
|
* @param event.code — код клавиши
|
|
182
182
|
*/
|
|
183
183
|
handleSelectAllEvent(e) {
|
|
184
|
+
if (this._shouldIgnoreKeyboardEvent(e)) return;
|
|
184
185
|
const { ctrlKey: t, metaKey: s, code: n } = e;
|
|
185
186
|
!t && !s || n !== "KeyA" || (e.preventDefault(), this.editor.selectionManager.selectAll());
|
|
186
187
|
}
|
|
187
188
|
/**
|
|
188
|
-
* Обработчик для удаления объектов (Delete).
|
|
189
|
+
* Обработчик для удаления объектов (Delete или Backspace).
|
|
189
190
|
* @param event — объект события
|
|
190
191
|
* @param event.code — код клавиши
|
|
191
192
|
*/
|
|
192
193
|
handleDeleteObjectsEvent(e) {
|
|
193
|
-
e.code
|
|
194
|
+
this._shouldIgnoreKeyboardEvent(e) || e.code !== "Delete" && e.code !== "Backspace" || (e.preventDefault(), this.editor.deletionManager.deleteSelectedObjects());
|
|
194
195
|
}
|
|
195
196
|
/**
|
|
196
197
|
* Обработчик для нажатия пробела.
|
|
@@ -199,7 +200,7 @@ class z {
|
|
|
199
200
|
* @param event.code — код клавиши
|
|
200
201
|
*/
|
|
201
202
|
handleSpaceKeyDown(e) {
|
|
202
|
-
if (e.code !== "Space") return;
|
|
203
|
+
if (e.code !== "Space" || this._shouldIgnoreKeyboardEvent(e)) return;
|
|
203
204
|
const { canvas: t, editor: s, isSpacePressed: n, isDragging: i } = this;
|
|
204
205
|
n || i || (this.isSpacePressed = !0, e.preventDefault(), t.set({
|
|
205
206
|
selection: !1,
|
|
@@ -219,7 +220,7 @@ class z {
|
|
|
219
220
|
* @param event.code — код клавиши
|
|
220
221
|
*/
|
|
221
222
|
handleSpaceKeyUp(e) {
|
|
222
|
-
e.code
|
|
223
|
+
e.code !== "Space" || this._shouldIgnoreKeyboardEvent(e) || (this.isSpacePressed = !1, this.isDragging && this.handleCanvasDragEnd(), this.canvas.set({
|
|
223
224
|
defaultCursor: "default",
|
|
224
225
|
selection: !0
|
|
225
226
|
}), this.canvas.setCursor("default"), this.editor.canvasManager.getObjects().forEach((t) => {
|
|
@@ -285,6 +286,35 @@ class z {
|
|
|
285
286
|
const t = e == null ? void 0 : e.target;
|
|
286
287
|
t && this.editor.transformManager.resetObject(t);
|
|
287
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Проверяет, должно ли событие клавиатуры быть проигнорировано
|
|
291
|
+
* Возвращает true если фокус находится в поле ввода или элементе из списка игнорируемых селекторов
|
|
292
|
+
* @param event - Событие клавиатуры
|
|
293
|
+
* @returns true если событие должно быть проигнорировано
|
|
294
|
+
*/
|
|
295
|
+
_shouldIgnoreKeyboardEvent(e) {
|
|
296
|
+
const t = e.target;
|
|
297
|
+
if (!t) return !1;
|
|
298
|
+
const s = ["input", "textarea", "select"], n = t.tagName.toLowerCase();
|
|
299
|
+
if (s.includes(n) || t.contentEditable === "true") return !0;
|
|
300
|
+
const { keyboardIgnoreSelectors: i } = this.options;
|
|
301
|
+
if (i != null && i.length)
|
|
302
|
+
for (const a of i)
|
|
303
|
+
try {
|
|
304
|
+
if (t.matches && t.matches(a) || t.closest && t.closest(a))
|
|
305
|
+
return !0;
|
|
306
|
+
} catch (o) {
|
|
307
|
+
this.editor.errorManager.emitWarning({
|
|
308
|
+
origin: "Listeners",
|
|
309
|
+
method: "_shouldIgnoreKeyboardEvent",
|
|
310
|
+
code: "INVALID_SELECTOR",
|
|
311
|
+
// eslint-disable-next-line max-len
|
|
312
|
+
message: `Invalid keyboard ignore selector: "${a}". Error: ${o.message}`,
|
|
313
|
+
data: o
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return !1;
|
|
317
|
+
}
|
|
288
318
|
/**
|
|
289
319
|
* Метод для удаления всех слушателей
|
|
290
320
|
*/
|
|
@@ -378,17 +408,17 @@ class Te {
|
|
|
378
408
|
this.worker.terminate();
|
|
379
409
|
}
|
|
380
410
|
}
|
|
381
|
-
const N = 12, ke = 2, Q = 8,
|
|
411
|
+
const N = 12, ke = 2, Q = 8, $ = 20, xe = 100, J = 20, K = 8, Be = 100, q = 32, ee = 1, Ze = "#2B2D33", te = "#3D8BF4", se = "#FFFFFF";
|
|
382
412
|
function W(c, e, t, s, n) {
|
|
383
413
|
const i = N, a = ke;
|
|
384
414
|
c.save(), c.translate(e, t), c.rotate(R.degreesToRadians(n.angle)), c.fillStyle = se, c.strokeStyle = te, c.lineWidth = ee, c.beginPath(), c.roundRect(-12 / 2, -12 / 2, i, i, a), c.fill(), c.stroke(), c.restore();
|
|
385
415
|
}
|
|
386
416
|
function he(c, e, t, s, n) {
|
|
387
|
-
const i = Q, a =
|
|
417
|
+
const i = Q, a = $, o = xe;
|
|
388
418
|
c.save(), c.translate(e, t), c.rotate(R.degreesToRadians(n.angle)), c.fillStyle = se, c.strokeStyle = te, c.lineWidth = ee, c.beginPath(), c.roundRect(-8 / 2, -20 / 2, i, a, o), c.fill(), c.stroke(), c.restore();
|
|
389
419
|
}
|
|
390
420
|
function ge(c, e, t, s, n) {
|
|
391
|
-
const i =
|
|
421
|
+
const i = J, a = K, o = Be;
|
|
392
422
|
c.save(), c.translate(e, t), c.rotate(R.degreesToRadians(n.angle)), c.fillStyle = se, c.strokeStyle = te, c.lineWidth = ee, c.beginPath(), c.roundRect(-20 / 2, -8 / 2, i, a, o), c.fill(), c.stroke(), c.restore();
|
|
393
423
|
}
|
|
394
424
|
const Ue = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE4Ljc1IDQuMzc1djMuNzVhLjYyNS42MjUgMCAwIDEtLjYyNS42MjVoLTMuNzVhLjYyNS42MjUgMCAwIDEgMC0xLjI1aDIuMTRsLTIuMDc3LTEuOTAzLS4wMi0uMDE5YTYuMjUgNi4yNSAwIDEgMC0uMTMgOC45NjcuNjI2LjYyNiAwIDAgMSAuODYuOTA5QTcuNDU2IDcuNDU2IDAgMCAxIDEwIDE3LjVoLS4xMDNhNy41IDcuNSAwIDEgMSA1LjM5Ni0xMi44MTJMMTcuNSA2LjcwM1Y0LjM3NWEuNjI1LjYyNSAwIDAgMSAxLjI1IDBaIi8+PC9zdmc+", ue = new Image();
|
|
@@ -431,28 +461,28 @@ const Re = {
|
|
|
431
461
|
ml: {
|
|
432
462
|
render: he,
|
|
433
463
|
sizeX: Q,
|
|
434
|
-
sizeY:
|
|
464
|
+
sizeY: $,
|
|
435
465
|
offsetX: 0,
|
|
436
466
|
offsetY: 0
|
|
437
467
|
},
|
|
438
468
|
mr: {
|
|
439
469
|
render: he,
|
|
440
470
|
sizeX: Q,
|
|
441
|
-
sizeY:
|
|
471
|
+
sizeY: $,
|
|
442
472
|
offsetX: 0,
|
|
443
473
|
offsetY: 0
|
|
444
474
|
},
|
|
445
475
|
// Середина горизонталей
|
|
446
476
|
mt: {
|
|
447
477
|
render: ge,
|
|
448
|
-
sizeX:
|
|
478
|
+
sizeX: J,
|
|
449
479
|
sizeY: K,
|
|
450
480
|
offsetX: 0,
|
|
451
481
|
offsetY: 0
|
|
452
482
|
},
|
|
453
483
|
mb: {
|
|
454
484
|
render: ge,
|
|
455
|
-
sizeX:
|
|
485
|
+
sizeX: J,
|
|
456
486
|
sizeY: K,
|
|
457
487
|
offsetX: 0,
|
|
458
488
|
offsetY: 0
|
|
@@ -561,7 +591,9 @@ const Ye = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMj
|
|
|
561
591
|
},
|
|
562
592
|
handlers: {
|
|
563
593
|
copyPaste: (c) => I(void 0, null, function* () {
|
|
564
|
-
yield c.clipboardManager.copy(), yield c.clipboardManager.paste()
|
|
594
|
+
yield c.clipboardManager.copy(), yield c.clipboardManager.paste(), c.clipboardManager.clipboard && c.canvas.fire("editor:object-duplicated", {
|
|
595
|
+
object: c.clipboardManager.clipboard
|
|
596
|
+
});
|
|
565
597
|
}),
|
|
566
598
|
delete: (c) => {
|
|
567
599
|
c.deletionManager.deleteSelectedObjects();
|
|
@@ -700,7 +732,7 @@ class Qe {
|
|
|
700
732
|
this.el.removeEventListener("mouseover", this._onBtnOver), this.el.removeEventListener("mouseout", this._onBtnOut), this.canvas.off("mouse:down", this._onMouseDown), this.canvas.off("object:moving", this._onObjectMoving), this.canvas.off("object:scaling", this._onObjectScaling), this.canvas.off("object:rotating", this._onObjectRotating), this.canvas.off("mouse:up", this._onMouseUp), this.canvas.off("object:modified", this._onObjectModified), this.canvas.off("selection:created", this._onSelectionChange), this.canvas.off("selection:updated", this._onSelectionChange), this.canvas.off("after:render", this._onSelectionChange), this.canvas.off("selection:cleared", this._onSelectionClear), this.el.remove();
|
|
701
733
|
}
|
|
702
734
|
}
|
|
703
|
-
class
|
|
735
|
+
class $e {
|
|
704
736
|
constructor({ editor: e }) {
|
|
705
737
|
this.editor = e, this.canvas = e.canvas, this._historySuspendCount = 0, this.baseState = null, this.patches = [], this.currentIndex = 0, this.maxHistoryLength = e.options.maxHistoryLength, this.totalChangesCount = 0, this.baseStateChangesCount = 0, this._createDiffPatcher();
|
|
706
738
|
}
|
|
@@ -903,7 +935,7 @@ class Je {
|
|
|
903
935
|
});
|
|
904
936
|
}
|
|
905
937
|
}
|
|
906
|
-
const
|
|
938
|
+
const Je = 0.1, Ke = 2, qe = 0.1, et = 90, x = 16, B = 16, O = 4096, T = 4096;
|
|
907
939
|
class D {
|
|
908
940
|
constructor({ editor: e }) {
|
|
909
941
|
this.editor = e, this.options = e.options, this._createdBlobUrls = [], this.acceptContentTypes = this.editor.options.acceptContentTypes, this.acceptFormats = this.getAllowedFormatsFromContentTypes();
|
|
@@ -1728,7 +1760,7 @@ class tt {
|
|
|
1728
1760
|
}
|
|
1729
1761
|
class st {
|
|
1730
1762
|
constructor({ editor: e }) {
|
|
1731
|
-
this.editor = e, this.options = e.options, this.minZoom = this.options.minZoom ||
|
|
1763
|
+
this.editor = e, this.options = e.options, this.minZoom = this.options.minZoom || Je, this.maxZoom = this.options.maxZoom || Ke, this.defaultZoom = this.options.defaultScale, this.maxZoomFactor = this.options.maxZoomFactor;
|
|
1732
1764
|
}
|
|
1733
1765
|
/**
|
|
1734
1766
|
* Метод рассчитывает и применяет зум по умолчанию для монтажной области редактора.
|
|
@@ -2283,59 +2315,56 @@ class at {
|
|
|
2283
2315
|
* @fires editor:object-copied
|
|
2284
2316
|
*/
|
|
2285
2317
|
copy() {
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2318
|
+
return I(this, null, function* () {
|
|
2319
|
+
const { canvas: e, errorManager: t } = this.editor, s = e.getActiveObject();
|
|
2320
|
+
if (!s) return;
|
|
2321
|
+
try {
|
|
2322
|
+
const g = yield s.clone(["format"]);
|
|
2323
|
+
this.clipboard = g, e.fire("editor:object-copied", { object: g });
|
|
2324
|
+
} catch (g) {
|
|
2325
|
+
t.emitError({
|
|
2326
|
+
origin: "ClipboardManager",
|
|
2327
|
+
method: "copy",
|
|
2328
|
+
code: "CLONE_FAILED",
|
|
2329
|
+
message: "Ошибка клонирования объекта",
|
|
2330
|
+
data: g
|
|
2331
|
+
});
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
if (typeof ClipboardItem == "undefined" || !navigator.clipboard) {
|
|
2301
2335
|
t.emitWarning({
|
|
2302
2336
|
origin: "ClipboardManager",
|
|
2303
2337
|
method: "copy",
|
|
2304
|
-
code: "
|
|
2305
|
-
|
|
2306
|
-
|
|
2338
|
+
code: "CLIPBOARD_NOT_SUPPORTED",
|
|
2339
|
+
// eslint-disable-next-line max-len
|
|
2340
|
+
message: "ClipboardManager. navigator.clipboard не поддерживается в этом браузере или отсутствует соединение по HTTPS-протоколу."
|
|
2341
|
+
});
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
if (s.type !== "image") {
|
|
2345
|
+
const g = `application/image-editor:${JSON.stringify(s.toObject(["format"]))}`;
|
|
2346
|
+
navigator.clipboard.writeText(g).catch((u) => {
|
|
2347
|
+
t.emitWarning({
|
|
2348
|
+
origin: "ClipboardManager",
|
|
2349
|
+
method: "copy",
|
|
2350
|
+
code: "CLIPBOARD_WRITE_TEXT_FAILED",
|
|
2351
|
+
message: `Ошибка записи текстового объекта в буфер обмена: ${u.message}`,
|
|
2352
|
+
data: u
|
|
2353
|
+
});
|
|
2354
|
+
});
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
const i = s.toCanvasElement().toDataURL(), a = i.slice(5).split(";")[0], o = i.split(",")[1], d = atob(o), r = new Uint8Array(d.length);
|
|
2358
|
+
for (let g = 0; g < d.length; g += 1)
|
|
2359
|
+
r[g] = d.charCodeAt(g);
|
|
2360
|
+
const l = new Blob([r.buffer], { type: a }), h = new ClipboardItem({ [a]: l });
|
|
2361
|
+
navigator.clipboard.write([h]).catch((g) => {
|
|
2362
|
+
t.emitWarning({
|
|
2363
|
+
origin: "ClipboardManager",
|
|
2364
|
+
method: "copy",
|
|
2365
|
+
code: "CLIPBOARD_WRITE_IMAGE_FAILED",
|
|
2366
|
+
message: `Ошибка записи изображения в буфер обмена: ${g.message}`
|
|
2307
2367
|
});
|
|
2308
|
-
}), this._cloneAndFire(e, s);
|
|
2309
|
-
return;
|
|
2310
|
-
}
|
|
2311
|
-
const i = s.toCanvasElement().toDataURL(), a = i.slice(5).split(";")[0], o = i.split(",")[1], d = atob(o), r = new Uint8Array(d.length);
|
|
2312
|
-
for (let g = 0; g < d.length; g += 1)
|
|
2313
|
-
r[g] = d.charCodeAt(g);
|
|
2314
|
-
const l = new Blob([r.buffer], { type: a }), h = new ClipboardItem({ [a]: l });
|
|
2315
|
-
navigator.clipboard.write([h]).catch((g) => {
|
|
2316
|
-
t.emitWarning({
|
|
2317
|
-
origin: "ClipboardManager",
|
|
2318
|
-
method: "copy",
|
|
2319
|
-
code: "CLIPBOARD_WRITE_IMAGE_FAILED",
|
|
2320
|
-
message: `Ошибка записи изображения в буфер обмена: ${g.message}`
|
|
2321
|
-
});
|
|
2322
|
-
}), this._cloneAndFire(e, s);
|
|
2323
|
-
}
|
|
2324
|
-
/**
|
|
2325
|
-
* Клонирует объект и вызывает событие 'editor:object-copied'.
|
|
2326
|
-
* @param canvas - экземпляр canvas
|
|
2327
|
-
* @param object - активный объект
|
|
2328
|
-
*/
|
|
2329
|
-
_cloneAndFire(e, t) {
|
|
2330
|
-
t.clone(["format"]).then((s) => {
|
|
2331
|
-
this.clipboard = s, e.fire("editor:object-copied", { object: s });
|
|
2332
|
-
}).catch((s) => {
|
|
2333
|
-
this.editor.errorManager.emitError({
|
|
2334
|
-
origin: "ClipboardManager",
|
|
2335
|
-
method: "_cloneAndFire",
|
|
2336
|
-
code: "CLONE_FAILED",
|
|
2337
|
-
message: "Ошибка клонирования объекта",
|
|
2338
|
-
data: s
|
|
2339
2368
|
});
|
|
2340
2369
|
});
|
|
2341
2370
|
}
|
|
@@ -2720,7 +2749,7 @@ class ne {
|
|
|
2720
2749
|
scaleType: r,
|
|
2721
2750
|
_onReadyCallback: l
|
|
2722
2751
|
} = this.options;
|
|
2723
|
-
if (He.apply(), this.canvas = new Ce(this.containerId, this.options), this.moduleLoader = new Ee(), this.workerManager = new Te(), this.errorManager = new V({ editor: this }), this.historyManager = new
|
|
2752
|
+
if (He.apply(), this.canvas = new Ce(this.containerId, this.options), this.moduleLoader = new Ee(), this.workerManager = new Te(), this.errorManager = new V({ editor: this }), this.historyManager = new $e({ editor: this }), this.toolbar = new Qe({ editor: this }), this.transformManager = new st({ editor: this }), this.canvasManager = new tt({ editor: this }), this.imageManager = new D({ editor: this }), this.layerManager = new P({ editor: this }), this.shapeManager = new it({ editor: this }), this.interactionBlocker = new nt({ editor: this }), this.clipboardManager = new at({ editor: this }), this.objectLockManager = new F({ editor: this }), this.groupingManager = new ot({ editor: this }), this.selectionManager = new rt({ editor: this }), this.deletionManager = new ct({ editor: this }), this._createMontageArea(), this._createClippingArea(), this.listeners = new z({ editor: this, options: this.options }), this.canvasManager.setEditorContainerWidth(e), this.canvasManager.setEditorContainerHeight(t), this.canvasManager.setCanvasWrapperWidth(s), this.canvasManager.setCanvasWrapperHeight(n), this.canvasManager.setCanvasCSSWidth(i), this.canvasManager.setCanvasCSSHeight(a), o != null && o.source) {
|
|
2724
2753
|
const {
|
|
2725
2754
|
source: h,
|
|
2726
2755
|
scale: g = `image-${r}`,
|
|
@@ -2885,7 +2914,8 @@ const lt = {
|
|
|
2885
2914
|
undoRedoByHotKeys: !0,
|
|
2886
2915
|
selectAllByHotkey: !0,
|
|
2887
2916
|
deleteObjectsByHotkey: !0,
|
|
2888
|
-
resetObjectFitByDoubleClick: !0
|
|
2917
|
+
resetObjectFitByDoubleClick: !0,
|
|
2918
|
+
keyboardIgnoreSelectors: []
|
|
2889
2919
|
};
|
|
2890
2920
|
function bt(c, e = {}) {
|
|
2891
2921
|
const t = y(y({}, lt), e), s = document.getElementById(c);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anu3ev/fabric-image-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.60",
|
|
4
4
|
"description": "JavaScript image editor built on FabricJS, allowing you to create instances with an integrated montage area and providing an API to modify and manage state.",
|
|
5
5
|
"module": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -14,12 +14,15 @@
|
|
|
14
14
|
"build": "vite build --config vite.config.prod.js",
|
|
15
15
|
"build:docs": "vite build --config vite.config.docs.js",
|
|
16
16
|
"preview": "vite preview",
|
|
17
|
-
"lint": "eslint \"src/**/*.{js,ts}\""
|
|
17
|
+
"lint": "eslint \"src/**/*.{js,ts}\"",
|
|
18
|
+
"test": "jest --coverage",
|
|
19
|
+
"test:watch": "jest --watch"
|
|
18
20
|
},
|
|
19
21
|
"devDependencies": {
|
|
20
22
|
"@babel/core": "^7.26.7",
|
|
21
23
|
"@babel/preset-env": "^7.26.7",
|
|
22
24
|
"@eslint/js": "^9.16.0",
|
|
25
|
+
"@types/jest": "^30.0.0",
|
|
23
26
|
"@typescript-eslint/eslint-plugin": "^8.36.0",
|
|
24
27
|
"@typescript-eslint/parser": "^8.36.0",
|
|
25
28
|
"eslint": "^8.57.1",
|
|
@@ -31,7 +34,11 @@
|
|
|
31
34
|
"eslint-plugin-sort-keys-fix": "^1.1.2",
|
|
32
35
|
"eslint-plugin-vue": "^9.32.0",
|
|
33
36
|
"globals": "^15.13.0",
|
|
37
|
+
"jest": "^29.7.0",
|
|
38
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
34
39
|
"prettier": "^3.4.2",
|
|
40
|
+
"ts-jest": "^29.4.1",
|
|
41
|
+
"ts-node": "^10.9.2",
|
|
35
42
|
"vite": "^6.3.5",
|
|
36
43
|
"vite-bundle-analyzer": "^0.21.0",
|
|
37
44
|
"vite-plugin-babel": "^1.3.0",
|